更多详情尽在微信公众号:嵌入式图像处理
常用写法
设计结构体类型的时候,同时定义结构体变量
struct{
int a;
int b;
}st; //定义一
这个st是一个结构体变量,无法再使用结构体来定义变量(内核使用)
struct A{
int a;
int b;
}st; //定义二
这个st是一个结构体变量,可以再使用struct A结构体类型来定义变量
设计结构体类型的时候,同时取别名定义一个新的结构体类型
typedef struct A{
int a;
int b;
}st_t; //定义三
st_t 是一个结构体类型,它实际上是struct A的别名,此时除了struct A可以定义变量外,还可以通过st_t来定义(常用)
typedef struct{
int a;
int b;
}st_t; //定义四
st_t 是一个结构体类型,此时只能通过st_t类型来定义变量。(不常用)
结构体初始化
struct man
{
char name[100];
int age;
};
结构体变量初始化法:
struct man m = { "tom", 12 };
struct man m = { .name = "tom", .age = 12 };
结构体数组初始化法:
struct man m[10] = { { "tom", 12 }, {"marry", 10 }, { "jack", 9 } };
结构体嵌套定义和初始化
struct names{
char first[100];
char last[100];
};
struct man{
struct names name;
int age;
};
struct man m = { { "wang", "wu" }, 20};
注:这种类似的嵌套定义在数据结构中很常见。
结构体大小计算
gcc 编译器的对齐规则
位置偏移: char(1byte) short(2byte) int(4byte) float(4byte) double(8byte)
相对偏移:相对于结构体首地址的偏移量。
结构体成员分配内存的规则
相对偏移 % 位置偏移 =0 就可以分配,如果不为0则补齐,补到求余为0为止。
最后结构体总的大小 % 最大的位置偏移 = 0,如果不为0则补齐。
注:定义一个结构体的时候指定的是具体元素的位长,不是字长。
64位linux系统struct内存对齐与取消内存对齐:
struct A{
char a; //1 0%1=0
short b; //2 1%2=1再补一位
int c; //4 4%4=0
}; //总大小8%最大偏移4=0,所以为8。
struct B{
char a; //1 0%1=0
int b; //4 1%4=1再补三位
short c; //2 8%2=0
}; //总大小10%最大偏移4=2,再补2位为0,总大小12
struct C{
int a; //4 0 % 4 = 0
char b; //1 4 % 1 =0
double c; //8 5 % 8 =5 +3 4+1+8+3 = 16
short d; //2 16 % 2 =0
}; //结构体的总大小18 % 最大的位置偏移8=2,再补6为0,总大小24
struct D{
int a; //4
char b; //1
double c; //8
short d; //2
}__attribute__((__packed__)); //取消内存对齐 = 15
结构体成员的访问
结构体变量在访问其成员的方法:首地址 + 成员偏移量。
在实际的编码中,使用原则如下:
<1>结构体的普通变量,在访问成员的时候,通过"."来访问。
结构体变量.成员
<2>结构体的指针变量,在访问成员的时候通过"->"或"."来访问。
结构体指针变量->成员或 (*结构体指针变量).成员
注意:结构体的指针变量必须保存一个有效的地址,它实际上访问的是它保存的地址中的成员。
结构体中的深拷贝和浅拷贝
浅拷贝:只是对指针的拷贝,拷贝后两个指针指向同一个内存空间。
深拷贝:不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。