为什么scanf("%hhu",char*)在本地时会覆盖其他变量?

Dan*_*tro 4 c gcc gcc4.7

标题说明了一切.我正在使用GCC 4.7.1(与CodeBlocks捆绑在一起),我遇到了一个奇怪的问题.考虑一下:

int main() {
    unsigned char a = 0, b = 0, c = 0;
    scanf("%hhu", &a);
    printf("a = %hhu, b = %hhu, c = %hhu\n", a, b, c);
    scanf("%hhu", &b);
    printf("a = %hhu, b = %hhu, c = %hhu\n", a, b, c);
    scanf("%hhu", &c);
    printf("a = %hhu, b = %hhu, c = %hhu\n", a, b, c);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于输入1,2和3,此输出

a = 1, b = 0, c = 0
a = 0, b = 2, c = 0
a = 0, b = 0, c = 3
Run Code Online (Sandbox Code Playgroud)

但是,如果我将a,b和c声明为全局变量,它将按预期工作.为什么会这样?

先感谢您

其他详情:

我正在运行Windows 8 64位.我也试过-std = c99,问题仍然存在.

进一步的研究

测试此代码

void printArray(unsigned char *a, int n) {
    while(n--)
        printf("%hhu ", *(a++));
    printf("\n");
}

int main() {
    unsigned char array[8];
    memset(array, 255, 8);
    printArray(array, 8);
    scanf("%hhu", array);
    printArray(array, 8);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

表明scanf将"%hhu"解释为"%u".它直接忽略了"hh".输入1的代码输出是:

255 255 255 255 255 255 255 255
1 0 0 0 255 255 255 255
Run Code Online (Sandbox Code Playgroud)

R..*_*R.. 9

重要的细节是您正在使用Windows,并且可能是过时的或不符合要求的C环境(编译器和标准库).MSVCRT只支持C89(即便如此,也不完全正确); 特别是,C89中没有"hh"修饰符,它可能将"hh"解释为"h"(即short).

  • 这是标准库比编译器更多的问题.如果OP的gcc正在使用MSVCRT(如果它是"mingw"就是这种情况)那么这肯定是个问题.如果你想在Windows上做现代C,目前唯一可行的选择是Cygwin. (4认同)
  • @DanielCastro:提供你的`scanf()`的Microsoft C标准库只支持C89,它不包含`hh`修饰符. (2认同)
  • 只是为了澄清。我想我之前的一些测试是错误的。将 %hu 与 unsigned char* 一起使用,尽管 UB 会按预期覆盖两个字节。MSVCRT 将 %hhu 解释为 %u。 (2认同)