第六章 数组
?数组,构造型数据类型;有序数据的集合,每
个元素都属于同一类型,用一个数组名和下标
唯一地确定数组中的元素。
?好处,让一批相同性质的数据用同一个变量名
,书写方便,可读性高;便于使用循环语句。
§ 6.1 一维数组的定义和使用
? 一、一维数组的定义和使用
? 定义:
? 类型名 数组名 [常量表达式 ];
? 例,int a[10];
定义一个含有 10个整型元素的数组,
? char c[20];
定义一个含有 20个字符元素的数组。
? ① 数组名遵循标识符取名规则
? ②用方括号,且其中常量表达式表示元素个数,
– 下标总是从 0开始。
– 即 a[10],c[20]是不存在的。
– 若定义 a[n],则下标从 0~ n-1是合法的。
? △但C语言中对下标不作合法性检查,所以允许在使用
中下标越界。这种情况须程序员自我检查。
? ③常量表达式可以包含常量和符号常量,不可使用变量,
C语言中不可用可调数组。
? ④使用时,只能逐个使用而不能一次使用整个数组。
即:只能对数组元素操作
注意!
物理意义:
?数组一旦定义:就
在内存中开辟出一
块连续的空间:空
间的首地址对应于
第一个元素,依次
排列。
地址 内 容下标
首地址 0
首地址 +1 1
32767
54
首地址 +2 2 87
首地址 +3 3 -900
首地址 +4 4 876
首地址 +5 5 -7890
首地址 +6
首地址 +7
首地址 +8
首地址 +9
6
7
8
9
-3654
9008
10
35
引用:
? 先定义,后使用。
? 只能单个使用数组元
素而不能一次使用整
个数组。
? 数组元素的表示为:
? 数组名 [下标 ]
? 下标可以是整型表达式
? 当确定到元素后,对该元
素的处理相同与该数组元
素相同类型的其它变量。
? 如:
x[0]=x[1]+sin(x[10])+100;
二、一维数组的初始化
? 初始化:即在数组定义时就赋初值
? C规定,只有静态存储和外部存储的的数组才可以初
始化。 #不同系统可能有不同,请上机试用。
? 1.对全部数组元素赋初值
– static int a[10]={0,1,2,3,4,5,6,7,8,9};
– 此时,a[0]=0,a[1]=1,......a[9]=9
– 对全部元素初始化时,数组长度可不写。
? 2.部分元素初始化,数组长度必须给出。
static int fibonacci[20]={1,1};
? 3.不能给数组整体赋初值。如, static int a[10]={ 0*10};
应写为, static int a[10]={0,0,0,0,0,0,0,0,0,0};
? 4.静态型和外部型数组不赋初始值,系统自动赋以 0值。
只初始化一部分的,未初始化的部分自动赋以 0值。
6.1.1 1维数组的定义
[案例 6.1] 从键盘上任意输入 10个整数, 要求按从小到大的顺序
在屏幕上显示出来 。
排序的方法有很多, 本题采用冒泡法 。
冒泡法的基本思想,通过相邻两个数之间的比较和交换, 使排序
码 ( 数值 ) 较小的数逐渐从底部移向顶部, 排序码较大的数逐渐从
顶部移向底部 。 就像水底的气泡一样逐渐向上冒, 故而得名 。
由 A[n]~A[1]组成的 n个数据, 进行冒泡排序的过程可以描述为

( 1) 首先将相邻的 A[n]与 A[n-1]进行比较, 如果 A[n]的值小于
A[n-1]的值, 则交换两者的位置, 使较小的上浮, 较大的下沉;接着
比较 A[n-1]与 A[n-2],同样使小的上浮, 大的下沉 。 依此类推, 直到
比较完 A[2]和 A[1]后, A[1]为具有最小排序码 ( 数值 ) 的元素, 称第
一趟排序结束 。
( 2) 然后在 A[n]~A[2]区间内, 进行第二趟排序, 使剩余元素中
排序码最小的元素上浮到 A[2];重复进行 n-1趟后, 整个排序过程结
束 。
数组初始化举例
? #include<stdio.h>
? void main()
? {int a[5]={1,2,3,4,5};
? int b[5]={1,2,3};
? int c[]={1,2,3,4,5};
? static int d[5];
? int e[5];
? int i;
? for (i=0;i<5;i++) printf("%d",a[i]);printf("\n");
? for (i=0;i<5;i++) printf("%d",b[i]);printf("\n");
? for (i=0;i<5;i++) printf("%d",c[i]);printf("\n");
? for (i=0;i<5;i++) printf("%d",d[i]);printf("\n");
? for (i=0;i<5;i++) printf("%d",e[i]);printf("\n");
? }
举例,{6.1]
/*案例代码文件名,AL6_1.C*/
/*功能:从键盘上任意输入 n个整数, 用冒泡法按从小到大地排序,
并在屏幕上显示出来 。 */
#include "stdio.h"
#define NUM 10 /*定义符号常量 ( 数据个数 N) */
main()
{ int data[NUM]; /*定义 1个 1维整型数组 data*/
int i,j,temp; /*定义循环变量和临时变量 */
clrscr(); /*库函数 clrscr():清屏 */
printf("Please input 10 numbers:\n");
for(i=0; i<NUM; i++)
scanf("%d",&data[i]);
/*冒泡法排序 */
for(i=0; i<NUM-1; i++) /*外循环:控制比较趟数 */
for(j=NUM-1; j>i; j--) /*内循环:进行每趟比较 */
if(data[j]<data[j-1]) /*如果 data[j]大于 data[j-1],交换两者的位置
*/
{temp=data[j];
data[j]=data[j-1];
data[j-1]=temp;
};
/*输出排序后的数据 */
printf("\nthe result of sort:\n");
for(i=0; i<NUM; i++)
printf("%d ",data[i]);
getch(); /*等待键盘输入任一字符, 目的使程序暂停 */
}
[程序演示 ]
[案例 6.2] 已知某课程的平时、实习、测验和期末成绩,求该课
程的总评成绩。其中平时、实习、测验和期末分别占 10%,20%、
20%,50%。
/*案例代码文件名,AL6_2.C*/
/*功能:从键盘上循环输入某课程的平时、实习、测验和期末成绩
,按 10%,20%,20%,50%的比例计算总评成绩,并在屏幕上显
示出来。按空格键继续循环,其他键终止循环。 */
#include,stdio.h”
main()
{ int i=1,j;
char con_key=?\x20?; /* ?\x20? 空格键的 ASCII码 */
float score[5],ratio[4]={0.1,0.2,0.2,0.5}; /*定义成绩,比例系数数组
*/
while(con_key=='\x20')
while(con_key=='\x20')
{clrscr();
printf("输入第 %2d个学生的成绩 \n",i++);
printf("平时 实习 测验 期末成绩 \n");
score[4]=0; /* score[4]:存储总评成绩 */
for(j=0; j<4; j++)
{scanf("%f",&score[j]);
score[4] += score[j] * ratio[j];
}
printf("总评成绩为,%6.1f\n",score[4]);
printf("\n按空格键继续,其它键退出 ");
con_key=getch(); /*getch()函数等待从键盘上输入一个字符
*/
}
}
[程序演示 ]
[Return]
§ 7.2 二维数组的定义和使用
? 多维数组的 空间想象,
? 二维数组 ── 一个表格或一个平面矩阵
? 一维数组 ── 一列长表或一个向量
? 多维数组 ── 多维空间的一个数据列阵
? 三维数组 ── 三维空间的一个方阵
一、二维数组的定义
? 类型名 数组名 [常量表达式 ][常量表达式 ]
? 例,int a[3][4],b[5][10];
? 定义 a为 3行 4列数组,b为 5行 10列数组。
? 定义了一维数组 a[3],其中每个元素又是
一个含 4个元素的一维数组, 即
? 二维数组是按行存放的,即最右边的下标变化
最快。
? a[0][0] a[0][1] a[0][2] a[0][3]
? a[1][0] a[1][1] a[1][2] a[1][3]
? a[2][0] a[2][1] a[2][2] a[2][3]
? △ 注意:不能写成 int a[3,4];
?定义三维数组,float a[2][3][4];
二、二维数组的使用
? 与一维数组类似,只能使用数组元素。
? 例:食堂有四种菜,每种菜各有 6种原、配料,
将其量 放入 a数组中,以便进行成本核算。
– float a[4][6];
– int i,j;
– for(i=0;i<4;i++)
– for(j=0;j<=5;j++)
– scanf("%f",&a[i][j])
三、二维数组的初始化
? 1.全部元素初始化
? ①按排列顺序赋初值
– static int a[2][3]={1,2,3,4,5,6};
? ② 将每行括起,分行赋初值
– static int a[2][3]={{1,2,3},{4,5,6}};
? ③ 按②时,第一维长度可略
– static int a[][3]={{1,2,3},{4,5,6}};
? 2.部分元素初始化,未赋初值的自动为 0。
– static int a[3][4]={{1},{0,6},{0,0,11}};
? 若对中间某行不赋值
– static int a[3][4]={{1},{},{9}};
? 分行赋初值时,若能告诉编译系统共有几
行,则第一维长度可省略。
例:有一个 3?4矩阵,求出其中最大
的那个元素的值,以及其所在的行号
和列号。
§ 7.3 字符数组
? 用来存放字符,一个
元素存放一个字符
? 一、定义
? char c[10];
? 二、初始化 (与前相似 )
? 全部元素初始化
? static char c[10]={'I',' ','a','m','
','h','a','p','p','y'};
? 此时可省略 10,即
? static char[]={'I',' ','a','m',' ',
'h','a','p','p','y'};
? 也可初始化一部分,则长
度不能省。 初始化一部分
时,未初始化的部分自动
赋以空字符。
三、字符串
? C中将字符串作为字符数组来处
理。 如上述一维字符数组存放
一个字符串 "I am happy"。
? △定义的字符数组长度必须 ≥实
际字符串长度。大于时:需知道
实际字符串的长度,以便操作
解决办法:自动在字符串后加结
束标志‘ \0?。
? △但字符数组不等于字符串,最
后不一定有 '\0'
? 存放字符串的字符数组初始化:
? static char c[]={"I am happy"};
? 或 static char c[]="I am happy";
? 相当于
? static char c[]={'I',' ','a','m',' ',
'h','a','p','p','y','\0'};
? 为了处理上的一致,有时人为
地在字符数组后加 '\0',作为字符
串处理。
四、字符数组 (字符串 )的使用
? 1.使用其中的一个字符,输入输出用 %c格式
? 例,for(i=0;i<10;i++) printf("%c",c[i]); 得,I am happy
? 2.用 %s格式,将整个字符数组作为字符串一次输入输出
? ⑴输出,例,printf("%s",c); c是数组名,不是数组元素名
? △此时,输出到‘ \0?结束,不论数组长度若干。 若
一个数组中包括一个以上 '\0',则遇第一个就结束。
? ⑵输入
? 例,scanf("%s",c); c数组名,不加地址运算符。为什么?
? △①用数组名,不加地址符
? ②遇回车或空格结束,并在末尾自动加 '\0'
? 例,scanf("%s",c);
? 输入 How are you? 则 c中放 How\0,其后补空格
H o w \0,.........
? ③ 一个 scanf输入多个字符串时,可用空格隔

– scanf("%s%s%s",c1,c2,c3);
– 输入 How are you? 则 c1,How\0
– c2,are\0
– c3,you?\0
? △ 与多维数值型数组类似,多维字符数组也是
合法的。
? 如二维字符数组可看成是一维字符数组,
其中每个元 素又是一个一维字符数组 (字符串 )

五、字符串处理函数 C库函数提供
? 1.字符串输出 puts(c); c字符数组名 输出时将 '\0'转换成
'\n', 相当于 printf("%s\n",c);
? 2.字符串输入
? gets(c); 字符数组名,函数值为 c的起始地址
? △遇空格不结束,只有遇回车才结束
? 例,gets(c);输入 How are you?
? 得 c,How are you?\0
? scanf(“%s”,c);输入 How are you?
? 得 c,How\0
? 3.连接二字符串 strcat(c1,c2);
? 连接 c1,c2,结果放入 c1,函数值为 c1的地址
? 连接时中间一个‘ \0?取消,二串变为一串
? △ c1的长度必须够容纳原 c1和 c2,但不够时也不检查
? 例,c1是一个二维数组,c2是一维数组
? strcat(c1[0],c2);
? 若 c1[0]长度不够,?
? 4.字符串拷贝 strcpy(c1,c2);将 c2复制到 c1中
? c1数组名 c2字符串常量或字符数组名
? △ c1长度不够时?
? △为什么有此函数?因为 c1=c2或 c1=“China”是非法的
(复习:赋值只能逐个元素赋,不能对整个数组赋)
? △只能整串拷贝,不能拷贝其中一部分,但有的系统可以
? 5.字符串比较 strcmp(c1,c2);
– c1,c2可为数组名或字符串常量
? 规则:按字典序 (ASCII码序 )
– 函数值,c1=c2时为 0; c1>c2时 正整数 ;
c1<c2时 负整数
? △为什么有此函数?因为
– c1==c2或 c1>c2或 if(c1>c2)等是非法的。
? 6.测试实际长度 strlen(c); c可为数组名或字符串常量
– 测得的实际长度不包括 '\0'
? 7.大小写转换
– strlwr(c) 大写 ─〉 小写
– strupr(c) 小写 ─〉 大写