4

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

 3 years ago
source link: https://bbs.pediy.com/thread-267332.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

结构体的定义

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

typedef struct _Student
{
int nId;
char szName[16];
double dbHeight;
}Student,*pStudent;

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

结构体的大小

结构体对齐方式:

数据成员对齐规则:

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

结构体整体对齐规则:

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

结构体变量和结构体指针

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. 结构体指针作为参数传参

传值和传地址的区别

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

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
采用引用计数机制,共享内存数据,解决野指针和内存浪费问题

[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班开始招生!!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK