【问题标题】:not sure what's going on in this code不知道这段代码发生了什么
【发布时间】:2011-08-01 04:13:56
【问题描述】:

我有一些 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

谁能解释一下?

【问题讨论】:

  • 没有。它上面有一个小的堆栈实现,但我想没有人想看它。
  • 谢谢,正在努力……
  • 这段代码是否有意图,或者您只是在问执行时的逻辑流程是什么?因为我没有看到 main() 中调用的堆栈代码中的任何内容,只是扫描和打印...
  • 没错。只是@jcomeau_ictx 似乎想要那里的所有代码。堆栈实现无关紧要。
  • @tekknolagi:我只想说,很高兴您尝试按照要求进行操作。下次尽量记住,最好让你的编译器错误和警告与代码示例相匹配,以便整个问题统一。在旁注中,我个人喜欢这个问题如何跟进你的最后一个问题。希望其余的实施顺利!

标签: c error-handling compiler-errors warnings


【解决方案1】:

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

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

printf("%s\n", s1);

注意s1 前面的&amp;缺席。在您的代码中,您使用了&amp;,它采用s1 的地址,其结果将是char ** 类型。这是错误类型,所以不要使用&amp;

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

scanf 也是如此,但有一个陷阱:您必须确保分配了足够的内存来处理用户输入,否则您将遇到缓冲区溢出并导致无法预料的结果。除此之外,printfscanf 是完美互补的。

无论如何,这会处理编译器警告,除了未使用的cmds 变量(在提供的代码中是不必要的)。此外,还有args 的部分——它确实应该是在shell 内部声明的变量,而不是作为参数传递,因为它的值甚至没有在shell 内部使用。

不知道其余的代码是怎么回事。考虑到您的 main 函数仅调用 shell,这是多余的。

【讨论】:

  • 感谢您的提示。但是,当我删除 & 符号 (&amp;) 时,我在运行时遇到了段错误,输入相同。
  • 就像我提到的,你必须分配一个char *缓冲区你自己,即,声明s1类似于char *s1 = (char*)malloc(50);。这为您提供了 50 个输入字符的空间。或者,只需使用一个数组:char s1[50];。无论哪种方式,只要记住,每当您需要输入时,您必须确保有足够的缓冲区来存储输入。
  • 那是因为你没有初始化指向保留内存来存储文本的指针——事实上你甚至没有保留这样的内存。
  • 你不能只删除 &。问题是 s1 未初始化。我认为您正在尝试使 s1 指向通过调用 shell() 中的 scanf() 获得的用户输入。但是,您没有分配任何空间来保存用户输入。尝试使 s1 成为数组而不是指针。此外,您必须更改 shell() 以接受指向数组的指针,该指针将是 char**,而不是 char *。要记住的是,在 C 中,所有参数都是按值传递的。传递指针时,指针值被复制,但调用者中指针的值保持不变。
  • @Sean:回应你最后的说法:是的,指针值被复制了,但是指向的数据没有被复制。 shell 函数中的指针参数和main 函数中的指针将指向同一个内存,因此shell 中的任何修改都可以从main 中看到。因此,将shell 更改为接受char ** 参数是不必要的,除非他计划为shell 内部的缓冲区分配内存。
猜你喜欢
  • 2019-11-27
  • 2013-03-15
  • 2023-02-24
  • 2016-06-09
  • 2018-07-28
  • 1970-01-01
  • 1970-01-01
  • 2012-08-29
相关资源
最近更新 更多