C++学习笔记(4)
学习是一件任重而道远的事情,与其焦虑不如动手起来,借助平台记录自己学习笔记,希望和大家多多交流,今天又是努力成为程序媛的一天!
10.数组
10.1概述
概念:就是一个集合,里面存放了相同类型的数据元素
- 数组中的每个数据元素都是相同的数据类型
- 数组是由连续的内存位置组成的
10.2一维数组
10.2.1 一维数组的定义方式
- 三种定义方式:
-
数据类型 数组名[ 数组长度 ];
[ 注意:数组的下标是从0开始的 ] -
数据类型 数组名[ 数组长度 ] = {值1,值2…};
[ 注意:长度多少,后面就写多少个值,如果初始化的数据,会自动用0来填充 ] -
数据类型 数组名[ ] = {值1,值2…};
[ 注意:可以不定义数组长度,但是后面一定要有值给数组一个初始化长度 ]
#include<iostream>
using namespace std;
int main() {
//一组数组表达
//1. 数据类型 数组名[数组长度];
int arr[3];
arr[0] = 1;//注意:数组的下标是从0开始的
arr[1] = 2;
arr[2] = 3;
for (int i = 0; i < 3; i++) {
cout << arr[i] << endl;
}
//2. 数据类型 数组名[数组长度] = { 值1,值2... };
int array[3] = { 1,5 };//注意:长度多少,后面就写多少个值,如果初始化数据不够会自动0来补充,记得加分号
for (int i = 0; i < 3; i++) {
cout << array[i] << endl;
}
//3. 数据类型 数组名[] = { 值1,值2... };
int arr3[] = { 1,4 };//注意:可以不定义数组长度,但是后面一定要有值给数组一个初始化长度,否则报错
for (int i = 0; i < 2; i++) {
cout << arr3[i] << endl;
}
}
运行结果
10.2.2 一维数组数组名
- 一维数组数组名的作用:
1.可以统计整个数组在内存中的长度;
利用sizeof可以获取数组所占内存空间大小
获取整个数组所占内存空间大小:sizeof(arr);
某个数组元素所占空间大小:sizeof(arr[x]);
sizeof(arr)与sizeof(arr[x])之比就是数组元素个数
2.可以获取数组在内存中的首地址;
默认输出十六进制,可以int强制转化为十进制
#include<iostream>
using namespace std;
int main() {
//1.通过数组名统计整个数组所占内存空间大小
int arr[3] = { 1,5,9 };
cout << "整个数组所占内存空间为:" << sizeof(arr) << endl;
cout << "每个元素所占内存空间为:" << sizeof(arr[0]) << endl;//每个元素数据类型相同,每个数据类型所占内存空间大小是固定的
cout << "数组中元素个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;//利用总空间大小/单个空间大小得出元素个数
//2.通过数组名查看数组首地址
cout << "数组首地址为:" << arr << endl;//默认16进制
cout << "数组首地址为:" << (int)arr << endl;//可以通过int强转类型变为10进制
cout << "第一个元素的地址为:" << (int)&arr[0] << endl;//访问第一个数组元素的地址
cout << "第二个元素的地址为:" << (int)&arr[1] << endl;
//arr = 100报错,数组名是常量,不可以进行赋值操作
system("pause");
return 0;
}
注意:数组名是常量,不可以进行赋值操作
运行结果:
- 小练习1:打印五只小猪的最大体重(可以找出数组中的最大值)
#include<iostream>
using namespace std;
int main() {
//五只小猪🐖称体重,找出最重的小猪体重
int arr[5] = { 58,60,80,90,65 };
int max = 0;//定义一个变量用来存储最大值
for (int i = 0; i < 5; i++) {
if (arr[i] > max) {
max = arr[i];//遍历每个小猪体重,和max进行比较,比认定max大就更新max
}
}
cout << "最大的体重为:" << max << endl;
system("pause");
return 0;
}
运行结果:
- 小练习2:数组倒置***,将原定一组数组元素,顺序倒过来输出,如arr[2] = {1,3};倒置后arr[2] = {3,1};
!!!
#include<iostream>
using namespace std;
int main() {
//实现数组倒置
//1.定义并输出原数组
int arr[5] = { 1,8,9,5,6 };
//数组下标的最大值为sizeof(arr) / sizeof(arr[0]) -1
for (int i = 0; i < 5; i++) {
cout << arr[i] << endl;
}
//2.实现数组倒置
//进行两个元素之间的转换,最开始的元素给最后一个
//直到开始索引小于结束索引为止
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--;
}
cout << "逆置后的数组:" << endl;
//打印逆置后的数组
for (int i = 0; i < 5; i++) {
cout << arr[i] << endl;
}
system("pause");
return 0;
}
运行结果:
10.2.3 冒泡排序♥
作用:最常用的排序算法,对数组内元素进行排序
1.比较相邻元素,如果第一个比第二个大,就交换二者
2.对每一对相邻元素做同样工作,执行完找到第一个最大值
3.每一轮都能找到该组最大值
4.重复以上步骤,每次比较次数-1,知道无需比较
5.实现升序降序操作
#include<iostream>
using namespace std;
int main() {
//定义一个数组
int arr[8] = { 5,8,6,1,0,7,2,3 };
cout << "原数组为:" << endl;
for (int i = 0; i < 8; i++) {
//输出原数组
cout << arr[i] << " ";
}
cout << endl;
//冒泡排序
//总共排序轮数为 元素个数 -1
for (int i = 0; i < 8 - 1; i++) {
//每一轮比较的次数 元素个数 - 轮数 - 1
for (int j = 0; j < 8 - i - 1; j++) {
//如果第一个比第二个大,交换两个数字
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 < 8; i++) {
//输出原数组
cout << arr[i] << " ";
}
system("pause");
return 0;
}
运行结果:
- 排序轮数为 元素个数 - 1
- 对比次数为 元素个数 - 轮数 - 1
10.3二维数组
在一维数组上,增加一个维度
10.3.1二维数组定义方式
- 数据类型 数组名[ 行数 ][ 列数 ];
- 数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 },{ 数据3,数据4} };
- 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2 ,数据3,数据4 };
- 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2 ,数据3,数据4 };
#include<iostream>
using namespace std;
int main() {
//二维数组定义方式
//1. 数据类型 数组名[行数][列数];
int arr[2][3];
arr[0][0] = 1;
arr[0][1] = 2;
arr[0][2] = 4;
arr[1][0] = 3;
arr[1][1] = 6;
arr[1][2] = 8;
//输出二维数组 外层循环打印行数 内层循环打印列数
//矩阵都可以用嵌套循环
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << arr[i][j] << endl;
}
}
//2. 数据类型 数组名[行数][列数] = { {数据1,数据2 },{ 数据3,数据4} };//相对更清晰
int arr2[2][3] = {
{1,2,3},
{4,8,9}
};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << arr2[i][j] << " ";
}
cout << endl;
}
//3. 数据类型 数组名[行数][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr3[2][3] = { 1,8,6,8,9,5 };
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << arr3[i][j] << " ";
}
cout << endl;
}
//4. 数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4 };
//行数可以省略,列数不可以!!
int arr4[][3] = { 4,7,9,2,77,5 };
system("pause");
return 0;
}
运行结果:
10.3.2二维数组定义方式
- 查看二维数组所占内存空间
- 查看二维数组的首地址
#include<iostream>
using namespace std;
int main() {
//数据类型 数组名[行数][列数] = { {数据1,数据2 },{ 数据3,数据4} };//相对更清晰
//查看内存空间大小
int arr2[2][3] = {
{1,2,3},
{4,8,9}
};
cout << "这个二维数组所占内存空间为:" << sizeof(arr2) << endl;
cout << "这个二维数组第一行所占内存空间为:" << sizeof(arr2[0]) << endl;
cout << "这个二维数组第一个元素所占内存空间为:" << sizeof(arr2[0][0]) << endl;
cout << "二维数组行数为:" << sizeof(arr2) / sizeof(arr2[0]) << endl;
cout << "二维数组列数为:" << sizeof(arr2[0]) / sizeof(arr2[0][0]) << endl;
//查看二维数组的首地址
cout << "二位数组的首地址为:" << (int)arr2 << endl;
cout << "二位数组第一行的首地址为:" << (int)arr2[0] << endl;
cout << "二位数组第一个元素的首地址为:" << (int)&arr2[0][0] << endl;//访问具体元素的地址时,前面要加&
cout << "二位数组第二个元素的首地址为:" << (int)&arr2[0][1] << endl;//访问具体元素的地址时,前面要加&
system("pause");
return 0;
}
运行结果:
- 二维数组的行数为 二维数组所占内存空间 / 一行所占空间 即
sizeof(arr) / sizeof(arr[0])
- 二维数组的列数为 二维数组一行所占内存空间 / 第一个元素所占内存空间大小 即
sizeof(arr[0]) / sizeof(arr[0][0])
10.3.3二维数组案例
考试成绩统计!
#include<iostream>
using namespace std;
#include<string>//使用它时要加头文件
int main() {
//二维数组案例:考试成绩统计
//1.创建二维数组
int arr[3][3] = {
{100,100,100},
{90,50,100},
{60,70,80}
};
//创建姓名数组 可以对应输出每个人的名字成绩
string names[3] = { "张三" , "李四" , "王五" };
//2.统计每个人的总分分数
for (int i = 0; i < 3; i++) {
int sum = 0;//统计总分
for (int j = 0; j < 3; j++) {
sum += arr[i][j];
}
cout << names[i] << "的总分为:" << sum << endl;
}
system("pause");
return 0;
}
运行结果:
11.函数
11.1概述
作用:将一段经常使用 的代码封装起来,减少重复代码
11.2函数的定义
函数的定义一般有5个步骤:
1.返回值类型;2.函数名;3.参数表列;4.函数体语句;5.return表达式
语法:
返回值类型 函数名 (参数列表)
{
函数体语句
return表达式
}
11.3函数的调用
语法:
函数名(参数)
举例:一个加法函数的定义和调用
#include<iostream>
using namespace std;
//定义一个求和函数
//函数语法:
//返回值类型 函数名 (参数列表){函数体语句 return表达式}
int add(int num1, int num2) {//形参
int sum = num1 + num2;
return sum;
}
int main() {
//在main函数中调用函数
int a = 10;
int b = 20;
//调用函数
//函数名(参数)
//函数有返回值,可以赋给它
int c = add(a, b);//实参
cout << "c=" << c << endl;
system("pause");
return 0;
}
运行结果:
注意:
- 导入参数列表时参数是要加数据类型的,中间隔开用,
- return的返回值必须和函数返回值类型对应
- 定义函数时,参数列表的参数并没有实际的值,只是形式上的参数,简称形参,调用函数时用的是实际的参数,简称实参,调用时,实参传递给形参
11.4值传递
意义:函数调用时实参数值传入给形参,值传递时,如果形参发生,并不会影响实参
#include<iostream>
using namespace std;
//值传递
//定义函数,实现两个数字进行交换函数
//如果函数不需要返回值,声明的时候可以写void
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 << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
输出结果:
注意:
- 如果函数不需要返回值,声明可以写void,表示无类型;
- 值传递时,形参的转变并不影响实参的输出,形参在变化,但是实参从头到尾都没有参与变化
11.5常见的样式
函数常见样式:
1.无参无返;2.有参无返;3.无参有返;4.有参有返
#include<iostream>
using namespace std;
//函数的常见样式
//1.无参无返
void test1() {
cout << "this is test1" << endl;
}
//2.有参无返
void test2(int a) {
cout << "this is test2 a = " << a << endl;
}
//3.无参有返
int test3() {
cout << "this is test3" << endl;
return 100;
}
//4.有参有返
int test4(int a) {
cout << "this is test3 a = " << a << endl;
return a - 1;
}
int main() {
//1.无参无返的调用
test1();
//2.有参无返的调用
test2(1000);
//3.无参有返的调用
int c = test3();//对于有返回值调用时需要变量来接收返回值
cout << "c = " << c << endl;
//4.有参有返的调用
int d = test4(11);
cout << "d = " << d << endl;
system("pause");
return 0;
}
运行结果:
11.6函数的声明
调用函数之前,对函数进行声明,提前告诉计算机有这么一个函数,这样函数定义不论出现在代码什么位置,只要开始引用了它,就不会报错,否则必须定义完函数才能调用这个函数。
- 函数声明可以多次,定义只能一次
#include<iostream>
using namespace std;
//函数声明
//定义一个比较函数,返回较大值
int max(int a, int b);//可以把函数写在main后面,就是提前声明,后面如果函数还没出来碰到也不会报错
//声明可以多次,定义只能一次
int main() {
int a = 10;
int b = 20;
cout << max(a, b) << endl;
system("pause");
return 0;
}
int max(int a, int b) {
return a > b ? a : b;
}
运行结果:
11.7函数的分文件编写
步骤:
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的源文件
- 在头文件写函数的声明
- 在源文件中写函数定义
- 运行的是.cpp源文件中的main()文件主程序
- main()主程序文件里要在开始引用头文件
- 自定义的头文件引用的时候用的是双引号“”,
#include “swap.h"
- 定义函数的.cpp文件里要在开头也引用头文件,格式同上,建立头文件和函数文件的关联
- 头文件开始也要写,这是框架格式
#include<iostream>;
using namespace std;
第四篇笔记到此结束,C++基础学习会持续更新在C++学习笔记合集中,当作学习笔记复习,如果能帮助其他小伙伴就更好了。
笔记是看b站黑马程序员的C++视频学习时做的记录,笔记中如果有错误和改进的地方,欢迎大家评论交流,up up up!!!
学习原视频来自:黑马程序员C++从0到1