简体   繁体   English

具有位域的工会成员的价值

[英]value of members of unions with bit-fields

I'm trying to learn how memory is allocated for unions containing bit-fields. 我正在尝试学习如何为包含位字段的联合分配内存。

I've looked at posts and questions similar to this and have understood that padding is involved most of the times depending on the order in which members are declared in structure. 我查看了与此类似的帖子和问题,并且了解到填充在大多数情况下都取决于成员在结构中声明的顺序。

1. 1。

union Example
{ int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);
}

Output: -1 输出:-1

2. 2。

union Example
{ unsigned int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);
}

Output: 3 输出3

Can someone please explain the output? 有人可以解释一下输出结果吗? Is it just the standard output for such cases? 仅仅是这种情况下的标准输出吗? I use the built-in gcc compiler in ubuntu 我在ubuntu中使用内置的gcc编译器

The way your compiler allocates bits for bit-fields in a union happens to overlap the low bits of j with the bits of i . 你的编译器分配在工会位字段位的方式发生的低位重叠j用的比特i Thus, when j is set to 15, the two bits of i are each set to 1. 因此,当j设置为15时, i的两位分别设置为1。

When i is a two-bit signed integer, declared with int i:2 , your compiler interprets it as a two-bit two's complement number. i是用int i:2声明的两位带符号整数时,编译器会将其解释为两位二进制的补码。 With this interpretation, the bits 11 represent −1. 通过这种解释,比特11代表-1。

When i is a two-bit unsigned integer, declared with unsigned int i:2 , it is pure binary, with no sign bit. i是由unsigned int i:2声明的两位无符号整数时,它是纯二进制,没有符号位。 With this interpretation, the bits 11 represent 3. 通过这种解释,位11代表3。

The program below shows that setting a signed two-bit integer to −1 or an unsigned two-bit integer to 3 produce the same bit pattern in the union, at least in your C implementation. 下面的程序显示,至少在您的C实现中,将有符号的两位整数设置为-1或将无符号的两位整数设置为3会在联合中产生相同的位模式。

#include <stdio.h>


int main(void)
{
    union Example
    {
        unsigned u;
        int i : 2;
        int j : 9;
        unsigned int k : 2;
    } ex;

    ex.u = 0;
    ex.i = -1;
    printf("ex.i = -1:  %#x.\n", ex.u);

    ex.u = 0;
    ex.j = 15;
    printf("ex.j = 15:  %#x.\n", ex.u);

    ex.u = 0;
    ex.k = 3;
    printf("ex.k =  3:  %#x.\n", ex.u);
}

Output: 输出:

ex.i = -1:  0x3.
ex.j = 15:  0xf.
ex.k =  3:  0x3.

Note that a compiler could also allocate the bits high-to-low instead of low-to-high, in which case the high bits of j would overlap with i , instead of the low bits. 请注意,编译器还可以从高到低而不是从低到高分配位,在这种情况下, j的高位将与i重叠,而不是低位。 Also, a compiler could use different sizes of storage units for the nine-bit j than it does for the two-bit i , in which case their bits might not overlap at all. 同样,编译器为9位j使用的存储单元大小可能与为2位i使用的存储单元大小不同,在这种情况下,它们的位可能根本不重叠。 (For example, it might use a single eight-bit byte for i but use a 32-bit word for j . The eight-bit byte would overlap some part of the 32-bit word, but not necessarily the part used for j .) (例如,它可能对i使用单个8位字节,但对j使用32位字。这8位字节会与32位字的某些部分重叠,但不一定与j所用的部分重叠。 )

Example1 例1

#include <stdio.h>

union Example
{ int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);
   printf("\nSize of Union : %lu\n" , sizeof(ex));

   return 0;
}

Output: 输出:

-1
Size of Union : 4

Observations: 观察结果:

From this ouput, We can deduce that even if we use 9 bits( max ), Compiler allocates 4 byte(because of padding). 从这个输出中,我们可以推断出,即使我们使用9位(最大值),编译器也会分配4字节(由于填充)。 Statement union Example ex; 声明union Example ex; allocates 4 bytes of memory for Union Example object ex. 为联合示例对象ex分配4字节的内存。 Statement ex.j=15; 语句ex.j=15; asigns 0x0000000F to that 4 Byte of memory. 将0x0000000F分配给该4字节的内存。 So for j it allocates 0-0-0-0-0-1-1-1-1 for 9 bits. 因此,对于j,它为9位分配0-0-0-0-0-1-1-1-1。 Statement printf("%d",ex.i); 语句printf("%d",ex.i); tries to print ex.i( which is 2 bits). 尝试打印ex.i(2位)。 We have 1-1 from the previous statement. 从前面的语句中我们得到1-1。

Here comes the interesting part, ex.i is of type signed int. 有趣的部分到了,例如ex.i的类型为int。 Hence first bit is used to assign signed representation and most cpu does signed representation in 2's complement form. 因此,第一位用于分配带符号的表示,大多数cpu以2的补码形式表示带符号的表示。 So if we does reverse 2's complement of 1-1 we will get value 1. So the ouput we get is -1. 因此,如果我们反转1-1的2的补数,我们将获得值1。因此,我们得到的输出为-1。

Example2 例2

#include <stdio.h>

union Example
{ unsigned int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);


   return 0;
}

Output: 输出:

3

Observations: 观察结果:

Statement union Example ex; 声明union Example ex; allocates 4 bytes of memory for Union Example object ex. 为联合示例对象ex分配4字节的内存。 Statement ex.j=15; 语句ex.j=15; asigns 0x0000000F to that 4 Byte of memory. 将0x0000000F分配给该4字节的内存。 So for j it allocates 0-0-0-0-0-1-1-1-1 for 9 bits. 因此,对于j,它为9位分配0-0-0-0-0-1-1-1-1。 statement printf("%d",ex.i); 语句printf("%d",ex.i); tries to print ex.i( which is 2 bits). 尝试打印ex.i(2位)。 We have 1-1 from the previous statement. 从前面的语句中我们得到1-1。

Same as Above example but here ex.i is of type unsigned int. 与上述示例相同,但此处ex.i的类型为unsigned int。 Hence no signed bit is used here for representation. 因此,这里没有符号位用于表示。 So whatever is stored in the 2 bit location is the exact value. 因此,存储在2位位置中的是确切值。 Hence the ouput is 3. 因此输出为3。

Hope i cleared your doubt. 希望我清除您的疑虑。 Please check for 2's and 1's complement in the internet. 请在互联网上检查2和1的补码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM