//c++ main()函数的返回值必须为int
#include <iostream> //标准的输入输出流
using namespace std; //声明一个命名空间 cout对象存在std作用域下
//单行注释
/* 多行注释
main是一个程序的入口
每个程序有且仅有一个main
*/
int main()
{
//cout标准输出流
//endl 换行
cout << "hello world!" << endl;
return 0;
}
1.3 变量
作用:给一段指定的内存空间起名字,方便操作这段内存
//c++ main()函数的返回值必须为int
#include <iostream> //标准的输入输出流
using namespace std; //声明一个命名空间 cout对象存在std作用域下
//单行注释
/* 多行注释
main是一个程序的入口
每个程序有且仅有一个main
*/
int main()
{
//cout标准输出流
//endl 换行
cout << "hello world!" << endl;
int a = 10;
cout << "a=" << a << endl;
return 0;
}
1.4 常量
作用:用于记录程序中不可更改的数据
c++定义常量的两种方法:
1. #define 宏常量:#define 常量名 常量值
通常在文件上方定义,表示一个常量
2.const修饰的变量:const 数据类型 常量名=常量值
通常在变量定义之前加关键字const,修改该变量为常量,不可修改
//define定义的宏常量
#define Day 7
int main()
{
cout << "一周总共有" << Day << "天" << endl;
const int month = 12;
//month = 24; //错误,const修饰的变量也称为常量
cout << "一年总共有" << month << "个月" << endl;
return 0;
}
1.5 关键字
作用: 关键字是c++中预先保留的单词(标识符)
在定义常量或者变量(标识符)的时候,不要使用关键字
1.6 标识符(变量名,函数名)命名规则
作用:(争取见名知意)
标识符不能是关键字;
标识符只能由字母,数字,下划线组成;
第一个字符必须为字母或下划线;
字母区分大小写;
int main()
{
//1.标识符不能是关键字;
//int int=1;
//2.标识符只能由字母,数字,下划线组成;
int a_b = 0;
int _ab = 0;
//第一个字符必须为字母或下划线;
//int 1_a=0
//字母区分大小写;
int aaa = 100;
int AAA = 100;//不是同一个
return 0;
}
2. 数据类型
创建一个常量或变量时,必须要指定相应的数据类型,否则无法给变量分配内存
数据类型存在的意义就是给变量分配合适的内存空间,不要造成资源浪费
2.1 整形
作用:整形变量表示的是整数类型的数据
int main()
{
//短整型 2字节 (-32768~32767)
short num1 = 10;
//short num1 = 32768; //输出-32768 超出上限后回到下限
//整形 4字节
int num2 = 10;
//长整型 4字节(win) 4(linux 32) 8(linux 64)
long num3 = 10;
//长长整形 8字节
long long num4 = 10;
return 0;
}
2.2 sizeof关键字
作用:统计数据类型所占内存的大小
语法:sizeof(数据类型/变量)
int a = 0;
sizeof(int) / sizeof(a)
short < int <= long <long long 整形大小比较
int main()
{
//短整型 2字节 (-32768~32767)
short num1 = 10;
//short num1 = 32768; //输出-32768 超出上限后回到下限
//sizeof(数据类型/变量)占用内存空间
cout << "短整型所占字节" << sizeof(num1) << endl;
cout << "短整型所占字节" << sizeof(short) << endl;
//整形 4字节
int num2 = 10;
//长整型 4字节(win) 4(linux 32) 8(linux 64)
long num3 = 10;
//长长整形 8字节
long long num4 = 10;
return 0;
}
2.3 浮点型
作用:用于表示小数(小数点前边也算有效数字)
浮点型变量分为两种类型:
单精度浮点型:float
双精度浮点型:double
区别:表示的有效数字范围不同
3.14 有效数字有3位 3,1,4(一般情况下不论是什么类型,都会显示6位有效数字,不管是什么类型)
默认情况下,编译器会把小数类型看作双精度
2.4 字符型
只能用单引号,单引号里边只能有一个字符,只占用一个字节的内存
char a = 'b'
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII码值放到存储单元中
2.5 转义字符
/t 可以整齐的输出数据(8个空格)
2.6 字符串
char str[] = "abc"
#include<string> string str = "abc"
#include <string>
int main()
{
//c风格字符串
//注意事项,加[]; =后面要用双引号包含字符串
char str[] = "hello world";
cout << str << endl;
//c++风格字符串
//注意事项 需要包含string头文件
string str2 = "hello world";
return 0;
}
2.7 布尔类型
作用:布尔数据类型代表真或假的值,占1个字节,非0的值都代表1,输出都为1(也包含负数 -1------> 1)
bool类型只有两个值:
True 真(本质是1)
False 假(本质是0)
int main()
{
bool flag = true;
cout << flag << endl; //1
bool flag2 = false;
cout << flag2 << endl; //0
cout << sizeof(bool) << endl; //1
return 0;
}
2.8 数据的输入
作用:用于从键盘获取数据 cin>>变量
int main()
{
bool a = 0;
cout << "请给a赋值" << endl;
cin >> a; //输入键盘值
cout << "整型变量a=" <<a<< endl;
return 0;
}
3. 运算符
作用:用于执行代码的运算
3.1 算术运算符
两个整数相除,结果依然是整数,将小数部分去除(3/2=1)
(/ %)除数≠0(分母),%本质是除法且两个小数之间可以做除法运算但不能做取余运算
++a 先加一再运算 a++ 先运算再加一
int main()
{
int a = 10;
int b = ++a * 10; //先加一再运算
cout << "b=" << b << endl; //a=11 11*10=110
int c = a++ * 10; //先运算再加一
cout << "c=" << c << endl; //10*10=100 a=11
return 0;
}
3.2 赋值运算符
3.3 比较运算符
3.4 逻辑运算符
4. 程序流程结构
4.1 选择结构
4.1.1 if 语句
4.1.2 三目运算符
在c++中三目运算符返回的是变量,可以继续赋值
int main()
{
//创建三个变量
//将a和b作比较,将变量大的值赋值给变量c
int a = 10;
int b = 20;
int c = 0;
c=(a > b ? a : b);
cout << "c=" << c << endl; //20
//在c++中三目运算符返回的是变量,可以继续赋值
(a > b ? a : b) = 100;
cout << "b=" << b << endl; //100
return 0;
}
4.1.3 switch语句
作用:执行多条件分支语句
int main()
{
//switch 语句
//8-10 经典
//5-7 非常好
//5烂片
//提示用户输入评分
cout << "请给电影打分" << endl;
int score = 0;
cin >> score;
cout << "您打的分数为" << score << endl;
switch (score)
{
case 10:
cout << "您认为这个是经典电影" << endl;
break; //不加break语句下边的条件是否符合都会输出内容
case 7:
cout << "您认为这个是非常好电影" << endl;
break;
default:
cout << "您认为这个是一般电影" << endl;
break;
}
/*if 和switch区别?
switch只能是整形或者字符型,不可以是一个区间
优点:结构清晰,执行效率高*/
return 0;
}
if 和switch区别?
switch缺点:只能是整形或者字符型,不可以是一个区间
优点:结构清晰,执行效率高
4.2 循环结构
4.2.1 while语句
int main()
{
//在屏幕中打印10个数
int num = 0;
//注意事项,一定要避免死循环的出现
while (num < 10)
{
num++;
cout << "num=" <<num<< endl;
}
return 0;
}
while循环练习案例
猜数字
#include <ctime> //time系统时间头文件包含
int main()
{
//添加随机数种子,利用当前系统的时间生成随机数,防止每次生成的随机数一样
srand((unsigned int)time(NULL));
//1.随机生成一个数 ,这个每次生成的随机数都是固定的,因此需要添加一个随机数种子
int num = rand() % 100 + 1; //0-99 +1 1-100
int val = 0;
while (1)
{
//2.玩家猜测
cin >> val;
//3.判断猜测
//猜对 结束游戏
//猜错 给出提示,继续第2步
if (val == num)
{
cout << "恭喜你猜测正确" << endl;
break;//可以用break关键字退出当前循环
}
else if(val < num)
{
cout << "猜测过小" << endl;
}
else
{
cout << "猜测过大" << endl;
}
}
return 0;
}
4.2.2 do while 循环语句
与while的区别在于:do while会先执行一次循环语句,再判断;while是先进行判断,再执行
int main()
{
//do while语句输出0-9
int num = 0;
do
{
cout << "num=" << num << endl;
num++;
} while (num<10);
return 0;
}
练习案例:水仙花数
每个位数字的3次方之和是它本身
int main()
{
int num = 100;
//1.将所有三位数输出
//2.找到水仙花数
//获取个位,十位,百位(先对10取余,再除以10)
//判断是否是水仙花数
do
{
int a = 0;
int b = 0;
int c = 0;
a = num % 10; //获取个位
b = num / 10 % 10;//获取十位
c = num / 100 ; //获取百位
if(a*a*a+b*b*b+c*c*c==num)
{
cout << "水仙花数:" << num << endl;
}
num++;
} while (num < 1000);
return 0;
}
4.2.3 for循环语句
案例:敲桌子7
int main()
{
//1.输出0-100的所有数
//2.找出特殊数字
//7的倍数(对7取模=0)
//个位有7 (对10取模=7)
//十位有7 (/10=7)
for (int i = 0; i <= 100; i++)
{
if (i%7 == 0||i%10==7||i/10==7)//如果是特殊数字,敲桌子
{
cout << "敲桌子:" << i << endl;
}
else
{
cout << i << endl;
}
}
return 0;
}
4.2.4 嵌套循环
作用:在循环中嵌套一层循环(10行10列*)
int main()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << "* ";
}
cout << endl;
}
return 0;
}
案例:九九乘法表
int main()
{
//九九乘法表
for (int i = 1; i < 10; i++)
{
for (int j = 1; j <= i; j++)
{
cout << i<<"*"<<j<<"="<<i*j<<" ";
}
cout << endl;
}
return 0;
}
4.3 跳转语句
4.3.1 break语句
作用:用于跳出选择结构或循环结构
int main()
{
//break的使用时机
//1. 出现在switch语句中
cout << "请选择难度:" << endl;
cout << "1" << endl;
cout << "2" << endl;
int num = 0;
cin >> num;
switch (num)
{
case 1:
cout << "难度1" << endl;
break;
case 2:
cout << "难度2" << endl;
break;
}
//2. 出现在循环语句中
for (int i = 0; i < 10; i++)
{
//如果i==5,退出循环
if (5 == i)
{
break;
}
cout << i;
}
//3.出现在嵌套语句中
for (int i = 0; i < 10; i++)
{
for (int j = 0; j <10; j++)
{
if (5 == j)
{
break;//跳出离它最近的循环
}
cout << "*"; //10行5列
}
cout << endl;
}
return 0;
}
4.3.2 continue语句
作用:在循环语句中,跳过本次循环中尚未执行的语句,继续执行下一次循环
continue与break的区别:continue并未跳出循环;而break跳出了循环
int main()
{
//奇数输出,偶数不输出
for (int i = 0; i <= 100; i++)
{
if (i % 2 == 0)
{
continue;//可以筛选条件,执行到此就不再向下执行,执行下一次循环
//break会退出循环,continue不会
}
cout << i << endl;
}
return 0;
}
4.3.3 goto语句
作用:可以无条件的跳转语句
语法:goto 标记
如果标记存在,就会跳到标记位置
int main()
{
//goto 语句
cout << "1" << endl;
cout << "2" << endl;
goto FLAG;
cout << "3" << endl;
cout << "4" << endl;
FLAG;
cout << "4" << endl;
return 0;
}
5. 数组
5.1 概述
所谓数组,就是一个集合,里面存放了相同类型的数据元素
特点1:数组中的每个数据元素都是相同的数据类型
特点2:数组是由连续的内存位置组成的
5.2 一维数组
5.2.1 一维数组定义方式
一维数组定义的三种方式:
int main()
{
//数组
//1. 数据类型 数组名[数组长度]
int arr[5];
//2.
int arr2[5] = { 10,20,30,40,50 };
for (int i = 0; i < 5; i++)
{
cout << arr2[i] << endl;
}
int arr2[5] = { 10,20,30 };//如果没有完全初始化,则用0补
for (int i = 0; i < 5; i++)
{
cout << arr2[i] << endl; //10,20,30,0,0
}
//3.不写数据元素,可以自己根据数据推测个数
//定义数组的时候必须知道数组的长度(arrs[5],或者不写5,指定具体的数值)
int arrs[] = { 1,2,3,4,5,6,7,8,9 };
return 0;
}
5.2.2 一维数组的数组名
用途:统计整个数组中内存的长度 sizeof(arr)
可以获取数组在内存中的首地址
int main()
{
//2.
int arr2[5] = { 10,20,30,40,50 };
cout << "整个数组占用内存空间为:" << sizeof(arr2)<<endl; //20
cout << "每个元素占用的内存空间:" << sizeof(arr2[0]) << endl;//4
cout << "数组中元素个数:" << sizeof(arr2)/sizeof(arr2[0]) << endl;//5
cout << "数组首地址:" <<(int)arr2 << endl; //十进制
cout << "第一个元素地址:" << (int)&arr2[0] << endl;
cout << "第二个元素地址:" << (int)&arr2[1] << endl;
return 0;
}
案例:五只小猪称体重(在数组中找到最大值)
int main()
{
//1. 创建五只小猪的体重
int arr2[5] = { 10,20,30,40,50 };
//2.从数组中找到最大值
int max = 0;
for (int i = 0; i < 10; i++)
{
//如果访问元素比最大值大,更新最大值
if (arr2[i] > max)
{
max = arr2[i];
}
}
cout << "最大值:" << max << endl;
return 0;
}
案例:数组元素逆置(12345--54321)
int main()
{
//实现数组元素逆置
int arr[4] = { 10,20,30,40 };
cout << "逆置前结果:" << endl;
for (int i = 0; i < 4; i++)
{
cout << arr[i] << endl;
}
//创建临时变量
int start = 0; //起始下标
int end = sizeof(arr) / sizeof(arr[0]) - 1;//最后下标
int temp = arr[0];
//在合法区间(start<end)进行互换
while (start < end)
{
//交换元素
arr[temp] = arr[start];
arr[start] = arr[end];
arr[end] = arr[temp];
//更新下标
start++;
end--;
}
cout << "逆置后结果:" << endl;
for (int i = 0; i < 4; i++)
{
cout << arr[i] << endl;
}
return 0;
}
5.2.3 冒泡排序
int main()
{
//利用冒泡排序实现升序序列
int arr[9] = {4,2,8,0,5,7,1,3,9};
cout << "排序前:";
for (int i = 0; i < 9; i++)
{
cout << arr[i] << " ";
}
//开始冒泡排序
//总共排序轮数为元素个数-1
for (int i = 0; i < 9-1; i++)
{
//内层循环对比 次数= 元素个数-当前轮数 -1
for (int j = 0; j < 9 - i - 1; j++)
{
//如果第一个数字比第二个数字大,交换两个数字
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
cout << "排序后:";
for (int i = 0; i < 9; i++)
{
cout << arr[i] << " ";
}
return 0;
}
5.2.4 二维数组的定义
1. 手动给每个元素进行赋值
2. 大括号里包小括号
3.
4.
6. 函数
函数可以多次声明,但是不能重复定义
7. 指针
7.1 指针的基本概念
指针的作用:可以通过指针间接访问内存
内存编号是从0开始记录的,一般用十六进制数字表示
可以利用指针变量保存地址
7.2 指针变量的定义和使用
int main()
{
//1. 定义指针
int a = 10;
// 指针定义的语法: 数据类型 * 指针变量名
int* p;
// 让指针记录变量a的地址
p = &a;
cout << "a的地址为: " << &a << endl; //两个地址一样
cout << "指针p为: " << p << endl;
//2. 使用指针
//可以通过解引用的方式来找到指针指向的内存
//指针前加 * 代表解引用,找到指针指向的内存中的数据
*p = 1000;
cout << "a= " << a << endl; //1000
cout << "*p= " << *p << endl; //1000
}
7.3 指针所占的内存空间
在32位操作系统下:占4个字节 64位下占8个字节
int main()
{
int a = 10;
int* p = &a;
//不管是什么数据类型 32位系统下 占4个字节;64位占8个
cout << "int指针所占内存空间大小:" << sizeof(p) << endl; //8
cout << "float指针所占内存空间大小:" << sizeof(float*) << endl; //8
cout << "double指针所占内存空间大小:" << sizeof(double*) << endl; //8
cout << "char指针所占内存空间大小:" << sizeof(char*) << endl; //8
}
7.4 空指针和野指针
空指针:指针变量指向内存编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
int main()
{
//空指针
//1. 空指针用于给指针变量进行初始化
int* p = NULL;
//2. 空指针是不可以进行访问的
//0-255之间的内存编号是系统占用的,因此不可以访问
*p = 100; //运行错误
cout << "char指针所占内存空间大小:" << sizeof(char*) << endl; //8
}
野指针:指针变量指向非法的内存空间
int main()
{
//野指针
//指针变量p指向非法的内存空间,这个内存空间不知道是什么
int* p = (int *)0x1100;
//访问野指针报错
cout << *p << endl;
//cout << "char指针所占内存空间大小:" << sizeof(char*) << endl; //8
}
7.5 const修饰指针
const修饰指针有三种情况:
1. const修饰指针 --常量指针 (const int * p)
特点:指针的指向可以改,但指针指向的值不可以改
2. const修饰常量 --指针常量 (int * const p)
特点:指针的指向不可以改,指针指向的值可以改
3. const既修饰指针又修饰常量
特点:指针的指向和指针指向的值都不可以改
记忆:const后边跟的是谁,谁就不能操作
1. const int * p 跟的是*,所以*不能操作,即不能改变值
2. int * const p 跟的是指针p,所以指针的指向不能改
1.
int a = 10;
int b = 15;
const int* p = &a;
//*p = 20;//错误,指针指向的值不可以改
p = &b;//正确,指针指向可以改
2.
int a = 10;
int b = 15;
int * const p = &a;
*p = 20;//正确,指针指向的值可以改
//p = &b;//错误,指针指向不可以改
}
3.
int a = 10;
int b = 15;
const int* const p = &a;
//*p = 20;//错误,指针指向的值都不可以改
//p = &b;//错误,指针指向不可以改
}
7.6 指针和数组
int main()
{
//指针和数组
//利用指针访问数组中的元素
int arr[5] = { 1,2,3,4,5 };
cout << "第一个元素为:" << arr[0] << endl;
int* p = arr;//arr就是数组的首地址
cout << "利用指针访问第一个元素为:" << *p << endl;
p++;//一个指针占多少个字节,p++就加多少
cout << "利用指针访问第二个元素为:" << *p << endl;
}
7.7 指针和函数
//实现两个数字进行交换
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "形参a=" << a << endl;
cout << "形参b=" << b << endl;
}
void swap02(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
cout << "形参a=" << *a << endl;
cout << "形参b=" << *b << endl;
}
int main()
{
//指针和函数
//1. 值传递
int a = 10;
int b = 20;
swap01(a, b); //只是形参发生了改变a=20,b=10,外侧的实参并未发生改变
cout << "a=" << a << endl; //10
cout << "b=" << b << endl; //20
//2. 地址传递
//如果是地址传递,可以修改实参的值
swap02(&a, &b); //a=20,b=10
cout << "a=" << a << endl; //20
cout << "b=" << b << endl; //10
return 0;
}
7.8 指针、数组、函数
封装一个函数,利用冒泡排序,实现对整型数组的升序排列
//数组地址 数组长度
void bubbleSort(int* arr,int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
//如果j>i,交换
if (arr[j] < arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//打印数组
void printarr(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << endl;
}
}
int main()
{
//1.创建数组
int arr[5] = { 1,2,3,4,5 };
//2.创建函数,进行冒泡排序
int len = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, len);
//3.打印排序后的数组
printarr(arr, len);
return 0;
}
8. 结构体
8.1 结构体的基本概念
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
8.2 结构体定义与使用
通过结构体创建变量的方式有三种:
#include<string>
//1. 创建学生数据类型:学生包括(姓名,年龄,分数)
struct Student
{
//成员列表
string name;
int age;
int score;
}s3;//2.3 顺便创建结构体变量
int main()
{
//2. 通过学生类型创建具体学生
//2.1 struct Stu s1;
//给s1属性赋值,通过.访问结构体变量中的属性
Student s1; //创建变量的时候,结构体类型可以省(struct)
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数" << s1.score << endl;
//2.2 struct Stu s2={.....}
struct Student s2 = { "李四",19,200 };
cout << "姓名:" << s2.name << "年龄:" << s2.age << "分数" << s2.score << endl;
//2.3 定义结构体时顺便创建结构体变量
s3.name = "王五";
s3.age = 21;
s3.score = 300;
cout << "姓名:" << s3.name << "年龄:" << s3.age << "分数" << s3.score << endl;
return 0;
}
总结:定义结构体时的关键字是struct,不可省略
创建结构体变量时,关键字struct可以省略
结构体变量利用操作符"."访问成员
8.3 结构体数组
作用:将自定义的结构体放入到数组中方便维护
#include<string>
//1. 定义结构体
struct Student
{
//成员列表
string name;
int age;
int score;
};
int main()
{
//2. 创建结构体数组
struct Student stuarry[3] =
{
{"张三",18,100},
{"里斯",19,200},
{"王五",20,300}
};
//3. 给结构体数组中的元素赋值
stuarry[2].name = "赵六";
stuarry[2].age = 80;
//4. 遍历结构体数组
for (int i = 0; i < 3; i++)
{
cout << "姓名:" << stuarry[i].name
<< "年龄:" << stuarry[i].age
<< "分数" << stuarry[i].score
<< endl;
}
return 0;
}
8.4 结构体指针
作用:通过指针访问结构体中的成员 ->访问成员
#include<string>
//结构体指针(Student 是数据类型)
struct Student
{
//成员列表
string name;
int age;
int score;
};
int main()
{
//2. 创建学生结构体变量
struct Student s = {"张三",19,5};
//3. 通过指针访问结构体变量
struct Student* p = &s;
//4. 通过指针访问结构体变量中的数据
cout << "姓名:" << p->name
<< "年龄:" << p->age
<< "分数:" << p->score
<< endl;
return 0;
}
8.5 结构体嵌套结构体
作用:结构体中的成员可以是另一个结构体
#include<string>
//结构体指针(Student 是数据类型)
struct Student
{
//成员列表
string name;
int age;
int score;
};
struct Teacher
{
//成员列表
int id;
string name;
int age;
struct Student stu;
};
int main()
{
//2. 创建老师
struct Teacher t = { 100,"李",50 };
t.stu.name = "张三";
t.stu.age= 19;
t.stu.score = 200;
cout << "姓名:" <<t.name
<< "年龄:" << t.age
<< "id:" << t.id
<<"学生姓名:"<<t.stu.name
<< "学生年龄:" << t.stu.age
<< "学生分数:" << t.stu.score
<< endl;
return 0;
}
8.6 结构体做函数参数
作用:将结构体作为参数向函数中传递
#include<string>
//结构体指针(Student 是数据类型)
struct Student
{
//成员列表
string name;
int age;
int score;
};
//打印学生信息的函数
//1. 值传递
void printStudent_1(struct Student s)
{
s.age = 100;
cout << "子函数1中结果姓名:" << s.name
<< "年龄:" << s.age
<< "分数:" << s.score
<< endl;
}
void printStudent_2(struct Student * s)
{
s->age = 200;
cout << "子函数2中结果姓名:" << s->name
<< "年龄:" << s->age
<< "分数:" << s->score
<< endl;
}
int main()
{
//创建学生结构体变量
struct Student s = {"张三",19,5};
cout << "main中结果姓名:" << s.name
<< "年龄:" << s.age
<< "分数:" << s.score
<< endl;
printStudent_1(s);//值传递
cout << "1后结果姓名:" << s.name
<< "年龄:" << s.age
<< "分数:" << s.score
<< endl;
printStudent_2(&s);//地址传递
cout << "2后结果姓名:" << s.name
<< "年龄:" << s.age
<< "分数:" << s.score
<< endl;
return 0;
}
8.7 结构体中const使用场景
作用:用const来防止误操作
#include<string>
//结构体指针(Student 是数据类型)
struct Student
{
//成员列表
string name;
int age;
int score;
};
void printstudents(Student *s)
{
s->age = 100;
cout << "姓名:" << s->name
<< "年龄:" << s->age
<< "分数:" << s->score
<< endl;
}
void printstudents_const(const Student *s)
{
//s->age = 100; 加入const后,误操作修改成员属性会报错
cout << "姓名:" << s->name
<< "年龄:" << s->age
<< "分数:" << s->score
<< endl;
}
int main()
{
struct Student s = {"张三",19,5};
//通过函数打印结构体变量信息
//printstudents(s); //值传递每次调用都会拷贝一份数据,调用几次,拷贝几次,占用的内存过大
printstudents(&s); //将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
//如果在函数体中修改内容,会违背本意,因此加const防止误操作
printstudents_const(&s);
return 0;
}
8.8 结构体案例
三个老师,每个老师带五个学生
#include<string>
#include<random>
#include<Ctime>
//结构体指针(Student 是数据类型)
struct Student
{
//成员列表
string name;
int score;
};
struct Teacher
{
//成员列表
string name;
struct Student stu[5];
};
void allocate(struct Teacher t[],int len) //传数组的时候,一般也要传数组有多长
{
string nameSeed = "abcde";
//给老师开始赋值
for (int i = 0; i < len; i++)
{
t[i].name = nameSeed[i];
//通过循环给每名老师所带的学生赋值
for (int j = 0; j < 5; j++)
{
t[i].stu[j].name = nameSeed[j];
int randdom = rand() % 61+40; //40-100
t[i].stu[j].score = randdom;
}
}
}
void printall(struct Teacher t[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "老师姓名:" << t[i].name;
//通过循环给每名老师所带的学生赋值
for (int j = 0; j < 5; j++)
{
cout << "\t学生姓名:" << t[i].stu[j].name
<< "学生成绩:" << t[i].stu[j].score
<< endl;
}
}
}
int main()
{
//随机数种子
srand((unsigned int)time(NULL));
//1. 创建3名老师数组
struct Teacher t[3] ;
//2. 创建一个给老师和学生赋值的函数
int len = sizeof(t) / sizeof(t[0]);
allocate(t, len);
//输出所有老师的所有学生
printall(t, len);
return 0;
}
8.8.2 案例2
#include<string>
//1. 定义结构体
struct Hero
{
//成员列表
string name;
int age;
};
//冒泡排序实现年龄升序排列
void bubbleSort(Hero hero[], int len)
{
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (hero[j].age > hero[j + 1].age)
{
struct Hero temp = hero[j];
hero[j] = hero[j + 1];
hero[j + 1] = temp;
}
}
}
}
//打印排序后数组
void printHero(struct Hero hero[],int len)
{
for (int i = 0; i < len; i++)
{
cout << "姓名:" << hero[i].name
<< "年龄:" << hero[i].age
<< endl;
}
}
int main()
{
//2. 创建结构体数组
struct Hero hero[3] =
{
{"张三",18},
{"里斯",19},
{"王五",20}
};
//
int len = sizeof(hero) / sizeof(hero[0]);
4. 遍历结构体数组
//for (int i = 0; i < len; i++)
//{
// cout << "姓名:" << hero[i].name
// << "年龄:" << hero[i].age
// << endl;
//}
//对数组中的年龄进行排序,升序
bubbleSort(hero, len);
printHero(hero, len);
return 0;
}