首页
论坛
课程
招聘
[基础知识] [分享]C语言基础九-结构体
2021-5-4 11:56 2202

[基础知识] [分享]C语言基础九-结构体

2021-5-4 11:56
2202

结构体的定义

short、int、long、char、float、double 这六个关键字代表C语言里的六种基本数据类型。C语言中,还提供了struct结构体数据类型,结构体是一种构造类型,由若干成员组成,每个成员可以是一个基本数据类型也可以又是一个构造类型,因此结构体可以用来存放一组不同类型的数据。例如:

1
2
3
4
5
6
typedef struct _Student
{
    int nId;
    char szName[16];
    double dbHeight;
}Student,*pStudent;

我们定义了一种Student结构体数据类型和一种pStudent结构体指针数据类型,可以使用Student、pStudent定义变量。

结构体的大小

结构体对齐方式:

  • 自然对齐

数据成员对齐规则:

  • 各成员变量存放的起始地址相对于结构体起始地址偏移量是sizeof(基本类型)整数倍
  • 如果成员为非基本类型,偏移量为其子成员中最大的基本类型长度的整数倍

结构体整体对齐规则:

  • 结构体的总大小是其成员中最大基本类型长度的整数倍

结构体变量和结构体指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
typedef struct _Student
{
    int nId;
    char szName[16];
    double dbHeight;
}Student,*pStudent;
 
//变量的定义
//1.结构体
Student tagStuA;
//2.指针
pStudent pTagStuB;
Student* pTagStuC;
 
//变量的初始化
//1.大括号初始化
Student tagStuC = {202101,"xiaoxin",100.0};
//1.单个成员赋值
tagStuC.dbHeight = 101.0;
//3.同结构体变量可以给同结构体变量赋值
Student tagStuD = tagStuC;
pStudent pTagStuE = &tagStuC;
 
//变量的访问, . 和 -> 运算符的优先级比 * 运算符高
printf("%s\n",tagStuC.szName);
printf("%s\n",pTagStuE->szName);

结构体应用

  1. 结构体数组
  2. 结构体指针数组
  3. 结构体作为参数传参
  4. 结构体指针作为参数传参

传值和传地址的区别

我们知道,一个结构体的成员可能有很多个,当我们定义结构体的时候,底层会根据我们的结构体成员算出对齐值,然后进行申请内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
typedef struct _Student
{
    int nId;
    char szName[16];
    double dbHeight;
}Student,*pStudent;
 
void ChangeValueA(Student tagStu)
{
    tagStu.szName = xiaoxin;
}
 
void ChangeValueB(pStudent pTagStu)
{
    pTagStu->szName = xiaoxin;
}
 
int main()
{
    Student tagStu;
    tagStu.szName = xiaoxin;
    //传值
    ChangeValueA(tagStu);
    //传地址
    ChangeValueB(&tagStu);
}

当结构体作为函数参数的时候,如果直接传结构体变量,函数参数相当于直接拷贝了一份结构体,这样特别消耗内存。当传入tagStu给函数的时候,函数的tagStu相当于重新申请的变量,拷贝了我们的实际参数tagStu,我们在函数内部修改不会改变实际参数的值,这就是传值。
如果我们想修改实际参数的值,需要把地址传过去,而指针就是地址,函数拷贝的是地址,根据地址修改里面的值,则可以改变实参的值,这个就是传地址。

浅拷贝shallow copy、深拷贝deep copy

  1. 结构体中只有基本类型成员时,结构体变量可以直接赋值给相同类型的结构体变量,浅拷贝没问题
  2. 当结构体包含指针成员时,浅拷贝会造成野指针问题
  3. 为结构体指针成员重新分配内存拷贝数据,深拷贝
  4. C语言中编译器默认结构体浅拷贝,深拷贝由程序员自己实现
  5. 深拷贝会造成内存浪费问题

写时拷贝copy-on-write
采用引用计数机制,共享内存数据,解决野指针和内存浪费问题


第五届安全开发者峰会(SDC 2021)议题征集正式开启!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回