C语言之学习结构体

本文详细介绍了C语言中的结构体类型,包括如何设计结构体来封装不同类型的数据,如学生的学号、姓名、性别和年龄。接着讨论了结构体变量的定义和初始化,以及结构体成员的访问和赋值。结构体可以嵌套,可以作为数组元素,且结构体的大小受到字节对齐规则的影响。最后提到了结构体在函数传递和内存对齐问题上的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.结构体类型的设计

       C语言提供了基本数据类型,如char,short,int,float…等类型,我们称之为内置类型。程序开发人员可以使用结构体来封装一些属性,设计出新的类型,在C语言中称之为结构体类型

结构体类型的设计:
        在C语言中,结构体是一种数据类型。(由程序开发者自己设计的类型)
        可以使用结构体(struct)来存放一组不同类型的数据。
        结构体的定义形式为:

struct 结构体名
{
成员列表(可以是基本数据类型,指针,数组或其他结构体类型)
};

1.1 设计一个学生类型

       客观事物(实体)是复杂的,要描述它必须从多方面进行,也就是用不同的数据类型来描述不同的方面。如学生实体可以这样来描述:
       学生学号(用字符串描述), 学生姓名(用字符串来描述),性别(用字符串来描述),年龄(用整型数描述)。这里用了属于2种不同数据类型,以及4个数据成员来描述学生实体。

图示:


 

 函数定义的花括号{}后面没有分号

2.结构体变量的定义和初始化

       既然结构体是一种数据类型,那么就可以用它来定义变量。结构体就像一个“模板”,定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”,将结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。
       结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要存储空间。
结构体变量在内存中表示(暂不考虑内存对齐问题) 

 结构变量初始化; 

#include<stdio.h>
struct Student
{
	char s_id[20];
	char s_name[20];
	char s_sex[10];
	int s_age;
};

int main()
{
	int a = 10;
	struct Student stud = { "09001","zyc","man",22 };

	printf("id:   %s \n",    stud.s_id);
	printf("name:   %s \n",  stud.s_name);
	printf("sex:   %s \n",   stud.s_sex);
	printf("id:   %d \n",    stud.s_age);

	return 0;
}

 

 

 结构体输出:

 结构体嵌套结构体: 

 结构体自定义:

 

 3.结构体成员访问(获取和赋值)

3.1结构体变量的成员,访问
获取和赋值结构体变量成员的一般形式为:
结构体变量,成员名:

结构体变量成员的访问:

注意:对结构体变量整体赋值有3种情况
1、定义结构体变量(用{}初始化)
2、用已定义的结构变量初始化
3、结构体类型相同的变量可以作为整体相互赋值

其他情况的使用过程中只能对成员逐一赋值

在C语言中不存在对结构体类型的强制转换(和内置类型的区别)

3.2结构体变量和指针
   内置类型能够定义指针变量,结构体类型也可以定义结构体类型指针。
   结构体类型指针访问成员的获取和赋值形式:
   (*p).成员名(.的优先级高于 ,( p)两边的括号不能少)
 或
      p->成员名(->是减号加大于号,中间没有空格,称为指向符)

3. 结构体变量和函数 

只是第打印而已,第一种方式比较好,数据安全,使用第二种方式可能会修改主函数sx的数据

4.结构体与数组

      所谓结构体数组,是指数组中的每个元素都是一个结构体类型。在实际应用中,C语言结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生,一个公司的员工等。

5.结构体大小

 

 由于存储变量地址对齐的问题,计算结构体大小的3条规则:
1、结构体变量的首地址,必须是结构体变量中的“最大基本数据类型成员所占字节数”的整数倍
2、结果体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍
3、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节数”的整数倍
假设是从0地址开始 

sizeof(struct node)=sizeof(sd)=12;

为什么要理解字节对齐问题?
1、内存大小的基本单位是字节(byte),理论上讲,可以从任意地址访问变量,但是实际上,CPU并非逐字节读写内存,而是以2,4或8的倍数的字节块来读写内存,因此就会对基本数据类型的地址作一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。
2、有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果放在偶地址开始的地方,那么一个读周期就可以读出32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
3、由于不同平台对齐方式可能不同,如此一来,同样的结构在不同的平台其大小可能不同,在无意识的情况下,互相发送的数据可能出现错乱,甚至引发严重的问题。
指定对齐值
预处理命令#pragma pack(n)可以改变默认对齐数。 n取值是1,2,4,8,16
VS中默认值=8,gcc中默认值=4;

 总结:
1、结构体变量的首地址,必须是MIN{“结构体最大基本数据类型成员所占字节数”,指定对齐方式}大小的整数倍
2、结构体每个成员相对于结构体首地址的偏移量,都是MIN{基本数据类型成员,指定对齐方式}大小的整数倍
3、结构体的总大小,为MIN{结构体“最最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式}大小的整数倍
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值