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

问题描述 投票:-2回答:4

这里的代码给出了不正确的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;
    }
c printf scanf
4个回答
2
投票

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

引用C11,章节§7.21.6.2

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

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

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

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

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

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

所以使用

 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


0
投票

尝试添加\n,如scanf("%d\n", &num);。也许它会有所帮助。如果使用该表达式,编译器无法通过,如scanf("%d", &ch);

© www.soinside.com 2019 - 2024. All rights reserved.