1

当我输入“A”时,下面的代码输出(我的编辑器 Visual Studio Express 2012),

65 65 65

但是在 Deitel C How to Program output 中给出的这个例子是不同的,例如:

一个 -13247 -858993599 -858993599

为什么?

#include <stdio.h>

union dummy {
  char c;
  short s;
  int i;
  long l;
} a;


int main(void) {

    printf("Enter a character\n");
    scanf("%c", &a.c);

    printf("%c printed as a char is %c.\n", a.c, a.c);
    printf("%c printed as a short is %hd.\n", a.c, a.s);
    printf("%c printed as an int is %d.\n", a.c, a.i);
    printf("%c printed as a long is %ld.\n", a.c, a.l);

    getch();
    return 0;
}
4

1 回答 1

3

编译器的行为似乎不同,并且两个示例都在具有不同字节顺序的不同机器上运行。

MSVC 正在用零初始化 a。然后你只覆盖c,其余的仍然为零。由于硬件字节序,c 存储在 s 的低字节,这也是 i 和 l 的低字节。所以 MSVC 输出 A 65 65 65 ('A'==65==0x41)。

Deitel C How to Program中使用的编译器将a初始化为0xcccccccc,并且只覆盖ac的内存,因为字节序不同,c是s的高字节,即i和l的高字节。如果将值打印为十六进制,您可以看到:A cc41 cccccc41 cccccccc41.

不同初始化的原因可能是,某些编译器将变量初始化为定义的模式(此处为 0xcc),以便您可以轻松检测是否正在访问未初始化的变量或内存块。通常只有在调试模式下编译程序时才会这样做。在这种情况下,有时 malloc 和 free 也会发生变化,这样不仅 malloc 将内存初始化为定义的模式,而且 free 在实际释放内存之前会覆盖内存。因此,如果您保留一个悬空指针并访问已释放的内存,您可以从内容中轻松看到您正在访问已释放的内存。

于 2013-10-31T08:37:58.583 回答