C语言struct、union、sizeof
简单的我就不讲了,直接上代码
#include <stdio.h> #include <malloc.h> //空的结构占用多少个内存呢(实际gcc编译器不占用内存,bcc和vc编译器编译错误,因为结构体创建之初就是为了集合各种不同变量,但是创建空的结构体就是违背了结构体意图,所以编译错误) struct TS { }; //1.创建柔性数组(第一次看见这种写法可能感觉怪怪的,但是就是有这种写法,你只需要记住,知道怎么用,就可以了) struct SoftArray { int len; int array[]; //这里实际不占用内存空间,只是一个标识符 }; struct SoftArray* creat_soft_array(int size) { struct SoftArray *sa = NULL; if(size > 0) { sa = (struct SoftArray *)malloc(sizeof(struct SoftArray) + sizeof(int)*size); sa->len = size; } return sa; } //2.释放柔性数组 void Delete_soft_array(struct SoftArray *sa) { if(sa->len > 0) { free(sa); } } //3.赋值 void fun(struct SoftArray *sa) { int i; for(i = 0;i < sa->len;i++) { sa->array[i] = i + 1; //1....N } } //4.打印柔性数组 void PrintSa(struct SoftArray *sa) { int i; for(i = 0;i < sa->len;i++) { printf("sa->aray[%d] = %d\n",i,sa->array[i]); } } //5.判断系统的大小端 //返回 1 = 小端模式 0 = 大端模式 int system_mode(void) { union SM { int i; char c; }; union SM sm; sm.i = 0x01; return sm.c; } //6.证明sizeof是编译阶段执行的,而不是运行阶段执行的 int fun3(void) { printf("Run fun3\n"); //如果没有打印出来这句话,说明运行阶段根本没有执行,而是在编译阶段直接替代了 return 1; } int main() { int ver = 0; int ret = sizeof(ver++); //大家猜猜执行完这句话 ret是多少,ver是多少 struct SoftArray *sb = NULL; printf("sizeof(struct TS) = %d\n",sizeof(struct TS));//输出0,gcc编译器空结构体不占用空间(bcc和vc编译器编译错误,提示错误信息是缺少结构体成员) printf("System_mode = %d\n",system_mode()); //输出1,所以我们系统是小端模式 printf("ret = %d ver = %d\n",ret,ver);//输出ret = 4 ver = 0,因为ver是int类型,占用4个字节,所以ret = 4,但是ver为什么等于0呢!因为sizeof是C语言关键字,而不是一个函数,在编译阶段就执行简单替代,所以不会执行ver++; printf("%d\n",sizeof(fun3()));//这里也是一样的,在编译阶段就进行简单替代,不会执行fun3()函数 printf("sizeof(struct SoftArray) = %d\n",sizeof(struct SoftArray)); //输出0,说明空结构体不占用内存空间 sb = creat_soft_array(10); //创建了10个int类型数据 fun(sb); PrintSa(sb); //打印输出1到10 Delete_soft_array(sb); return 0; }
程序里面注释其实已经写得很明白了
我主要是说下可能有的人认为,struct SoftArray* creat_soft_array(int size);这个函数里面创建了一个struct SoftArray *sa = NULL;结构体指针sa,但是这个是一个局部的变量,作用域就在这个函数内,然后你函数返回还返回这个结构体的地址给main函数创建另外一个结构体指针sb,这块是不是有问题?就是说变量在函数内声明,函数执行完释放掉了,你在返回这个这个变量地址,这里很有可能有问题的!
解答:其实不会的,因为这里我们用的动态内存的方式所以不会的,这里你可以参考这个文章https://blog.csdn.net/liuchunjie11/article/details/80431184