Struct关键字

空结构体多大?

很遗憾,不是0,而是1。为什么呢?你想想,如果我们把struct student看成一个模子的话,你能造出一个没有任何容积的模子吗?

显然不行。编译器也是如此认为。编译器认为任何一种数据类型都有其大小,用它来定义一个变量能够分配确定大小的空间。

既然如此,编译器就理所当然的认为任何一个结构体都是有大小的,哪怕这个结构体为空。那万一结构体真的为空,它的大小为什么值比较合适呢?假设结构体内只有一个char型的数据成员,那其大小为1byte(这里先不考虑内存对齐的情况).也就是说非空结构体类型数据最少需要占一个字节的空间,而空结构体类型数据总不能比最小的非空结构体类型数据所占的空间大吧。这就麻烦了,空结构体的大小既不能为0,也不能大于1,怎么办?定义为0.5个byte?但是内存地址的最小单位是1 个byte,0.5个byte怎么处理?解决这个问题的最好办法就是折中,编译器理所当然的认为你构造一个结构体数据类型是用来打包一些数据成员的,而最小的数据成员需要1 个byte,编译器为每个结构体类型数据至少预留1 个byte的空间。所以,空结构体的大小就定位1 个byte。

 

柔性数组(在结构体中)

       typedef struct st_type

       {

              int i;

              int a[0];

       }type_a;   

sizeof type_a = 4

那个0个元素的数组没有占用空间,而后我们可以进行变长操作了。通过如下表达式给结构体分配内存:type_a*p=(type_a*)malloc(sizeof(type_a)+100*sizeof(int));

这样我们为结构体指针p分配了一块内存

但是这时候我们再用sizeof(*p)测试结构体的大小,发现仍然为4

原因:

在定义这个结构体的时候,模子的大小就已经确定不包含柔性数组的内存大小柔性数组只是编外人员,不占结构体的编制。

只是说在使用柔性数组时需要把它当作结构体的一个成员,仅此而已。再说白点,柔性数组其实与结构体没什么关系,只是“挂羊头卖狗肉”而已,算不得结构体的正式成员。

当然,上面既然用malloc函数分配了内存,肯定就需要用free函数来释放内存:

free(p);

 

struct与class的区别

在C++里struct关键字与class关键字一般可以通用,只有一个很小的区别。

struct的成员默认情况下属性是public的,   class成员却是private的。

既然struct关键字与class关键字可以通用,你也不要认为结构体内不能放函数了。

1.18 union关键字

在C++里,union的成员默认属性页为public。union主要用来压缩空间。

如果一些数据不可能在同一时间同时被用到,则可以使用union。

大小端模式对union类型数据的影响

这里需要考虑存储模式:大端模式和小端模式。

大端模式(Big_endian) :字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。

小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中

读c语言深度剖析 -- 简谈Struct union(大端小端)_第1张图片

C写的用程序确认当前系统的存储模式

int checkSystem()

{

union check

{

int i;

ihar ch;

}c;

c.i =1;

return(c.ch= =1);

}

 现在你可以用这个函数来测试你当前系统的存储模式了。当然你也可以不用函数而直接去查看内存来确定当前系统的存储模式。

如下图:

读c语言深度剖析 -- 简谈Struct union(大端小端)_第2张图片

图中0x01(高字节)的值存在低地址上,说明当前系统为小端模式。

不过要说明的一点是,某些系统可能同时支持这两种存储模式,你可以用硬件跳线或在编译器的选项中设置其存储模式。