C 不确定是什么';这段代码是怎么回事

C 不确定是什么';这段代码是怎么回事,c,error-handling,compiler-errors,warnings,C,Error Handling,Compiler Errors,Warnings,我有一些C代码,我不太确定到底发生了什么 #include <stdio.h> #include <stdlib.h> #define DIM1 7 #define DIM2 5 #define RES_SIZE 1000 typedef double stackElementT; typedef struct { stackElementT *contents; int maxSize; int top; int min2; } stackT; v

我有一些C代码,我不太确定到底发生了什么

#include <stdio.h>
#include <stdlib.h>
#define DIM1 7
#define DIM2 5
#define RES_SIZE 1000

typedef double stackElementT;

typedef struct {
  stackElementT *contents;
  int maxSize;
  int top;
  int min2;
} stackT;

void StackInit(stackT *stackP, int maxSize) {
    stackElementT *newContents;
    newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize);
    if (newContents == NULL) {
        fprintf(stderr, "Not enough memory.\n");
        exit(1);
    }

    stackP->contents = newContents;
    stackP->maxSize = maxSize;
    stackP->top = -1;
}

void StackDestroy(stackT *stackP) {
    free(stackP->contents);
    stackP->contents = NULL;
    stackP->maxSize = 0;
    stackP->top = -1;
}

int StackIsEmpty(stackT *stackP) { return stackP->top < 0; }

int StackIsFull(stackT *stackP) { return stackP->top >= stackP->maxSize-1; }

void StackPush(stackT *stackP, stackElementT element) {
    if(StackIsFull(stackP)) {
        fprintf(stderr, "Can't push element: stack is full.\n");
        exit(1);
    }
    stackP->contents[++stackP->top] = element;
}

stackElementT StackPop(stackT *stackP) {
    if(StackIsEmpty(stackP)) {
        fprintf(stderr, "Can't pop element: stack is empty.\n");
        exit(1);
    }
    return stackP->contents[stackP->top--];
}
int shell(char* s1, int arg) {
    printf(">   ");
    scanf("%s %d%*c", &s1, &arg);
    return arg;
}

int main() {
    char cmds[DIM1][DIM2] = {{"push"}, {"pop"}, {"add"}, {"ifeq"}, {"jump"}, {"print"}, {"dup"}};
    char* s1; int arg;
    arg = shell(s1, arg);
    printf("%s\n", &s1);
}

有人能解释一下吗?

当您使用
%s
格式说明符时,它需要一个指向字符串开头的指针值。在C语言中,这种类型是
char*

使用
main
函数,变量
s1
的类型为
char*
。因此,
s1
printf
的有效参数,因此此行有效:

printf("%s\n", s1);
注意
s1
前面没有
。在您的代码中,您使用了
&
,它的地址为
s1
,其结果将是
char**
类型。这是错误的类型,因此不要使用
&

问题是,
printf
实际上无法判断它的参数是什么类型,因为它是一个可变函数。它只是根据格式字符串中指定的类型,使用存在的任何参数

同样的事情也适用于scanf
,但是有一个陷阱:必须确保为用户输入分配足够的内存,否则会出现缓冲区溢出,导致无法预测的结果。除此之外,
printf
scanf
是完全互补的

总之,除了未使用的
cmds
变量(在提供的代码中不需要该变量)之外,这还会处理编译器警告。另外,
args
——它实际上应该是在
shell
中声明的变量,而不是作为参数传递,因为它的值在
shell
中甚至没有使用


不知道剩下的代码是怎么回事。考虑到您的
main
函数只调用
shell

是多余的,当您使用
%s
格式说明符时,它需要一个指向字符串开头的指针值。在C语言中,这种类型是
char*

使用
main
函数,变量
s1
的类型为
char*
。因此,
s1
printf
的有效参数,因此此行有效:

printf("%s\n", s1);
注意
s1
前面没有
。在您的代码中,您使用了
&
,它的地址为
s1
,其结果将是
char**
类型。这是错误的类型,因此不要使用
&

问题是,
printf
实际上无法判断它的参数是什么类型,因为它是一个可变函数。它只是根据格式字符串中指定的类型,使用存在的任何参数

同样的事情也适用于scanf
,但是有一个陷阱:必须确保为用户输入分配足够的内存,否则会出现缓冲区溢出,导致无法预测的结果。除此之外,
printf
scanf
是完全互补的

总之,除了未使用的
cmds
变量(在提供的代码中不需要该变量)之外,这还会处理编译器警告。另外,
args
——它实际上应该是在
shell
中声明的变量,而不是作为参数传递,因为它的值在
shell
中甚至没有使用



不知道剩下的代码是怎么回事。考虑到您的
main
函数只调用
shell

是多余的。它上面有一个小堆栈实现,但我想没有人想查看它。谢谢,正在处理它……这段代码有没有意图,或者您只是问执行时的逻辑流是什么?因为我没有看到在main()中调用的堆栈代码中的任何内容,所以只需要扫描和打印…完全正确。只是@jcomeau_ictx似乎希望所有的代码都在那里。堆栈实现是不相关的。@tekknolagi:我只想说,很高兴你尝试了所要求的。下次请记住,最好让编译器的错误和警告与代码示例相匹配,这样整个问题就统一了。顺便说一句,我个人喜欢这个问题是你最后一个问题的后续问题。希望其余的实施进展顺利!不。上面有一个小堆栈实现,但我想没人想看它。谢谢,正在研究它……这段代码有什么意图,或者你只是问执行时的逻辑流是什么?因为我没有看到在main()中调用的堆栈代码中的任何内容,所以只需要扫描和打印…完全正确。只是@jcomeau_ictx似乎希望所有的代码都在那里。堆栈实现是不相关的。@tekknolagi:我只想说,很高兴你尝试了所要求的。下次请记住,最好让编译器的错误和警告与代码示例相匹配,这样整个问题就统一了。顺便说一句,我个人喜欢这个问题是你最后一个问题的后续问题。希望其余的实施进展顺利!谢谢你的提示。然而,当我删除了符号(
&
)时,我在运行时得到了一个segfault,输入相同。正如我提到的,您必须自己分配一个
char*
缓冲区,即声明
s1
类似于
char*s1=(char*)malloc(50)。这为您提供了50个字符的输入空间。或者,只需使用一个数组:
chars1[50]。无论哪种方式,只要记住,无论何时需要输入,都必须确保有足够的缓冲区来存储输入。这是因为您尚未初始化指向保留内存的指针以存储文本-事实上,您甚至没有保留此类内存。您不能仅删除&。问题是s1未初始化。我认为您试图使s1指向从shell()中调用scanf()获得的用户输入。但是,您尚未分配任何资源