第 5章 数组
5.1 数组概述
5.2 一维数组的定义及应用
5.3 二维数组的定义及应用
5.4 多维数组的定义及应用
5.5 字符数组
5.1 概述
在程序设计中,常需要大量相同数据类型的变量来保存数据,若采用简单变量的定义方式,则需要大量不同的标识符作为变量名,并且这些变量在内存中的存放是随机的,随着这种变量的增多,组织和管理好这些变量会使程序变得复杂。对于这种情况,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。
在 C语言中,数组具有以下几个特点:
数组元素的个数即数组的长度必须在定义时确定,在程序中不可改变。
在同一数组中的数组元素的类型是相同的。
数组元素的作用相当于简单变量。
同一数组中的数组元素在内存中占据的地址空间是连续的。
5.2 一维数组的定义及应用
5.2.1 一维数组的定义
一维数组通常是指由一个下标来确定数组元素的数组,它的定义格式为:
类型说明符 数组名 [常量表达式 ];
说明:
( 1)数据类型符可以是 int,char和 float等基本类型或构造类型,它表明每个数组元素所具有的数据类型。
( 2)数组名的命名规则同变量名完全相同。,[]”是下标运算符,它的个数反映了数组的维数,一维数组只有一个下标运算符。数组名不能与其它变量名相同。
( 3)常量表达式的值是数组的长度,即数组中所包含的元素个数。
常量表达式通常是一个整形常量或整型常量表达式,不可以含有变量,这是因为定义数组长度的表达式的值的计算是在编译时完成的,而变量的取值是在程序运行时得到的。
( 4)如同简单变量一样,相同类型的数组、变量可以在一个类型说明符下一起说明,数组之间数组和变量之间用逗号隔开。
( 5) C语言数组元素的编号是从 0开始的。
( 6)在定义数组的过程中,表示数组元素个数的常量表达式为空时,决定数组元素个数的因素有以下两种情况:一是在对数组进行定义的同时,系统给出了该数组中每个元素的初值,即对其初始化,从而可以确定该数组中元素的个数 ;二是该数组已在其他场合定义了与之相关的长度,其具体情况是该数组是一个在函数外部中已经定义了的外部数组。
( 7) C语言规定,数组不能以整体的形式参加数据处理,参加数据处理的只能是数组的元素。若是结构体数组等,则只能是其最底层的成分分量,即属于基本数据类型的成分分量。
( 8)数组也有存储属性的问题,它根据存储属性关键字和定义的物理位置决定该数组的存在性和可见性。数组定义以后,编译系统 (计算机 )将在内存中自动地开辟一块连续的存储单元用于存放数组元素,数组名表示存储单元的首地址,存储单元的多少由数组的类型和数组的大小决定。
5.2.2 一维数组的引用
与变量一样,数组也必须先定义后使用。 C语言规定数组元素只能逐个被引用,不能一次引用整个数组。数组元素的引用方式为:数组名 [下标 ]
对数组元素进行引用时应注意下标的范围。 C语言规定下标的范围在:下界 ≤下标<上界,且下界为零,上界为数组定义时常量表达式的值。
在程序的运行中,也可以利用赋值语句给数组元素赋值。
说明:
( 1)下标表达式可以是整型常量表达式或含变量的整型表达式
( 2) C编译系统对数组不做下标“越界”的检查。
关于数组的引用需要注意以下 4点
( 1)数组元素和普通的基本类型变量一样,可出现在任何合法的
C语言表达式中,也可作为函数参数使用。
( 2) C语言规定数组不能整体引用,每次只能引用数组的一个元素。例如,不能用赋值表达式语句对数组元素进行整体赋值,
因为在 C语言中,数组名具有特殊的含义,它代表数组的首地址。
( 3)由于系统在运行过程中并不自动检测元素下标值是否越界,
因此在编写程序时必须格外小心,由程序设计者自己来确保元素的正确引用,以免因下标越界而造成对其他存储单元中数据的破坏。
( 4)下面的引用方式都是非法的:
score(5); /*不能使用圆括号 *
matrix(2,3); /*不能使用圆括号,且不能将行下标和列下标写在一个括号内 */
matrix[2,3]; /*不能将行下标和列下标写在一个括号内 */
score=(1,2,3,4,5); /*不能用赋值表达式语句对数组元素进行整体赋值 */
5.2.3 一维数组的初始化
C语言中除了可用赋值语句或输入语句给数组元素赋值外,
还可以在定义数组时直接给数组元素赋初值,其初始化形式如下:
存储类型 数据类型 数组名 [常量表达式 ]={初始值表 };
初始值表为数组元素的初始值数据,不止一个数据时,其间用逗号分开。数组初始化是在编译阶段进行的。这样将减少运行时间,提高效率。一维数组可以用以下几种方式对数组元素进行初始化:
1.对全部或部分数组元素赋初值例如,int x[8]=
{1,2,3,4,5,6,7,8};
2.数组进行初始化时,方括号中的常量表达式也可以缺省。例如:
int data[]={13,15,17,6};
3.对全部数组元素初始化为 0时,可以写成:
int x[5]={0,0,0,0,0};或更简单地有,int x[5]={0};
注意:如果不对数组元素赋初值,系统不保证数组元素具有特定的值,但如果赋予哪怕仅一个数组元素的初值,则其余的数组元素会得到特定的值,0”。
当初始数据个数少于数组元素个数时,则多于数据个数的那些元素赋予零值。例如,int ndigit[5]={2,4,6};
其结果是,ndigit[0]←2,ndigit[1]←4,ndigit[2]←6,
ndigit[3]←0,ndigit[4]←0 。
大括号对中间的初始数据可以缺省,但是用于分隔数据的逗号是不可以省略的。缺省的数据被编译系统视为零值。例如,int data[4]={,2,,4};其结果是:
ndigit[0]←0,ndigit[1]←2,ndigit[2]←0,ndigit[3]←4 。
数组的应用
5.2.4 一维数组的应用
可以在程序执行过程中,对数组作动态赋值。这时可用循环语句配合 scanf函数逐个对数组元素赋值。
5.3 二维数组的定义及应用
二维数组的应用很广,例如平面上的一组点的集合就可用二维数组表示.每个点由代表着 x轴的横坐标和代表着 y轴的纵坐标来表示。
平面上的点可用二维数组来表示:
5.3.1 二维数组的定义
二维数组是指带两个下标的数组,在逻辑上可以将二维数组看成是一张具有行和列的表格或一个矩阵,下标 1表示行,
下标 2表示列,它的定义格式为:
类型说明符 数组名 [常量表达式 1][常量表达式 2];
式中各组成部分的作用同一维数组。例如,
int a[2][3],b[5][10];
说明:
( 1)定义 a为 2行 3列的整型数组,共有 2× 3=6个元素 ;b为 5行
10列的整型数组,共有 5× 10=50个元素。
( 2)这种定义方式便于把二维数组看成一种特殊的一维数组。
例如,将 a看作一个一维数组,共有两个元素 a[0],a[1],而这两个元素每个又是包含了 3个整型数据的一维数组。因此,
可以把 a[0]和 a[1]看作两个一维数组的数组名,其中 a[0]数组包含 3个元素 a[0][0],a[0][1]和 a[0][2],a[1]数组也包含了 3个元素 a[1][0],a[1][1]和 a[1][2]。
二维数组结构
C语言规定,在计算机中二维数组的元素是按行的顺序依次存放的,即在内存中,先顺序存放二维数组第一行的元素,再顺序存放二维数组第二行的元素,依此类推。实际的硬件存储器是连续编址的,也就是说存储器单元是按一维线性排列的,放完一行之后顺次放入第二行。
C语言的这种处理方法在数组初始化和用指针表示数组时很方便。
5.3.2 二维数组的引用
二维数组元素的引用与一维数组相似,也只能逐个被引用,其格式为:
数组名 [下标 1][下标 2]
数组在引用时下标的范围,应满足如下条件,0≤下标 1<
常量表达式 1,0≤下标 2<常量表达式 2。
5.3.3 二维数组的初始化
由于二维数组在内存中是按行存放的,因此二维数组的初始化也是按行进行赋值的。
给二维数组的全部元素赋初值。
例如,int x[2][4]={{1,2,3,4},{6,7,8,9}};
给二维数组的部分元素赋初值。
例如,int x[3][5]={{1},{6,7},{ }};
给二维数组的全部元素赋初值,可以不指定第一维的长度,但第二维的长度不能省略。例如,
int x[][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
5.3.4 二维数组的存储形式
在 C语言中,二维数组中元素的排列顺序是按行连续存放的,
即在内存中先顺序存放
完第一行元素,再继续存放第二行元素,直到最后一行。例如,int a[2][3];则数组 a中元素的排列顺序如图 5-4所示。该数组的元素在内存中的存放形式如图
5.4 多维数组的定义及应用
和二维数组的定义类似,多维数组定义的形式为:
[存储属性 ] 数据类型 数组名 [常量表达式 1][常量表达式 2] [常量表达式 3]…
例如:
int b[2][5][6];float c[3][4][5][6];
其中,b是整型的三维数组 ;c是单精度的四维数组
5.5 字符数组的定义及应用
当一维数组或二维数组的元素是字符型时,称它们为字符数组。处理字符数组时,可借助于系统提供的字符串处理函数。本节将介绍几个常用字符串处理函数,它们包含在 string.h头文件中。为加深概念,将结合字符数组的应用实例来介绍字符串处理函数。
5.5.1 字符数组的定义
字符数组的定义方式和数值型数组的定义方式相同,其类型说明符为 char。例如:
char a[15],c[50];
char b[10][50];
5.5.2 字符数组的初始化
5.5.2 字符数组的初始化
1.对数组元素赋值,与数值数组相同。如,char
b[10]={‘0’,‘1’,‘2’,‘3’,‘4’);”。把五个字符分别赋给 b[0]到 b[4],
其余元素自动为空字符 (‘\0’)。
2.将字符串赋给指定的数组。例如:
char word[]={"C_language"};
注意:在程序的执行语句部分,不允许把字符串赋给一个数组,只能在声明的时候进行初始化。
单个字符用单引号括起来,字符串用双引号括起来。
采用将字符串赋给数组时,除了将字符串中各字符逐个地按顺序赋给字符数组中的各元素外,系统还自动地在最后一个字符后面加一个 '\0'字符作为字符串的结束标志,
5.5.3 字符数组元素的引用
在 C语言中,字符数组与数值型数组一样,也只能对字符数组元素逐个引用。在程序中,对字符数组元素的引用常常会出现在赋值语句中
5.5.4 字符数组的输入输出
字符串是存放在字符数组中的,因此字符串的输入输出就是字符数组的输入输出。字符串的输入输出可以有两种格式:一种采用,%c”格式符,另一种采用,%s”格式符。用,%c”格式符逐个字符输入输出,每次输入或输出一个字符,这种输入输出方式和一般数组的输入输出相同。
5.5.5 字符数组程序设计举例
1.选择法排序
假定有一个包括 n个数的序列,要求按递增的次序对该序列进行排序。算法的步骤如下。
①从 n个数中选出最小数,然后将此数与第一个数交换位置。
②除第一个数外,其余的 (n-1)个数再按步骤①的方法选出次小的数,与第二个数交换位置。
③重复步骤① n-1遍,最后完成递增序列的排序实例
输入一行字符,统计其中有多少个单词,单词之间用空格分隔
分析:单词的数目可通过空格出现的次数确定,连续空格按一个处理,
一行开头的空格不统计。程序中用
num统计单词的个数,用 word作为判断是否单词的标志,word=0
表示未出现单词,word=1表示出现单词程序代码
#include<stdio.h>
void main()
{
char str[100],c;
int i,num,word;
num=word=0;
gets(str);
for(i=0;(c=str[i])!='\0';i++)
if(c==' ')
word=0;
else if(word==0)
{word=1;num++;}
printf("共有单词,%d。 \n",num);
}
5.1 数组概述
5.2 一维数组的定义及应用
5.3 二维数组的定义及应用
5.4 多维数组的定义及应用
5.5 字符数组
5.1 概述
在程序设计中,常需要大量相同数据类型的变量来保存数据,若采用简单变量的定义方式,则需要大量不同的标识符作为变量名,并且这些变量在内存中的存放是随机的,随着这种变量的增多,组织和管理好这些变量会使程序变得复杂。对于这种情况,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。
在 C语言中,数组具有以下几个特点:
数组元素的个数即数组的长度必须在定义时确定,在程序中不可改变。
在同一数组中的数组元素的类型是相同的。
数组元素的作用相当于简单变量。
同一数组中的数组元素在内存中占据的地址空间是连续的。
5.2 一维数组的定义及应用
5.2.1 一维数组的定义
一维数组通常是指由一个下标来确定数组元素的数组,它的定义格式为:
类型说明符 数组名 [常量表达式 ];
说明:
( 1)数据类型符可以是 int,char和 float等基本类型或构造类型,它表明每个数组元素所具有的数据类型。
( 2)数组名的命名规则同变量名完全相同。,[]”是下标运算符,它的个数反映了数组的维数,一维数组只有一个下标运算符。数组名不能与其它变量名相同。
( 3)常量表达式的值是数组的长度,即数组中所包含的元素个数。
常量表达式通常是一个整形常量或整型常量表达式,不可以含有变量,这是因为定义数组长度的表达式的值的计算是在编译时完成的,而变量的取值是在程序运行时得到的。
( 4)如同简单变量一样,相同类型的数组、变量可以在一个类型说明符下一起说明,数组之间数组和变量之间用逗号隔开。
( 5) C语言数组元素的编号是从 0开始的。
( 6)在定义数组的过程中,表示数组元素个数的常量表达式为空时,决定数组元素个数的因素有以下两种情况:一是在对数组进行定义的同时,系统给出了该数组中每个元素的初值,即对其初始化,从而可以确定该数组中元素的个数 ;二是该数组已在其他场合定义了与之相关的长度,其具体情况是该数组是一个在函数外部中已经定义了的外部数组。
( 7) C语言规定,数组不能以整体的形式参加数据处理,参加数据处理的只能是数组的元素。若是结构体数组等,则只能是其最底层的成分分量,即属于基本数据类型的成分分量。
( 8)数组也有存储属性的问题,它根据存储属性关键字和定义的物理位置决定该数组的存在性和可见性。数组定义以后,编译系统 (计算机 )将在内存中自动地开辟一块连续的存储单元用于存放数组元素,数组名表示存储单元的首地址,存储单元的多少由数组的类型和数组的大小决定。
5.2.2 一维数组的引用
与变量一样,数组也必须先定义后使用。 C语言规定数组元素只能逐个被引用,不能一次引用整个数组。数组元素的引用方式为:数组名 [下标 ]
对数组元素进行引用时应注意下标的范围。 C语言规定下标的范围在:下界 ≤下标<上界,且下界为零,上界为数组定义时常量表达式的值。
在程序的运行中,也可以利用赋值语句给数组元素赋值。
说明:
( 1)下标表达式可以是整型常量表达式或含变量的整型表达式
( 2) C编译系统对数组不做下标“越界”的检查。
关于数组的引用需要注意以下 4点
( 1)数组元素和普通的基本类型变量一样,可出现在任何合法的
C语言表达式中,也可作为函数参数使用。
( 2) C语言规定数组不能整体引用,每次只能引用数组的一个元素。例如,不能用赋值表达式语句对数组元素进行整体赋值,
因为在 C语言中,数组名具有特殊的含义,它代表数组的首地址。
( 3)由于系统在运行过程中并不自动检测元素下标值是否越界,
因此在编写程序时必须格外小心,由程序设计者自己来确保元素的正确引用,以免因下标越界而造成对其他存储单元中数据的破坏。
( 4)下面的引用方式都是非法的:
score(5); /*不能使用圆括号 *
matrix(2,3); /*不能使用圆括号,且不能将行下标和列下标写在一个括号内 */
matrix[2,3]; /*不能将行下标和列下标写在一个括号内 */
score=(1,2,3,4,5); /*不能用赋值表达式语句对数组元素进行整体赋值 */
5.2.3 一维数组的初始化
C语言中除了可用赋值语句或输入语句给数组元素赋值外,
还可以在定义数组时直接给数组元素赋初值,其初始化形式如下:
存储类型 数据类型 数组名 [常量表达式 ]={初始值表 };
初始值表为数组元素的初始值数据,不止一个数据时,其间用逗号分开。数组初始化是在编译阶段进行的。这样将减少运行时间,提高效率。一维数组可以用以下几种方式对数组元素进行初始化:
1.对全部或部分数组元素赋初值例如,int x[8]=
{1,2,3,4,5,6,7,8};
2.数组进行初始化时,方括号中的常量表达式也可以缺省。例如:
int data[]={13,15,17,6};
3.对全部数组元素初始化为 0时,可以写成:
int x[5]={0,0,0,0,0};或更简单地有,int x[5]={0};
注意:如果不对数组元素赋初值,系统不保证数组元素具有特定的值,但如果赋予哪怕仅一个数组元素的初值,则其余的数组元素会得到特定的值,0”。
当初始数据个数少于数组元素个数时,则多于数据个数的那些元素赋予零值。例如,int ndigit[5]={2,4,6};
其结果是,ndigit[0]←2,ndigit[1]←4,ndigit[2]←6,
ndigit[3]←0,ndigit[4]←0 。
大括号对中间的初始数据可以缺省,但是用于分隔数据的逗号是不可以省略的。缺省的数据被编译系统视为零值。例如,int data[4]={,2,,4};其结果是:
ndigit[0]←0,ndigit[1]←2,ndigit[2]←0,ndigit[3]←4 。
数组的应用
5.2.4 一维数组的应用
可以在程序执行过程中,对数组作动态赋值。这时可用循环语句配合 scanf函数逐个对数组元素赋值。
5.3 二维数组的定义及应用
二维数组的应用很广,例如平面上的一组点的集合就可用二维数组表示.每个点由代表着 x轴的横坐标和代表着 y轴的纵坐标来表示。
平面上的点可用二维数组来表示:
5.3.1 二维数组的定义
二维数组是指带两个下标的数组,在逻辑上可以将二维数组看成是一张具有行和列的表格或一个矩阵,下标 1表示行,
下标 2表示列,它的定义格式为:
类型说明符 数组名 [常量表达式 1][常量表达式 2];
式中各组成部分的作用同一维数组。例如,
int a[2][3],b[5][10];
说明:
( 1)定义 a为 2行 3列的整型数组,共有 2× 3=6个元素 ;b为 5行
10列的整型数组,共有 5× 10=50个元素。
( 2)这种定义方式便于把二维数组看成一种特殊的一维数组。
例如,将 a看作一个一维数组,共有两个元素 a[0],a[1],而这两个元素每个又是包含了 3个整型数据的一维数组。因此,
可以把 a[0]和 a[1]看作两个一维数组的数组名,其中 a[0]数组包含 3个元素 a[0][0],a[0][1]和 a[0][2],a[1]数组也包含了 3个元素 a[1][0],a[1][1]和 a[1][2]。
二维数组结构
C语言规定,在计算机中二维数组的元素是按行的顺序依次存放的,即在内存中,先顺序存放二维数组第一行的元素,再顺序存放二维数组第二行的元素,依此类推。实际的硬件存储器是连续编址的,也就是说存储器单元是按一维线性排列的,放完一行之后顺次放入第二行。
C语言的这种处理方法在数组初始化和用指针表示数组时很方便。
5.3.2 二维数组的引用
二维数组元素的引用与一维数组相似,也只能逐个被引用,其格式为:
数组名 [下标 1][下标 2]
数组在引用时下标的范围,应满足如下条件,0≤下标 1<
常量表达式 1,0≤下标 2<常量表达式 2。
5.3.3 二维数组的初始化
由于二维数组在内存中是按行存放的,因此二维数组的初始化也是按行进行赋值的。
给二维数组的全部元素赋初值。
例如,int x[2][4]={{1,2,3,4},{6,7,8,9}};
给二维数组的部分元素赋初值。
例如,int x[3][5]={{1},{6,7},{ }};
给二维数组的全部元素赋初值,可以不指定第一维的长度,但第二维的长度不能省略。例如,
int x[][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
5.3.4 二维数组的存储形式
在 C语言中,二维数组中元素的排列顺序是按行连续存放的,
即在内存中先顺序存放
完第一行元素,再继续存放第二行元素,直到最后一行。例如,int a[2][3];则数组 a中元素的排列顺序如图 5-4所示。该数组的元素在内存中的存放形式如图
5.4 多维数组的定义及应用
和二维数组的定义类似,多维数组定义的形式为:
[存储属性 ] 数据类型 数组名 [常量表达式 1][常量表达式 2] [常量表达式 3]…
例如:
int b[2][5][6];float c[3][4][5][6];
其中,b是整型的三维数组 ;c是单精度的四维数组
5.5 字符数组的定义及应用
当一维数组或二维数组的元素是字符型时,称它们为字符数组。处理字符数组时,可借助于系统提供的字符串处理函数。本节将介绍几个常用字符串处理函数,它们包含在 string.h头文件中。为加深概念,将结合字符数组的应用实例来介绍字符串处理函数。
5.5.1 字符数组的定义
字符数组的定义方式和数值型数组的定义方式相同,其类型说明符为 char。例如:
char a[15],c[50];
char b[10][50];
5.5.2 字符数组的初始化
5.5.2 字符数组的初始化
1.对数组元素赋值,与数值数组相同。如,char
b[10]={‘0’,‘1’,‘2’,‘3’,‘4’);”。把五个字符分别赋给 b[0]到 b[4],
其余元素自动为空字符 (‘\0’)。
2.将字符串赋给指定的数组。例如:
char word[]={"C_language"};
注意:在程序的执行语句部分,不允许把字符串赋给一个数组,只能在声明的时候进行初始化。
单个字符用单引号括起来,字符串用双引号括起来。
采用将字符串赋给数组时,除了将字符串中各字符逐个地按顺序赋给字符数组中的各元素外,系统还自动地在最后一个字符后面加一个 '\0'字符作为字符串的结束标志,
5.5.3 字符数组元素的引用
在 C语言中,字符数组与数值型数组一样,也只能对字符数组元素逐个引用。在程序中,对字符数组元素的引用常常会出现在赋值语句中
5.5.4 字符数组的输入输出
字符串是存放在字符数组中的,因此字符串的输入输出就是字符数组的输入输出。字符串的输入输出可以有两种格式:一种采用,%c”格式符,另一种采用,%s”格式符。用,%c”格式符逐个字符输入输出,每次输入或输出一个字符,这种输入输出方式和一般数组的输入输出相同。
5.5.5 字符数组程序设计举例
1.选择法排序
假定有一个包括 n个数的序列,要求按递增的次序对该序列进行排序。算法的步骤如下。
①从 n个数中选出最小数,然后将此数与第一个数交换位置。
②除第一个数外,其余的 (n-1)个数再按步骤①的方法选出次小的数,与第二个数交换位置。
③重复步骤① n-1遍,最后完成递增序列的排序实例
输入一行字符,统计其中有多少个单词,单词之间用空格分隔
分析:单词的数目可通过空格出现的次数确定,连续空格按一个处理,
一行开头的空格不统计。程序中用
num统计单词的个数,用 word作为判断是否单词的标志,word=0
表示未出现单词,word=1表示出现单词程序代码
#include<stdio.h>
void main()
{
char str[100],c;
int i,num,word;
num=word=0;
gets(str);
for(i=0;(c=str[i])!='\0';i++)
if(c==' ')
word=0;
else if(word==0)
{word=1;num++;}
printf("共有单词,%d。 \n",num);
}