栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C语言】1. 结构体struct(结构体概念、结构体指针、结构体作为函数参数、传值与传地址、内存对齐(struct与union))

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C语言】1. 结构体struct(结构体概念、结构体指针、结构体作为函数参数、传值与传地址、内存对齐(struct与union))

目录
  • 1. 结构体struct
    • 1.1 结构体类型的概念
    • 1.2 结构体变量的定义
      • 1.2.1 声明结构体类型,再定义变量(最常用)
      • 1.2.2 在声明结构体类型时,定义变量
      • 1.2.3 直接定义结构体类型变量
    • 1.3 结构体变量的引用
  • 2. 结构体数组
  • 3. 结构体指针
    • 3.1 概念
    • 3.2 第一种方法是使用点运算符引用结构成员
    • 3.3 第二种方法是指向运算符引用结构成员
  • 4. 结构体作为函数参数
    • 4.1 使用结构体变量作为函数参数
    • 4.2 使用指向结构体变量的指针作为函数参数
  • 5. 传值与传地址
    • 5.1 传值
    • 5.2 传地址
    • 5.3 传值举例
    • 5.4 传地址举例
  • 6. 内存对齐(struct 与 union)
    • 6.1 struct 与 union区别
    • 6.2 结构体内存对齐
    • 6.3 联合体内存对齐

1. 结构体struct 1.1 结构体类型的概念

“结构体”是一种构造类型,它是由若干“成员”组成的,其中的每一个成员可以是一个基本数据类型也可以是一个构造类型。
假如在程序中要使用“学生”这样一个类型,学生具有姓名、性别、年龄等属性
声明结构体使用的关键字是struct,其一般形式为:

struct 结构体名
{
	成员列表
};

关键字struct表示声明结构,其后的结构体名表示该结构的类型名
注意:大括号最后面有一个分号“ ; ”,不要忘记
例如:

struct Student
{
	char _name[10];
	char _gender[10];
	int _age;
};

使用关键字struct声明一个名为Student的结构体类型,在结构体中定义的变量是Student结构的成员。

1.2 结构体变量的定义 1.2.1 声明结构体类型,再定义变量(最常用)
//创建结构体模板
struct Student
{
	char _name[10];
	char _gender[10];
	int _age;
};
//使用该模板创建3个变量stu1,stu2,stu3
struct Student stu1,stu2,stu3;

缺点就是定义变量时必须带上struct
可以使用typedef进行简写,这样在定义变量时比较简洁

//结构体模板struct Student重新命名为Stu
typedef struct Student
{
	char _name[10];
	char _gender[10];
	int _age;
}Stu;
//使用Stu创建3个变量stu1,stu2,stu3
Stu stu1,stu2,stu3

此处使用typedef为结构体模板struct Student定义一个别名Stu

1.2.2 在声明结构体类型时,定义变量
struct Student
{
	char _name[10];
	char _gender[10];
	int _age;
}stu1,stu2,stu3;
1.2.3 直接定义结构体类型变量
struct 
{
	char _name[10];
	char _gender[10];
	int _age;
}stu1,stu2,stu3;

缺点:不能用该结构定义新的变量。

1.3 结构体变量的引用
结构体变量名.成员名

在引用结构的成员时,可以在结构的变量名的后面加上成员运算符“ . ”和成员的名字

Stu._name = "Hanmei";
Stu._age = 15;
2. 结构体数组

定义结构体数组的一般形式如下:

struct 结构体名
{
	成员列表
}数组名;
struct Student
{
	char _name[10];
	char _gender[10];
	int _age;
}stu[10];

也可以先声明结构体类型再定义结构体数组

typedef struct Student
{
	char _name[10];
	char _gender[10];
	int _age;
}Stu;

在主函数中定义结构体数组

Stu stu[10];
3. 结构体指针 3.1 概念

结构体指针:指向结构体变量的指针
定义结构体指针的一般形式:

结构体类型* 指针名

定义一个指向struct Student结构类型的 p 指针变量如下:

struct Student* p;

使用指向结构体变量的指针访问成员有以下两种方法:

3.2 第一种方法是使用点运算符引用结构成员
(*p).成员名;

注意:*p一定要使用括号,因为点运算符的优先级是最高的

3.3 第二种方法是指向运算符引用结构成员
p->成员名;

假如student为结构体变量,p为指向结构体变量的指针,则下列3种形式的效果是等价的

student.成员名;
(*p).成员名;
p->成员名;

在使用"->"引用成员时,要注意分析以下情况:
p->iGrade; //表示指向结构体变量中成员iGrade的值
p->iGrade++; //表示指向结构体变量中成员iGrade的值,使用后该值加1
++p->iGrade; //表示指向结构体变量中成员iGrade的值加1,计算后再使用

4. 结构体作为函数参数 4.1 使用结构体变量作为函数参数

使用结构体变量作为函数的实际参数时,采取的是“值传递”,它会将结构体变量所占内存单元的内容全部顺序传递给形参,形参也必须是同类型的结构体变量

void Display(struct Student stu);

在形参的位置使用结构体变量,但是函数调用期间,形参也要占用内存单元,这种传递方式在空间和时间上开销都比较大
另外,根据函数参数传值方式,如果在函数内部修改了变量中成员的值,则改变的值不会返回到主调函数中

4.2 使用指向结构体变量的指针作为函数参数

在传递结构体变量的指针时,只是将结构体变量的首地址进行传递,并没有将变量的副本进行传递

void Display(struct Student *stu);
5. 传值与传地址 5.1 传值

实际是把实参的值赋值给行参,相当于copy。那么对行参的修改,不会影响实参的值

5.2 传地址

实际是传值的一种特殊方式,只是他传递的是地址,不是普通的赋值,那么传地址以后,实参和行参都指向同一个对象,因此对形参的修改会影响到实参

5.3 传值举例



值传递:可以看到a,b的值并没有被交换
在main函数中swap(a,b)将a,b两个值传给了调用函数swap中的x,y,在swap调用函数中完成了x和y的交换,但是只是完成了x,y的交换,跟主函数中的a,b没有任何关系。这只是一次单向的传递过程,x,y是定义在函数swap中的局部变量,当函数调用结束后,它俩就over了,被残忍抛弃了(子函数的生命期为子函数开始调用到结束调用,调用结束后就主动释放了),因此它们没有渠道把交换的值传回给a,b

5.4 传地址举例



传地址是实参和行参都指向同一个对象,因此对形参的修改会影响到实参

6. 内存对齐(struct 与 union) 6.1 struct 与 union区别

struct:用户自定义数据类型,是一些变量的集合体。
union:也是一种特殊的自定义类型,也包含一系列的成员,特征是这些成员公用同一块内存空间,所以联合变量的大小,至少是最大成员的大小。
(1)struct可以存储多个成员信息,而union只能存储最后一个成员的信息;(2)struct会给每一个成员分配内存空间,而union的所有成员公用一块内存空间;
(3)union的不同成员赋值,将会对其他成员重写,而struct的不同成员赋值是互不影响的。

6.2 结构体内存对齐

(1)第一个成员在偏移量为0的地址处;
(2)其他成员变量对齐到某个数字的整数倍地址处,这个数是编译器默认的对齐数与该成员大小的较小值,VS中默认是8,也可以使用#pragma pack来修改默认对齐数;
(3)结构体的总大小为最大对齐数的整数倍。

6.3 联合体内存对齐

(1)联合的大小至少是最大成员的大小;
(2)当最大成员的大小不是最大对齐数的整数倍时,要对齐到最大对齐数的整数倍。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/604796.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号