本文并不讲C语言的基础
1 空struct的大小
- C语言中的struct可以看成是变量的集合
如果一个struct里面什么都没有,是空的,那么它的大小是多少呢?(不考虑C++语言的特性)
实际上这在不同的编译器中还是不一样的。比如下面的代码:
#include <stdio.h>
struct TS
{
};
int main()
{
struct TS t1;
struct TS t2;
printf("sizeof(struct TS) = %d\n", sizeof(struct TS));
printf("sizeof(t1) = %d, &t1 = %p\n", sizeof(t1), &t1);
printf("sizeof(t2) = %d, &t2 = %p\n", sizeof(t2), &t2);
return 0;
}
- 使用gcc 4.4.5 编译运行结果如下:
- 使用vs 2017编译运行会报错:
所以这个问题,其实没有什么意义(在我看来)。
2 结构体与柔性数组
- 我们都知道C语言中的数组都是固定大小的。一开始定义数组的时候,就需要确定数组的大小。这样其实很不友好,如果确定数组大小后后面大小又不够,就需要给数组重新分配内存空间,这样会带来比较大的开销。柔性数组可以解决这个问题。
- 柔性数组是一种数组大小待定的数组
- 在C语言中,可以使用结构体产生柔性数组
- C语言中,结构体的最后一个元素可以是大小未知的数组。
其中SoftArray 中的array,仅仅是一个待使用的标识符,不占用存储空间。所以sizeof(struct SoftArray) = 4;
2.1 柔性数组的使用方法
- 下图是定义柔性数组,并在需要的时候为柔性数组分配合适的内存空间的代码示例:
上述代码完成后,将得到如下图所示的柔性数组:
在上图的柔性数组中,第一个元素存的是柔性数组的长度,即5 。 后面的5个元素就是柔性数组的内容。
2.2 柔性数组使用代码案例分析
- 下面的代码是创建柔性数组并初始化,然后打印的C语言代码:
#include <stdio.h>
#include <malloc.h>
struct SoftArray{
int len;
int array[];
};
struct SoftArray* Creat_Soft_Array(int size){
struct SoftArray* ret = NULL;
if(size > 0){
ret = (struct SoftArray*)malloc(sizeof(int) + size * sizeof(int));
ret->len = size;
}
return ret;
}
void delete_soft_array(struct SoftArray* sa){
free(sa);
}
void Init_SoftArray(struct SoftArray* sa){
int i = 0;
if(NULL != sa){
for(i = 0; i<sa->len ; ++i){
sa->array[i] = i+1;
}
}
}
int main(){
int i = 0;
struct SoftArray* sa = Creat_Soft_Array(5);
Init_SoftArray(sa);
for(i = 0; i<sa->len; ++i){
printf("%d\n", sa->array[i]);
}
delete_soft_array(sa);
return 0;
}
- 运行结果如下:
3 C语言中的union分析
- C语言中的union在语法上与struct类似
- 与struct不同的是union值分配最大成员的空间,其他成员共享这个空间。
- 某一时刻只有一个成员是存在的。
3.1 使用union判断系统大小端
union的使用受系统大小端的影响。系统大小端如果不懂,请自行google搜索
如下图:
- 如下代码,如果打印的是1,就是小端,如归打印的是0,就是大端
#include <stdio.h>
int system_mode()
{
union SM
{
int i;
char c;
};
union SM sm;
sm.i = 1;
return sm.c;
}
int main()
{
printf("System Mode: %d\n", system_mode());
return 0;
}
- 在我的虚拟机Ubuntu上运行结果是1,小端模式。
4 总结
- struct 结构体中的每个数据成员都有独立的存储空间
- struct 可以通过最后的数组标识符产生柔性数组
- union中所有数据成员共享同一个存储空间
- union的使用会受系统大小端的影响