为什么scanf中需要%hd?
我创建了一个非常简单的程序,其中包含一个值,然后将其记忆到局部变量值,最后使用第二个选项,程序打印该值。
我的问题是:为什么只有在scanf参数中添加“h”时程序才能工作? 换句话说:scanf()和我的本地int值变量之间有什么样的关系?
谢谢!
pS(我用Dev-C ++(GCC)编译它。用Visual Studio工作)
#include main () { int value = 0; short choice = 0; do { printf("\nYour Choice ---> "); scanf("%d", &choice); /* replace with "%hd" and it works */ switch (choice) { case 1: printf("\nEnter a volue to store "); scanf("%d", &value); getchar(); printf("\nValue: %d", value); break; case 2: printf("\nValue: %d", value); break; } } while (choice < 3); getchar(); }
使用scanf
,“h”修饰符表示它正在读取一个短整数,这是您的变量choice
恰好。 所以“%hd”只需要写两个字节(在大多数机器上)而不是“%d”写入的4个字节。
有关详细信息,请参阅scanf上的此参考页面
变量choice
类型为short
,这就是为什么你需要scanf中的%h
说明符读入它(实际上你不需要这里的d
)。 int
类型只需要%d
。 请在此处查看有关转化的说明
你正在读短片。 h是必要的,因为默认情况下%d是int的大小。 请参阅scanf上的此参考页面 。
看起来你的问题是choice
是一个short
,通常是2个字节长,而%d
期望一个整数,通常是4个字节长…所以scanf
破坏了堆栈上choice
后的任何东西。
choice
是short
,%d指定int
。
当您指定%d时,scanf必须假定关联的参数是指向int
大小的内存块的指针,并将为其写入一个int
。 当发生这种情况时,它可能会写入相邻但不是choice
一部分的数据,结果是不确定的,可能不是很好! 如果它在一个编译器中工作而不是另一个编译器只是未定义行为的本质!
在GCC -Wformat中,当你犯这个错误时应该给你一个警告。
来自comp.lang.c FAQ:
- 为什么代码没有
short int s; scanf("%d", &s);
short int s; scanf("%d", &s);
工作? - 有人告诉我,将
%lf
与printf
一起使用是错误的。 如果scanf
需要%lf
,printf
如何使用%f
作为double
类型?
%d
用于读取int
,而不是short。 你的代码从未真正“起作用” – 只是看起来在这种情况下你没有注意到你想要的和你所获得的未定义行为之间的任何差异。
scanf用于输入short类型变量的修饰符是%hd。 因此,您需要指定正确的修饰符。
scanf("%d",&integer); // For integer type scanf("%hd",&short_int); // For short type
因此它不起作用。
根据数字填充,字节序和其他此类问题,您可能将输入值的上部或下部存储到选项中; 您将其余的输入值存储到可能用于或不用于其他任何内容的内存中。