C语言数组基础知识讲解

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数组基础知识讲解

1. 数组简介

数组(Array)由一系列同种数据类型的元素组成。编译器可以从数组声明中知道数组中元素的数目,以及这些元素的数据类型。例如:

double dbl[20]; /* 包含20 个double 类型元素的数组*/

int c[12]; /* 包含12 个int型元素的数组*/

char ch[40]; /* 包含40 个char 型元素的数组*/

方括号[] 表明它们是数组,[] 里的数字表明数组包含的元素数目。

数组中的元素是相邻的,初始化之前,元素的值可能是随机的。下图形象地表现了这种相邻关系。

使用数组名和下标(subscript number 或index)就可以访问特定的元素。下标始于0,止于n - 1。例如:c[0] 是数组c 的第一个元素,而c[11] 是它的最后一个元素,也就是第12 个元素。

2. 初始化

int c[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

如上所示,我们使用大括号中一系列逗号分隔的值来初始化数组。我们把这个称之为初始化列表。大括号是必须的!逗号和值之间的空格可有可无。初始化后,数组c 的第一个元素c[0] 的值为0,以此类推。

下面的小程序输出数组iarr中所有元素的值。

#include

int main(void)

{

intiarr[4] = { 0, 1, 2, 3 };

int i = 2;

printf("%d ", iarr[0]); /* 输出0 */

printf("%d ", iarr[1]); /* 输出1 */

printf("%d ", iarr[i]); /* 输出2 */

printf("%d ", iarr[1+2]); /* 输出3 */

return 0;

}

如上所示,访问数组元素时,[] 里的可以是常量,可以是变量,也可以是表达式。[] 里还可以是返回值为整型的函数调用。总之,只要[] 里的值是整数类型都可以。

注意,上面的程序,如果把intiarr[4] = { 0, 1, 2, 3 }; 改成intiarr[4];(即没有初始化),则它里面的元素的值是随机的,也就是本来就存在于那段内存空间的值。如果改成intiarr[4]; 后再把它放在int main(void) 之前,则它里面的元素的值都是0。具体原因我在后续的教程会说明。

如果初始化列表中的值的个数少于数组元素个数,则余下的元素都会被初始化为0。例如:intiarr[4] = { 0, 1 };

iarr[0] 和iarr[1] 分别为0 和1;iarr[2] 和iarr[3] 都被初始化为0。注意,初始化列表中的值的个数可以少于数组元素个数,但是超过数组元素个数却是不对的!

初始化数组时,[] 里可以留空。例如:

intiarr[] = { 1, 2, 3 };

编译器会算出初始化列表中的值的个数,然后构造包含那么多个元素的数组。如上例,编译器会算出列表中一共有3 个值,然后把iarr构造成包含3 个元素的数组。例如:

#include

int main(void)

{

intiarr[] = { 1, 2, 3 };

printf("%d ", iarr[0]); /* 输出1 */

printf("%d ", iarr[1]); /* 输出2 */

printf("%d ", iarr[2]); /* 输出3 */

return 0;

}

我们可以用以下表达式算出iarr中元素的个数:

sizeofiarr / sizeofiarr[0]

其中,sizeofiarr算出数组iarr占用的内存大小,sizeofiarr[0] 算出iarr[0] 占用的内存大小(也就是数组iarr中每个元素占用的内存大小),它们相除就得出iarr的元素个数。sizeof是一个运算符,具体用法我以后会说。

3. 指派初始值(Designated Initializers)

指派初始值这个特性是C99 增加的,它允许我们直接初始化数组中特定的元素。C99 以前,如果我们要初始化数组中的某个元素,如第三个元素,必须同时初始化它之前的元素。例如:intiarr[10] = { 0, 0, 300 };

而C99 中,我们可以这样初始化特定的元素:

intiarr[10] = { [2] = 300 }; /* 指派初始化iarr[2] 为300 */

其余的元素都会被初始化为0 。下面我们来看一个小程序。

#include

int main(void)

{

intiarr[5] = { 6, 3, [3] = 1, 5, [1] = 8};

printf("%d ", iarr[0]);

printf("%d ", iarr[1]);

printf("%d ", iarr[2]);

printf("%d ", iarr[3]);

printf("%d ", iarr[4]);

return 0;

}

输出为:

6

8

1

5

从中可以看出两点:

A. 如果指派初始值后面还有值,则后面的值会被用于初始化后续的元素。上例中,

iarr[3] 被初始化为1 ,它后续的元素iarr[4] 被初始化为5。

B. 如果初始化列表中多次出现对某元素的初始化,则以最后一次为准。上例中,

iarr[1] 先被初始化为3,然后被[1] = 8 指派初始化为8。

4. 给数组元素赋值

我们可以利用下标给特定的元素赋值。例如:

intiarr[5];

iarr[0] = 100; /* 赋值给第一个元素*/

iarr[4] = 120; /* 赋值给第五个元素*/

iarr[2] = 180; /* 赋值给第三个元素*/

C 不允许直接使用数组对别的数组进行赋值,也不允许使用初始化列表对数组进行赋值。例如:

int iarr_1[5] = { 1, 2, 3, 4, 5 }; /* 正确*/

int iarr_2[5];

iarr_2 = iarr_1; /* 错误!*/

iarr_2[5] = { 3, 4, 5, 6, 7 }; /* 错误!*/

iarr_2[5] = iarr_1[5]; /* 越界!*/

最后一个语句发生了越界!因为这两个数组都只有5 个元素,而使用下标5 访问的是第六个元素!

5. 数组界限(array bounds)

使用下标时,我们必须确保下标没有越界。例如:

intiarr[46];

这个数组的下标范围是0 到45,确保下标没有超出这个范围是我们的责任,因为编译器不会对下标越界进行检测!

C 标准没有定义下标越界的后果,也就是说,当我们写的程序中出现下标越界的问题,程序可能正常工作,也可能异常退出,还有可能出现其它奇怪的情况。

#include

int main(void)

{

int var_1 = 20;

intarr[5];

int var_2 = 40;

printf("var_1: %d, var_2: %d ", var_1, var_2);

arr[-1] = -1;

arr[5] = 5;

printf("%d %d ", arr[-1], arr[5]);

printf("var_1: %d, var_2: %d ", var_1, var_2);

return 0;

}

上述程序使用Dev-C++ 4.9.9.2 编译运行的输出为:

相关文档
最新文档