【问题标题】:Why does changing the order of variable definitions change the functioning of code为什么改变变量定义的顺序会改变代码的功能
【发布时间】:2017-12-09 11:51:10
【问题描述】:

Dev-c++有两段代码,第一段正常,另一段不行,为什么??

/* this code is working properly*/

#include<stdio.h>  
int main()
{  
    char op;    // this is the point 
    int a,b,c;  // where another code differs
    printf("Enter the two no.s:");
    scanf("%d %d",&a,&b);
    printf("Enter the operation(+/-/*//):");
    scanf("%s",&op);
    switch(op)
    { 
     case '+': c=a+b;
               printf("%d",c);
               break;

     case '-': c=a-b;
               printf("%d",c);
               break;  

     case '*': c=a*b;
               printf("%d",c);
               break;  

     case '/': c=a/b;
               printf("%d",c);
               break;  

     default: printf("Invalid Operation");
     }
}

/* this code is not working properly; only altered the declaration sequence of int and char*/

#include<stdio.h> 
int main()
{  
     int a,b,c;   
     char op;
     printf("Enter the a:");
     scanf("%d %d",&a,&b);
     printf("Enter the operation(+/-/*//):");
     scanf("%s",&op);
     switch(op)
     { 
     case '+' : c=a+b;
               printf("%d",c);
               break;

     case '-' : c=a-b;
               printf("%d",c);
               break;  

     case '*' : c=a*b;
               printf("%d",c);
               break;  

     case '/' : c=a/b;
               printf("%d",c);
               break;  

     default: printf("Invalid Operation");
     }
}

【问题讨论】:

  • scanf("%s",&amp;op); -> op 是一个单一的char,但您正在尝试读取字符串 -> 未定义的行为
  • 无论如何 - scanf("%s",&amp;op) 是 UB,因为 opchar。两个 sn-ps 都坏了。
  • 替换 %s-->%c
  • 这是一个很好的例子,为什么它被称为“未定义的行为”而不是错误或崩溃或其他任何东西。环境(因此是随机的)上下文影响程序的行为方式。如您所见,这可能从“似乎表现正确”(一个极端)到崩溃(另一个极端)。介于两者之间的是更可怕的事情:“大多数时候行为正确”(偶尔出现的错误通常出现在客户端,但从未出现在调试器中)。原因已经被指出了两次:不幸的是(通常)C 编译器没有检测到 scanf() 的错误用法。
  • scanf("%s",&amp;op); -> scanf(" %s",&amp;op);。注意%c前面的空格。

标签: c dev-c++


【解决方案1】:

这是你的问题:

scanf("%s",&op);

%s 格式说明符需要一个指向可以存储字符串的数组的第一个字符的指针。你传入的是单个字符的地址。

因此,当您输入诸如+ 之类的符号时,它会被写入op,但随后会向op 之后的任何内存写入空字节以完成字符串。通过写入您不应该写入的内存,这会调用undefined behavior

对于未定义的行为,任何事情都可能发生。您的程序可能会崩溃,它可能会显示意外的结果,或者它可能看起来工作正常。此外,进行看似无关的更改,例如添加 printf 以进行调试或(如您的情况)更改变量的顺序可能会改变未定义行为的表现方式。

要读取单个字符,您需要使用%c 格式说明符。您还需要在格式字符串之前添加一个空格以消耗空格,即来自先前scanf 调用的换行符。这是必需的,因为 %c 本身不会跳过空格,这与 %d%s 等其他格式说明符不同。

scanf(" %c",&op);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-07
    • 2017-08-18
    • 2018-06-13
    • 2016-06-20
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多