我有一些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);
}
输入:push 4
。它会打印J+
而不是“推送”,但会正常打印4
。
它还在编译时提供了这些警告:
stack.c: In function ‘shell’:
stack.c:60: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
stack.c: In function ‘main’:
stack.c:71: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
stack.c:65: warning: unused variable ‘cmds’
stack.c:69: warning: ‘arg’ is used uninitialized in this function
有人可以解释一下吗?
答案 0 :(得分:3)
当您使用%s
格式说明符时,它期望一个值是指向字符串开头的指针。在C中,此类型为char *
。
使用main
功能,变量s1
的类型为char *
。因此,s1
是printf
的有效参数,因此该行有效:
printf("%s\n", s1);
请注意&
前s1
的缺席。在您的代码中,您使用&
,其中s1
的地址为char **
,其结果为&
。这是错误的类型,因此不使用printf
。
问题是,scanf
实际上不能告诉它的参数是什么类型,因为它是一个可变函数。根据格式字符串中指定的类型,它只使用那里的任何参数。
同样适用于printf
,但存在一个缺陷:您必须确保分配足够的内存来考虑用户输入,否则您将遇到缓冲区溢出,导致无法预测的结果。除此之外,scanf
和cmds
完全互补。
Anyhoo,除了未使用的args
变量之外,它还会处理编译器警告(在提供的代码中没有必要)。此外,还有shell
的一部分 - 它实际上应该是在shell
内声明的变量,并且不作为参数传递,因为它的值甚至不在main
内使用。 / p>
不知道其余代码是什么。考虑到shell
函数只调用{{1}},这是多余的。