5 数组
5.1 概述
所谓数组,就是一个集合,里面存放了相同类型的数据元素
**特点1:**数组中的每个数据元素都是相同的数据类型
**特点2:**数组是由连续的内存位置组成的
5.2 一维数组
5.2.1 一维数组定义方式
一维数组定义的三种方式:
数据类型 数组名[ 数组长度 ];
数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
数据类型 数组名[ ] = { 值1,值2 ...};
int main() {
//定义方式1
//数据类型 数组名[元素个数];
int score[10];
//利用下标赋值
score[0] = 100;
score[1] = 99;
score[2] = 85;
//利用下标输出
cout << score[0] << endl;
cout << score[1] << endl;
cout << score[2] << endl;
//第二种定义方式
//数据类型 数组名[元素个数] = {值1,值2 ,值3 ...};
//如果{}内不足10个数据,剩余数据用0补全
int score2[10] = { 100, 90,80,70,60,50,40,30,20,10 };
//逐个输出
//cout << score2[0] << endl;
//cout << score2[1] << endl;
//一个一个输出太麻烦,因此可以利用循环进行输出
for (int i = 0; i < 10; i++)
{
cout << score2[i] << endl;
}
//定义方式3
//数据类型 数组名[] = {值1,值2 ,值3 ...};
int score3[] = { 100,90,80,70,60,50,40,30,20,10 };
for (int i = 0; i < 10; i++)
{
cout << score3[i] << endl;
}
system("pause");
return 0;
}
总结1:数组名的命名规范与变量名命名规范一致,不要和变量重名
总结2:数组中下标是从0开始索引
5.2.2 一维数组数组名
一维数组名称的用途:
- 可以统计整个数组在内存中的长度
- 可以获取数组在内存中的首地址
#include<iostream>
using namespace std;
#include <string>
int main() {
//数组名用途
//1、可以获取整个数组占用内存空间大小
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << "整个数组所占内存空间为: " << sizeof(arr) << endl;
cout << "每个元素所占内存空间为: " << sizeof(arr[0]) << endl;
cout << "数组的元素个数为: " << sizeof(arr) / sizeof(arr[0]) << endl;
//2、可以通过数组名获取到数组首地址
cout << "数组首地址为: " << (int)arr << endl;
cout << "数组中第一个元素地址为: " << (int)&arr[0] << endl;
cout << "数组中第二个元素地址为: " << (int)&arr[1] << endl;
//arr = 100; 错误,数组名是常量,因此不可以赋值
system("pause");
return 0;
}
注意:数组名是常量,不可以赋值
总结1:直接打印数组名,可以查看数组所占内存的首地址
总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小
练习案例1:五只小猪称体重
案例描述:
在一个数组中键入了五只小猪的体重
找出并打印最重的小猪体重。
#include<iostream>
using namespace std;
//五只小猪称体重
int main()
{
int arr[5];
int max = 0;
for (int i = 0; i < 5; i++)
{
cout << "请输入第" << i+1 << "只小猪的体重" << endl;
cin >> arr[i];
}
for (int j = 0; j < 5; j++)
{
if (max < arr[j])
{
max = arr[j];
}
}
cout << "最重的小猪体重为" << max << endl;
system("pause");
return 0;
}
**练习案例2:**数组元素逆置
**案例描述:**请声明一个5个元素的数组,并且将元素逆置.
(如原数组元素为:1,3,2,5,4;逆置后输出结果为:4,5,2,3,1);
#include<iostream>
using namespace std;
int main()
{
int arr[] = { 1,2,3,4,5 };
int start = 0;
int end = sizeof(arr) / sizeof(arr[0])-1;
while(start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
5.2.3 冒泡排序
作用: 最常用的排序算法,对数组内元素进行排序
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。
- 重复以上的步骤,每次比较次数-1,直到不需要比较
#include<iostream>
using namespace std;
//对{ 4,2,8,0,5,7,1,3,9 }排序
int main()
{
int arr[] = { 4,2,8,0,5,7,1,3,9 };
for (int i = 0; i < 9 - 1; i++)//排序的总轮数等于 元素个数-1
{
for (int j = 0; j < 9 - 1 - i; j++)//每次对比次数等于 元素个数- 1 -当前对比轮数
{
if (arr[j] < arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0; i < 9; i++)
{
cout << arr[i];
}
cout << endl;
system("pause");
return 0;
}
5.3 二维数组
二维数组就是在一维数组上,多加一个维度。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nFioYqzf-1608817912426)(assets/1541905559138.png)]
5.3.1 二维数组定义方式
二维数组定义的四种方式:
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性
#include<iostream>
using namespace std;
//二维数组定义方式
int main() {
//方式1
//数组类型 数组名 [行数][列数]
int arr[2][3];
arr[0][0] = 1;
arr[0][1] = 2;
arr[0][2] = 3;
arr[1][0] = 4;
arr[1][1] = 5;
arr[1][2] = 6;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
//方式2
//数据类型 数组名[行数][列数] = { {数据1,数据2 } ,{数据3,数据4 } };
int arr2[2][3] =
{
{1,2,3},
{4,5,6}
};
//方式3
//数据类型 数组名[行数][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr3[2][3] = { 1,2,3,4,5,6 };
//方式4
//数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr4[][3] = { 1,2,3,4,5,6 };
system("pause");
return 0;
}
总结:在定义二维数组时,如果初始化了数据,可以省略行数
5.3.2 二维数组数组名
- 查看二维数组所占内存空间
- 获取二维数组首地址
#include<iostream>
using namespace std;
int main() {
//二维数组数组名
int arr[2][3] =
{
{1,2,3},
{4,5,6}
};
cout << "二维数组大小: " << sizeof(arr) << endl;
cout << "二维数组一行大小: " << sizeof(arr[0]) << endl;
cout << "二维数组元素大小: " << sizeof(arr[0][0]) << endl;
cout << "二维数组行数: " << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "二维数组列数: " << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;
//地址
cout << "二维数组首地址:" << arr << endl;
cout << "二维数组第一行地址:" << arr[0] << endl;
cout << "二维数组第二行地址:" << arr[1] << endl;
cout << "二维数组第一个元素地址:" << &arr[0][0] << endl;
cout << "二维数组第二个元素地址:" << &arr[0][1] << endl;
system("pause");
return 0;
}
5.3.3 二维数组应用案例
考试成绩统计:
案例描述:有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 100 | 100 | 100 |
李四 | 90 | 50 | 100 |
王五 | 60 | 70 | 80 |
#include<iostream>
#include<string>
using namespace std;
//**考试成绩统计:**
//
//案例描述:有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,** 请分别输出三名同学的总成绩**
//
//| | 语文 | 数学 | 英语 |
//| ---- | ---- | ---- | ---- |
//| 张三 | 100 | 100 | 100 |
//| 李四 | 90 | 50 | 100 |
//| 王五 | 60 | 70 | 80 |
int main()
{
//1.创建二维数组
int arr[][3] =
{
{100,100,100},
{90,50,100},
{60,70,80}
};
string name[3] = { "张三","李四","王五" };
string subject[3] = { "语文","数学", "英语" };
//2.统计每个人总分数
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
int num1 = 0;//统计分数变量
for (int j = 0; j < sizeof(arr[0])/ sizeof(arr[0][0]); j++)
{
num1 += arr[i][j];
}
cout << name[i] << "同学的总分" << num1 << endl;
cout << name[i] << "同学的平均分" << num1/3 << endl;
}
//每位同学的平均分
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
int num2 = 0;
for (int j = 0; j < sizeof(arr[0]) / sizeof(arr[0][0]); j++)
{
num2 += arr[j][i];
}
cout << subject[i] << "的平均分" << (num2/((sizeof(arr[0])) / (sizeof(arr[0][0])))) << endl;
}
system("pause");
return 0;
}
6 函数
6.1 概述
**作用:**将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。
6.2 函数的定义
函数的定义一般主要有5个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
语法:
返回值类型 函数名 (参数列表)
{
函数体语句
return表达式
}
- 返回值类型 :一个函数可以返回一个值。在函数定义中
- 函数名:给函数起个名称
- 参数列表:使用该函数时,传入的数据
- 函数体语句:花括号内的代码,函数内需要执行的语句
- return表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据
**示例:**定义一个加法函数,实现两个数相加
//函数定义
int add(int num1, int num2)
{
int sum = num1 + num2;
return sum;
}
6.3 函数的调用
**功能:**使用定义好的函数
语法:函数名(参数)
示例:
//函数定义
int add(int num1, int num2) //定义中的num1,num2称为形式参数,简称形参
{
int sum = num1 + num2;
return sum;
}
int main() {
int a = 10;
int b = 10;
//调用add函数
int sum = add(a, b);//调用时的a,b称为实际参数,简称实参
cout << "sum = " << sum << endl;
a = 100;
b = 100;
sum = add(a, b);
cout << "sum = " << sum << endl;
system("pause");
return 0;
}
总结:函数定义里小括号内称为形参,函数调用时传入的参数称为实参
6.4 值传递
- 所谓值传递,就是函数调用时实参将数值传入给形参
- 值传递时,如果形参发生改变,并不会影响实参
示例:
void swap(int num1, int num2)
{
cout << "交换前:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
int temp = num1;
num1 = num2;
num2 = temp;
cout << "交换后:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
//return ; 当函数声明时候,不需要返回值,可以不写return
}
int main() {
int a = 10;
int b = 20;
swap(a, b);
cout << "mian中的 a = " << a << endl;
cout << "mian中的 b = " << b << endl;
system("pause");
return 0;
}
6.5 函数的常见样式
常见的函数样式有4种
- 无参无返
- 有参无返
- 无参有返
- 有参有返
示例:
#include<iostream>
#include<string>
using namespace std;
//函数常见样式
//1.无参无返函数
void test0()
{
cout << "ceshi" << endl;
}
//2.有参无返
void test1(int a)
{
cout << "test1" << endl;
}
//3.有参无返
int test02()
{
cout << "test02" << endl;
return 1000;
}
//4.有参有返
int test03(int b)
{
cout << b << endl;
return b;
}
int main()
{
test0();//无参无返函数调用
test1(100);//有参无返调用
int a = test02();//有参无返调用
cout << a << endl;
int b = test03(10000);//有参有返调用
cout << b << endl;
system("pause");
return 0;
}
6.6 函数的声明
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
- 函数的声明可以多次,但是函数的定义只能有一次
示例:
#include<iostream>
#include<string>
using namespace std;
//函数的声明 -----------------比较函数,实现两个整形数字比较,返回大的值
//声明可以多次,定义只能一次
//声明
int max(int a, int b);
int max(int a, int b);
//定义
int max(int a, int b)
{
return a > b ? a : b;
}
int main() {
int a = 100;
int b = 200;
cout << max(a, b) << endl;
system("pause");
return 0;
}
6.7 函数的分文件编写
**作用:**让代码结构更加清晰
函数分文件编写一般有4个步骤
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
示例:
//swap.h文件
#include<iostream>
using namespace std;
//实现两个数字交换的函数声明
void swap(int a, int b);
//swap.cpp文件
#include "swap.h"
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
//main函数文件
#include "swap.h"
int main() {
int a = 100;
int b = 200;
swap(a, b);
system("pause");
return 0;
}
7 指针
7.1 指针的基本概念
指针的作用: 可以通过指针间接访问内存
-
内存编号是从0开始记录的,一般用十六进制数字表示
-
可以利用指针变量保存地址
7.2 指针变量的定义和使用
指针变量定义语法: 数据类型 * 变量名;
示例:
#include<iostream>
using namespace std;
//1.定义指针
int main()
{
int a = 10;
//指针定义语法L 数据类型* 指针变量
int* p;//创建指针变量
p = &a;//让指针变量记录变量a的地址
cout << "a的地址为" << &a << endl;
cout << p << endl;
//2.使用指针
//可以通过解引用方式找到指针指向的内存
//指针前加* 可以操作指针指向的内存
*p = 1000;
cout << a << endl;
cout << *p << endl;
system("pause");
return 0;
}
指针变量和普通变量的区别
- 普通变量存放的是数据,指针变量存放的是地址
- 指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用
总结1: 我们可以通过 & 符号 获取变量的地址
总结2:利用指针可以记录地址
总结3:对指针变量解引用,可以操作指针指向的内存
7.3 指针所占内存空间
提问:指针也是种数据类型,那么这种数据类型占用多少内存空间?
示例:
#include<iostream>
using namespace std;
//1.定义指针
int main()
{
int a = 10;
int* p = &a;
cout << *p << endl;//解引用
cout << "p所占内存空间=" << sizeof(p) << endl;
cout << "p所占内存空间=" << sizeof(int*) << endl;
cout << "p所占内存空间=" << sizeof(char*) << endl;
cout << "p所占内存空间=" << sizeof(float*) << endl;
cout << "p所占内存空间=" << sizeof(double*) << endl;
system("pause");
return 0;
}
总结:所有指针类型在32位操作系统下是4个字节
7.4 空指针和野指针
空指针:指针变量指向内存中编号为0的空间
**用途:**初始化指针变量
**注意:**空指针指向的内存是不可以访问的
示例1:空指针
#include<iostream>
using namespace std;
int main2501()
{
//空指针
//1.空指针用于给指针变量进行初始化
int* p = NULL;
//2.空指针是不可以进行访问的 因为0-255之间的内存编号是系统占用的,不可访问
cout << *p << endl;//报错
system("pause");
return 0;
}
int * p = (int *)0x1100;
//访问野指针报错
cout << *p << endl;
system("pause");
return 0;
}
总结:空指针和野指针都不是我们申请的空间,因此不要随意访问。
7.5 const修饰指针
const修饰指针有三种情况
- const修饰指针 — 常量指针
- const修饰常量 — 指针常量
- const即修饰指针,又修饰常量
int main() {
int a = 10;
int b = 10;
//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 = 100; //错误
system("pause");
return 0;
}
技巧:看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量
7.6 指针和数组
**作用:**利用指针访问数组中元素
示例:
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int * p = arr; //指向数组的指针
cout << "第一个元素: " << arr[0] << endl;
cout << "指针访问第一个元素: " << *p << endl;
for (int i = 0; i < 10; i++)
{
//利用指针遍历数组
cout << *p << endl;
p++;
}
system("pause");
return 0;
}
7.7 指针和函数
**作用:**利用指针作函数参数,可以修改实参的值
示例:
//值传递
void swap1(int a ,int b)
{
int temp = a;
a = b;
b = temp;
}
//地址传递
void swap2(int * p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main() {
int a = 10;
int b = 20;
swap1(a, b); // 值传递不会改变实参
swap2(&a, &b); //地址传递会改变实参
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递
7.8 指针、数组、函数
**案例描述:**封装一个函数,利用冒泡排序,实现对整型数组的升序排序
例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
示例:
#include<iostream>
using namespace std;
//
//** 案例描述:** 封装一个函数,利用冒泡排序,实现对整型数组的升序排序
//
//例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
void excccc(int arr[], int b)
{
for (int i = 0; i < 10 - 1; i++)
{
for (int j = 0; j < 10 - 1 - i; j++)
{
if (arr[j] > arr[j + 1])//用数组
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int s = 0; s < 10; s++)
{
cout << arr[s] << " ";
}
cout << endl;
}
void excccc1(int arr[], int b)
{
for (int i = 0; i < 10 - 1; i++)
{
int* t = arr;
for (int j = 0; j < 10 - 1 - i; j++)//用指针
{
if (*t > *(t+1))
{
int temp = *t;
*t = *(t+1);
*(t+1) = temp;
}
t++;
}
}
for (int s = 0; s < 10; s++)
{
cout << *arr << " ";
arr++;
}
cout << endl;
}
int main()
{
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
excccc1(arr,10);
for (int s = 0; s < 10; s++)
{
cout << arr[s] << " ";
}
cout << endl;
system("pause");
return 0;
}
总结:当数组名传入到函数作为参数时,被退化为指向首元素的指针
8 结构体
8.1 结构体基本概念
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
8.2 结构体定义和使用
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名 = { 成员1值 , 成员2值…}
- 定义结构体时顺便创建变量
示例:
#include<iostream>
#include<string.h>
using namespace std;
//1.创建学生数据类型,学生包括(姓名,年龄,分数)
//自定义数据类型,一些类型集合组成的一个类型
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
float score;
}s3;
//2.通过学生类型创建具体学生
int main()
{
//2.1 strucct Student s1;
//struct Student s1;
Student s1;//创建变量时 struct 可以省略省略 定义时不允许省略
//给s1属性赋值,通过”.“访问结构体变量中的属性
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout << "姓名: " << s1.name << "年龄" << s1.age << "分数" << s1.score << endl;
//2.2 strucct Student s2 = {....};
struct Student s2 = {"李四",18,80};
cout << "姓名: " << s2.name << "年龄" << s2.age << "分数" << s2.score << endl;
//2.3 定义结构体时顺便创建结构体变量 -------------不建议
s3.name = "王五";
s3.age = 19;
s3.score = 120;
cout << "姓名: " << s3.name << "年龄" << s3.age << "分数" << s3.score << endl;
system("pause");
return 0;
}
总结1:定义结构体时的关键字是struct,不可省略
总结2:创建结构体变量时,关键字struct可以省略
总结3:结构体变量利用操作符 ‘’.’’ 访问成员
8.3 结构体数组
**作用:**将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }
示例:
#include<iostream>
using namespace std;
#include<string>
//结构体数组
//1.定义结构体
struct Student
{
string name;//姓名
int age;//年龄
int score;//分数
};
int main()
{
//2.创建结构体数组
Student arr[] =
{
{"张三",18,100},
{"李四",20,84},
{"王麻子",25,10000}
};
//3.给结构体中元素赋值
arr[2].name = "赵四";
arr[2].age = 18;
arr[2].score = 88;
//4.遍历结构体变量
for (int i = 0; i < 3; i++)
{
cout << "姓名:" << arr[i].name
<< " 年龄:" << arr[i].age
<< " 分数:" << arr[i].score << endl;
}
system("pause");
return 0;
}
8.4 结构体指针
**作用:**通过指针访问结构体中的成员
- 利用操作符
->
可以通过结构体指针访问结构体属性
示例:
#include<iostream>
#include<string>;
using namespace std;
//结构体指针
//1.学生的结构体定义
struct Student
{
string name;//姓名
int age;//年龄
int score;//分数
};
int main()
{
//1.创建结构体变量
Student s1 = {"张三",18,56};
//2.通过指针指向结构体变量
Student* p = &s1;
//3.通过指针访问结构体变量中的数据
//通过机构体指针 访问结构体中的属性 ,需要利用 ’->‘符号
cout << "姓名" << p->name << "年龄" << p->age << "分数" << p->score << endl;
system("pause");
return 0;
}
总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员
8.5 结构体嵌套结构体
作用: 结构体中的成员可以是另一个结构体
**例如:**每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
#include<iostream>
#include<string>
using namespace std;
struct Student
{
string name;
int age;
int score;
};
void pringStudent(Student s)
{
s.age = 100;
cout << "子函数中姓名 " << s.name << " 年龄" << s.age << " 分数" << s.score << endl;
}
void pringStudent1(Student* s)
{
s->age = 100;
cout << "子函数中姓名 " << s->name << " 年龄" << s->age << " 分数" << s->score << endl;
}
int main()
{
//结构体做函数参数
//将学生传入到一个参数中,打印学生身向上所有信息
//创建结构体变量
Student s;
s.name = "张三";
s.age = 19;
s.score = 656;
//在main函数中打印结果
cout << "main函数中姓名" << s.name << " 年龄" << s.age << " 分数" << s.score << endl;
pringStudent(s);//值传递
cout << "main函数中姓名" << s.name << " 年龄" << s.age << " 分数" << s.score << endl;
pringStudent1(&s);//地址传递
cout << "main函数中姓名" << s.name << " 年龄" << s.age << " 分数" << s.score << endl;
system("pause");
return 0;
}
总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
8.7 结构体中 const使用场景
**作用:**用const来防止误操作
示例:
#include<iostream>
#include<string>
using namespace std;
struct Student
{
string name;
int age;
int score;
};
void printstu(const Student* s)//将函数中的形参改为指针节省空间,且不会复制新的副本出来
{
//s->age 18;//操作失败,因为加了const修饰
cout << "main函数中姓名" << s->name << " 年龄" << s->age << " 分数" << s->score << endl;
}
int main()
{
//创建结构体变量
Student s;
s.name = "张三";
s.age = 19;
s.score = 656;
printstu(&s);//地址传递
cout << "main函数中姓名" << s.name << " 年龄" << s.age << " 分数" << s.score << endl;
system("pause");
return 0;
}
8.8 结构体案例
8.8.1 案例1
案例描述:
学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下
设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员
学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
最终打印出老师数据以及老师所带的学生数据。
示例:
#include<iostream>
#include<string>
#include<ctime>
using namespace std;
//### 8.8 结构体案例
//
//#### 8.8.1 案例1
//
//** 案例描述:**
//
//学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下
//
//设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员
struct Stu
{
string sname;
int scorce;
};
struct tea
{
string tname;
Stu arr[5];
};
//学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
//最终打印出老师数据以及老师所带的学生数据。
//
//
//
//** 示例:**
//给老师和学生赋值
void aoolcateSpace(tea* t,int len)
{
string nameseed = "ABCDE";
//给老师赋值
tea* t1 = t;
for (int i = 0; i < len; i++)
{
t1->tname = "Teacher_";
t1->tname += nameseed[i];
//通过循环给老师学生赋值
srand((size_t)time(NULL));//随机数种子
for (int j = 0; j < 5; j++)
{
(t1->arr[j]).sname = "student_";
(t1->arr[j]).sname += nameseed[j];
int rodomn = rand() % 61 +40;//40~99
t1->arr[j].scorce = rodomn;
}
t1++;
}
}
void pringinfo(tea a[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "老师姓名:" << a[i].tname << endl;
for (int j = 0; j < 5; j++)
{
cout << "\t学生姓名" << a[i].arr[j].sname << " 学生分数" << a[i].arr[j].scorce << endl;
}
}
}
int main()
{
//1.创建三名老师数组
struct tea tarr[3];
//2.通过函数给3名老师的信息赋值,并给老师带的同学信息赋值
int len = sizeof(tarr) / sizeof(tarr[0]);
aoolcateSpace(tarr, len);
//3.打印所有信息
pringinfo(tarr, len);
system("pause");
return 0;
}
8.8.2 案例2
案例描述:
设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。
通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
五名英雄信息如下:
{"刘备",23,"男"},
{"关羽",22,"男"},
{"张飞",20,"男"},
{"赵云",21,"男"},
{"貂蝉",19,"女"},
struct hero
{
string name;
int age;
string sex;
};
//冒泡排序
void bubbleSort(hero arr[] , int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (arr[j].age > arr[j + 1].age)
{
hero temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//打印数组
void printHeros(hero arr[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "姓名: " << arr[i].name << " 性别: " << arr[i].sex << " 年龄: " << arr[i].age << endl;
}
}
int main() {
struct hero arr[5] =
{
{"刘备",23,"男"},
{"关羽",22,"男"},
{"张飞",20,"男"},
{"赵云",21,"男"},
{"貂蝉",19,"女"},
};
int len = sizeof(arr) / sizeof(hero); //获取数组元素个数
bubbleSort(arr, len); //排序
printHeros(arr, len); //打印
system("pause");
return 0;
}