C++ 入门学习经验 08——数组中:为什么数组长度是 5,却不能访问 a[5]?
大家好啊!这里是 阳阳的博客 ,一个正在努力学习技术的大学生。
上一篇我们正式开始了数组这个知识点,聊了数组是什么、为什么需要数组,以及数组适合解决什么问题。
如果说上一篇是认识数组,那今天这篇,我们就先讲讲这个数组的一些基础知识。
因为很多同学刚开始学数组的时候,真正把自己绕晕的地方,往往不是定义数组,也不是赋值,而是下面这些问题:
数组为什么从 0 开始?
数组长度明明是 5,为什么
a[5]还会出问题?下标到底表示第几个元素?
为什么有时候程序没报错,但输出结果却奇奇怪怪?
所以今天这篇,我们就专门聊聊数组里最容易踩坑的地方。
好了,废话不多说,咱们直接开始。
一、数组长度是 5,到底是什么意思?
先来看最简单的数组:
int a[5];
这句话表示:
数组 a 有 5 个位置。
我们把它画出来:
下标:
0 1 2 3 4
内容:
? ? ? ? ?
这里一定要注意。
数组长度是 5。
表示:
一共有 5 个元素
分别是:
a[0]
a[1]
a[2]
a[3]
a[4]
到这里刚好已经是 5 个位置了。
所以:
a[5]
其实是:
第 6 个位置
这个位置根本不存在。
所以访问它,就是越界。
二、为什么很多同学总喜欢从 1 开始?
因为生活习惯。
比如:
第一名第二名第三名第四名第五名
我们几乎不会说 第零名。
所以很多同学看到:
int a[5];
脑子里会自动变成:
a[1]
a[2]
a[3]
a[4]
a[5]
感觉特别自然。
我刚开始也是这么想的。
结果一写程序,就开始出问题。
后来我发现一个比较容易接受的方法。
不要把下标理解成第几个。
而是理解成:距离起点偏移了多少格。因为我们可以理解成:0 代表没有移动。
比如:
下标:
0 1 2 3 4
元素:
10 20 30 40 50
a[0]
表示:
从起点移动 0 格。
所以拿到第一个元素。
a[1]
表示:
从起点移动 1 格。
所以拿到第二个元素。
三、数组越界为什么危险?
很多同学第一次写数组,都会这样:
#include <iostream>
using namespace std;
int main()
{
int a[5] = {1,2,3,4,5};
cout << a[5];
return 0;
}
然后发现:
程序居然运行了。
甚至还能输出一个数字。 这里恰恰是数组最危险的地方。
因为:
a[5]
访问的是数组外面的内存。
而这块内存里,可能刚好有一些数据。
所以程序有时候:
会输出奇怪数字
会崩溃
会运行正常
会偶尔出错
四、最容易写错的,其实是循环
来看一个特别经典的错误。
int a[5];
for(int i=0;i<=5;i++)
{
cin >> a[i];
}
大家先暂停思考一下。
这段代码有没有问题?
但实际上:
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
循环执行了 6 次。
最后一次:
a[5]
直接越界。
正确写法应该是:
for(int i=0;i<5;i++)
{
cin >> a[i];
}
注意这里:
i < 5
不要写:
i <= 5
这个地方我觉得真的特别容易出现问题。尤其是考试紧张的时候。有时候代码看起来完全一样。
结果就是那个等号,让程序悄悄跑偏了。
五、怎么快速判断会不会越界?
这里我分享一个我自己常用的方法。
就是:先写出数组长度,再写出合法下标。
比如:
int a[5];
先别急着写代码。
脑子里先想:
长度:
5
合法下标:
0 1 2 3 4
那循环范围自然就是:
for(int i=0;i<5;i++)
因为:
i :
0 1 2 3 4
正好对应数组下标。
再比如:
int score[10];
先想:
长度:
10
合法下标:
0 1 2 3 4 5 6 7 8 9
循环就写:
for(int i=0;i<10;i++)
永远不要凭感觉。
很多数组错误,其实不是不会写。
而是脑子里默认:
1 ~ 10
结果代码里却是:
0 ~ 9
少看一个数字,或者多写一个数字,程序就开始出问题。
六、刚开始学数组,不要急着记复杂规则
说实话,我刚开始学数组的时候,也查过很多资料。
有人讲内存连续。
有人讲地址偏移。
有人讲:
a[i]
等价于
*(a+i)
当时看得我头皮发麻。
感觉:
一个数组而已,怎么后面还连着这么多东西?
后来我发现。
对于刚开始学 C++ 的同学来说。
先记住下面三句话,其实就够用了。
第一句话
数组长度是:
n
合法下标:
0 ~ n-1
第二句话
数组下标:
表示移动多少格。
a[0]
表示:
移动 0 格。
a[3]
表示:
移动 3 格。
所以它对应第四个元素。
第三句话
循环写数组时:
优先写:
for(int i=0;i<n;i++)
看到:
<=
最好停下来检查一下。
问问自己:
会不会多循环一次?
七、总结
数组本身就比普通变量复杂一点。
因为它开始让我们同时关注:
数据有几个
下标是多少
循环范围是什么
哪个位置正在被访问
这些东西刚开始混在一起,确实容易乱。
我觉得这里最重要的一件事就是:
刚开始学习的时候多画图。
比如:
int a[5]={1,2,3,4,5};
画出来:
下标:
0 1 2 3 4
元素:
1 2 3 4 5
然后再去看:
a[2]
或者:
for(int i=0;i<5;i++)
一下子就清楚很多。
刚开始学的时候,慢一点没关系。
别觉得画图浪费时间。
很多题目,画出来之后,思路会顺畅很多。
八、写在最后
总之,数组真正难住很多同学的地方,并不是定义数组,而是下标和越界。
因为我们的生活习惯总喜欢从 1 开始数。但 C++ 数组偏偏从 0 开始。刚接触的时候,看着确实有点别扭。不过不用一开始就把所有东西都理解得特别透。
先记住:
长度是 n,下标范围就是 0 到 n-1。
写循环优先用
i < n。出现越界问题时,先检查循环条件。
慢慢写几道题之后,你会发现数组其实没有想象中那么难。
那这篇就先到这里。
如果这篇文章对你有帮助,麻烦点赞、关注和收藏吧,谢谢! 😄
有什么问题或者想法,欢迎在评论区留言,我们一起交流!
我们下篇见~
更多推荐
所有评论(0)