结构体概念
结构体是一个用户自定义的数据类型,可以存储不同类型的数据。
结构体的定义
下面创建一个学生信息的集合。
struct students
{
string name;
int age;
float score;
}
这样就定义了一个简单的结构体。
之后,在主函数中利用.来进行对结构体中元素的访问。
int main()
{
struct students s1;
s1.name = "jack";
s1.age = 20;
s1.score = 200;
//另一种写法
struct students s2= { "danny", 18, 170};
}
还有一种写法是直接在定义结构体的同时创建一个变量,后来直接在主函数中访问修改。
#include<iostream>
#include<string>
using namespace std;
struct students
{
string name;
int score;
int age;
}s3;
int main()
{
s3.name = "john";
s3.score = 180;
s3.age = 19;
cout<<s3.name<<s3.age<<s3.score<<endl;
return 0;
}
结构体数组
下面用刚刚定义的结构体定义一个结构体数组
#include<iostream>
#include<string>
using namespace std;
struct students
{
string name;
int score;
int age;
}
int main()
{
struct students stuArr[3]=
{
{"jack", 200, 20},{"danny", 170, 18},{"john", 180, 19}
}
//在后面也可以用访问数组的办法进行修改,如stuArr[0].name = "cindy";
for(int i = 0; i < 3; i++)
{
cout<<"name: "<<stuArr.name
<<"age: "<<stuArr.age
<<"score: "<<stuArr.score
<<endl;
}
return 0;
}
结构体指针
结构体指针的构建有三步,首先是创建一个结构体变量,然后利用指针指向结构体变量,最后通过指针访问结构体变量中的数据。
我们还是以上面的例子来解释结构体指针的创建。
#include<iostream>
#include<string>
using namespace std;
struct students
{
string name;
int age;
float scores;
}
int main()
{
struct students s1 = {"danny", 18, 200};
struct students * p = &s1;
cout<<"name "<<p ->name<<
"age "<<p->age<<
"scores "<<p-><<endl; //利用结构体指针访问属性需要使用箭头符号
return 0;
}
结构体的嵌套
当老师想利用结构体来管理自己的学生时,首先所有的老师和老师所带的属性就可以成为一个结构体,而他的学生则又是另一个结构体,这时就需要结构体之间的嵌套来实现表述。
#include<iostream>
#include<string>
uisng namespace std;
struct students
{
string name;
int age;
float scores;
}
struct teacher
{
int age;
string name;
struct students stu;
}
int main()
{
teacher t1;
t1.age = 30;
t1.name = "lucy";
t1.stu.name = "danny";
t1.stu.age = 17;
t1.stu.scores = 100;
//下面的输出方式与前面的一样
结构体做函数参数
将结构体做函数参数,可以将结构体作为函数参数向函数中传递,与之前的函数参数传递一样,也分为值传递和地址传递。
#include<iostream>
#include<string>
using namespace std;
void printstudents(struct students s1) //值传递
{
s1.age=40;
cout<<"name: "<<s1.name<<"age: "<<s1.age<<"score: "<<s1.score<<endl;
}
void printstudents1(struct students *p) //地址传递
{
p->age = 40;
cout<<"name: "<<p->name<<"age: "<<p->age<<"score: "<<p->score<<endl;
}
struct students
{
string name;
int age;
float score;
}
int main()
{
struct students s1{
s1.name = "jack";
s1.age = "18";
s1.score = "70";
}
printstudents(s1);
printstudents1(&s1);
上面程序的运行结果是只有第二个函数打印的年龄发生了变化。
这里的效果与之前的一样,值传递最后改变的只是形参,而地址传递才会真正改变实参。值传递只能在子函数中实现交换,无法使主函数中的值发生变化。
要注意一件事情,在实际的开发当中,如果使用结构体中的值来传递数值的话,会占用大量内存空间,因此,会将传递的值改为指针实现地址传递,将大大减少需要开辟的内存空间
为了防止在只读的函数体当中发生值的改变,需要在结构体指针前加一个常量声明
void printstudents(const students *s1){
cout<<s1->name<<s1->age<<s1->score;
}
这样可以防止误操作将要打印的数据改变。