概述
上文介绍的都是基本数据类型(整形、浮点型、字符型等),现在开始接触另外3种复合数据结构:数组、结构体、共用体。
数组(array)是若干同类变量的聚合,允许通过统一的名字引用其中的变量。数组的特定元素通过下标(index)访问。在C语言里,数组都由连续内存区构成,最低地址对应首元素,最高地址对应末元素。数组可以是一维的,也可以是多维的。C语言中,最常用的数组是串(string),就是以空字符结尾的一维数组。数组和指针的关系特别紧密,讨论其中一个常常涉及其中另一个。
数组和变量一样,也是先定义,后使用。数组定义的形式是类型名、标识符、维数。比如:int a[10],这就定义了一个含有10个整型元素的数组。
可以在定义数组的同时进行初始化,这时就无需指定元素个数。如:
int a[]={0,1,2,3,4,5,6,7,8,9};
无尺寸数组初始化
假设我们希望通过数组初始化创建错误信息表,如下所示:
char e1[12]="Read errorn";
char e1[13]="Write errorn";
char e1[18]="Cannot open filen";
显然,当使用手工计算字符个数来决定正确的数组的大小时,工作冗长且容易出错。使用无尺寸数组(unsized array)时,C自动计算数组的大小。在初始化语句中遇到无尺寸数组后,C编译程序自动生成恰好存放常量串的数组。由此,以上初始化代码变为:
char e1[ ] = "Read errorn";
char e2[ ] = "Write errorn";
char e3[ ] = "Cannot open filen";
除使程序变得简洁外,无尺寸数组初始化还能确保改变常量串时数组尺寸的恒正确。
无尺寸数组初始化也适用于多维数组。此时,除第一维可以不定义尺寸外,其他维的大小必须准确说明。这样,程序员可以建立变长表,由编译程序自动分配足够内存。例如,初始化无尺寸数组sqrt的数组声明如下所示:
int sqrs[][2] = {
{1,1};
{2,4};
{3,9};
{4,16};
{5,25};
{6,36};
{7,49};
{8,64};
};
相对于定尺寸数组声明,无尺寸数组的优点是,可以随意加长或缩短表的长度,而不必改变数组的尺寸。
C语言规定,只能引用数组的一个元素,而不能一次引用整个数组。数组引用的方式:标识符[下标]
保存数组所需内存量直接与基类型和数组大小有关。对一维数组而言,以字节为单位的总内存量可由下式计算得到:
总字节数 = sizeof(基类型)× 数组长度
C语言不检查数组边界,程序可以在数组两边越界,写入其他变量,甚至写入程序代码段。作为程序员,必要时应自己加入边界检查。本质上,一维数组就是在连续内存中按下标顺序存储的同类信息组成的表。下图是数组a开始于内存位置1000的内存映像。a的声明是:
char a[7]
字符数组:顾名思义,就是存放字符的数组。
char str[20]={'h','e','l','l','o','w','o','r','l','d'};
for(i=0;i<20;i++)
printf("%c",str[i]); //遍历输出字符数组的值
C语言中,字符串也是用字符数组来存储的。需要注意的是字符数组和字符串的长度,用‘ ’代表一个字符串的结束,所以系统会自动为字符串增加一个‘ ’作为结束符。
//以下两种方式是等价的
char str[9] = "I like C";
char str[9] = {'I',' ','l','i','k','e',' ','C','