人们通常借助计算机完成统计每月的支出、日降雨量、季度销售额等任务。企业借助计算机管理薪资,库存和客户交易记录等。作为程序员,不可避免地要处理大量相关数据。 通常,数组能高效便捷地处理这种数据。本篇简单地介绍了数组,将进一步地学习如何使用数组。 着重分析如何编写处理数组的函数。这种函数把模块化编程的优势应用到数组。通过本篇的学习。你将明白数组和指针关系密切。
数组
前面介绍过,数组由数据类型相同的一系列元素组成。需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型。编译器根据这些信息正确地创建数组。普通变量可以使用的类型,数组元素都可以用。考虑下面的数组声明:
/*一些数组声明*/
int main()
{
float candy[365]; /*内含365个float类型元素的数组/
char code[12]; /*内含12个char类型元素的数组*/
int states[50]; /*内含50个int类型元素的数组*/
)
方括号( [ ] )表面都candy,code 和states是数组,方括号中的数字表面数组中的元素个数。
要访问数组中的元素,通过使用数组下标数(也成为索引)表示数组中的个元素,数组的元素编号是从0开始的,所以condy[0]表示candy数组的第一个元素,candy[364]表示第365个元素,也就是最后一个元素。
初始化数组
数组通常被用来储存程序需要的数据。例如,一个内含12个整数元素的数组可以能存12个月的天数。在这种情况下,在程序一开始就初始化数组比较好,下面介绍初始化数组的方法。
只储存单个值的变量有时也称为标量定量*(scalar variable)*,我们已经很熟悉如何初始化这种变量
int fix = 1;
float flax = PI * 2;
代码中的PI已定义为宏。C使用新的语法来初始化数组,如下所示:
int main ()
{
int powers[10] = {
1,2,4,6,9,16,32,64,128,256}; //从ANSI C开始支持这种相始化.
……
}
如上所示,用以逗号分隔的值列表(用花括号括起来)来初始化数组,各值之间用逗号分隔。在逗号和值之间可以使用空格。根据上面的初始化,把1赋给数组的首元素(powers[0]),以此类推不支持ANSI的编译器会把这种形式的初始化识别为语法错误,在数组声明前加上关键字static可解决此问题。
使用数组前必须先初始化它。与普通变量类似,在使用数组元素之前,必须先给它们赋初值。编译器使用的值是内存相应位置上的现有值。
初始化列表中的项数应与数组的大小致。如果不一致会怎样? 我们还是以一个程序为例,但初始化列表中缺少两个元素,如以下程序所示:
int main()
{
int arr[5] = {
1,2,3};
for(int i=0;i<5;i++)
printf("arr[%d] 的值为 %d \n",i,arr[i]);
return 0;
}
输出如下:
如上所示,编译器做得很好。当初始化列表中的值少于数组元素个数时,编译器会把剩余的元素初始化为0,也就是说,如果不初始化数组,数组元素和未初始化的普通变量一样, 其中储存的都是随机值,但是,如果部分初始化数组,剩余的元素就会被初始化为0。如果初始化列表的项数多于数组元素个数,编译器可没那么仁慈,它会毫不留情地将其视为错识。但是,也没有必要因此嘲笑编译器。其实, 可以省略方括号中的数字,让编译器自动匹配数组大小和初始化列表种的项数。
int main()
{
const int days[] = {
31, 28,31,30,31, 30,31, 31, 30, 31 };
int index;
for (index = 0; index < sizeof(days)/ sizeof (days[0]); index++)
printf("Month :%d has %d days. \n", index + 1, days[index]);
return 0;
}
以上程序注意两点:
- 如果初始化数组时省略方括号中的数字,编译器会根据初始化列表中的项数来确定数组的大小。
- 注意for循环中的测试条件。由于人工计算容易出错,所以让计算机来计算数组的大小。sizeof运算符给出它的运算对象的大小(以字节为单位)。所以sizeof(days) 是整个数组的大小(以字节为单位),sizeof(day[0])是数组中一个元素的大小(以字节为单位)。整个数组的大小除以单个元素的大小就是数组元素的个数。
我们的本意是防止初始化值的个数超过数组的大小,让程序找出数组大小。我们初始化时间了10个值,结果就只打印了10 个值!这就是自动计数的弊端:无法察觉初始化列表中的项数有误。还有种初始化数组的方法, 但这种方法仅限于初始化字符数组。 我们在字符串处以介绍。
指定初始化器(C99)
C99增加了一个新特性:指定初始化器*(designated initializer)*。 利用该特性可以初始化指定的数组元素。例如,只初始化数组中的最后一个元素。对于传统的C初始化语法,必须初始化最后一个元素之前的所有元素,才能初始化它,
int arr[6] = {
0,0,