首页 文章

为什么printf与%d说明符给出错误的结果?

提问于
浏览
-1

这里的代码给出了不正确的int num值,如果我输入的num是例如11,则printf函数将输出0.但是如果我将static添加到int num,则printf生成的输出是正确的 . 有人可以解释原因 . 如果我将第二个scanf的格式说明符设为%c,那么也可以正确打印int值 .

#include<stdio.h>
    int main()
     {
      int num;//making it static gives correct result
      char ch;int c;
      printf("enter the value of num and ch:\n");
      scanf("%d",&num);    
      scanf("%d",&ch);
      printf("num = %d and ch = %c",num,ch);
      return 0;
    }

3 回答

  • 2

    它不是专门针对 printf() ,问题是由对 scanf() 的错误调用引起的 .

    引用 C11 ,章节§7.21.6.2

    [...]除非通过*指示赋值抑制,否则转换的结果将放在由尚未收到转换结果的format参数后面的第一个参数指向的对象中 . 如果此对象没有适当的类型,或者无法在对象中表示转换结果,则行为未定义 .

    对于 %d 转换说明符,预期的参数类型是

    d [....]相应的参数应该是指向有符号整数的指针 .

    但是,你所提供的只是一个指向 char 的指针 . 不匹配 . Undefined behavior .

    OTOH,用于 %c 转换说明符,

    c匹配字段宽度指定的字符序列(如果指令中没有字段宽度,则为1) . 如果不存在l length修饰符,则相应的参数应该是指向足以接受序列的字符数组的初始元素的指针 . 没有添加空字符 .

    所以使用

    scanf("%c",&ch);
    

    是正确的 . 或者,您也可以使用

    scanf("%hhd",&ch);    //char is signed
     scanf("%hhu",&ch);   //char is unsigned
    
  • 2

    这个

    char ch;
    scanf("%d", &ch);
    

    将调用 Undefined Behavior ,因为您使用的是整数格式,以将其存储在字符中 .

  • 1

    您观察到的很可能是因为第二个 scanf 错误( char 工具大)格式说明符会覆盖 num 所在的自动变量内存 .

    使 num 静态将其移动到全局变量内存并且它(种类)有效,但它仍然是未定义的行为,某些内存已被覆盖某处,您可能稍后付出代价 . 因此,唯一的选择是指定正确的格式说明符,如您所述 %c .

相关问题