学习日记---第7天(结构体)

笔记复习

1.结构体指针

结构体指针指的是指向结构体变量的指针

作用:通过指针访问结构体中的成员

相比于直接访问结构体变量,使用结构体指针访问结构体中的变量占用内存更少,效率更高,并且由于指针的特殊性质,结构体指针可以修改结构体中的实参。

定义语法:结构体名 * 指针名;

调用语法:指针名->属性名

代码示例如下:


#include<iostream>
using namespace std;

struct student {
	string name;
	int age;
	int score;
};

int main() {
	student s = {"张三",18,100 };
	//int* p = &s;
//不能依旧跟前面一样使用int*类型的指针,因为student*类型的值不能用于初始化int*类型的实体
	struct student* p = &s;//给指针p结构体变量s的地址相当于给p一个访问s里面属性的权限
	//通过指针访问结构体变量中的数据
	cout << "name:" << p->name << "age:" << p->age << "score:" << p->score << endl;
	return 0;
}

2.结构体嵌套结构体

即结构体中的成员可以是另一个结构体的变量,将结构体的变量放在想要包含该结构体变量的结构体定义中即可

具体实例:每个老师辅导一个学员,在老师的结构体中记录一个学生的结构体

那么我们需要定义两个结构体,分别是老师和学生,这时候我们需要先定义学生结构体,因为在学生结构体中不记录老师结构体,而在老师结构体中记录了学生结构体,如果老师结构体先被定义那么编译器就认不出学生结构体,会报错

定义学生结构体

struct student {
	string name;
	int age;
	int score;
};

定义老师结构体

struct teacher {
	int id;
	string name;
	int age;
	student stu;
    //将原本放在main函数中的结构体变量定义放在teacher结构体定义中
	//teacher 结构体中包含了一个名为 stu 的成员,这个成员是 student 类型的。
	// //这意味着每个 teacher 对象都会包含一个 student 对象作为它的一个属性。
    //即每个老师都带一位学生
};

那么在调用的时候,我们依旧使用点函数,先表明我们要调用teacher结构体变量的stu属性,再调用stu属性中的其他属性

main函数中的代码如下:

int main() {
	teacher t;
	t.id = 10000;
	t.name = "老王";
	t.age = 50;
	t.stu.name = "小王";
	t.stu.age = 20;
	t.stu.score = 60;

	cout << "老师姓名:" << t.name << "老师编号:" << t.id << "老师年龄:" << t.age
		<< "学员姓名:" << t.stu.name << "学员年龄:" << t.stu.age << "学员成绩:" << t.stu.score << endl;
	return 0;
}

完整代码如下: 

#include<iostream>
using namespace std;

struct student {
	string name;
	int age;
	int score;
};

struct teacher {
	int id;
	string name;
	int age;
	student stu;
};

int main() {
	teacher t;
	t.id = 10000;
	t.name = "老王";
	t.age = 50;
	t.stu.name = "小王";
	t.stu.age = 20;
	t.stu.score = 60;
	cout << "老师姓名:" << t.name << "老师编号:" << t.id << "老师年龄:" << t.age
		<< "学员姓名:" << t.stu.name << "学员年龄:" << t.stu.age << "学员成绩:" << t.stu.score << endl;
	return 0;
}

3.结构体做函数参数

作用:将结构体作为参数向函数中传递

传递的方式有两种,分别是值传递标题二和地址传递

a.值传递

struct student {
	string name;
	int age;
	int score;
};

void printstu1(student s) {//参数列表中写传入参数的类型student和名字s
	cout << "子函数1中 name:" << s.name << "age:" << s.age << "score:" << s.score << endl;
}

b.地址传递

struct student {
	string name;
	int age;
	int score;
};

void printstu2(student *p) {//参数列表中写student*指明指针的类型
	cout << "子函数2中 name:" << p->name << "age:" << p->age << "score" << p->score << endl;
}

值传递和地址传递的区别是,1.地址传递速度更快    2.当我们在值传递函数中修改属性的值时,修改的只是形参的值,并不会修改实参的值,当我们在地址传递的函数中修改属性的值时,形参和实参的值都会被修改,例如:

#include<iostream>
#include<string>
using namespace std;

struct student {
	string name;
	int age;
	int score;
};

//1.值传递
void printstu1(student s) {
	s.age = 25;//仅改变形参
	cout << "子函数1中 name:" << s.name << "age:" << s.age << "score:" << s.score << endl;
}
//2.地址传递
void printstu2(student *p) {
	p->age = 100;//同时改变形参和实参
	cout << "子函数2中 name:" << p->name << "age:" << p->age << "score" << p->score << endl;
}

int main() {
	student s;
	s.name = " 张三";
	s.age = 20;
	s.score = 85;
    //结构体做函数参数
	printstu1(s);
    //结构体地址做函数参数
	printstu2(&s);//函数接收的是地址,要在s前面加取址符
	cout << "main函数中打印 name:" << s.name << "age:" << s.age << "score" << s.score << endl;

	return 0;
}

总结:当我们想要改变main函数中的数据时,同地址传递,反之用值传递

4.const关键字在结构体中的使用

前面我们讲地址传递比值传递速度更快,但这会带来一个缺点,即地址传递会修改掉实参的值,那么这时候我们就可以const关键字来防止这种操作发生,原理就是前面学到的常量指针

具体使用实在函数参数列表中指针的前面加上const,使函数接收的是一个常量指针,即指针的指向可以修改,但指针指向的值无法修改的一个指针,代码示例如下:

#include<iostream>
#include<string>
using namespace std;

struct student {
	string name;
	int age;
	int score;
};

void stu(const student *p) {
    //函数接收的是一个常量指针,这样我们在函数体内部就无法修改指针指向的值
	//加上const之后,一旦有修改的操作就会报错,因此当出现实参的值被修改时,可以通过该操作检查代码
	cout << "name:" << p->name << "age:" << p->age << "score:" << p->score << endl;
};

int main() {
	//创建结构体变量
	student s = { "张三",15,70 };
	//通过函数来打印结构体变量的信息
	stu(&s);
	return 0;
};

下期预告

1.两个案例深入理解结构体

2.通讯录管理系统项目实战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值