配色: 字号:
计算机程序设计基础(C语言)第7章 数组
2022-11-06 | 阅:  转:  |  分享 
  
第7章 数 组本章要点: 一 维 数 组 二 维 数 组 字符数组用一组具有相同名字、不同下标的下标变量来代表一组具有相同性质的一组
数据,这就是数组。数组是同类型数据的集合,集合中的每个数据称为数组元素或下标变量,数组元素的类型相同、个数确定。下标变量中如果只用
一个下标,则称为一维数组,用两个下标则称之为二维数组,用三个下标称之为三维数组,依此类推。 基本概念7.1一 维 数 组7.1.1
一维数组的定义定义形式为: [存储类别] 类型标识符 数组名[常量表达式], …; 例如:int a[
6],b[34]; double x[100],y[100]; 说明:类型标识符”表明了数组元素的数
据类型,称为数组的基类型。常量表达式是由常量、符号常量和运算符组成的表达式,它的值规定了数组中数组元素的个数(数组的长度 ) 常量
表达式中不能含有变量。int n; scanf("%d",&n);int a[n];数组在内存中占据一片
连续的存储单元,数组中的每个数组元素在这片连续的存储单元中按序存储。C语言规定数组名表示该连续存储单元的首地址(首字节编号)。 数
组的定义语句给每个数组元素分配了一定的存储单元,和简单变量一样它们的值是不确定的、是随机的,只有通过赋值或赋初值才能得到确定的值。
同类型的数组的定义和普通变量的定义可以出现在同一个定义语句中。如: int a[6],b[20],i,j;数组初始化的一般形
式为: [存储类别] 类型标识符 数组名[常表]={初值表};数组初始化常见的几种形式:对所有数组元素赋初值,此时数组定义中表
示数组长度的常量表达式可以省略。例如,int a[6]={0,1,2,3,4,5};例如,int a[]={5,6,7,8};可以
只给一部分数组元素赋初值,此时数组长度一般不省略。例如: int a[6]={0,1,2}; 后面
3个元素由C编译系统自动赋值为0。7.1.2 一维数组的初始化 引用形式为: 数组名[下标表达式] 例如:
a[0]=123;        scanf(“%d”,&a[3]);
printf(“%d”,a[5]); a[i++]=2a[i+j];7.1.3 一维数组元素的引用【例7.
1】输入10个整型数据,然后分别按顺序和逆序的方式输出。#include "stdio.h“#define N 10 main(
){ int i,a[N]; for(i=0;i / for(i=0;i "\n"); for(i=N-1;i>=0;i--) printf("%d",a[i]);/逆序输出/}在引用数组
元素时应注意: ① 引用数组元素时,下标表达式的值是确定的。 ② 数组元素本身可以看作是一个普通变量,代表内存中的一个存储单元。
因此数组元素可以在任何相同类型简单变量允许使用的位置引用。 ③ 数组引用时,下标值应该在已定义的数组大小范围内。常出现的错误是:
int a[100]; a[100]=4;应严格区分定义数组时使用的a[100]和引用数组元素时使用的
a[100] 7.1.4 一维数组应用【例7.2】从键盘输入10个整数存放在数组中,输出其中最大的一个数和它在数组中的位序。【例
7.3】 用数组处理Fibonacci数列问题,输出Fibonacci数列的前36项数据。 #include "stdio.h"#
define N 10 main( ){ int num[N]={1,32,14,56,74,3,56,6,9,12},
x, i; printf("input x:"); scanf("%d", &x); for(i=
0; i printf("该数在数组中不存在\n"); else printf("该数在数组中的下标
是%d\n",i);}【例7.4】已知一个一维数组中的各个元素值均不相同,编写程序查找数组中是否有值为x的数组元素。如果有,输出相
应的下标;如果没有,输出“该值在数组中不存在”字样信息 。 #include "stdio.h"#define N 10
main( ){ int num[N]={1,32,14,56,74,3,56,6,9,12}, x, i; printf(
"input x:"); scanf("%d", &x); for(i=0; i if (num[i]==x) break; if(i==N) printf("
该数在数组中不存在\n"); else printf("该数在数组中的下标是%d\n",i);}【例7.5
】 编写程序,利用选择法对10个整数进行递减排序,并输出排序后的结果。 选择法排序的思路是: 先从全体待排序的n个数据中找出最大
的数,把它放到数组的第0个位置上,完成第1趟选择排序; 接着再在剩余的n-1个数据中找出最大的数放到数组的第1个位置上,完成第2趟
选择排序,……, 如此反复,经过n-1趟选择排序后,原始数组已经有序。 交换: 19 9 7
6 3第4趟查找: 19 9 7 6 3交换: 19 9
7 6 3第3趟查找: 19 9 6 7 3交
换: 19 9 6 7 3第2趟查找: 19 3 6
7 9交换: 19 3 6 7 9第1趟查找: 7
3 6 19 9排序前: 7 3 6 19 9第
四趟 3 4第三趟 4 3 6 【例7.6】 编写程序,利用冒泡法对10个整数进行递增排序。 第一趟
12 4 15 6 34 12 15 6 3 4 12 15 6 34 12 6 15 3
4 12 6 3 15第二趟 4 6 3 12 7.2 二 维 数 组例: 求一个矩阵的转置矩阵3
5 6 7 6 8 2 92 4 5 62 4 5 66 8
2 93 5 6 7定义二维数组的一般形式为:[存储类别] 类型标识符 数组名[常表1][常表2],…;
例如:int a[2][3];说明:① 二维数组定义中的第1个下标表示该数组具有的行数,第2个下标表示该数组具有的列数,两个
下标之积是组成该数组的元素的个数,即二维数组的长度。② 二维数组在内存中占据一片连续的存储单元。7.2.1 二维数组的定义③ 在
C语言中,一个二维数组可以看作是一个特殊的一维数组,其中一维数组中的每个元素又是一个一维数组,即二维数组是由元素类型为数组类型的一
维数组构成的一维数组。 因此C系统就把a[0]、a[1]看作是一维数组的数组名。 int a[2][3];二维数组初始化的几种常见
形式: (1) 按行给二维数组元素赋初值。如: int a[2][3]={{1,2,3}, {6,7,8}};
(2) 将所有数据写在一个花括弧内,按数组在内存中的排列顺序对各数组元素赋初值。如: int a[2][3
]={1,2,3,6,7,8}; (3) 给二维数组所有元素赋初值,二维数组第一维的长度可以省略。 如:int
a[2][3]={1,2,3,6,7,8}; 等价于: int a[ ][3]={1,2,
3,6,7,8}; (4)在定义时也可以只对部分元素赋初值而省略第一维的长度,但应按行赋初值。如: int a
[ ][3]={{0,2},{6}};7.2.2 二维数组的初始化二维数组元素的引用形式为: 数组名[下标表达
式1][下标表达式2]数组元素的行列下标都从0开始。可以对二维数组元素进行与普通变量相同的操作,因为它们的本质就是一个普通变量,如
运算、赋值等。如:a[0][0]=a[0][2]/3-30;    printf("%d",a[1][1]);
区分在定义数组时使用的维数和各维大小与引用数组元素时下标值的不同。如:  int a[3][5];  a[3][5]=6;7.2
.3 二维数组元素的引用 【例7.8】输入12个整型数据形成一个具有3行4列的二维数组,然后按数组的逻辑排列形式输出。 #inc
lude "stdio.h"#define M 3 #define N 4 main( ){ int i,j,
a[M][N]; for(i=0;i nf("%d",&a[i][j]); / 按行顺序输入 / for(i=0;i j=0;j printf("\n"); / 一行输出完后,要换行 / } }7.2.4 二维数组应用举例【
例7.9】 编写程序求一个3?4整数矩阵中的最大元素及它所在的行号和列号。#include "stdio.h"#define M
3 / 预定义二维数组的行数 /#define N 4 / 预定义二维数组的列数 /main( ){ int m
[M][N],i,j,max,row,col; for(i=0;i scanf("%d",&m[i][j]); / 按行输入各个数组元素 / max=m[0][0]; row=0
; col=0; / 假定m[0][0]最大 / for(i=0;i ;j++) if(m[i][j]>max){ max=m[i][j];row=i;col=j;} printf(
"The max value is [%d][%d]=%d\n",row,col,max);}【例7.10 】将一个二维数组的行和
列元素互换,存到另一个二维数组中。 #define M 2#define N 3main( ){int a[M][N]={{1,2
,3},{4,5,6}},b[N][M],i,j;for(i=0;i { printf("%5d",a[i][j]); b[j][i]=a[i][j]; } printf("\
n"); }printf("array b:\n");for(i=0;i printf("%5d",b[i][j]); printf("\n"); }} 【例7.11】已知一个小组5个学生的4门课
成绩,要求分别求每门课的平均成绩和每个学生的平均成绩。 cour1 cour2 cour
3 cour4 stud1 87 69 98 62 st
ud2 59 92 68 77 stud3 78
88 45 60 stud4 89 62
97 94 stud5 72 99 75 64ma
in( ) {int i,j;double score[6][5]={{87,69,98,62},{59,92,68,77},  
  {78,88,45,60},{89,62,97,94},{72,99,75,64}} for(i=0;i<5;i++)
/ 统计每个学生的平均成绩 / {for(j=0;j<4;j++)   score[i][4]+=score[i][
j]; score[i][4]= score[i][4]/4; printf("Average of student %d is
%6.2lf\n",i+1,score[i][4]); }} for(j=0;j<4;j++) / 统计每门课程的平均
成绩 / {for(i=0;i<5;i++) score[5][j]+=score[i][j];
score[5][j]= score[5][j]/5;   printf("Average of course %d is %6.
2lf\n",j+1,score[5][j]); }【例7.12】 在屏幕上输出如下形式的杨辉三角形。 #include
"stdio.h"#define N 10main( ){int yh[N][N],i,j; for(i=0;i / 初始杨辉三角形的两条侧边上的值/ yh[i][0]= yh[i][i]=1; for(i=2;i for(j=1;j h[i-1][j]; for(i=0;i ,yh[i][j]); printf("\n"); }}11 11 2 11 3 3 11 4 6 4
11 5 10 10 5 11 6 16 20 16 6 1 …… 7.3 字符数组字符数组是存放字符
型数据的数组。常用的字符数组为一维字符数组和二维字符数组。 7.3.1 字符数组的定义char str1[5];char str
2[3][10]; 用赋值语句可以对字符数组元素逐个赋初值。例如: str1[0]= ''C'';  str1[1]=
''h''; str1[2]= ''i''; str1[3]= ''n''; str1[4]= ''a'';
"hello"对字符串的处理常常采用一维字符数组实现 。注意串长度和字符数组长度的区别。7.3.2字符串与字符数组字符数组与字符
串的区别字符数组中并不限定字符是什么字符数组末尾加’\0’后,可把它”看作”字符串变量不能通过赋值语句把字符串常量或其它字符数组中
的字符串直接赋给字符串变量字符串是字符数组的一种具体应用逐个字符对字符数组初始化(不会自动在最后一个字符后加’\0’ ). 例
如: char str1[5]={ ‘C’, ‘h’, ‘i’,‘n’,‘a’}; char str2
[2][3]={ ‘W’,‘i’,‘n’,‘d’,‘o’,‘w’};如果初值个数小于数组长度,C编译系统将其余的元素自动定为空字符
(即‘\0’)用字符串常量对字符数组初始化(系统会自动在最后一个字符后加’\0’) 例如:
char c1[13]={"Good morning"}; char c2[2][10
]={"Hello","World"};8.3.3 字符数组的初始化 不可以用赋值语句给字符数组整体赋一串字符. 如: c
har c1[13]; c1 = “Good morning”;逐个字符输入输出scanf(
)和printf()函数中用格式符“%c” ,循环7.3.4 字符数组的输入输出 char str[5];for(i=0;i<5;
i++) scanf(“%c”,&str[i]);for(i=4;i>=0;i--) printf(“%c”,str[
i]); 必须在接受到“回车”时,scanf()才开始读取数据。 如果按“回车”时,输入的字符少于scanf()循环读取的字符,
scanf()继续等待用户将剩下字符输入;否则,scanf()循环只将前面的字符读入。 逐个读入字符结束后,不会自动在末尾加’\0
’。所以输出时,最好也使用逐个字符输出。字符串整体输入输出 scanf() 函数中用格式符“%s”整体输入 例如:从键盘上读入12
个字符并输出:char str[12];scanf("%s",str);printf("%s",str); ①用“%s”输入
输出字符串, 以上函数的第二个参数都要求是字符数组的首地址,如字符数组名。 ②按照“%s”格式输入字符串时,输入的字符串中不
能有空格(由空格键或Tab键产生,空格或是输入数据的结束标志),否则空格后面的字符不能读入,这时scanf()函数认为输入的是两个
字符串。 如输入: I am happy 则输出 : I 必须是字符数
组名printf()函数中用格式符“%s”整体输出 printf("%s",str); 输出项是一个地址值。可以是字符数组名、字
符指针或字符数组元素的地址。 函数从这一地址开始依次输出,直至遇到第一个’\0’。 ‘\0’是结束标志,不在输出字符之列,输出
结束后不自动换行。1. 字符串输入和输出函数(#include "string.h ") (1)字符串输出函数puts()函数的调
用形式为: puts(str);功能:从str指定的地址开始,一次将存储单元中的各个字符输出到显示器,直到遇到‘\0’。 例如下
列程序段:char str[ ]= “China”; puts(str);注意:在输出时将字符串结束
标志转换成''\n'',即输出完字符串后换行。 7.3.5 字符串(字符数组)处理函数 (2)字符串输入函数gets( )函数的调用
形式: gets(字符数组);功能:从键盘输入一个字符串(可包含空格),直到遇到回车符,并将字符串存放到由str指定的字符数组(
或内存区域)中。换行符读入后,不作为字符串的内容,系统自动用’\0’代替。函数调用完成后,输入的字符串存放在str开始的内存空间中
。 2. 字符串连接函数strcat( )函数调用形式为:   strcat(字符数组1 ,字符数组2)功能:将以str2为首地址
的字符串连接到str1字符串的后面。从str1原来的字符串结束标志’\0’处开始连接。 例如:  cha
r strl[13]={“I love ”}; char str2[ ]={“China”};
printf("%s",strcat(str1,str2)); 输出结果为: I
love China str1必须足够大 格式:strcpy (字符数组1,字符串2)功能: 将字符数组2拷贝到字符数组1中
; 例如:char str1[10],str2[ ]={“Computer”}; strcpy(str1, str2)
; 执行后str1中的内容为: Computer;注意:字符数组1的长度应大到足够容纳字符串2.字符数组2的形式可以
是字符数组名也可以是字符串常量. 如: strcpy(str1, “Computer”); 3.字符串拷贝函数 strcpy
( ) 格式:strcmp (字符串1,字符串2); 功能:对两个字符串从左到右逐个字符进行比较,直到相应位置上的字符不一样或遇到
‘\0’, 比较结果由函数返回如果字符串1=字符串2, 函数返回值为0如果字符串1>字符串2, vc中函数返回值为1如果字符
串1<字符串2, vc中函数返回值为-1printf("%d ",strcmp("zbcd",“abcd"));4、字符串比较函数
strcmp( )格式:strlen (字符串);功能: 测试字符串的实际长度(不包括‘\0’) 如:char str[1
5]={“I love china”}; printf(“%d”, strlen(str)); 结果: 12 5、测字符串
长度函数strlen( )7.3.6 字符数组应用【例7.13 】编写程序求一个字符串的逆串。 如:字符串”abcdefg”的逆串为:”gfedcba”。 main( ){ char str[50]; int c,i,j,n; printf("Please input the string:\n"); scanf("%s",str); for(n=0;str[n]!=‘\0’;n++); for(i=0,j=n-1;i
献花(0)
+1
(本文系籽油荃面原创)