C语言进阶——struct和union分析10
struct的小秘密:
- C语言中的struct可以看作变量的集合
- struct的问题:空结构体占用多大内存呢?
程序实例1:
#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,codeblocks,vs这种编译器可以接受空结构体,不会报错
- 像vc和bcc编译器就不能接受空结构体这种概念
- 对于空结构体这个概念,是一个灰色地带,不存在哪种编译器做出的选择更加正确
结构体与柔数组:
- 柔性数组即数组大小待定的数组
- C语言可以由结构体产生柔性数组
- C语言结构体中的最后一个元素可以是大小未知的数组
程序示例2:
struct SoftArray { int len; int array[]; };
那么就有一个问题了,sizeof(struct SoftArray);的大小是多少呢?SoftArray 中的array仅是一个待定使用的标识符,不占用存贮空间
程序示例3:(柔性数组的用法)
struct SoftArray { int len; int array[]; }; //...... struct SoftArray sa; sa =(struct SoftArray *)malloc(sizeof(struct SoftArray)+sizeof(int)*5); sa->len=5;
这只是一个代码片段,定义了一个int类型的柔性数组,长度为5
程序示例4:
1 #include <stdio.h> 2 #include <malloc.h> 3 4 struct SoftArray 5 { 6 int len; 7 int array[]; 8 }; 9 10 struct SoftArray* create_soft_array(int size) 11 { 12 struct SoftArray* ret = NULL; 13 14 if( size > 0 ) 15 { 16 ret = (struct SoftArray*)malloc(sizeof(struct SoftArray) + sizeof(int) * size); 17 18 ret->len = size; 19 } 20 21 return ret; 22 } 23 24 void delete_soft_array(struct SoftArray* sa) 25 { 26 free(sa); 27 } 28 29 void func(struct SoftArray* sa) 30 { 31 int i = 0; 32 33 if( NULL != sa ) 34 { 35 for(i=0; i<sa->len; i++) 36 { 37 sa->array[i] = i + 1; 38 } 39 } 40 } 41 42 int main() 43 { 44 int i = 0; 45 struct SoftArray* sa = create_soft_array(10); 46 47 func(sa); 48 49 for(i=0; i<sa->len; i++) 50 { 51 printf("%d\n", sa->array[i]); 52 } 53 54 delete_soft_array(sa); 55 56 return 0; 57 }
定义了一个柔性数组,并且给它赋值,然后将值打印出来,大佬们自己看一下,我相信你们用眼睛瞟一下就懂了,嘻嘻。
C语言中的union:
- C语言中的union在语法上和struct相似
- union只分配最大成员的空间,所有成员共享这个空间
union的注意事项:union的使用受系统大小端的影响,大小端是什么意思呢,我就用一段代码给大家介绍一下
程序示例5:
union C { int i; char c; }; union C c; c.i=1; printf("%d\n",c.c); //?
这段代码片段会打印什么呢,需要和我们的系统来决定:
小端模式:会从低地址到高地址来存贮这个1,也就是我们平常习惯的方式,因为打印的时候就是从低地址读取到高地址,,所以会打印出来1
大端模式:会从高地址到低地址来存贮这个1,也就是说这个1存贮在高位,由于打印的时候是从低位读取打印,所以会打印0
注意:这段代码其实很巧妙,我们给c里面的i(int类型 四个字节),然后打印c里面的的c(char类型),大家自己好好体会一下
程序示例6:(判断自己的系统是哪种模式)
#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; }
如果输出为1,那么就是小端模式,如果输出为0,那么就是大端模式
小结:
- struct中的每个数据成员具有独立的存贮空间
- struct可以通过最后的数组标识符产生柔性数组
- union中的所有数据成员共享一个存贮空间
- union的使用会受到系统大小端的影响