联合中的char数组如何工作?

时间:2015-10-02 09:01:43

标签: c

static int i = 2;
union U {
  int a, b;
  char c[3];
}u;


 int main(){
   u.b = 0x6;
   for(;i; u.b++)
    u.b = u.a << i--;
  printf("%d %o %s", u.a, u.b, u.c);
 return 0;
}

这段代码给出了字符数组的输出为3.现在我知道这段代码特别是当我存储到一个变量并访问其他一些变量时,会产生几个Undefined Behaviour,但仅仅是为了实验的目的,任何人都可以向我解释为什么u.c的值为3

注意:内部存储器结构更好理解

3 个答案:

答案 0 :(得分:1)

在for循环之后,union u包含位:

0x00000033
分成字符的

0x33 0x00 0x00

所以

c[0]=0x33
c[1]=0x00
c[2]=0x00

和0x33恰好是数字'3'的ASCII代码;

答案 1 :(得分:0)

你可以巧妙地测试它打印a的十六进制代码:

printf("\n%X\n", u.a);

输出为0x33,即ASCII 3

for循环

  • b=0x06
  • 开始
  • 然后左移2 =&gt; b=0x18
  • Inc b =&gt; b = 0x19
  • 然后左移b 1 =&gt; b=0x32
  • Inc b =&gt; b= 0x33

您定义一个联合,然后与b重合。 a和[{1}}的前3个字节也可由b访问。

BTW printf输出取决于数据的字节顺序。

在您的情况下, Little Endian c打印ASCII 3,因为printf是:

c

如果 Big Endian c[0]=0x33 c[1]=0x00 c[2]=0x00 没有打印任何内容,因为printf是:

c

答案 2 :(得分:0)

u.a,u.b和c的字节都占用相同的内存。既然你自己和u.b具有相同的类型,它们本质上是相同的变量。循环

int i=2;
u.b = 6;
for(;i; u.b++)
    u.b = u.a << i--;

可以写成(仅为了清晰起见,使用u.b):

u.b = 6;

u.b = u.b << 2;  // u.b is now 24 (one bit shift left is multiplying by 2)
u.b++;           // u.b is now 25

u.b = u.b << 1; // u.b is now 50
u.b++;          // u.b is now 51.

现在,首先是低字节的PC上的32位整数的内存布局是字节方式,51-00-00-00。

将这些字节解释为字符串,就像你告诉printf进行%s转换一样,意味着51被视为ascii值,表示字母 3 。幸运的是,下一个字节确实是0,因为整数很小,所以字符串终止。 printf将打印 3