有关结构体的知识点

结构体定义和结构体变量初始化

结构体本质上还是一种数据类型,但它可以包含若干个“成员”,每个成员的类型可相同也可不同。定义结构体的格式如下:

//结构体的定义
struct 结构体名称
{
   成员列表;
};

注:在定义任何一个结构体时,{}后的;一定不能忘!!!

例:定义一个学生类型的结构体,包括学号,姓名,性别,年龄

struct Student//定义一个名为Student的结构体
{
   int s_id;
   char s_name[20];
   char s_sex[5];
   int s_age;
}stu;//在结构体声明的同时定义了一个结构体变量stu

在结构体中要想访问成员时,要使用结构体成员运算符点(.)访问,一般形式是 结构体变量名.成员名

若我们想使用以上的Student结构体中的成员,就可以直接输入结构体变量名和相应运算符stu. 编译器就会自动跳出内部包含的成员供你使用,如果没有自动跳出,就说明输入的结构体变量名有误或结构体成员运算符使用有误。例如:

对以上结构体进行初始化操作,即: struct Student stu1 = { 01,"zhangsan","man",18 };

若想对以上的成员值进行修改,不是字符串的可以直接进行结构体成员变量和相应运算符访问修改,是字符串的要使用strcpy()函数

注:在使用strcpy()函数时,要引入头文件#include<string.h>

嵌套结构体

定义:在结构体中又包含其他结构体

struct Score
{
	float c_score;//语文成绩
	float m_score;//数学成绩
	float e_score;//英语成绩
};
struct Address
{
	char province[20];//省
	char city[10];//市
};

struct Student
{
	char name[10];//姓名
	int age;//年龄
	char sex[10];//性别
	Score stu_score;//成绩结构体
	Address address;//地址结构体
};//学生结构体

我们在学生结构体里嵌套了成绩结构体和地址结构体,初始化如下:

Student s = { "www",17,"male",{88,99,55},{"shanxi","xian"} };

如果想要对语文成绩进行更改到98,应为:s.stu_score.c_score=98;

如果想要对市进行更改为yulin,应为:strcpy(s.address.city,"yulin");

由此说明,若想访问此嵌套结构体里的变量,应使用两次"."如果结构体嵌套了三层,那么就应该使用三次"."去定位

结构体指针

一旦定义了指向结构体变量的指针,就可以通过该指针间接引用所指向的结构体变量,结构体指针定义如下:

​
struct Student//定义一个名为Student的结构体
{
   int s_id;
   char s_name[20];
   char s_sex[5];
   int s_age;
}stu;//在结构体声明的同时定义了一个结构体变量stu

​Student stu1={1,"zhangsan","man",20);//对结构体进行赋初值操作
Student *p=&stu1;//定义指向结构体变量的指针变量p

此时若想对各个成员值进行更改,就要使用指针变量进行修改,一定是(*结构体指针变量).成员名

等价于 结构体指针->成员名。这里的 ->为指向运算符。因为成员运算符"."优先级高于间接引用运算符"*",所以这里的()不能省略,例:

​Student stu1={1,"zhangsan","man",20);//对结构体进行赋初值操作
Student *p=&stu1;//定义指向结构体变量的指针变量p
(*p).s_id=2;//p->s_id=2
strcpy((*p).s_name,"lisi");//strcpy(p->s_name,"lisi")
strcpy((*p).s_sex,"woman");//strcpy(p->s_sex,"woman")
(*p).s_age=18;//p->s_age=18

结构体数组

定义:数组的每个元素都是一个结构体。例:

​
struct Student//定义一个名为Student的结构体
{
   int s_id;
   char s_name[20];
   char s_sex[5];
   int s_age;
}stu;//在结构体声明的同时定义了一个结构体变量stu

​struct Student stu1[3]={{1,"zahngsan","man",17},{2,"lisi","man",16},{3,"lihua","woman",23}};

stu1s_ids_names_sexs_age
stu1[0]1zahngsanman17
stu1[1]2lisiman16
stu1[2]3lihuawoman23

要进行修改时:

stu1[0].s_id=10;//将stu1[0]的id更改为10
strcpy(stu1[2].s_name,"huahua");//将stu1[2]的名字改为huahua

若想对结果进行输出,用一个for循环打印就好

结构体大小

如何计算结构体大小:

①结构体变量的首地址,必须是结构体变量中的“最大基本数据类型成员所占字节数”的整数倍

②结构体变量的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节整数倍

③结构体变量的总大小,是结构体变量中“最大基本数据类型成员所占字节数”的整数倍

例:

struct Student//定义一个名为Student的结构体
{
   int s_id;//4
   char s_name[20];//1
   char s_sex[5];//1+2
   int s_age;//4
}stu;//12    
struct node
{
   char ca[20];//1
   char cb[20];//1+2
   int c;//4
};//8

计算结构体大小时,要考虑内存对齐,也叫字节对齐,主要是为了提升CPU效率

什么是内存对齐呢?

①内存的大小基本单位是字节,理论上讲,可以访问任意地址,但由于CPU是以2,4,8的倍数的字节块来访问的,所以就会对基本数据类型的地址做出限制,即必须是2,4,8的倍数,这样就使得数据类型按照一定的规则进行排序,这就是对齐

②有些平台每次读地址都是从偶地址开始,如果一个int(X86,32位系统)存放在偶地址开始的地方,那么读一个周期就能找到这32bit(4字节)。如果存放在奇地址开始的地方,那就需要读两个周期,并对读到结果的高低字节进行拼凑才能得到这32bit,这显然降低了效率

③由于平台不同,字节对齐方式可能不同,所以同样的结构在不同的平台得到的大小可能不同,在无意识情况下,互发数据,可能导致数据出现错乱

Windows默认对齐方式 8字节

Linux      默认对齐方式4字节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值