为什么scanf中需要%hd?

时间:2010-07-15 16:25:40

标签: c

我用菜单创建了一个非常简单的程序, 取一个值,然后记住它 局部变量值,最后用 第二个选项,程序打印值。

我的问题是: 为什么程序只有在我添加“h”时才能工作 到scanf参数? 换句话说:有什么样的关系 scanf()和我的本地int值变量之间?

谢谢!

P.S。 (我用Dev-C ++(GCC)编译它。 使用Visual Studio,它可以工作)

#include <stdio.h>

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();
}

9 个答案:

答案 0 :(得分:11)

使用scanf时,“h”修饰符表示它正在读取一个短整数,您的变量恰好是choice。所以“%hd”只需要写两个字节(在大多数机器上)而不是“%d”写入的4个字节。

有关详细信息,请参阅此reference page on scanf

答案 1 :(得分:2)

变量choice的类型为short,因此您需要在scanf中使用%h说明符来读取它(实际上您不需要d这里)。 int类型只需要%d。请参阅有关转化的说明here

答案 2 :(得分:1)

你正在读短片。 h是必需的,因为默认情况下%d是int的大小。请参阅此reference page on scanf

答案 3 :(得分:1)

看起来您的问题是choiceshort,(通常)是2个字节长,而%d需要一个整数,通常是4个字节长......所以scanf任何东西都会出现在堆栈上的choice之后。

答案 4 :(得分:1)

choiceshort,%d指定int

当您指定%d时,scanf必须假定关联的参数是指向int大小的内存块的指针,并且会向其写入int。当发生这种情况时,可能会写入choice附近但不属于{{1}}的数据,结果未定义,可能不太好!如果它在一个编译器中工作而不是另一个编译器只是 undefined 行为的本质!

在GCC -Wformat中,当你犯这个错误时应该给你一个警告。

答案 5 :(得分:1)

答案 6 :(得分:0)

%d用于阅读int,而不是短片。你的代码从来没有真正“起作用” - 在这种情况下你似乎没有注意到你想要的东西和你得到的未定义的行为之间的任何差异。

答案 7 :(得分:0)

scanf用于输入short类型变量的修饰符是%hd。因此,您需要指定正确的修饰符。

scanf("%d",&integer);  // For integer type
scanf("%hd",&short_int); // For short type

因此它不起作用。

答案 8 :(得分:0)

根据数字填充,字节序和其他此类问题,您可能将输入值的上部或下部存储到选项中;您将其余的输入值存储到可能用于或不用于其他任何内容的内存中。