#include <stdio.h>
typedef struct size
{
unsigned int a:1;
unsigned int b:31;
unsigned int c:1;
} mystruct;
int main()
{
mystruct a;
printf("%d", sizeof(a));
return 0;
}
int b:31
,输出为8。int b:1
,输出为4. int b:32
,输出为12。有人可以解释一下这个原因吗?
答案 0 :(得分:37)
这是重要的顺序。以下代码将给出Output:8
#include<stdio.h>
typedef struct size
{
unsigned int b:32;
unsigned int a:1;
unsigned int c:1;
}mystruct;
int main(int argc, char const *argv[])
{
mystruct a;
printf("\n %lu \n",sizeof(a));
return 0;
}
Unsigned int是一个32位整数,占用4个字节。内存在内存中连续分配。
选项1:
unsigned int a:1; // First 4 bytes are allocated
unsigned int b:31; // Will get accomodated in the First 4 bytes
unsigned int c:1; // Second 4 bytes are allocated
输出:8
选项2:
unsigned int a:1; // First 4 bytes are allocated
unsigned int b:32; // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated
unsigned int c:1; // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated
输出:12
选项3:
unsigned int a:1; // First 4 bytes are allocated
unsigned int b:1; // Will get accomodated in the First 4 bytes
unsigned int c:1; // Will get accomodated in the First 4 bytes
输出:4
选项4:
unsigned int b:32; // First 4 bytes are allocated
unsigned int a:1; // Second 4 bytes are allocated
unsigned int c:1; // Will get accomodated in the Second 4 bytes
输出:8
答案 1 :(得分:29)
你没有说你是否知道什么是位域,但我会假设你这样做。
在您的实现上,显然unsigned int
是一个32位整数,占用4个字节。这解释了第一个和第二个例子。显然,总共33位的3个位域不适合单个unsigned int
,因此在第一个示例中需要8个字节。总共3位的3个位域肯定适合unsigned int
,因此在第二个示例中只有4个字节。
此外,位域不能跨越多个整数。这是第三个例子。我不记得这是标准的要求,还是实施的细节。无论哪种方式,因为b
是32位,它自己填充整个unsigned int
,迫使a
和c
占用他们自己的unsigned int
,在中间之前和之后。因此,12个字节。
答案 2 :(得分:10)
编译器将结构的大小四舍五入为32位,每个对象的大小可以尝试引用32位,同时它保留了位字段的顺序。
因此,如果中间有一个32位项目,每侧有1位项目,则需要分配3个32位字,因此:12个字节。
对于另外两种情况,这只是一个问题,即你的位域序列可以打包到多少32位对象,同时仍保留字段顺序。
答案 3 :(得分:9)
根据Steve jessop's answer只是为了通过添加一些可能有用的文件来实现他的答案。
结构或联合的成员可以具有除可变修改类型之外的任何完整对象类型。此外,可以声明成员由指定数量的位组成(包括符号位,如果有的话)。这样的成员称为位字段,其宽度前面有冒号
实现可以分配足够大的任何可寻址存储单元来保存位字段。 如果剩余足够的空间,则紧跟在结构中另一个位字段之后的位字段将被打包到同一单元的相邻位中。如果剩余的空间不足,则是否将不适合的位域放入下一个单元或重叠相邻单元是实现定义的。单元内位域分配的顺序(高位到低位) - order或low-order to high-order)是实现定义的。可寻址存储单元的对齐未指定。
在结构对象中,非位字段成员和位字段所在的单位的地址按声明的顺序增加。指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。在结构对象中可能有未命名的填充,但不是在它的开头。
- ISO / IEC 9899:201x 6.7.2.1