程序编译但终止执行。为什么?

时间:2011-07-12 14:50:01

标签: c gcc

int main() {  
    char first,second,third,fourth,fifth;  
    scanf("%c %c %c %c %c",first,second,third,fourth,fifth);  
    printf("%c%c%c%c%c",first,second,third,fourth,fifth);  
    getch();  
    return 0;  
}

上述程序编译时没有任何错误(GNU GCC),但执行时最小化“当前窗口”并再次终止而没有任何错误。为什么呢?

更新

int main() {
    char first,second,third,fourth,fifth;
    scanf("%c %c %c %c %c",&first,&second,&third,&fourth,&fifth);
    printf("%c%c%c%c%c",first,second,third,fourth,fifth);
    getch();
    return 0;
}

以上代码是在收到答案后更改的,但行为方式仍然相同,只是编译器确实抛出了任何错误甚至是警告。

3 个答案:

答案 0 :(得分:2)

因为您将未初始化的值作为指针传递给scanf。尝试

scanf("%c %c %c %c %c", &first, &second, &third, &fourth, &fifth);

答案 1 :(得分:2)

使用scanf时,必须在每个变量前面添加一个Ampersand符号,因为你必须传入指向非指针变量的指针,而不仅仅是一个变量本身,如下所示:

scanf("%c %c %c %c %c",&first,&second,&third,&fourth,&fifth);

答案 2 :(得分:2)

快速解决方案。

因为您将char变量传递给scanf而不是指针。

scanf("%c %c %c %c %c", &first, &second, &third, &fourth, &fifth);

经验法则。

icemanind提到“当使用scanf时,你必须用Ampersand为每个变量加上前缀”,但这太宽泛了。如果你严格遵循该规则,你可能会传递指针指向-...相反,根据经验,你必须

  • 将要写入的变量的地址传递到

  • 目标的类型必须与格式标记的规范完全匹配

关于后者:例如,如果您传递%d格式令牌的双指针,则会被搞砸。

预防。

如果您使用过编译器警告,在您的特定情况下-Wformat,但在一般情况下只使用-Wall(最好也是-Wextra),编译器会警告您:

gcc -Wall -Wextra foo.c

warning.cc: In function `int main()':
warning.cc:4: warning: format argument is not a pointer (arg 2)
warning.cc:4: warning: format argument is not a pointer (arg 3)
warning.cc:4: warning: format argument is not a pointer (arg 4)
warning.cc:4: warning: format argument is not a pointer (arg 5)
warning.cc:4: warning: format argument is not a pointer (arg 6)

对于好奇:此警告基于一个针对格式字符串的编译器扩展(请参阅gcc的list of attributes

  

format属性指定函数采用printf,scanf,strftime或strfmon样式参数,这些参数应根据格式字符串进行类型检查。例如,声明:

      extern int
      my_printf (void *my_object, const char *my_format, ...)
            __attribute__ ((format (printf, 2, 3)));