• 黑马C++ 01基础 —— 指针、结构(重点和难点)


    01 指针

    指针定义和使用

    在这里插入图片描述

    指针变量定义语法: 数据类型 * 变量名;指针就是地址

    指针变量和普通变量的区别

    • 普通变量存放的是数据,指针变量存放的是地址
    • 指针变量可以通过" * "操作符操作指针变量指向的内存空间,这个过程称为解引用

    要点

    • 定义指针:数据类型 * 指针变量名
    • 使用指针:通过**“解引用”的方式找到指针指向的内存**,指针前加*号代表解引用,找到指针指向的内存中的数据
    • *p = 1000,通过*p修改内存或者访问内存

    总结

    • 1: 我们可以通过 & 符号 获取变量的地址
    • 2:利用指针可以记录地址
    • 3:对指针变量解引用,可以操作指针指向的内存
    //p保存的是一个地址
    //利用指针来保存地址,指针就是一个地址
    #include
    using namespace std;
    
    int main()
    {
    	//1.定义指针
    	int a = 10;
    
    	//指针定义的语法:数据类型 * 指针变量名
    	int* p;
    
    	//让指针记录变量a的地址,打印结果一样
    
    	p = &a;		//a的地址存放在变量p中
    	cout << "a的地址:" << &a << endl;
    	cout << "指针p为:" << p << endl; //p记录a的地址
    
    	//2.使用指针
    	//可以通过“解引用”的方式找到指针指向的内存
    	//指针前加*号代表解引用,找到指针指向的内存中的数据
    	*p = 1000;	//通过*p修改内存或者访问内存
    	cout << "a = " << a << endl;
    	cout << "*p = " << *p << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    运行结果
    在这里插入图片描述

    指针所占内存空间

    在这里插入图片描述

    • 所有指针类型在32位操作系统下是4个字节,64位操作系统下是8个字节
    #include
    using namespace std;
    
    int main()
    {
    	//指针占用的空间大小
    	int a = 10;
    	//int* p;
    	//p = &a;//指针指向数据a的地址
    
    	int* p = &a;//等价于int* p; p = &a;
    
    	//在32位操作系统下,指针占4个字节空间大小,不管是什么数据类型
    	//在64位操作系统下,指针占8个字节空间大小
    	cout << "sizeof(int*) = " << sizeof(int*) << endl;  //sizeof(p) 4
    	cout << "sizeof(float*) = " << sizeof(float*) << endl;
    	cout << "sizeof(double*) = " << sizeof(double*) << endl;
    	cout << "sizeof(char*) = " << sizeof(char*) << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 结果
      在这里插入图片描述

    空指针

    刚开始不知道指针该指向哪里,初始化有地方可指,后期有地方可指应该重新更改指向。

    • 空指针:指针变量指向内存中编号为0的空间
    • 用途初始化指针变量
    • 注意:空指针指向的内存是不可以访问的,0~255之间的内存编号是系统占用的,因此不可以访问
    #include
    using namespace std;
    
    int main()
    {
    	//空指针
    	//1.空指针用于给指针变量进行初始化
    	int* p = NULL;//0是空指针的地址编号
    
    	//2.空指针是不可以进行访问
    	//0~255之间的内存编号是系统占用的,因此不可以访问
    	//*p = 100;//会报错
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    野指针

    • 野指针:指针变量指向非法的内存空间
    • 空指针和野指针都不是我们申请的空间,因此不要访问
    #include
    using namespace std;
    
    int main()
    {
    	//野指针:指针变量指向非法的内存空间
    	//程序中,尽量避免野指针
    	//指针变量p指向内存地址编号为0x1100的空间
    	int* p = (int*)0x1100;
    
    	//访问野指针报错 
    	cout << *p << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    const修饰指针(难点)

    • 看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量

    常量指针(修饰指针可以改指针)

    • const修饰指针 —— 常量指针 const int *p = &a
    • 特点:指针的指向可以修改,但指针指向的值不能修改
    • 常量指针不能修改的是常量,可以修改指针里面的地址
    • 如下图所示,a与b中的值都为10,指针p可以指向b,但b中的值必须是10

    在这里插入图片描述

    指针常量(修饰常量可以改常量)

    • const修饰常量 —— 指针常量 int * const p = &a
    • 特点:指针的指向不可以修改,指针指向的值可以修改
    • 指针常量不可以修改的是指针,可以修改的是常量

    在这里插入图片描述

    修饰指针和常量

    • const既修饰指针,又修饰常量
    • 特点:指针的指向和指针指向的值都不能修改
      在这里插入图片描述
    #include
    using namespace std;
    
    int main()
    {
    	int a = 10;
    	int b = 10;
    
    	//1.const修饰指针——常量指针,常量就是const
    	const int* p = &a;//特点:指针的指向可以修改,但指针指向的值不可以修改
    	//*p = 20; 错误
    	p = &b;//正确
    
    	//2.const修饰常量——指针常量
    	//特点:指针的指向不可以修改,指针指向的值可以修改
    	int* const p1 = &a;//const后面跟着常量
    	*p1 = 20;//正确
    	//p = &b;//错误,指针指向不可改
    
    	//3.const既修饰指针,又修饰常量
    	const int* const p2 = &a;//特点:指针的指向和指针指向的值都不可以改
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    指针与数组(难点)

    • 作用:利用指针访问数组中元素
    • 数组名就是数组的首地址,所以可以将首地址赋值给指针
    • int* p = arr; 数组名arr就是数组的首地址
    • p++ 指向数组下一个位置,指针后移4个字节

    在这里插入图片描述

    #include
    using namespace std;
    
    int main()
    {
    	//指针和数组
    	//利用指针访问数组中的元素
    
    	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    	cout << "第一个元素为:" << arr[0] << endl;
    
    	int* p = arr;	//数组名arr就是数组的首地址
    	cout << "利用指针访问第一个元素:" << *p << endl;
    	p++;	//让指针向后偏移4个字节
    	cout << "利用指针访问第二个元素:" << *p << endl;
    
    	cout << "利用指针遍历数组:" << endl;
    	int* p2 = arr;
    	for (int i = 0; i < 10; i++)
    	{
    		//cout << arr[i] << endl;
    		cout << *p2 << " ";//p2指的是数组地址,*p2指向地址所在的值
    		p2++;
    	}
    	cout << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 结果
      在这里插入图片描述

    指针与函数(难点)

    • 作用:利用指针作函数参数,可以修改实参的值
    • 如果不想修改实参,就用值传递,如果想修改实参,就用地址传递
    • *p1、*p2分别表示所在地址的值,地址传递改变实参本质是地址所在值进行改变(比如交换),但指针所指的地址是不变的(值变,地址不变)。
      在这里插入图片描述
    #include
    using namespace std;
    
    //实现两个数字进行交换
    void swap01(int a, int b)// 形参a,b发生改变,实参没有改变
    {
    	int temp = a;//temp保存的是a的值
    	a = b;
    	b = temp;
    
    	cout << "swap01 a = " << a << endl;
    	cout << "swap01 b = " << b << endl;
    }
    
    void swap02(int* p1, int* p2)
    {
    	//temp保存的是a的值10,*p1保存的是变量a的地址,*p2保存的是变量b的地址
    	int temp = *p1;
    	*p1 = *p2;
    	*p2 = temp;
    }
    
    int main()
    {
    	//指针和函数
    	//1.值传递(形参改变不了实参)
    	int a1 = 10;
    	int b1 = 20;
    	swap01(a1, b1);
    
    	cout << "a1 = " << a1 << endl;
    	cout << "b1 = " << b1 << endl;
    	cout << endl;
    
    	//2.地址传递(形参改变实参)
    	//地址传递可以修饰实参
    	int a2 = 10;
    	int b2 = 20;
    	swap02(&a2, &b2);// p1和p2都要传递地址
    
    	cout << "a2 = " << a2 << endl;
    	cout << "b2 = " << b2 << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 结果
      在这里插入图片描述

    指针、数组与函数案例(重难点!!!)

    案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序
    例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 }

    • 当数组名传入到函数作为参数时,被退化为指向首元素的指针
    • 把一个数组传递到函数中,就是用指针接收数组首地址!!!!!

    超级重点:

    • arr单独表示时是指数组的首地址,arr[i] 表示的是数组第i个元素
    • 同样指针p单独表示时是指数组的首地址,而p[i]则表示的是数组第i个元素
    • 指针单独表示就是代表其中的地址值本质上arr和指针p是一个东西!!!

    非常重要的结论如下

    • 下面的int* p等价于int p[ ];int* q等价于int q[ ],两种写法是相等的,可以相互替换。一个是用指针传递数组,一个使用数组传递数组。两种写法结果是相等的。
    #include
    using namespace std;
    
    //冒泡排序函数  参数1  数组的首地址  参数2  数组的长度
    void bubbleSort(int* p, int len)	// arr表示数组的首地址,len是数组的长度
    {
    	for (int i = 0; i < len - 1; i++) //p本质是一个数组,int* p表示数组第一个元素
    	{
    		for (int j = 0; j < len - i - 1; j++)
    		{
    			//如果j > j+1的值,交换数字
    			if (p[j] > p[j + 1])
    			{
    				int temp = p[j];
    				p[j] = p[j + 1];
    				p[j + 1] = temp;
    			}
    		}
    	}
    }
    
    //打印数组
    void printArray(int* q, int len)// 传入的是数组的首地址以及数组长度
    {
    	for (int i = 0; i < len; i++)//q本质是一个数组,int* q表示数组第一个元素
    	{
    		cout << q[i] << " ";
    	}
    	cout << endl;
    }
    
    int main()
    {
    	//1.先创建一个数组
    	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
    
    	//数组长度
    	int len = sizeof(arr) / sizeof(arr[0]);
    
    	//2.创建函数,实现冒泡排序(传入数组及其长度)
    	bubbleSort(arr, len);// arr就是数组的地址
    
    	//3.打印排序后的数组
    	printArray(arr, len);
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    02 结构体

    结构体定义和使用

    语法:struct 结构体名 { 结构体成员列表 };最后一定要加封号

    通过结构体创建变量的方式有三种:

    • struct 结构体名 变量名
    • struct 结构体名 变量名 = { 成员1值 , 成员2值…}
    • 定义结构体时顺便创建变量(在写struct最后就可以)不建议用

    总结

    • 1:定义结构体时的关键字是struct,struct不可省略
    • 2:创建结构体变量时,关键字struct 可以省略
    • 3:结构体变量利用操作符 ‘’.‘’ 访问成员
    #include
    #include
    using namespace std;
    
    
    //1.创建学生数据类型——学生包括(姓名、年龄、分数)
    //自定义数据类型,一些类型集合组成的一个类型
    //语法  struct 类型名称 {成员列表}
    struct Student
    {
    	//姓名
    	string name;
    	//年龄
    	int age;
    	//分数
    	int score;
    }s3;	//创建结构体时顺便创建变量
    
    //2.通过学生类型创建具体的学生(三种创建方式)
    int main()
    {
    	//2.1 struct Student s1
    	//结构体创建时struct关键字可以省略,结构体定义时struct关键字不可以省略
    	struct Student s1;
    	// Student s1;这样创建也是可以的
    	//给s1属性赋值,通过“.”访问结构体变量中的属性
    	s1.name = "张三";
    	s1.age = 18;
    	s1.score = 100;
    
    	cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
    
    	//2.2 struct Student s2={...}
    	struct Student s2 = { "李四",19,80 };
    
    	cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl;
    
    	//2.3 定义结构体时顺便创建结构体变量
    	s3.name = "王五";
    	s3.age = 20;
    	s3.score = 80;
    
    	cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 分数:" << s3.score << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    结果
    在这里插入图片描述

    结构体数组

    • 作用:将自定义的结构体放入到数组中方便维护
    • 语法 struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }
    #include
    #include
    using namespace std;
    
    //结构体数组
    //1.定义结构体
    struct Student
    {
    	//成员变量
    	string name;//姓名
    	int age;//年龄
    	int score;//分数
    };
    
    
    int main()
    {
    	//2.创建结构体数组
    	//类似于struct Student s2={"李四",19,80}
    	struct Student stuArray[3] =
    	{
    		{"张三",18,100},
    		{"李四",28,99},
    		{"王五",38,66}
    	};
    
    	//3.给结构体数组中的元素赋值,将王五的信息覆盖
    	stuArray[2].name = "赵六";
    	stuArray[2].age = 80;
    	stuArray[2].score = 60;
    
    	//4.遍历结构体数组
    	for (int i = 0; i < 3; i++)
    	{
    		cout << "姓名:" << stuArray[i].name << " "
    			<< "年龄:" << stuArray[i].age << " "
    			<< "分数:" << stuArray[i].score << endl;
    	}
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 结果
      在这里插入图片描述

    结构体指针

    • 作用:通过指针访问结构体中的成员
    • 利用操作符 -> 可以通过结构体指针访问结构体属性
    #include
    #include
    using namespace std;
    
    //结构体指针
    //通过指针访问结构体中的成员,利用操作符 `- > `可以通过结构体指针访问结构体属性
    
    //定义学生结构体
    struct Student
    {
    	string name;//姓名
    	int age;//年龄
    	int score;//分数
    };
    
    int main()
    {
    	//1.创建学生的结构体变量
    	struct Student s = { "张三",18,100 };
    
    	//2.通过指针指向结构体变量
    	struct Student* p = &s;//struct可以省略
    
    	//3.通过指针访问结构体变量中的数据
    	//通过结构体指针访问结构体中的属性,需要用“->”,即指针通过 -> 操作符可以访问成员
    	cout << "姓名:" << p->name << " " << "年龄:" 
    		 << p->age << " "  << "分数:" << p->score << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 结果
      在这里插入图片描述

    结构体嵌套结构体

    在这里插入图片描述

    作用: 结构体中的成员可以是另一个结构体

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

    #include
    #include// 姓名是string类型
    using namespace std;
    
    //定义学生结构体
    struct student
    {
    	string name;//姓名
    	int age;//年龄
    	int score;//分数
    };
    
    
    //定义老师结构体
    struct teacher
    {
    	int id;//教师编号
    	string name;//教师姓名
    	int age;//年龄
    	struct 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.name << endl;
    	cout << "辅导学生姓名:" << t.stu.name << " 年龄:" << t.stu.age 
    		 << " 考试分数:" << t.stu.score << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 结果
      在这里插入图片描述

    结构体做函数参数(难点)

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

    传递方式有两种:

    • 值传递
    • 地址传递
    #include
    #include
    using namespace std;
    
    //定义学生结构体
    struct student
    {
    	string name;//姓名
    	int age;//年龄
    	int score;//分数
    };
    
    //打印学生信息函数
    //1.值传递   (形参改变不改变实参)
    void printStudent1(struct student s)
    {
    	s.age = 100;// 形参内部打印年龄为100
    	cout << "子函数1  姓名:" << s.name << " 年龄:" << s.age 
    		 << " 分数:" << s.score << endl;
    }
    
    //2.地址传递  (形参改变可以改变实参)
    void printStudent2(struct student* p)//用指针接收地址,指针地址传递用“->”
    {
    	p->age = 80;
    	cout << "子函数2  姓名:" << p->name << " 年龄:" << p->age 
    		 << " 分数:" << p->score << endl;
    }
    
    int main()
    {
    	//结构体做函数参数
    	//将学生传入到一个参数中,打印学生身上的所有信息
    
    	//创建结构体变量
    	struct student s;
    	s.name = "张三";
    	s.age = 20;
    	s.score = 85;
    
    	//值传递,age形参值会改变,但实参值不变
    	printStudent1(s);
    	cout << "main函数 姓名:" << s.name << " 年龄:" << s.age
    		 << "  分数:" << s.score << endl;
    	cout << endl;
    
    	//地址传递,age形参值会改变,实参值也会跟着改变
    	printStudent2(&s);	
    	cout << "main函数 姓名:" << s.name << " 年龄:" << s.age 
    		 << " 分数:" << s.score << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 结果:上面是值传递,下面是地址传递
      在这里插入图片描述

    结构体const使用

    作用:用const来防止误操作

    #include
    #include
    using namespace std;
    
    //const使用场景
    //学生结构体定义
    struct student
    {
    	//成员列表
    	string name;  //姓名
    	int age;      //年龄
    	int score;    //分数
    };
    
    //将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
    void printStudent(const student* stu) //加const防止函数体中的误操作
    {
    	//stu->age = 100; //加const修饰防止误操作,防止修改
    	cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" 
    		 << stu->score << endl;
    }//指针访问用“->”
    
    
    int main()
    {
    	student stu = { "张三",18,100 };
    	printStudent(&stu);
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 结果:防止结构体数据进行修改,无法使用stu->age = 100进行年龄修改
      在这里插入图片描述

    结构体案例1

    案例描述:

    学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:

    • 设计学生和老师的结构体,在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员

    • 学生的成员有姓名、考试分数,创建数组存放3名老师通过函数给每个老师及所带的学生赋值

    • 最终打印出老师数据以及老师所带的学生数据
      在这里插入图片描述

    • 这里struct Teacher tArray[ ]可以用struct Teacher* tArray替代,使用的是指针,其他的不变。

    #include
    #include
    #include
    using namespace std;
    
    //定义学生结构体
    struct Student
    {
    	string sName;//姓名
    	int score;//分数
    };
    
    //定义老师结构体
    struct Teacher
    {
    	string tName;//教师姓名
    	struct Student sArray[5];//学生数组
    };
    
    //给老师和学生赋值的函数,使用数组和长度
    void allocateSpace(struct Teacher tArray[], int len)
    {
    	//string nameSeed = "ABCDE";	// 老师3个,每个老师指导5个学生
    	char nameSeed[] = "ABCDE";  // 这种方法也可以
    	//给老师赋值
    	for (int i = 0; i < len; i++)
    	{
    		tArray[i].tName = "Teacher_";
    		tArray[i].tName += nameSeed[i];
    
    		//通过循环给每名老师所带的学生赋值
    		for (int j = 0; j < 5; j++)
    		{
    			tArray[i].sArray[j].sName = "Student_";
    			tArray[i].sArray[j].sName += nameSeed[j];
    			int random = rand() % 61 + 40;//学生分数在40~100(如果61改为60则范围是40~99)
    			tArray[i].sArray[j].score = random;
    		}
    
    	}
    }
    
    //打印所有信息,使用数组和长度
    void printInfo(struct Teacher tArray[], int len)
    {
    	for (int i = 0; i < len; i++)
    	{
    		cout << "老师姓名:" << tArray[i].tName << endl;
    		for (int j = 0; j < 5; j++)
    		{
    			cout << "\t学生姓名:" << tArray[i].sArray[j].sName << "  "
    				 << " 考试分数:" << tArray[i].sArray[j].score << endl;
    		}
    		cout << endl;
    	}
    }
    
    int main()
    {
    	//随机数种子
    	srand((unsigned int)time(NULL));// 加#include
    
    	//1.创建3名老师的数组
    	struct Teacher tArray[3];
    
    	//2.通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
    	int len = sizeof(tArray) / sizeof(tArray[0]);// 这里 len = 3
    	allocateSpace(tArray, len);
    
    	//3.打印所有老师及所带的学生信息
    	printInfo(tArray, len);
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 结果
      在这里插入图片描述

    结构体案例2

    案例描述:设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。
    通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

    五名英雄信息如下:

    		{"刘备",23,"男"},
    		{"关羽",22,"男"},
    		{"张飞",20,"男"},
    		{"赵云",21,"男"},
    		{"貂蝉",19,"女"},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    #include
    #include
    using namespace std;
    
    
    //1.设计英雄结构体
    struct Hero
    {
    	string name;//姓名
    	int age;//年龄
    	string sex;//性别
    };
    
    //冒泡排序——实现年龄升序排列
    void bubbleSort(struct Hero heroArray[], int len)
    {
    	for (int i = 0; i < len - 1; i++)
    	{
    		for (int j = 0; j < len - i - 1; j++)
    		{
    			//如果j下标的元素年龄大于j+1下标的元素年龄,就交换两个元素
    			if (heroArray[j].age > heroArray[j + 1].age)
    			{
    				struct Hero temp = heroArray[j];//temp是结构体类型
    				heroArray[j] = heroArray[j + 1];
    				heroArray[j + 1] = temp;
    			}
    		}
    	}
    }
    
    //打印排序后数组中的信息
    void printHero(struct Hero heroArray[], int len)
    {
    	for (int i = 0; i < len; i++)
    	{
    		cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
    			<< " 性别:" << heroArray[i].sex << endl;
    	}
    }
    
    int main()
    {
    	//2.创建数组存放5名英雄
    	struct Hero heroArray[5] =
    	{
    		{"刘备",23,"男"},
    		{"关羽",22,"男"},
    		{"张飞",20,"男"},
    		{"赵云",21,"男"},
    		{"貂蝉",19,"女"},
    	};
    	int len = sizeof(heroArray) / sizeof(heroArray[0]);
    
    	cout << "排序前打印:" << endl;
    	for (int i = 0; i < len; i++)
    	{
    		cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
    			<< " 性别:" << heroArray[i].sex << endl;
    	}
    	cout << endl;
    
    	//3.对数组进行排序,按照年龄进行升序排列
    	bubbleSort(heroArray, len);
    	cout << "排序后打印:" << endl;
    
    	//4.将排序后的结果打印输出
    	printHero(heroArray, len);
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 结果
      在这里插入图片描述
  • 相关阅读:
    流批一体随想
    收银系统十大排名(2023年十大收银软件品牌排行榜)
    Python——BeautifulSoup库
    理解CSS的层叠性和继承性
    拼接字符串,得到字典序最小的结果
    springboot心灵治愈交流平台源码和论文
    [已解决]react打包部署
    一心为农,以智取胜——张继群的智慧农业之路
    【JAVA】Retrofit详解和使用
    BST搜索二叉树
  • 原文地址:https://blog.csdn.net/qq_42731062/article/details/126297349