不要年纪轻轻,就觉得自己进入了人生低谷,其实,后来你会发现你还有很大的下降空间。
一、struct
1、在网络协议、通信控制、嵌入式系统、驱动开发等地方,我们经常要传送的不是简单的字节流(char 型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。另外平时在编写函数时参数尽量不要多于4个,否则用起来麻烦还容易出错,效率会降低(具体与CPU有关,何况ARM的芯片对于参数超过4个的函数另做处理,具体查资料)。此时用结构体传参数就会方便很多。
struct lsh
{
}p;//sizeof(p)==1;编译器认为任何一种数据类型都有其大小,用它来定义一个变量能够分配确定大小的空间,即使是空结构体。
2、typedef struct lsh {
int i;
int a[];
static int n; //有些编译器能过,但是我用gcc会报错。
}type_lsh;//sizeof(type_lsh) == sizeof(i)==sizeof(int)==4;可以看出变长数组并不占空间。
type_lsh *p = (type_lsh*)malloc(sizeof(type_lsh)+100*sizeof(int));
此时sizeof(*p)==4;这么神奇的吗?sizeof(p) == 8;//因系统而已。
由此来看变长数组不属于结构体,只是简单的看成一个成员而已。
3、结构体大小的计算
由上面也可以看出大小并不是成员变量的简单相加,在平时应用时我们经常用sizeof求一下。自己计算则要考虑到系统储存结构体变量的地址对齐
1)大小等于最大成员的大小整数倍
2)结构体内的成员的首地址相对于结构体收地址的偏移量是其类型大小的整数倍。例如:int类型是4个字节,那么int型成员的首地址相对于结构体首地址的偏移量应该是4的整数倍。
3)满足1),2)的情况,编译器会在结构体成员之间进行字节的填充。
从上面我们也看到malloc()动态分配的以及静态的变量(静态(全局)区)是不计算在内的,sizeof()计算分配在栈内大小。
#include <stdio.h>
struct test
{
char a;
int b;
};
struct t1
{
char c;
struct test str1;
long long d;
};
int main()
{
struct t1 t;
printf("&t.c:%d\n",&t.c);
printf("&t.tr1.a:%d\n",&t.str1.a);
printf("&t.str1.b:%d\n",&t.str1.b);
printf("&t.d:%d\n",&t.d);
printf("len:%d\n",sizeof(t));
return 0;
}
输出: