浅谈近30天的C++学习
学习了近一个月的C++,今天呢,来浅浅的谈一下这近30天的C++学习
目录
C++的学习呢,目前我是采用的使用B站视频进行学习,后期再使用电子书《C++从入门到精通》来进行学习,具体目录如下
基础部分
这一部分呢,就是C++的一个基础了,没有太多的分类,不像函数,变量,类型,运算符之类的有好几个板块。
书写hello world
这个部分可以说是绝大部分编程语言的开始,hexo也一样哦,虽然hexo是博客框架,但第一篇文章还是HELLO WORLD!
这里呢,把代码放在这里,然后简单的做一个注释
1 |
|
注释
这个在上面就写出来了,还是单独写一下吧
1 | //单行注释 |
变量
作用:给一段指定的内存空间起名,方便操作这段内存
示例:
1 |
|
注意:C++在创建变量时,必须给变量一个初始值,否则会报错
感觉无非就是int a = 10;然后挨个换,只需要将变量记住就好了,比如double,float,等
常量
这个居然学掉了,我也是非常震惊,居然就直接跳过了,不过目前学的C++来看,目前还没有用上常量,也是,目前,当然也补上了
作用:用于记录程序中不可更改的数据
定义方法
define 常量名 常量值
注意:#define要写在main函数前面,我习惯于在using namesapce或者#includeconst 数据类型 常量名 = 值
示例
1 |
|
关键字
这个不多介绍,像什么int,cout,system,return,float,if,while,等等
标识符命名规则
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | (-2^15 ~ 2^15-1) |
int(整型) | 4字节 | (-2^31 ~ 2^31-1) |
long(长整形) | Windows为4字节,Linux为4字节(32位),8字节(64位) | (-2^31 ~ 2^31-1) |
long long(长长整形) | 8字节 | (-2^63 ~ 2^63-1) |
一般呢,我们前期是使用int居多,当然只是目前的前期来看,也会有其他的
sizeof关键字
作用:查看一个类型占用的内存字节
语法:sizeof(数据类型)
示例为:
1 |
|
所输出的则为:int所占用的字节为4字节
实型(浮点型)
我的理解呢,就是把后面的小数点输出,然后多余的就用0补足,直接举例子理解
1 |
|
科学记数法
这里看到里面提到了科学计数法,就简单来讲一下,顺便来说说自己的理解吧,应该是很好理解了。
这里的科学计数法就是上面的,3e2,和3e-2了,那么这个是什么意思呢,简单来说,就是:几e几就是几乘几的10的几次方,3e2就是3乘以10的2次方,负数呢就是乘0.1来计算,比如4e7就是4乘以十的七次方,5e-7就是5乘以0.1的七次方
字符型
字符型,即char函数,用于显示单个字符,且只能用单引号’ ‘,示例
1 |
|
上面就会输出hello啦,虽然感觉不如cout实用
转义字符
只列个表和列出自己比较常用的几个
自己常用的为
- \n 在c语言中常用,c++使用 endl
- “用来放入文字,用cout输出”
转义字符 | 含义 | ASCII码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符”\” | 092 |
\’ | 代表一个单引号(撇号)字符 | 039 |
\” | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 数字0 | 000 |
\ddd | 8进制转义字符,d范围0~7 | 3位8进制 |
\xhh | 16进制转义字符,h范围0~9,a~f,A~F | 3位16进制 |
字符串型
刚刚已经提到过了,char,但是char是C语言中的,c++中使用string进行字符串输出
注意:需要引入头文件#include
示例:
1 |
|
输出为何星梦
布尔类型
作用:布尔数据类型代表真或假的值
bool类型只有两个值:
- true —- 真(本质是1)
- false —- 假(本质是0)
bool类型占==1个字节==大小
示例:由于占的大小已经写出来了,就不去单独用sizeof了
1 |
|
输出结果先为1(真),再为0(假)
数据的输入cin
数据输入使用cin关键字,然后可以给变量赋值,比如以下的示例(示例中还有布尔类型,浮点型等等,但是形式上之类的都差不多,都是输入一个值,然后把这个值赋值给变量)
1 | //数据输入cin |
程序就会先让你输入你的名字,在输出你的名字之后呢,就会输出一段文字为:你的名字为“你输入的名字,不带引号”
运算符
作用:用于执行代码的运算
运算符类型 | 作用 |
---|---|
算术运算符 | 用于处理四则运算 |
赋值运算符 | 用于将表达式的值赋给变量 |
比较运算符 | 用于表达式的比较,并返回一个真值或假值 |
逻辑运算符 | 用于根据表达式的值返回真值或假值 |
算术运算符
作用:用于处理四则运算
算术运算符包括以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | 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; |
加减乘除正和负这几个简单的就先不说了,主要谈取模(取余)、前置递增,后置递增,前置递减,后置递减
取模(取余)
取模,又称取余,余,即余数,所以出现了上面的10 %(取模于)3,结果是1,那么这个结果的运算过程就是10/(除以)3=3余数是1,则余1,则取模的结果就是1
前置递增
即自己进行+1操作不过符号写在前面,如
1 | a = ++b; |
后置递增
也是自己进行+1操作,但是符号写在后面,如
1 | a = b++; |
前置递减
即自己进行-1操作,符号在前,如
1 | a = --b |
后置递减
如上,符号在后,如
1 | a = b-- |
比较运算符
作用:用于表达式的比较,并返回一个真值(1)或假值(0),真值和假值在布尔类型里有提到过
比较运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
简单写一下
1 |
|
所以我们就得到了以下的结果
1 | 0 |
逻辑运算符
逻辑运算符有以下符号:
运算符 | 术语 | 示例 | 结果 | ||||
---|---|---|---|---|---|---|---|
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 | ||||
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。 | ||||
\ | \ | 或 | a \ | \ | b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
逻辑运算符的”非”(!)—— 专门唱反调的小捣蛋 “非”运算符就像个调皮鬼,专门跟你对着干!你说”对”,它偏说”错”;你说”错”,它偏说”对”。比如:
1 | bool 下雨 = true; |
这个”!”就像在说:”才不是这样呢!”[1][3] 逻辑运算符的”与”(&&)—— 严格的全优生 “与”运算符就像个追求完美的学霸,要求所有科目都考A才行。比如:
1 | bool 作业写完 = true; bool 天气好 = true; if(作业写完 && 天气好) { // 必须两个条件都满足 cout << "可以出去踢球啦!"; } |
就像妈妈说的:”作业写完并且天气好才能出去玩”——少一个都不行![1][8] 逻辑运算符的”或”(||)—— 好说话的选项控 “或”运算符就像个很好说话的朋友,”这个也行,那个也行”。比如:
1 | if(有会员卡 || 有优惠券) { // 满足一个就行 cout << "可以享受折扣!"; } ``` |
这个例子中,必须有钱,并且(妈妈同意或者没有肚子疼)才能吃
使用小贴士 1. “非”(!)优先级最高,像老师总最先批改他的作业 2. “与”(&&)比”或”(||)优先级高,就像乘法比加法优先 3. 记不住优先级?用括号()把想先算的包起来最保险! 就像数学里的”先算括号里的”一样
程序流程结构
C/C++支持最基本的三种程序运行结构:==顺序结构、选择结构、循环结构==
- 顺序结构:程序按顺序执行,不发生跳转
- 选择结构:依据条件是否满足,有选择的执行相应功能
- 循环结构:依据条件是否满足,循环多次执行某段代码
选择结构
if语句
if即英文中的如果,也就是判断是否满足一个条件,如果满足就执行满足条件的语句,不满足则看是单行if还是多行if进行条件语句的判断
单行if
单行if的语法为:
1 | if(条件){ 条件满足执行的语句 } |
那么就来个简单的例子
1 |
|
解释
这里就解释一下这行代码的意义,首先我定义了一个整形a,并给a赋值为0,当if条件判断的时候,判断到条件a等于了0,就开始执行语句,也就是下方的hello world,所以最后就输出了helloworld
多行if
多行if则就是有着多行的if,不只是有一个if,说起多行,其实也是只有两行,语法为
1 | if(条件){ 条件满足执行的语句 }else{ 条件不满足执行的语句 }; |
很简单的,假如我输入一个数字,判断是否大于50,如果大于50就输出一行字,为:“您输入的数字(具体的数字),大于50,否则输入您输入的数字(具体的数字小于50)”
示例
1 |
|
示例中因为多行if为两个if,就会出现一种情况,当num>=50的时候还是会输入这个数字大于50,所以没有办法只能用上下面的多条件if了,所以多条件if的示例就不举出来了
多条件if
多条件if就是多了一个单词,上面大家也看到了,也就是
1 | else if(条件){执行语句} |
那么示例呢,就照着上面那个就可以了!
三目运算符
作用: 通过三目运算符实现简单的判断
语法:表达式1 ? 表达式2 :表达式3
解释:
如果表达式1的值为真,执行表达式2,并返回表达式2的结果;
如果表达式1的值为假,执行表达式3,并返回表达式3的结果。
其实三目运算符的话算一个比较简单和简便的判断,判断呢也就是上面的表述这么简单,依旧是来个示例吧!
1 |
|
这个示例里面,C就等于20了,那么为什么呢,就来解释一下:
我们的表达式是a>b?a:b;,把这个表达式赋值给C,那么这个三目运算符的意思就是,如果a>b成立(真),执行的语句就是c=a,反之,如果a>b不成立,那么就执行c=b,我们开头是一个表达式(a>b),随后根据表达式进行判断,如果这个表达式为真,就执行?后的第一个表达式(表达式2),如果表达式为假,那么就执行?后的第二个表达式,也就是表达式3,我们可以再换一个例子
1 |
|
这次呢,我们的c就等于了10,那么为什么呢,因为这个表达式C = a<b?a:b;的意思是,如果a<b,如果a<b成立,那么C就等于?后的a,但是如果a<b不成立,那么,c就等于表达式3,也就是c=b,那么很明显,a(20)<b(10),是不成立的,那么这个表达式就是假的,就会执行表达式3,也就是c=b,所以c=了10
swithc语句
作用:执行多条件分支语句
语法:
1 | switch(表达式) |
注意1:switch语句中表达式类型只能是整型或者字符型
注意2:case里如果没有break,那么程序会一直向下执行
总结:与if语句比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间
这些是手册里面给出来的,也比较好理解,就是switch,然后后面跟表达式,但是表达式里面不写等于,小于,大于等于,小于等于这一类的比较运算符,直接写这个表达式,在case后面写这个表达式等于多少,再写执行的语句,我们依旧来写一下这个吧,差点给while和switch整混了,接下来依旧是示例,那么,很需要的注意就是,你得先把要写的最高的写在前面,比如你要写0-10分的评分,不能从0写起,得从10写起,不然程序就会把从低到高的都执行一遍,当然也得把break写进去,就像上面的注意2所提到的一样
1 |
|
这个就不用解释了吧,各位应该也看得出来,也就是case 后面的是分数,你输入的多少分,就会提示相应的数,但是会有小BUG,比如比0小,比10大就输入不出来,得套if,这个以后再说吧,我会肯定是会写的QWQ
循环结构
while循环
这是我最喜欢的一个循环啦,稍后再说为什么,先来看作用和语法
作用:满足循环条件,执行循环语句
语法:while(循环条件){ 循环语句 }
解释:==只要循环条件的结果为真,就执行循环语句==
我们先来写个程序,就可以解释我为什么喜欢这个了,还是依旧的跟上面的switch差不多,但是呢,这一次我要求只能输入比5大的才能退出循环,然后我们将套用if,评分改为0-5分
1 |
|
这回呢,如果你输入的是0,1,2,3,4,都会继续让你输入,直到你输入了5跳出了循环才可以退出,当然也可以自己手动叉掉
do while 循环语句
作用: 满足循环条件,执行循环语句
语法: do{ 循环语句 } while(循环条件);
注意:与while的区别在于do…while会先执行一次循环语句,再判断循环条件
那么我们只需要明白do会先执行一次语句,再执行循环,那么来个示例和解释:
1 |
|
解释一下,因为会先执行一遍do里面的语句,也就是会先进行以下操作
1 | cout<<num<< endl; |
会先输出我们已经定义的num,也就是0.然后执行完后开始执行循环,循环的条件就是while后面的(num<10),即,当num<10的时候,会一直执行循环,也就是一直会让num进行自加操作,直到num不再<10,所以到9就会直接结束循环。
for 循环
这是我比较喜欢的一个循环,因为可以直接定义,但是还是更喜欢while
作用: 满足循环条件,执行循环语句
语法:for(起始表达式;条件表达式;末尾循环体) { 循环语句; }
这里呢,简单写以下,并且给下注释之类的
1 |
|
具体的解释就照着手册写一个吧,都差不多,
执行顺序为0开始,也就是先定义我们的a,然后是1,也就是条件表达式,我给的是a<10这个条件,然后执行语句输出我们的a,然后再执行第三步,将a自加,然后当a加到条件a<10了,也就是最大的a=9了,就会结束循环,那么我们输出的就为
1 | 0 |
当然,for里面还可以套if,else if.else,while等等的循环语句和选择语句之类的,就不举例了,因为没想到可以写点什么,没有什么思路
嵌套循环
说白了就是循环里面套循环,比如for里面套for,然后if里面套if,if的if里面套for等等
简单的来一个示例吧,比如嵌套循环中我依旧要你对我评分,因为要多个循环套,所以我加上了switch,必须要输入等于100分才能退出循环
1 |
|
这里发现有个错误,就是注释掉的for,这一段还是我问AI问出来的,因为我发现我输入100后还是无法跳出循环,问了AI后才知道其实已经跳出循环了,不过跳出的是while的循环,而不是for的循环,for的循环是要小于101才可以,所以无奈,这个程序的for只能省区了,真可惜啊,不过用法是知道了的啊
跳转语句
break语句
作用: 用于跳出选择结构或者循环结构
break使用的时机:
- 出现在switch条件语句中,作用是终止case并跳出switch
- 出现在循环语句中,作用是跳出当前的循环语句
- 出现在嵌套循环中,跳出最近的内层循环语句
这个呢,其实大家可以发现了,上面的else if中我就使用了break来跳出循环,所以就不再单独写了continue语句
在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
这个其实很好理解,我们写个例子,然后来解释一下那么我们看,这个程序运行的结果会是什么,其实我的理解刚开始都有点问题,我以为是会跳过一次b的输出,结果不是,而是整个b都不进行输出,因为什么呢,因为我们的continue已经在a执行完后跳过了剩下需要执行的语句,也就是我们的cout<<”b=”<<b<< endl;这个语句已经被跳过了,就不会再执行了,真要用的话,我感觉应该会在if里面用,至少我应该会这么干。1
2
3
4
5
6
7
8
9
10
11
using namespace std;
int main(){
for(int a = 10 ,b=5;a < 20 && b < 20;a++,b++){
cout<<"a="<< a << endl;
continue;
cout<<"b="<< b << endl;
}
system("pause");
return 0;
}goto语句
这个就很简单了,只需要了解,当然你会写也行,毕竟说这个东西不怎么用,而且程序里写多了还让人看不懂,读起来不方便,简单的说一下语法和意思,再写一下。
作用:可以无条件跳转语句
语法: goto 标记;
解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
好,那么如果看不懂可以直接写一个示例,再来解释就好说了!
先谈一个易错点!
1 |
|
那么我们的结果会是什么?我们的结果本来应该是一直输出我是第X行到第九行,但是有了goto后,执行完第三行,就直接到第八行了,但是这种会造成如果你的代码很多,就不方便查找,我目前不认为有什么用
数组
一维数组
一维数组定义方式
一维数组定义的三种方式:
数据类型 数组名[ 数组长度 ];
数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
数据类型 数组名[ ] = { 值1,值2 ...};
在这里呢,我喜欢第三种方式,所以我也没有去学习前面两个
注意点
1.数组名的命名规范与变量名命名规范一致,不要和变量重名
2.数组中下标是从0开始索引
那么,我们就来写一下和解释一下吧!1
2
3
4
5
6
7
8
9
10
11
12
13
using namespace std;
int main(){
int score[] = {1,2,3,4,5};
//手动输出
cout<<score[0]<< endl;
cout<<score[1]<< endl;
cout<<score[2]<< endl;
cout<<score[3]<< endl;
cout<<score[4]<< endl;
system("pause");
return 0;
}
1 |
|
好,写完之后我们来解释一下,第一个没有利用循环,所以直接引用数组然后输出,数组是从0开始的,所以5个数字从0开始,到4也就是5个,所以输出五个只需要从0到4就可以了,之后呢,我们就开始了第二个,开始利用循环输出,我们首先列出这个数组,然后利用for进行输出,因为我们列了10个数,又因为是从0开始,所以小于10,也就是最大是9,0-9呢刚好把这十个数组输出完就好了,所以循环中的cout里面的score后面跟的是[i],而不是数字。
所以啊,这又是一个易错点,使用第三个方式的时候要在后面加[],没写我又忘记了小提示
请允许我偷懒一下下,后面的就应该是不写注释和说明了,太累了,光一个那个,冒泡排序就整懵逼了一天,写了这么多,这一篇下来快接近10000字(1w字)了,实在是有些hold不住了,后面的就不解释了,可能有些是解释了的,但是后面大部分不会解释了QWQ
一维数组数组名
一维数组名称的用途:
- 可以统计整个数组在内存中的长度
- 可以获取数组在内存中的首地址
这一堆不想自己写了,就直接搬教程来吧,来解释一下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22int 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;
}解释
冒泡排序
这个是真的不好理解,对于我这种数学不好的,真的很难理解啊!我这个就不过多解释了,请AI吧,为了这个AI是问烂了,视频是反复看了,才差不多解决了,先请AI解释,再自己尝试解释一下吧。
冒泡排序代码
1 |
|
AI解释冒泡排序
其实AI的有些可以不用看,我看了都头大,而且我这写的其实也没错,但是他说我有错,我程序反正是没报错啥的,我的话就是,能跑没有违背我的逻辑就行当然可以!下面我将用完全零基础、没学过编程的小白也能轻松理解的方式,来一步一步解释你提供的这段代码到底在做什么,以及它背后的“冒泡排序”是怎么回事。
🌟一句话总结:
这段代码的作用是:
👉 把一组乱序的数字,从小到大重新排列(也就是“排序”),用的方法叫“冒泡排序”。
就像把一堆高矮不一的人按身高从矮到高排队一样!
🧩我们先来看这组数字
代码里有一行:
1 | int arr[] = {0,6,4,8,7,3,1,5,9,2}; |
这句话的意思就是:
我们有一排数字,放在一个叫 arr
的“小盒子队伍”里,顺序是:
0, 6, 4, 8, 7, 3, 1, 5, 9, 2
现在它们很乱,我们要让它们变成:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ✅
这就是排序的目标!
💡什么是“冒泡排序”?——生活化比喻
想象一下,你面前站了10个人,每个人手里拿着一个数字,但他们站得乱七八糟。
你要让他们按数字从小到大排队。怎么办?
冒泡排序的做法是这样的:
你从第一个人开始,每次比较相邻两个人的数字:
- 如果左边的人数字比右边的大 → 就让他们换位置
- 然后继续看下一组两个人
- 一直走到最后
这样一轮走完,会发生一件神奇的事:
🔥最大的那个数会像“泡泡”一样,慢慢“浮”到最后面!
所以这个方法叫做:“冒泡排序” —— 最大的数像气泡一样往上冒到底部(其实是最后)。
然后你再从头来一遍,这次不用管最后一个(因为它已经是最大、排好了),只排前面的。
再来一次……再来一次……直到所有人都排好队为止。
🧱代码拆解:每一部分都在干什么?
我们现在把代码一句一句地“翻译”成人话。
第一步:包含工具包 + 开始程序
1 |
|
✅ 这些是固定开头,你可以理解为:
“我要开始写一个小机器人程序了,它能打印东西、做计算。”
第二步:定义数组(那一排数字)
1 | int arr[] = {0,6,4,8,7,3,1,5,9,2}; |
🧠 意思是:
我准备了一个小队伍(叫 arr),里面放了10个整数(int 是整数的意思),分别是:0,6,4,…2
你可以把它想象成一排并列的格子,每个格子里有一个数字:
位置 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
数字 | 0 | 6 | 4 | 8 | 7 | 3 | 1 | 5 | 9 | 2 |
第三步:核心——双层循环实现“冒泡”
这部分是最难懂的,但我们慢慢来。
1 | for(int i = 0; i < 9 - 1; i++) { |
我们分层讲:
🔁 外层循环:要进行多少轮?
1 | for(int i = 0; i < 9 - 1; i++) |
等等,为什么是 9-1
?其实这里有点小错误或不严谨,应该是 <10-1
或者直接写 <9
。
但它的意思是:大概要做 8 轮左右的检查(实际应该做 9 轮才对,后面会说)。
💡 比喻:你要带这队人排好队,可能需要走很多趟,每趟都让他们两两比较交换。
🔁 内层循环:每一轮怎么比较?
1 | for(int j = 0; j < 10 - 1 - i; j++) |
意思是:
从第一个位置开始,一直到“还没排好的部分”的末尾,挨个比较两个相邻的人。
随着 i
变大(轮数增加),10 - 1 - i
会变小,说明我们越来越不需要检查已经排好的后面几个数字。
比如:
- 第1轮:要比较 0~8 位置(共9次)
- 第2轮:只需要比到第7个(因为最后一个已经最大了)
- ……
- 最后几轮:只剩前面几个没排好,很快就能搞定
这就像是:
随着时间推移,队伍后面的高个子已经归位了,你就不用再管他们了,只调整前面的小个子就行。
⚖️ 判断语句:谁大谁小?要不要换?
1 | if(arr[j] > arr[j+1]) |
意思是:
如果当前位置的数字比下一个位置的大 → 就要换位置!
例如:
当前位置是 6
,下一个是 4
→ 6 > 4 → 要换!
换成:
左边是
4
,右边是6
—— 更有序了!
🔄 交换两个数(三步走)
1 | int temp = arr[j]; // 先把左边的数记下来(临时存起来) |
这就像两个人换位置时:
A说:“我先去旁边站一会儿(temp)”,
B说:“那我站你位置”,
A再站到B原来的位置。
完成交换 ✅
🎬 举个简单例子:前几步发生了什么?
原始数组:[0,6,4,8,7,3,1,5,9,2]
第一轮开始:
- 比较 0 和 6 → 0<6,不换 →
[0,6,...]
- 比较 6 和 4 → 6>4 → 换!→
[0,4,6,8,7,3,1,5,9,2]
- 比较 6 和 8 → 不换
- 比较 8 和 7 → 换 →
[...,7,8,...]
- 继续下去……
这一轮结束后,最大的数 9
会被一步步往后推,最终到达倒数第二位?等等……
哎呀!问题来了!
❗注意:代码有个小bug!
原代码中:
1 | for(int i = 0; i < 9 - 1; i++) |
即 i < 8
,也就是说最多只循环 8次。
但我们有 10个数字,理论上最多需要 9轮 才能确保全部排好。
👉 所以正确的写法应该是:
1 | for(int i = 0; i < 10 - 1; i++) // 即 i < 9 |
否则,最后可能还有两个数没排好!
🔧 修改建议:
1 | // 应该改成: |
或者更通用一点:
1 | int n = sizeof(arr)/sizeof(arr[0]); // 得到数组长度 |
这样才能适应不同长度的数组。
✅ 排序完成后输出结果
1 | cout << "排序后" << endl; |
意思是:
打印一句话“排序后”,然后一个一个地把排好序的数字打印出来,每行一个。
最终你会看到:
1 | 排序后 |
🎉 成功啦!
🖼️ 总结图示:整个过程像波浪一样推进
每一趟冒泡,就像是一个“排序波”从前扫到后,把当前最大的数送到正确位置。
1 | 初始: [0,6,4,8,7,3,1,5,9,2] |
🧠 再深入一点点:算法效率怎么样?
虽然冒泡排序很容易理解,但它其实不太高效。
- 对于 10 个数字,最多要比较将近 100 次(具体是 ~n²/2)
- 如果有一万个数字,它要比较上亿次!太慢了!
所以在真实项目中,程序员一般不会用冒泡排序,而是用更快的方法(如快速排序、归并排序等)。
但!它是学习排序思想的最佳起点,因为它逻辑清晰、容易理解。
✅ 最终结论:给小白的一句话口诀
“两两相比,大的往后挪;一遍一遍走,直到全排妥。”
这就是冒泡排序!
📝附:修正后的完整代码(推荐版本)
1 |
|
如果你想让我用动画、流程图、表格对比等方式进一步展示这个过程,也可以告诉我哦 😊
以上内容均由AI搜集总结并生成,仅供参考
自我解释代码
我都不确定自己能不能解释清楚,还是大概说一下吧
首先是定义了一个数组,然后数组里放了这一堆数字,然后使用for循环来创建一个emmm外层循环和内层循环
二维数组
二维数组就是在一维数组上,多加一个维度。
二维数组定义方式
二维数组定义的四种方式:
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
比较喜欢第二种,方便读取和操作二维数组数组名
- 查看二维数组所占内存空间
- 获取二维数组首地址
都是一样的示例,跟一维数组差不多,都是使用sizeof,元素地址要用&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
28int 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个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
语法:
1 | 返回值类型 函数名 (参数列表) |
- 返回值类型 :一个函数可以返回一个值。在函数定义中
- 函数名:给函数起个名称
- 参数列表:使用该函数时,传入的数据
- 函数体语句:花括号内的代码,函数内需要执行的语句
- return表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据
示例:**定义一个加法函数,实现两个数相加
1 | //函数定义 |
函数的调用
功能:使用定义好的函数
语法:函数名(参数)
示例:
1 | //函数定义 |
总结:函数定义里小括号内称为形参,函数调用时传入的参数称为实参
值传递
- 所谓值传递,就是函数调用时实参将数值传入给形参
- 值传递时,==如果形参发生,并不会影响实参==
示例:
1 | void swap(int num1, int num2) |
总结: 值传递时,形参是修饰不了实参的
函数的常见样式
常见的函数样式有4种
- 无参无返
- 有参无返
- 无参有返
- 有参有返
示例:
1 | //函数常见样式 |
函数的声明
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
- 函数的声明可以多次,但是函数的定义只能有一次
示例:
1 | //声明可以多次,定义只能一次 |
函数的分文件编写
作用:让代码结构更加清晰
函数分文件编写一般有4个步骤
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
示例:
1 | //swap.h文件 |
1 | //swap.cpp文件 |
1 | //main函数文件 |
案例
选择结构案例—-三只小猪称体重
1 |
|
选择结构案例—-三目运算符
1 | //三目运算符 语法:表达式?表达式2:表达式3由?和:构成 |
循环结构案例—-猜数字
1 | //猜数字游戏 |
循环结构案例—-水仙花数
1 | //水仙花数 |
循环结构案例—-敲桌子
1 | //案例-敲桌子 |
嵌套循环案例—-九九“惩罚”表
为什么说是惩罚表?一会代码完了会解释的
1 | //嵌套循环 |
一维数组案例—-五只小猪称体重
1 | //一堆数组五只小猪称体重 |
一维数组案例—-元素逆置
1 |
|
二维数组案例—-考试成绩统计
1 |
|
Over
那么C++的学习的记录是目前告一段落了,但是大概可能会一个月以后再次更新一次也说不定哈!