结构体
语法:
1>
struct 结构体名称{
数据类型 变量名1;
数据类型 变量名2;
...
};
2>
struct 结构体名称{
数据类型 变量名1;
数据类型 变量名2;
...
}结构体变量名; 注意:该语法在定义结构体时,同时定义了一个结构体变量
3>
struct{
数据类型 变量名1;
数据类型 变量名2;
...
}结构体变量名; 注意:该语法定义的结构体只能有一个结构体变量
注意:结构体中的变量称为成员变量
定义与初始化结构体变量
struct 结构体名称 结构体变量名 = {值1,值2,值2,...};
struct 结构体名称 结构体变量名;
使用结构体变量操作成员
取值
语法:结构体变量名.成员变量名
改值
语法:结构体变量名.成员变量名 = 值;
注意:如果结构体中的成员变量是基本类型或者指针可以使用等号赋值,如果是字符数组则需要使用strcpy进行拷贝操作,如果成员变量是指针会导致浅拷贝.
结构体变量可以直接赋值给结构体变量
memcpy:拷贝指定内存中的数据到指定内存中去
语法: void *memcpy(void *dest, const void *src, size_t n);
参数: dest:目标地址 src:资源地址 n:拷贝长度,单位字节
typedef与结构体
1>
typedef struct 结构体名称 别名; 别名只能在定义的代码块中使用
2>
typedef struct 结构体名称 {
数据类型 变量名1;
数据类型 变量名2;
...
}别名; 别名可以在任意函数中使用,所以推荐使用该语法
结构体指针
结构体名称 *指针变量名 = &结构体变量名;
结构体指针操作成员变量
结构体指针变量->成员变量名
结构体指针变量->成员变量名 = 值;
结构体数组
数据类型 数组名[长度] = {值,值,值,...};
结构体指针数组
结构体名称 *数组名[长度] = {结构体指针1,结构体指针2,...};
结构体成员变量是指针变量
1>给结构体成员为指针变量的使用 = 赋值可能会产生浅拷贝
2>如果结构体变量的成员变量是指针变量,并没有进行初始化,此时该指针为野指针
3>如果结构体指针变量堆区初始化,使用完该结构体变量后要释放该指针变量指向的堆区,否则会导致内存泄漏
4>如果结构体中有指针数组,并且该指针数组中存储的指针指向堆区,那么先释放该数组中存储的地址指向的内存,再释放该数组
结构体嵌套
#include <stdio.h>
typedef struct a{
}A;
typedef struct b{
A a;
}B;
注意:如果结构体中有其他结构体指针成员变量,并且该指针成员变量堆区初始化,此时应先释放该指针成员变量的地址,再释放自己,即从里到外逐层释放.否则会造成内存泄漏
结构体对齐
1>自动对齐
原则:
结构体中的第一个成员在与结构体变量,偏移量为0的地址处.
确定结构体的分配单位,(即结构体中最大的基本类型长度)
其他成员的偏移量==成员自身长度的整数倍
收尾工作:结构体的总大小==分配单位的整数倍
注意:按成员顺序从上向下
2>强制对齐
#pragma pack (value) 指定的对齐值为基本类型长度的一种即(1.2.4.8)
位域
概述:结构体的成员以二进制位为单位存储,这种叫做位域
unsigned int a:2 表示a只占int类型中的2位二进制位,a的类型还是unsigned int
abcd叫相邻位域,可以压缩,不能超过自身类型大小
注意:不能对位域取地址 给位域赋值,不能超过位域的大小(会导致溢出)
共用体
特点:其成员共用一段内存
语法:
union 枚举名{
变量名,变量名,...
};
枚举
特点:限定其值的范围
语法:
enum 枚举名{
变量名,变量名,...
};
标签:变量,成员,数据类型,共同体,指针,C语言,枚举,变量名,结构 From: https://blog.csdn.net/weixin_74792661/article/details/143919293