空指针
- 空指针: 指针变量指向内存中编号为0的空间
- ⽤途:初始化指针变量
注意:空指针指向的内存是不可以访问的
int main() {
//指针变量p指向内存地址编号为0的空间
int * p = NULL;
//访问空指针报错
//内存编号0 ~255为系统占用内存,不允许用户访问
cout << *p << endl;
}
野指针
指针变量指向⾮法的内存空间
//指针变量p指向内存地址编号为0x1100的空间
int * p =(int *)0x1100;
//访问野指针报错
cout<< *p << endl;
空指针和野指针都不是我们申请的空间,因此不要访问。
const修饰的变量 const 数据类型 常量名 = 常量值
通常在变量定义前加关键字const,修饰该变量为常量,不可修改
const修饰指针
const修饰指针有三种情况:
- const修饰指针 — 常量指针
- const修饰常量 — 指针常量
- const既修饰指针,⼜修饰常量
#include <iostream>
using namespace std;
int main() {
int a = 10;
int b = 100;
// 看const右侧紧跟着的是指针还是常量, 是指针就是常量指针, 是常量就是指针常量
//const修饰的是指针,指针的指向可以改, 指针指向的值不能更改
const int *p1 = &a;
p1 = &b; // 可以 指针的指向可以改,
*p1 = 100; // 不可以 指针指向的值不能更改
// 不可以 // 指针指向的值不能更改
//const修饰的是常量 , 指针的指向不可以改,指针指向的值可以更改
int * const p2 = &a;
// p2 = &b; // 不可以 指针的指向不可以改,
*p2 = 100; // 可以 指针指向的值可以更改
//const 既修饰指针也修饰常量 都不能改
const int * const p3 = &a;
// p3 = &b; // 不可以
// *p3 = 300; // 不可以
//
}
结构体
结构体属于⽤⼾⾃定义的数据类型,允许⽤⼾存储不同的数据类型
语法: struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的⽅式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名 = { 成员1值 , 成员2值…}
- 定义结构体时顺便创建变量
#include <iostream>
#include <cstring>
using namespace std;
// 结构体的定义
struct student{
// 成员列表
string name;
int age;
int score ;
} stu3;
int main() {
// struct 结构体名 变量名
// struct student stu1;
student stu1; // struct 关键字可以省略
stu1.name = "eric";
stu1.age = 20;
stu1.score = 100;
cout<< "stu1.name = " << stu1.name << endl;
cout<< "stu1.age = " << stu1.age << endl;
cout<< "stu1.score = " << stu1.score << endl;
//- struct 结构体名 变量名 = { 成员1值 , 成员2值...}
struct student stud2 = {"james", 12, 61};
cout<< "stud2.name = " << stud2.name << endl;
cout<< "stud2.age = " << stud2.age << endl;
cout<< "stud2.score = " << stud2.score << endl;
//- 定义结构体时顺便创建变量
stu3.name = "taylor";
stu3.age = 23;
stu3.score = 80;
cout<< "stu3.name = " << stu3.name << endl;
cout<< "stu3.age = " << stu3.age << endl;
cout<< "stu3.score = " << stu3.score << endl;
}
- 定义结构体时的关键字是struct,不可省略
- 创建结构体变量时,关键字struct可以省略
- 结构体变量利用操作符 ‘’.’’ 访问成员
结构体数组
作⽤:将⾃定义的结构体放⼊到数组中⽅便维护
语法: struct 结构体名 数组名[元素个数] = { {} , {} , … {} }
#include <iostream>
#include <cstring>
using namespace std;
// 结构体的定义
struct student{
// 成员列表
string name;
int age;
int score ;
} ;
int main() {
struct student arr[3] = {{"tom", 13, 100},
{"bob", 33, 78}, {"eric", 18, 50}};
// 遍历
for (int i = 0; i < 3; ++i) {
cout<< "name = "<< arr[i].name << " age = "<< arr[i].age << " score = "<< arr[i].score <<endl;
}
}
结构体指针
作⽤:通过指针访问结构体中的成员
利⽤操作符 -> 可以通过结构体指针访问结构体属性
#include <iostream>
#include <cstring>
using namespace std;
// 结构体的定义
struct student{
// 成员列表
string name;
int age;
int score ;
} ;
int main() {
struct student stu = {"james", 12, 61};
// 将 stu 的地址 赋给指针变量 p
struct student * p = &stu;
// 修改
p->score = 100;
cout<< "name = " << p->name << endl;
cout<< "name = " << stu.name<< endl;
cout<< "age = " << p->age<< endl;
cout<< "age = " << stu.age<< endl;
cout<< "score = " << p->score<< endl;
cout<< "score = " << stu.score<< endl;
}
结构体嵌套结构体
结构体作为成员属性
作⽤: 结构体中的成员可以是另⼀个结构体
例如:每个⽼师辅导⼀个学员,⼀个⽼师的结构体中,记录⼀个学⽣的结构体
#include <iostream>
#include <cstring>
using namespace std;
struct student{
string name;
int age;
int score ;
};
struct teacher{
int id; // 工号
string name;
int age;
struct student stu; // 结构体作为成员属性
};
int main() {
struct teacher t1;
struct student s1 = {"hanmeimei", 22, 90};
t1.id = 99999;
t1.name = "eric";
t1.age = 70;
// t1.stu.name = "bob";
// t1.stu.age = 20;
// t1.stu.score = 120;
t1.stu = s1;
cout << t1.id << endl;
cout << t1.name << endl;
cout << t1.age << endl;
cout << t1.stu.name << endl;
cout << t1.stu.age << endl;
cout << t1.stu.score << endl;
}
结构体做函数参数
作⽤:将结构体作为参数向函数中传递
传递⽅式有两种:
- 值传递
- 地址传递
#include <iostream>
#include <cstring>
using namespace std;
struct student{
string name;
int age;
int score ;
};
// 值传递
void printStudent(student stu){
stu.age = 100;
cout<< "stu.name = " << stu.name << endl;
cout<< "stu.age = " << stu.age << endl;
cout<< "stu.score = " << stu.score << endl;
}
// 地址传递
void printStudent2(student *stu){
stu->age = 100;
cout<< "stu.name = " << stu->name << endl;
cout<< "stu.age = " << stu->age << endl;
cout<< "stu.score = " << stu->score<< endl;
}
int main() {
struct student s1 = {"hanmeimei", 22, 90};
printStudent(s1);
cout<< "s1.name = " << s1.name << endl;
cout<< "s1.age = " << s1.age << endl;
cout<< "s1.score = " << s1.score << endl;
printStudent2(&s1);
cout<< "s1.name = " << s1.name << endl;
cout<< "s1.age = " << s1.age << endl;
cout<< "s1.score = " << s1.score << endl;
}
总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
结构体中 const使⽤场景
作⽤:⽤const来防⽌误操作
#include <iostream>
#include <cstring>
using namespace std;
struct student{
string name;
int age;
int score ;
};
// const 修饰的是指针 指针的指向可以改, 指针指向的值不能更改
void printStudent(const student *stu){
stu->age = 100; // 不可以
cout<< "stu.name = " << stu->name << endl;
cout<< "stu.age = " << stu->age << endl;
cout<< "stu.score = " << stu->score<< endl;
}
int main() {
struct student s1 = {"hanmeimei", 22, 90};
printStudent(&s1);
cout<< "s1.name = " << s1.name << endl;
cout<< "s1.age = " << s1.age << endl;
cout<< "s1.score = " << s1.score << endl;
}
结构体案例
学校正在做毕设项⽬,每名⽼师带领5个学⽣,总共有3名⽼师,需求如下设计学⽣和⽼师的结构体,其中在⽼师的结构体中,有⽼师姓名和⼀个存放5名学⽣的数组作为成员 学⽣的成员有姓名、考试分数,创建数组存放3名⽼师,通过函数给每个⽼师及所带的学⽣赋值 最终打印出⽼师数据以及⽼师所带的学⽣数据。
#include <iostream>
#include <cstring>
using namespace std;
struct Student{
string name;
int score ;
};
struct Teacher{
string name;
struct Student sArray[5];
};
void allocateSpace(Teacher tArray[], int len){
string tName = "teacher";
string sName = "student";
string nameSeed = "ABCDE";
for (int i = 0; i < len ; ++i) {
tArray[i].name = tName + nameSeed[i];
for (int j = 0; j < 5; ++j) {
tArray[i].sArray[j].name = sName + nameSeed[j];
tArray[i].sArray[j].score = 100;
}
}
}
void print(Teacher tArray[], int len){
for (int i = 0; i < len ; ++i) {
cout << tArray[i].name << endl;
for (int j = 0; j < 5; ++j) {
cout << tArray[i].sArray[j].name << endl;
cout << tArray[i].sArray[j].score << endl;
}
cout << "------------------------------------" << endl;
}
}
int main() {
Teacher tArray[3]; // 老师数组
allocateSpace(tArray, 3);
print(tArray, 3);
}