6.1.1 一维数组的一般形式
首先看看一维数组定义的一般形式:
例如:
上面这行代码的含义:定义了一个数组,名字为a,这个数组有10个元素。有几点要说明:
(1)数组名就是变量名,如上面的a。
(2)数组名后面是中括号(方括号)括起来的常量表达式,如上面的[10],注意不能写成圆括号,如“int(10);”,另外常量表达式一般都是一个数字,虽然非要写成诸如2*5也可以,但直接写10更直观。
图6.1 inta[10]数组包含的元素示意图,注意下标范围0~9,绝不包含10
(3)所谓一维数组,也就是带一对中括号[],以后还会学带两对中括号[][]的数组,这叫二维数组,后面会讲到。
(4)a[10]中的数字10表示a数组中有10个元素,下标从0开始,这10个元素是a[0],a[1],a[2],…,a[9],千万注意,不包括a[10],下标范围是0~9,这是一个极其容易犯错误的地方。为什么说极其容易犯错误,那是因为针对“inta[10];”这个数组定义,虽然能够合法引用的元素是a[0]~a[9],但当非法引用a[10](如给a[10]赋值)时,系统并不提示任何错误,但是这样引用会产生极大的程序隐患,因为a[10]所属的这块内存并不属于开发者,所以不能使用,如果往这个内存地址写了数据(给a[10]赋值),结果很有可能导致把程序中其他某个用到该内存地址的变量的值给覆盖掉了,轻则导致程序运行的并不是想要的结果,重则导致程序不定时的彻底报错崩溃,极难排查原因,如图6.1所示。
看看如下范例,可以设置一个断点并把鼠标放到a[10]上观察:
这里设置断点并且程序运行到断点处停止下来时的截图如图6.2所示。
图6.2 程序停止到断点处时观察给超出下标范围的非法数组元素赋值的结果
从图6.2中不难看出,系统所认可的a数组的元素下标为0~9(因为展开该数组后只看到了0~9这10个元素),也就是a[0]~a[9],但上面代码是给a[10]赋值(a[10]=8;),显然10这个下标超出了0~9这个范围,是非法的,但系统对于这种非法行为并不提示错误(依旧让程序能够编译和执行起来),这会造成巨大的程序运行安全隐患(程序可能会立即崩溃、不定时崩溃、出现无法预期的结果等诡异情形)。
(5)如果定义一个含有100个元素的a数组(inta[100];),那么这100个元素的合法引用范围应该是a[0]~a[99],同样不包括a[100]。
(6)定义数组时提到的常量表达式,可以是一个数字如10,也可以是常量表达式如2+8,但不能包含变量。也就是说,C语言不允许对数组的大小做动态定义,数组大小不能依赖于程序运行过程中变量的值。换一种理解方式:数组定义的时候,数组大小就已经固定了。看看如下范例:
(7)“int a[10];”相当于定义了10个整型变量a[0]~a[9],那如果想一次定义1000个变量,也非常简单——“inta[1000];”即可,还是要特别注意,定义后能引用的数组元素是a[0]~a[999]。这样,就不需要像前面那样使用不同的变量名(如inta,b,c,d,e,f,g,…;)来定义多个变量了。