C++《基础笔记一》

前言

配套视频:B站黑马程序员
C++从入门到精通https://www.bilibili.com/video/BV1et411b73Z
为方便大家学习,在此发布C++基础入门部分配套讲义,原作者为黑马程序

《基础笔记一》

本阶段主要是初识C++的编程语法规范,主要难点内容为:数组、函数、指针、结构体。

1 C++初识

1.1 变量

作用:给一段指定的内存空间起名,方便操作这段内存

语法:数据类型 变量名 = 初始值;
示例:

#include<iostream>
using namespace std;

int main() 
{
	cout << "hello c++" << endl;  //打印hello c++  并换一行
	int a = 10;  //创建变量
	cout << "a=" << a << endl;
	system("pause");
	return 0;
}
hello c++
a=10
请按任意键继续. . .

注意:C++在创建变量时,必须给变量一个初始值,否则会报错

1.2 常量

作用:用于记录程序中不可更改的数据

C++定义常量两种方式

#define 宏常量: #define 常量名 常量值

通常在文件上方定义,表示一个常量
const修饰的变量 const 数据类型 常量名 = 常量值

通常在变量定义前加关键字const,修饰该变量为常量,不可修改
示例

#include<iostream>
using namespace std;
//宏常量
#define Day 7
int main()
{
	cout << "一周总共有:" << Day << "天" << endl;

	const int month = 12;    //const修饰的变量,在之后就不可以在修改值,只能为常量了
	cout << "一年总共有:" << month << "月份" << endl;
	
	system("pause");
	return 0;

}
一周总共有:7天
一年总共有:12月份
请按任意键继续. . .

1.3 关键字

在定义变量或者常量时候,不要用关键字
C++关键字如下:

asmdoifreturntypedef
autodoubleinlineshorttypeid
booldynamic_castintsignedtypename
breakelselongsizeofunion
caseenummutablestaticunsigned
catchexplicitnamespacestatic_castusing
charexportnewstructvirtual
classexternoperatorswitchvoid
constfalseprivatetemplatevolatile
const_castfloatprotectedthiswchar_t
continueforpublicthrowwhile
defaultfriendregistertruedelete
gotoreinterpret_casttry

示例

#include<iostream>
using namespace std;

int main()
{
	/*
	标识符不可以是关键字
	标识符由 字母、数字、下划线组成
	标识符开头不能为数字
	*/
	int num1 = 1, num2 = 2,sum;
	sum = num1 + num2;
	cout << sum << endl;
	system("pause");
	return 0;
}
3
请按任意键继续. . .

2 数据类型

C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存

2.1 整型

short短整型 2字节
int整形 4字节
long长整形 4字节
long long 长长整型 8字节

2.2 浮点型(实型)

单精度float 4字节
双精度double 8字节

2.3 字符型

注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号
注意2:单引号内只能有一个字符,不可以是字符串

char ch = ‘a’; 1字节

2.4 字符串型

作用:用于表示一串字符

两种风格

C风格字符串: char 变量名[] = “字符串值”
C++风格字符串: string 变量名 = “字符串值”

2.5 转义字符

**作用:**用于表示一些不能显示出来的ASCII字符

现阶段我们常用的转义字符有:\n \ \t

| | |

\n换行(LF) ,将当前位置移到下一行开头
\t水平制表(HT) (跳到下一个TAB位置)
\v垂直制表(VT)
\\代表一个反斜线字符""

2.6 布尔类型 bool

**作用:**布尔数据类型代表真或假的值

bool类型只有两个值:

true — 真(本质是1)
false — 假(本质是0)

bool类型占1个字节大小

2.7 sizeof关键字

**作用:**利用sizeof关键字可以统计数据类型所占内存大小
语法: sizeof( 数据类型 / 变量)

2.8 数据的输入

作用:用于从键盘获取数据
**关键字:**cin

语法: cin >> 变量

3 运算符

**作用:**用于执行代码的运算

本章我们主要讲解以下几类运算符:

运算符类型作用
算术运算符用于处理四则运算
赋值运算符用于将表达式的值赋给变量
比较运算符用于表达式的比较,并返回一个真值或假值
逻辑运算符用于根据表达式的值返回真值或假值

3.1 算术运算符

作用:用于处理四则运算

算术运算符包括以下符号:

运算符术语示例结果
+正号+33
-负号-3-3
+10 + 515
-10 - 55
*10 * 550
/10 / 52
%取模(取余)10 % 31
++前置递增a=2; b=++a;a=3; b=3;
++后置递增a=2; b=a++;a=3; b=2;
-前置递减a=2; b=-a;a=1; b=1;
-后置递减a=2; b=a-;a=1; b=2;

总结:
在除法运算中,除数不能为0
只有整型变量可以进行取模运算
前置递增先对变量进行++,再计算表达式,后置递增相反

5 数组

5.1 概述

所谓数组,就是一个集合,里面存放了相同类型的数据元素

**特点1:**数组中的每个数据元素都是相同的数据类型

**特点2:**数组是由连续的内存位置组成的

5.2 一维数组

5.2.1 一维数组定义方式
一维数组定义的三种方式:

数据类型 数组名[ 数组长度 ];
数据类型 数组名[ 数组长度 ] = { 值1,值2 …}; //没有全部填写完时,会用0来填补剩余数据
数据类型 数组名[ ] = { 值1,值2 …};

示例

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
int main()
{
	//int arr[5];    //第一种表达方式
	//arr[0] = 10;
	//arr[1] = 20;
	//arr[2] = 30;
	//arr[3] = 40;
	//cout << arr[3] << endl;


	int arr2[] = { 10,20,30,40 };     //第二种表达方式
	for (int i = 0; i < 4; i++)
	{
		cout << arr2[i] << endl;
	}
	


	system("pause");      //暂停结果显示
	return 0;
}
10
20
30
40
请按任意键继续. . .

5.2.2 一维数组数组名
一维数组名称的用途:

可以统计整个数组在内存中的长度
可以获取数组在内存中的首地址

示例:

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
int main()
{
	//可以统计整个数组在内存中的长度
	//可以获取在内存中的首地址

	int arr1[9] = {13,34,54,23,454,6,6,776,444};
	
	cout << sizeof(arr1) << endl;       //9个数,每个数占用4个字节
	cout << sizeof(arr1) / sizeof(arr1[0]) << endl; //统计数组的元素个数,总长度/索引为0的长度
	cout << arr1 << endl;  //16进制表示地址位置
	cout << "数组中第一个元素地址为: " << &arr1[0] << endl;
	cout << (int)arr1 << endl;  //10进制表示地址位置

	system("pause");      //暂停结果显示
	return 0;
}
36
9
0039FC70
数组中第一个元素地址为: 0039FC70
3800176
请按任意键继续. . .

**注意:**数组名是常量,不可以赋值

总结1:直接打印数组名,可以查看数组所占内存的首地址

总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小

5.2.3 冒泡排序
作用: 最常用的排序算法,对数组内元素进行排序

比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。
重复以上的步骤,每次比较次数-1,直到不需要比较

示例:

 #include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
int main()
{
	int arr[] = { 3,45,6,65,23,64,1,4,7 };
	cout << "排序前:" << endl;
	for (int i = 0; i < 9; i++)
	{
		cout << arr[i] << " ";
	}
	 
	//开始冒泡排序
	for (int i = 0; i < 9-1; i++)  //总共排序轮数
	{
		//内层循环对比
		for (int j = 0; j < 9-i-1; j++)//第一次需要交换8次,第二次交换7次,第三次交换6次...
		{
			//如果第一个数字比第二个数字大,则交换两个数字
			//交换完后,第2个数与第3个数进行对比
			//把最大的数逐渐放到最右边
			if (arr[j]>arr[j+1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}

	cout << "排序后:" << endl;
	for (int i = 0; i < 9; i++)
	{
		cout << arr[i] << " ";
	}


	system("pause");      //暂停结果显示
	return 0;
}
排序前:
3 45 6 65 23 64 1 4 7 排序后:
1 3 4 6 7 23 45 64 65 请按任意键继续. . .

5.3 二维数组


 二维数组就是在一维数组上,多加一个维度。

5.3.1 二维数组定义方式
二维数组定义的四种方式:

数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 }};
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性

示例:

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
int main()
{
	int arr[2][3] = 
	{  
		{ 1,2,3 } ,
		{4, 5, 6}  
	};
	for (int i = 0; i < 2; i++) //外层循环打印行数
	{
		for (int j = 0; j < 3; j++) //内层循环打印列数
		{
			cout << arr[i][j] << " ";
		}
		cout << endl;

	}



	system("pause");      //暂停结果显示
	return 0;
}
1 2 3
4 5 6
请按任意键继续. . .

5.3.2 二维数组数组名

查看二维数组所占内存空间
获取二维数组首地址

示例:

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
int main()
{
	//可以查看占用内存空间大小
	//可以查看二维数组的首地址
	int arr[2][3]=
	{
		{1,2,3},
		{4,5,6}
	};
	cout << "二维数组占用空间为: " << sizeof(arr) << endl; //4x6=24

	cout << "二维数组首地址为:" << arr << endl;
	cout << "二维数组第一个元素首地址:" << &arr[0][0] << endl;
	system("pause");      //暂停结果显示
	return 0;
}
二维数组占用空间为: 24
二维数组首地址为:00D5FD58
二维数组第一个元素首地址:00D5FD58
请按任意键继续. . .

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 函数的调用

功能使用定义好的函数

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

int add(int num1, int num2)    //加法函数  num1和num2为形参
{
	int sum = num1 + num2;
	return sum;
}


int main()
{

	int a, b;
	a = 10;
	b = 20;
	int c=add(a, b);    //a和b为实参
	cout << "c= " << c << endl;



	system("pause");      //暂停结果显示
	return 0;
}
c= 30
请按任意键继续. . .

6.4 值传递

所谓值传递,就是函数调用时实参将数值传入给形参
值传递时,如果形参发生,并不会影响实参

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串


//定义函数,实现两个数字进行交换
//如果函数不需要返回值,声明的时候可以写void,后面也不需要写return
void swap(int num1, int num2)     
{
	
	int temp = num1;
	num1 = num2;
	num2 = temp;
	cout << "在形参函数中交换后" << endl;
	cout << num1 << endl;
	cout << num2 << endl;
}

int main()
{
	
	int a = 10, b = 20;
	cout << "交换前,未调用交换函数" << endl;
	cout << "a= " << a << endl;   
	cout << "b= " << b << endl;

	swap(a, b);

	cout << "即使调用了函数之后,在main函数中值未改变" << endl;
	cout << "a= " << a << endl;    //这样写是错误的,因为并没有交换
	cout << "b= " << b<< endl;     //函数的形参发生改变,并不会影响实参 传值不传址
	                                 //在swap中,实现了互换,但实参中的a b并没有互换
	system("pause");             //暂停结果显示
	return 0;
}
交换前,未调用交换函数
a= 10
b= 20
在形参函数中交换后
20
10
即使调用了函数之后,在main函数中值未改变
a= 10
b= 20
请按任意键继续. . .
总结: 值传递时,形参是修饰不了实参的

6.5 函数的常见样式

常见的函数样式有4种:
无参无返
有参无返
无参有返
有参有返

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//函数常见样式
//1、无参无返    相当于goto语句 插入一段代码而已
void test01()
{
	cout << "第一个test案例" << endl;
}
//2、无参有返      纯粹的把值 给调用代码  
int test02() 
{
	cout << "第二个test案例" << endl;
	return 1000;
}

//3、有参无返       相当于goto语句 插入一段代码,并且此代码需要给定数值才会运行 
void test03(int a)
{
	cout << "第三个test案例" << "a=" << a << endl;
}
//4、有参有返
int test04(int a)
{
	cout << "第四个test案例" << "a=" << a << endl;
	return a;
}

int main()
{


	test01();            //1、无参无返

	int num1=test02();  //2、无参有返      
	cout << num1 << endl;

	test03(1000);        //3有参无返

	test04(10000);


	system("pause");      //暂停结果显示
	return 0;
}
第一个test案例
第二个test案例
1000
第三个test案例a=1000
第四个test案例a=10000
请按任意键继续. . .

6.6 函数的声明

作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
函数的声明可以多次,但是函数的定义只能有一次

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串


int max(int a, int b);  //函数的声明 告诉编译器我有定义函数,只是把他放在了后面

int main()
{
	int a = 39, b = 34;
	cout << max(a, b) << endl;



	system("pause");      //暂停结果显示
	return 0;
}

//函数的声明
//比较函数,返回较大的值
int max(int a, int b)
{
	return  a > b ? a : b;
}

39
请按任意键继续. . .

6.7 函数的分文件编写

作用:让代码结构更加清晰

函数分文件编写一般有4个步骤

创建后缀名为.h的头文件
创建后缀名为.cpp的源文件
在头文件中写函数的声明
在源文件中写函数的定义

#源文件main并且加入头文件 #include"swap.h"
#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
#include"swap.h"
函数的分文件编写
实现两个数字交换的函数
//
函数的声明
//void swap(int a, int b);
函数的定义
//void swap(int a, int b)
//{
//	int temp = a;
//	a = b;
//	b = temp;
//
//	cout << "a= " << a << endl;
//	cout << "b= " << b << endl;
//}
int main()
{
	int a = 10;
	int b = 20;
	swap(a,b);



	system("pause");      //暂停结果显示
	return 0;
}
#头文件 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;
}

7 指针

7.1 指针的基本概念

指针的作用: 可以通过指针间接访问内存

内存编号是从0开始记录的,一般用十六进制数字表示

可以利用指针变量保存地址

7.2 指针变量的定义和使用

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

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串



int main()
{
	//1、定义指针
	int a = 10;
	int *p;//创建了一个指针,但未指向内存中的某块地址,野指针
	p = &a;  //初始化指针p地址,指向a地址。&取址符号
	cout << "a的地址为: " << &a << endl;
	cout << "p的地址为: "<<p << endl;

	//2、使用指针
	//可以通过解引用的方式来找到指针指向的内存
	//指针前加 *代表解引用,就可以找到指针所指向的内存中的数据
	*p = 1000;       //p操作该地址的数据,解引用
	cout << "a=" << a << endl;
	cout << "*p=" << *p << endl;

	a = 1;
	cout << "a=" << a << endl;

	system("pause");      //暂停结果显示
	return 0;
}
a的地址为: 0022FB5C
p的地址为: 0022FB5C
a=1000
*p=1000
a=1
请按任意键继续. . .

7.3 指针所占内存空间

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串



int main()
{
	//指针所占用内存的空间  在32位操作系统指针都是占4个字节,64位占用8位
	
	int a = 10;
	int *p=&a;
	cout << "sizeof(p)=" << sizeof(p) << endl;



	system("pause");      //暂停结果显示
	return 0;
}
sizeof(p)=4
请按任意键继续. . .

7.4 空指针和野指针

空指针:指针变量指向内存中编号为0的空间

**用途:**初始化指针变量

**注意:**空指针指向的内存是不可以访问的

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串



int main()
{
	//空指针
	//1、空指针用于给指针变量进行初始化
	int *p =NULL;    //0~255之间的内存编号是系统占用的,因此不可以访问
	
	//2、空指针是不可以进行访问的
	cout << p << endl;
	system("pause");      //暂停结果显示
	return 0;
}
00000000
请按任意键继续. . .

> 野指针:指针变量指向非法的内存空间

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
int main()
{
	//野指针 随便指向地址   实际开发中,避免出现野指针
	int *p = (int *)3234324;
	cout << *p << endl;

	system("pause");      //暂停结果显示
	return 0;
}

> 总结:空指针和野指针都不是我们申请的空间,因此不要访问。

7.5 const修饰指针

> const修饰指针有三种情况
const修饰指针 — 常量指针
const修饰常量 — 指针常量
const即修饰指针,又修饰常量

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

int main()
{
	//const修饰指针——常量指针   const int *p=&a;  
	                             //指针指向的值不能变,指向可变
	int a = 10;
	int b = 20;
	const int *p = &a;
	p = &b;

	//const修饰常量——指针常量   int * const p2=&a;
	                            //指向不可变,指针指向的值能变
	int * const p2 = &a;
	*p2 = 100;

	//const修饰指针和常量——    const int * const p3=&a;
	                             //什么都不能变
	   const int * const p3 = &a;
	   //*p3 = 100;  //错误,不可以改值
	   //p3 = &b;    //错误,不可以改指向
	   
	system("pause");      //暂停结果显示
	return 0;
}

7.6 指针和数组

**> **作用:利用指针访问数组中元素

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串



int main()
{
	//利用指针访问数组中的元素
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int * p = arr;  //指向数组
	cout << "利用指针访问第一个元素:" << *p << endl;

	p++;  //利用指针向后偏移
	cout << "利用指针访问第二个元素: " << *p << endl;


	//利用指针遍历数组
	int *p2 = arr;
	for (int i = 0; i < 10; i++)
	{
	
		cout << *p2 << endl;
		p2++;
	}
	system("pause");      //暂停结果显示
	return 0;
}
利用指针访问第一个元素:1
利用指针访问第二个元素: 2
1
2
3
4
5
6
7
8
9
10
请按任意键继续. . .

7.7 指针和函数

**作用:**利用指针作函数参数,可以修改实参的值

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//值传递
void swap1(int a ,int b)
{
	int temp = a;
	a = b; 
	b = temp;
}
void swap02(int *p1, int *p2)  //  调用函数时,  地址传递
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;

}

int main()
{
	//指针和函数
	//1、值传递与地址传递  的区别
	//值传递不会改变实参   地址传递会改变实参     按项目要求自己决定
	int a = 10, b = 20;
	swap02(&a,&b);
	cout <<"a="<< a << endl;
	cout <<"b="<< b << endl;

	system("pause");      //暂停结果显示
	return 0;
}
a=20
b=10
请按任意键继续. . .
**总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递**

7.8 指针、数组、函数

**案例描述:**封装一个函数,利用冒泡排序,实现对整型数组的升序排序

例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//参数1 数组的首地址     参数2  数组长度
void bubblesort(int *arr,int len)//传数组的首地址   数组的长度 ,int * arr 也可以写为int arr[]
{
	for (int i = 0; i < len-1; i++)
	{
		for (int j = 0; j < len-i-1; j++)
		{
			if (arr[j] > arr[j+1])
			{
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}

	}
}


//打印函数
void printArray(int *arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}

int main()
{
	//封装一个函数,利用冒泡排序,实现对整型的数组进行排序

	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
	int len = sizeof(arr) / sizeof(arr[0]);   //数组的长度
	bubblesort(arr, len);  //arr后什么也不写就代表数组的首地址
	
	printArray(arr,len);

	system("pause");      //暂停结果显示
	return 0;
}
1
2
3
4
5
6
7
8
9
10
请按任意键继续. . .

8 结构体

8.1 结构体基本概念

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型

8.2 结构体定义和使用

> 语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:

struct 结构体名 变量名
struct 结构体名 变量名 = { 成员1值 , 成员2值…}
定义结构体时顺便创建变量

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//1、创建学生的数据类型
struct Student
{
	//成员列表
	string name;
	//姓名
	int age;
	//分数
	int score;
}s3;


int main()
{

	//2、通过学生类型创建具体学生
	// 第一种方式使用结构体    struct Student s1
	struct Student  s1;
	s1.name = "张三";
	s1.age = 18;
	s1.score = 100;
	cout << "姓名: " << s1.name << "  年龄: " << s1.age << "    分数: " << s1.score << endl;

	//  第二种方式使用结构体    struct Student s2={....}
	struct Student s2 = { "李四",19,80 };
	cout << "姓名: " << s2.name << "  年龄: " << s2.age << "    分数: " << s2.score << endl;
	//  第三种方式使用结构体    在定义结构体时顺便创建结构体变量

	s3.name = "王五";
		s3.age = 20;
		s3.score = 60;

		cout << "姓名: " << s3.name << "  年龄: " << s3.age << "    分数: " << s3.score << endl;
	system("pause");      //暂停结果显示
	return 0;
}
姓名: 张三  年龄: 18    分数: 100
姓名: 李四  年龄: 19    分数: 80
姓名: 王五  年龄: 20    分数: 60
请按任意键继续. . .
总结1:定义结构体时的关键字是struct,不可省略

总结2:创建结构体变量时,关键字struct可以省略

总结3:结构体变量利用操作符 ‘’.’’ 访问成员

8.3 结构体数组

**作用:**将自定义的结构体放入到数组中方便维护

语法:struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//结构体数组
//1、定义一个结构体
struct Student
{
	string name;
	int age;
	int score;
};

int main()
{
	//2、创建结构体数组
	struct Student stuArray[3] =
	{
		{"张三",100},{"李四",28,70},{"王五",25,99}  //不赋值的化默认为0
	};
	//3、给结构体数组中的元素赋值
	stuArray[2].name = "赵六";
	stuArray[2].age = 15;
	//4、遍历结构体数组
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名: " << stuArray[i].name << "  年龄:" << stuArray[i].age << "  分数:" << stuArray[i].score << endl;

	}
	system("pause");        //暂停结果显示
	return 0;
}
姓名: 张三  年龄:100  分数:0
姓名: 李四  年龄:28  分数:70
姓名: 赵六  年龄:15  分数:99
请按任意键继续. . .

8.4 结构体指针

**作用:**通过指针访问结构体中的成员

利用操作符 ->可以通过结构体指针访问结构体属性

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串


struct Student
{
	string name;
	int age;
	int score;
};

int main()
{
	//创建学生的结构体变量
	struct Student s = { "张三",18,100 };

	//通过创建结构体指针  指向结构体变量
	struct Student  *p = &s;
	//通过指针访问结构体变量中的数据
	cout << "姓名:" << p->name<<" 年龄:" << p->age << " 分数:" << p->score << endl;

	system("pause");      //暂停结果显示
	return 0;
}
姓名:张三 年龄:18 分数:100
请按任意键继续. . .

总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员

8.5 结构体嵌套结构体

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

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

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//定义学生的结构体
struct student
{
	string name;//姓名
	int age;    //年龄
	int score;   //分数
};
						
//定义老师结构体
struct teacher
{
	int id;
	string name;
	int age;
	struct student s;
};

int main()
{
	//结构体嵌套结构体
	//创建老师
	teacher t1;
	t1.id = 223;
	t1.age = 33;
	t1.name = "阿达";
	t1.s.name = "小王";
	t1.s.age = 13;
	t1.s.score = 100;

	cout << "老师的姓名: " << t1.name << "  老师的编号: " << t1.id << "  老师的年龄: "<<t1.age
		<< " 老师辅导的学生姓名: " << t1.s.name << "  学生的年龄: " << t1.s.age << "  学生的分数: " << t1.s.score << endl;
	system("pause");      //暂停结果显示
	return 0;
}
老师的姓名: 阿达  老师的编号: 223  老师的年龄: 33 老师辅导的学生姓名: 小王  学生的年龄: 13  学生的分数: 100
请按任意键继续. . .

**总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题

8.6 结构体做函数参数

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

传递方式有两种:

值传递
地址传递

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
//结构体做函数参数
//将学生传入到一个参数中,打印学生身上的所有信息

//定义学生结构体
struct student
{
	string name;
	int age;
	int score;
};

//打印学生信息函数
void printStudent(struct student s)
{
	cout << "  姓名:" <<s.name<< " 年龄: " << s.age << "  分数:" << s.score << endl;
	s.age = 500;
}

void printStudent2(struct student *p)
{
	cout << "  姓名:" << p->name << " 年龄: " << p->age << "  分数:" << p->score << endl;
	p->age = 100;  //把年龄改为100
}

int main()
{

	struct student s;
	s.name = "张三";
	s.age = 20;
	s.score = 85;
	printStudent(s); //值传递
	cout << " 年龄: " << s.age << endl;
	printStudent2(&s);//地址传递
	cout << " 年龄: " << s.age << endl;
	
	system("pause");      //暂停结果显示
	return 0;
}
  姓名:张三 年龄: 20  分数:85
 年龄: 20
  姓名:张三 年龄: 20  分数:85
 年龄: 100
请按任意键继续. . .

总结:如果不想修改主函数中的数据,用值传递,反之用地址传递

8.7 结构体中const使用场景

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

struct student
{
	string name;
	int age;
	int score;
};
//将函数中的形参改为指针,可以减少内存空间,不会复制新的副本出来
//并且加了const不可以改形参的值,常量指针,保持外部实参的值,以防止函数内将其误操作
void printstudent( const student *s) //有const之后,就不能修改s.中的值了,会报错
{
	cout << "姓名:" << s->name << "      年龄:" << s->age << "     得分" << s->score << endl;
	
}
int main()
{
	//创建结构体变量
	struct student s = { "张三",15,70 };
	//通过函数来打印学生信息
	printstudent(&s);
	
	system("pause");      //暂停结果显示
	return 0;
}
姓名:张三      年龄:15     得分70
请按任意键继续. . .

8.8 结构体案例一

案例描述:

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

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

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

最终打印出老师数据以及老师所带的学生数据。

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串
#include<ctime>

//3个老师,分别带5个学生


//学生的结构定义
struct Student
{
	string sName;
	int score;
};

//老师的结构定义
struct Teacher
{
	string tName;
	struct Student sArray[5];
};



//给老师和学生赋值的函数
void allocateSpace(struct Teacher tArray[],int len)
{
	string 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;//取随机数0~60  另外再加40
			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;
		}
	}
}
int main()
{
	//随机数种子
	srand((unsigned int)time(NULL));
	//创建3名老师的数组
	struct Teacher tArray[3];
	int len = sizeof(tArray) / sizeof(tArray[0]);
	//通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
	allocateSpace(tArray, len);
	//打印所有老师及所带的学生信息
	printInfo(tArray,len);

	system("pause");      //暂停结果显示
	return 0;
}
老师姓名: Teacher_A
        学生姓名:  Student_A   考试分数: 42
        学生姓名:  Student_B   考试分数: 42
        学生姓名:  Student_C   考试分数: 58
        学生姓名:  Student_D   考试分数: 94
        学生姓名:  Student_E   考试分数: 62
老师姓名: Teacher_B
        学生姓名:  Student_A   考试分数: 75
        学生姓名:  Student_B   考试分数: 50
        学生姓名:  Student_C   考试分数: 57
        学生姓名:  Student_D   考试分数: 77
        学生姓名:  Student_E   考试分数: 44
老师姓名: Teacher_C
        学生姓名:  Student_A   考试分数: 42
        学生姓名:  Student_B   考试分数: 70
        学生姓名:  Student_C   考试分数: 69
        学生姓名:  Student_D   考试分数: 81
        学生姓名:  Student_E   考试分数: 64
请按任意键继续. . .

8.9 结构体案例二

设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

五名英雄信息如下:
{“刘备”,23,“男”},
{“关羽”,22,“男”},
{“张飞”,20,“男”},
{“赵云”,21,“男”},
{“貂蝉”,19,“女”},

#include<iostream>     //c++中的头文件,调用c++系统程序
using namespace std;    //c++命名空间(调用关键字的命名含义)
#include<string>       //引用字符串

//英雄的结构体定义
struct Hero
{
	string name;
	int age;
	string sex;
};

//冒泡排序
void bubbleSort(struct Hero heroarray[], int len)
{
	for (int i = 0; i < len; 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];
					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()
{
	//1、英雄的结构体
	//2、创建数组存放5名英雄
	//3、对数组进行排序,按照年龄进行排序
	//4、将排序后的结果打印输出

	struct Hero heroarray[5] =
	{
		{"赵云",23,"男"},
		{"关羽",22,"男"},
		{"张飞",24,"男"},
		{"黄忠",20,"男"},
		{"貂蝉",21,"女"},
	};
	int len = sizeof(heroarray) / sizeof(heroarray[1]);
	cout << "排序前的打印结果 " << endl;
	for (int i = 0; i < len; i++)
	{
		cout << "姓名:" << heroarray[i].name << "  年龄:" << heroarray[i].age << "  性别:" << heroarray[i].sex << endl;
	}
	bubbleSort(heroarray, len);
	cout << "排序后的打印结果 " << endl;
	printHero(heroarray,len);

	system("pause");      //暂停结果显示
	return 0;
}
排序前的打印结果
姓名:赵云  年龄:23  性别:男
姓名:关羽  年龄:22  性别:男
姓名:张飞  年龄:24  性别:男
姓名:黄忠  年龄:20  性别:男
姓名:貂蝉  年龄:21  性别:女
排序后的打印结果
姓名:黄忠  年龄:20  性别:男
姓名:貂蝉  年龄:21  性别:女
姓名:关羽  年龄:22  性别:男
姓名:赵云  年龄:23  性别:男
姓名:张飞  年龄:24  性别:男
请按任意键继续. . .

后记

进步始于交流,收获源于分享。希望一起走过的日子里,我们能够更多地交流心得,共同进步 - You are not alone。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值