C 语言中的数组

数组是编程语言中用来存储元素的集合。在 C 语言中,集合是储存相同类型元素的集合。并且可以通过一个名称来来访。

--------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | …… | N-1 |
--------------------------------------------
第一个元素                              最后一个元素

在数组中,数组的访问是用索引位置 0 开始的,最后一个元素的位置的索引是 N-1。所以你存入的第一个元素的位置编号是 0 ,而不是 1 。请大家注意这点。

1. 数组的声明

数组的声明与变量的声明十分类似,只不过需要在变量名的后面添加一对方括号。如同下面,我们声明了一个可以包含 10 个整数的数组一样。

int intArray[10];

在这种形式下,你必须指明指明数组的大小,也就是方括号中的数值。

或者你在初始化的时候使用大括号直接赋值,这样就不用直接指明数组的大小。

int intArray[]={1,2,3,4,5};

虽然没有指明数组的大小,但是其大小就是初始化的元素的数量。 C 语言中的数组一旦声明,其大小是不可以变化的。

上面的方式可能是在之前教课书中看到的。

在 C99 标准中,引入了一种新的方式来声明数组。就是使用变量。之前你可以使用常量来声明。但是不可以使用变量。这次。规则发生了变化。你可以用变量来声明。

int a=10, intArray[a];

2. 数组的初始化

数组的初始化其实就是将声明和赋值合在一起。

上面一节,我们用了直接初始化赋值来声明数组变量,也就是

int intArray[]={1,2,3,4,5};

还有别的初始化方式。如下面的例子所示:

int intArray[10]={1,2,3,4,5};

你可以给数组的容积为 10 个整数,但是只给前 5 个位置赋值。

这里根据 C99 的标准,还引入了更加高级的赋值方式。

int intArray[20]={1,2,3,4,5,[8]=8,9,10,11,[19]=19};

我们在这里声明了一个整数数组,可以容纳 20 个整数。前面 5 个位置,依次赋值 1、2、3、4、、5,这个时候我们跳过中间的 6 和 7 的位置,直接给第 8 个位置赋值为 8 ,然后后面的第 9 至 11 的位置依次赋值 9、10、11,最后再对第 19 个位置赋值为 19 。

数组与变量一样,必须经过初始化或者赋值才能使用。否则数组中的元素将是随意存放的。

3. 数组的使用

数组的使用和变量的使用基本一致,只不过你面对的是一个集合,而不是一个单一的元素。因此,你要访问其中的元素的话,就要使用变量名加索引位置的方式,也就是 intArray[4] = 9 这样的方式进行。

4. 示例

#include <stdio.h>

int main()
{
     int a = 10;
     int b[10];
     int c[] = {1, 2, 3, 4, 5};
     int d[10] = {1, 2, 3, 4, 5};
     int e[20] = {1, 2, 3, 4, 5, [8] = 8, 9, 10, 11, [19] = 19};
     int f[a];

     for (int i = 0; i < 10; i++)
     {
          printf("b[%d] = %dn", i, b[i]);
     }

     for (int i = 0; i < 5; i++)
     {
          printf("c[%d] = %dn", i, c[i]);
     }

     for (int i = 0; i < 10; i++)
     {
          printf("d[%d] = %dn", i, d[i]);
     }

     for (int i = 0; i < 20; i++)
     {
          printf("e[%d] = %dn", i, e[i]);
     }

     for (int i = 0; i < 10; i++)
     {
          printf("f[%d] = %dn", i, f[i]);
     }

     return 0;
}

运行结果

b[0] = -692187488
b[1] = 32767
b[2] = -692187472
b[3] = 32767
b[4] = -1365075304
b[5] = 32673
b[6] = 0
b[7] = 0
b[8] = 0
b[9] = 0
c[0] = 1
c[1] = 2
c[2] = 3
c[3] = 4
c[4] = 5
d[0] = 1
d[1] = 2
d[2] = 3
d[3] = 4
d[4] = 5
d[5] = 0
d[6] = 0
d[7] = 0
d[8] = 0
d[9] = 0
e[0] = 1
e[1] = 2
e[2] = 3
e[3] = 4
e[4] = 5
e[5] = 0
e[6] = 0
e[7] = 0
e[8] = 8
e[9] = 9
e[10] = 10
e[11] = 11
e[12] = 0
e[13] = 0
e[14] = 0
e[15] = 0
e[16] = 0
e[17] = 0
e[18] = 0
e[19] = 19
f[0] = 0
f[1] = 0
f[2] = 1700966438
f[3] = 0
f[4] = -1365075304
f[5] = 32673
f[6] = -692187320
f[7] = 32767
f[8] = -692187264
f[9] = 32767

在上面的例子中,展示了数组的声明,初始化和使用。通过循环语句逐个访问数组中的元素,并将这个元素的值打印在屏幕上。

这里面还展示了如果不进行初始化会发生什么,也就是数组中存储的数据是不确定的。因此只有初始化的数组还有使用的价值。这个和很多编程语言是不同的。当然,我们也可以在声明完数组后直接使用,但是只能访问自己赋值过的部分,因为没有赋值过的部分值仍然是不确定的。

5. 小结

数组是程序中用来存储相同类型元素的集合体。在 C 语言中数组只能用来存储相同类型的元素。数组的索引是从 0 开始的,而不是我们数学中常用的 1 ,这点是当年编程语言高度耦合硬件的残留习惯。所以你要访问的最后一个元素的索引是 N-1 ,其中 N 是你定义的数组的大小。访问数组外的元素,也就是访问的索引溢出是一个经常发生的错误。很多黑客也会利用这点来访问内存中的未知位置。