C

C 知识量:16 - 74 - 317

10.1 数组><

初始化数组- 10.1.1 -

数组由数据类型相同的一系列元素组成。需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型。普通变量可以使用的类型,数组元素都可以使用。例如:

int main(void) {
    int number[365];
    float f[16];
    char c[255];
}

方括号“[]”表明number、f和c都是数组,方括号中的数字表明数组中元素的个数。

如果要访问数组中的元素,应当使用数组下标数(索引)表示数组中的各元素,数组元素编号从0开始,因此,number[0]表示数组中第1个元素,number[364]表示第365个元素。

在使用数组前,最好对数组进行初始化。C中使用以下语法来初始化数组:

int main(void) {
    int number[5] = {1, 2, 3, 4, 5};
}

以上代码中,用以逗号分隔的值列表来初始化数组,值列表需要用花括号括起来,在逗号和值之间可以使用空格。注意:不支持ANSI的编译器不支持以上形式的语法,在数组声明前加上关键字static可以解决这个问题。

有时需要将数组设置为只读,此时,应当使用const声明和初始化数组。注意:应当总是使用声明来初始化const数据,因为一旦声明为const,便不能再给它赋值。以上数组可以修改为:

int main(void) {
    const int number[5] = {1, 2, 3, 4, 5};
}

如果不初始化数组,数组元素和未初始化的普通变量一样,其中存储的值都是垃圾值。但是,如果部分初始化数组,即初始化列表的项数小于数组元素个数,剩余的元素就会被初始化为0。例如:

#include <stdio.h>

int main(void) {
    int number[8] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 8; i++)
        printf("%d %d\n", i, number[i]);
    system("pause");
    return 0;

运行结果为:

0 1
1 2
2 3
3 4
4 5
5 0
6 0
7 0

如果初始化列表的项数多于数组元素个数,编译器就会报错。其实,可以在数组初始化时省略方括号中的数字,由编译器自动匹配数组大小和初始化列表中的项数。例如:

int main(void) {
    int number[] = {1, 2, 3, 4, 5};
}

指定初始化器- 10.1.2 -

C99增加了一个新特性,即指定初始化器,可以用来初始化指定的数组元素。例如:如果只想初始化数组的最后一个元素,在此之前需要使用以下语法:

int number[5] = {0, 0, 0, 0, 99};

如果使用C99标准的指定初始化器,则可以使用以下方法:

int number[5] = {[4] = 99};

对于一般的初始化,在初始化一个元素后,未初始化的其他元素都会被设置为0。一个更加复杂的使用指定初始化器的示例:

#include <stdio.h>

int main(void) {
    int number[8] = {56, [4] = 99, 55, [0] = 88};
    for (int i = 0; i < 8; i++)
        printf("%d %d\n", i, number[i]);
    system("pause");
    return 0;
}

运行结果为:

0 88
1 0
2 0
3 0
4 99
5 55
6 0
7 0

通过以上代码可以看出:

  • 如果在指定初始化器后有更多的值,那么后面的值会用于初始化指定元素后面的元素,比如示例中的值“55”被赋值给了number[5]。

  • 如果再次初始化指定的元素,那么最后的初始化会取代之前的初始化。比如number[0]的值由56修改为88。

给数组元素赋值- 10.1.3 -

声明数组后,可以借助数组下标给数组元素赋值。C不允许把数组作为一个单位赋给另一个数组,除初始化以外,也不允许使用花括号列表的形式赋值。示例:

#define SIZE 5

int main(void) {
    int x[SIZE] = {1, 2, 3, 4, 5}; //初始化没问题
    int y[SIZE];
    y = x; //不允许把数组作为一个单位赋给另一个数组
    y[SIZE] = x[SIZE]; //数组下标越界
    y[SIZE] = {6, 7, 8, 9, 10}; //不是初始化,不起作用
}

其中,y[SIZE] = x[SIZE]实际就是y[5]=x[5],数组x和y的最后一个元素下标应是4,因此,都越界了。

数组边界- 10.1.4 -

在使用数组时,要防止数组下标超出边界。必须确保下标是有效的值,因为编译器不会检查这种错误。C语言按照信任程序员的原则不检查数组下标是否正确,这样可使程序运行的更快,同时,在程序运行前,数组下标也可能尚未确定。一定注意:数组元素下标编号从0开始。

指定数组大小- 10.1.5 -

在C99标准之前,声明数组时只能在方括号中使用整型常量表达式。所谓整型常量表达式,是由整型常量构成的表达式。示例:创建数组。

int main(void) {
    int x = 5;
    int y = 6;
    float a1[5]; //可以
    float a2[5 * 2 + 8]; //可以
    float a3[sizeof (int) + 2]; //可以,sizeof表达式被视为整型常量
    float a4[-4]; //不可以,表达式的值必须大于0
    float a5[0]; //不可以,表达式的值必须大于0
    float a6[1.4]; //不可以,不是整型常量
    float a7[(int) 3.5]; //可以,已被强制转换为整型常量
    float a8[x]; //C99之前不可以
    float a9[y]; //C99之前不可以
}

C99标准允许最后两项数组声明方式,这种数组称为变长数组,简称VLA。变长数组有一些限制,例如,声明时不能进行初始化。