第6章 数组 公共计算机基础教研部
本章要点 掌握一维、二维数组的定义和引用方法、 存储结构和初始化方法。 掌握有关一维数组的有关算法 掌握数组的运算。 公共计算机基础教研部
6.1 数组的概念 6.2 一维数组的定义和引用 6.3 二维数组的定义和引用 6.4 字符数组 主要内容 6.1 数组的概念 6.2 一维数组的定义和引用 6.3 二维数组的定义和引用 6.4 字符数组 公共计算机基础教研部
唉,有这么多不同主题的书。在哪里才能找到有关中国音乐的书呢? 为什么要使用数组 唉,有这么多不同主题的书。在哪里才能找到有关中国音乐的书呢? 公共计算机基础教研部
为什么要使用数组 文学类 中国音乐类 计算机类 西方音乐类 公共计算机基础教研部
为什么要使用数组 数组 内存 120 65 98 4 容器中保 存的物品 数组的元素 日常生活中的容器 程序中的数组 公共计算机基础教研部
6.1 数组的概念 C语言为这些数据,提供了一种构造数据类型:数组。所谓数组就是一组具有相同数据类型的数据的有序集合。 一个班学生的学习成绩 一行文字 一个矩阵 这些数据的特点是: 1、具有相同的数据类型 2、使用过程中需要保留原始数据 C语言为这些数据,提供了一种构造数据类型:数组。所谓数组就是一组具有相同数据类型的数据的有序集合。 公共计算机基础教研部
6.1 数组的概念 Rate 数组是可以在内存中连续存储多个元素的结构 数组中的所有元素必须属于相同的数据类型 1.5 3.2 0.09 45.3987 1 2 3 下标 数组元素 下标标明了元素在数组中的位置 数组名 Rate[ 4 ] 数组大小 公共计算机基础教研部
数组类型 一维数组 多维数组 示例:学生单门课程的成绩 2-D, 3-D, 4-D 89 90 77 … 示例:学生两门课程的成绩 1 2 学号 1 73 90 33 科目 45 80 87 公共计算机基础教研部
数组类型 公共计算机基础教研部
datatype arrayName[size]; 6.2 一维数组的定义和引用 6.2.1 定义一维数组 datatype arrayName[size]; 类型说明符 int、char、float … 数组名 常量表达式: 数组大小 int num[50]; char list[20]; double level[6]; # define LIMIT 20 . . . int code[LIMIT]; 公共计算机基础教研部
… a[0] a[1] a[7] a[8] a[9] int a[10]; 定义一个有10个int型元素的数组 数组首地址 公共计算机基础教研部 12
… a[0] a[1] a[7] a[8] a[9] int a[10]; 数组大小必须是常量表达式(常量或符号常量),其值必须为正,不能为变量。 数组一旦定义,不能改变大小 数组大小最好用宏来定义,以适应未来可能的变化 #define SIZE 10 int a[SIZE]; a[0] a[1] … a[7] a[8] a[9] 公共计算机基础教研部 13
6.2 一维数组的定义和引用 6.2.1 定义一维数组 数组说明中常见的错误 定义方式: 数据类型 数组名[常量表达式]; 6.2 一维数组的定义和引用 6.2.1 定义一维数组 定义方式: 数据类型 数组名[常量表达式]; 数组说明中常见的错误 ① float a[0]; /* 数组大小为0没有意义 */ ② int b(2); /* 不能使用圆括号 */ ③ int k=5; int a[k]; /* 不能用变量说明数组大小*/ 公共计算机基础教研部
6.2 一维数组的定义和引用 6.2.2 引用一维数组元素 1.数组元素的引用方式: 数组名[下标] 下标可以是整型常量或整型表达式。 6.2 一维数组的定义和引用 6.2.2 引用一维数组元素 1.数组元素的引用方式: 数组名[下标] 下标可以是整型常量或整型表达式。 例如: a[0]=a[5]+a[7]-a[2*3] 注意: 定义数组时用到的“数组名[常量表达式]” 和引用数组元素时用到的“数组名[下标]” 是有区别的。 例如∶ int a[10]; t=a[6]; 公共计算机基础教研部
6.2 一维数组的定义和引用 数组的下标都是从0开始 对数组每个元素的使用与普通变量无异 可以用任意表达式作为下标,动态决定访问哪个元素 6.2 一维数组的定义和引用 数组的下标都是从0开始 对数组每个元素的使用与普通变量无异 可以用任意表达式作为下标,动态决定访问哪个元素 for (i=0; i<SIZE; i++) a[i] = 2 * i; 公共计算机基础教研部
如果下标值小于0或超过数组长度时会出现什么情况? ... i b[0] b[1] b[2] b[3] b[4] n m main() { int m=20,n=10,b[5],i; for(i=0;i<=5;i++) b[i]=i; printf("m=%d,n=%d\n", m,n); } 1 2 3 4 10 5 20 #include <stdio.h> int main() { int a=1, c=2, b[5], i; printf("%x,%x,%x\n",b,&c,&a); for (i=0; i<=11; i++) b[i] = i; printf("%d ",b[i]); } printf("\na=%d,c=%d\n",a,c); return 0; m=20,n=5 公共计算机基础教研部 17
如果下标值小于0或超过数组长度时会出现什么情况? ... i b[0] b[1] b[2] b[3] b[4] n m main() { int m=20,n=10,b[5],i; for(i=0;i<=10;i++) b[i]=i; printf("m=%d,n=%d\n", m,n); } 1 2 3 4 10 5 20 6 #include <stdio.h> int main() { int a=1, c=2, b[5], i; printf("%x,%x,%x\n",b,&c,&a); for (i=0; i<=11; i++) b[i] = i; printf("%d ",b[i]); } printf("\na=%d,c=%d\n",a,c); return 0; 7 m=6,n=5 给出运行结果的同时,系统报错 8 9 10 公共计算机基础教研部 18
下标越界是大忌! 编译程序不检查是否越界 下标越界,将访问数组以外的空间 那里的数据是未知的,不受我们掌控,可能带来严重后果 公共计算机基础教研部
<例> 引用数组元素。利用循环给数组元素a[0]~a[9]赋值为0~9,然后按逆序输出各元素的值。 6.2 一维数组的定义、引用 6.2.2 引用一维数组元素 #include <stdio.h> void main() { int i,a[10]; for (i=0; i<=9;i++) a[i]=i; for(i=9;i>=0; i--) printf("%d ″,a[i]); printf("\n″); } 运行结果如下: 9 8 7 6 5 4 3 2 1 0 2.一维数组元素引用的程序实例 公共计算机基础教研部
6.2 一维数组的定义和引用 6.2.2 引用一维数组元素 一维数组的输入/输出(字符数组例外) for (i=0;i<10;i++) 6.2 一维数组的定义和引用 6.2.2 引用一维数组元素 一维数组的输入/输出(字符数组例外) int a[10],i; 输入方法: 输入第i个数组元素: 输入整个数组元素: scanf("%d",&a[i]); for (i=0;i<10;i++) scanf("%d",&a[i]); 公共计算机基础教研部
6.2 一维数组的定义和引用 6.2.2 引用一维数组元素 一维数组的输入/输出(字符数组例外) for (i=0;i<10;i++) 6.2 一维数组的定义和引用 6.2.2 引用一维数组元素 一维数组的输入/输出(字符数组例外) int a[10],i; 输出方法: 输出第i个数组元素: 输出整个数组元素: printf("%d",a[i]); for (i=0;i<10;i++) printf("%d",a[i]); 公共计算机基础教研部
6.2 一维数组的定义和引用 float price[4]; printf(“Enter prices of 4 books\n”); 6.2 一维数组的定义和引用 内存 float price[4]; printf(“Enter prices of 4 books\n”); for (i = 0;i <= 3; i++) { scanf(“%f”,&price[i]); } 12.34 price[0] price[1] price[2] price[3] 1002.10 17.5 11.12 price 公共计算机基础教研部
6.2 一维数组的定义和引用 例 int a[10]; printf(“%d”,a); () 6.2 一维数组的定义和引用 例 int a[10]; printf(“%d”,a); () 必须 for(j=0;j<10;j++) printf(“%d\t”,a[j]); () 例 int data[5]; data[5]=10; //C语言对数组不作越界检查,使用时要 注意 公共计算机基础教研部
如何使两个数组的值相等 解决方法 main() 法1:逐个元素赋值 { b[0]=a[0]; 法2:通过循环赋值 int i; for (i=0;i<4;i++) { b[i] = a[i]; } main() { int a[4] = {1,2,3,4}, b[4]; b = a; } 原因: 数组名表示数组的首地址,其值不可改变! 公共计算机基础教研部 25
6.2 一维数组的定义和引用 6.2.3 一维数组的初始化 static int a[5]; 6.2 一维数组的定义和引用 6.2.3 一维数组的初始化 说明: 数组不初始化,其元素值为随机数 对static数组元素不赋初值,系统会自动赋以0值 int a[5]={1,2,3,4,5}; 等价于: a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5; 只给部分数组元素赋初值 static int a[5]; 等价于:a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0; 当全部数组元素赋初值时,可不指定数组长度 如 int a[5]={6,2,3}; 等价于: a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0; 如 int a[3]={6,2,3,5,1}; () 数组定义后的初值仍然是随机数,一般需要我们来初始化 int a[5] = { 12, 34, 56 ,78 ,9 }; int a[5] = { 0 }; int a[] = { 11, 22, 33, 44, 55 }; 数组大小最好用宏来定义,以适应未来可能的变化 #define SIZE 10 int a[SIZE]; 数组大小定义好后,将永远不变 int a[ ]={1,2,3,4,5,6}; 编译系统根据初值个数确定数组维数 公共计算机基础教研部
判断正误: (3) int n=1,a[n]; 或 int n; scanf("%d",&n); int a[n]; (4) 数组长度必须是整型常量及其表达式,不得为变量,而数组元素下标可以是变量! (3) int n=1,a[n]; 或 int n; scanf("%d",&n); int a[n]; (4) int a[5],i; for (i=0;i<5;i++) printf("%d\n",a[i]); (1) int a[3]={1,2,3}; (2) int b[3]; b[3]={1,2,3}; b={1,2,3}; 解决方法: b[0]=1,b[1]=2,b[2]=3; 公共计算机基础教研部
6.2 一维数组的定义、引用 6.2.4 一维数组程序举例 <例> 从键盘输入10名学生的《C程序设计》的考试分数,编程输出最高分。 公共计算机基础教研部
计算最大值算法 max(i=2) max(i=3) max(i=0) 公共计算机基础教研部
{ int grade[SIZE],i,max; printf("Enter 10 integers:\n"); #define SIZE 10 main() { int grade[SIZE],i,max; printf("Enter 10 integers:\n"); for(i=0;i<SIZE;i++) { printf("%d:", i+1); scanf("%d",&grade[i]); } max=grade[0]; for(i=1;i<SIZE;i++) { if(grade[i]>max) max=grade[i]; printf("Maximum value is %d\n",max); <例> 从键盘输入10名学生的《C程序设计》的考试分数,编程输出最高分。 步骤: 1. 输入:for循环输入10个整数 2. 处理: (a) 先令max=grade[0] (b) 依次用grade[i]和max比较(循环) 若grade[i]>max,令max=grade[i] 3. 输出:max 编写:体操评分程序 公共计算机基础教研部
<例> 用数组求Fibonacci数列前20个数 ……... 1 4 5 2 3 19 #include <stdio.h> main() { int i; int f[20]={1,1}; for(i=2;i<20;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) { if(i%5==0) printf("\n"); printf("%12d",f[i]); } 2 3 5 公共计算机基础教研部
(2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在第n-1个元素位置 (3)重复上述过程,共经过n-1趟冒泡排序后,排序结束 <例> 用冒泡法对10个数排序 排序过程: (1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第 n个数比较为止——第一趟冒泡排序,结果最大的数被安置在最后一个元素位置上 (2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在第n-1个元素位置 (3)重复上述过程,共经过n-1趟冒泡排序后,排序结束 公共计算机基础教研部
<例> 49 38 65 97 76 13 27 30 初始关键字 n=8 38 38 49 65 76 13 27 30 97 第一趟 38 49 65 13 27 30 76 第二趟 38 49 13 27 30 65 第三趟 38 13 27 30 49 第四趟 13 13 27 30 38 第五趟 13 27 30 第六趟 13 27 第七趟 13 27 38 49 30 38 13 27 49 76 13 27 65 38 49 30 97 13 30 65 76 27 49 27 97 30 76 65 76 97 30 97 公共计算机基础教研部
读入5个值保存在数组中 85 90 46 71 16 #define N 5 …… int grade[N],temp; for(i=0;i<N;i++) scanf("%d",&grade[i]); for(i=0;i<N-1;i++) { for(j=0;j<N-1-i; j++) if(grade[j] > grade[j+1]) temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; } 读入5个值保存在数组中 85 90 46 71 16 公共计算机基础教研部
for(j=0; j<N-1-i; j++) 变量j是从0到3的 #define N 5 …… for(i=0; i<N-1; i++) { for(j=0; j<N-1-i; j++) if(grade[j] > grade[j+1]) temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; } i=0 第1趟 即:i=0 第1趟 时 grade[0] 和grade[1]比较 grade[1] 和grade[2]比较 grade[2] 和grade[3]比较 grade[3] 和grade[4]比较 最大值放到grade[4]中 j=0 从头开始比较 j<4 j=1 j<4 j=2 j<4 条件成立 条件成立 条件不成立 j=3 j<4 j=4 内层循环终止 85 即,i=0 第1趟 时 内存循环 for(j=0; j<N-1-i; j++) 变量j是从0到3的 46 90 temp=16 temp=71 temp=46 90 71 46 16 90 71 90 90 16 公共计算机基础教研部
#define N 5 …… for(i=0; i<N-1; i++) { for(j=0; j<N-1-i; j++) if(grade[j] > grade[j+1]) temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; } i=1 第2趟 j=0 从头开始比较 内存循环for( j=0; j<N-1-i; j++)中 j的取值从0到2 grade[0] 和grade[1]比较 grade[1] 和grade[2]比较 grade[2] 和grade[3]比较 找出次大值放到grade[3]中 85 46 90 71 90 46 16 90 71 90 90 16 公共计算机基础教研部
#define N 5 …… for(i=0; i<N-1; i++) { for(j=0; j<N-1-i; j++) if(grade[j] > grade[j+1]) temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; } i=1 第2趟 46 85 46 71 85 90 85 71 16 90 46 16 85 90 85 71 90 90 16 公共计算机基础教研部
#define N 5 …… for(i=0; i<N-1; i++) { for(j=0; j<N-1-i; j++) if(grade[j] > grade[j+1]) temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; } i=2 第3趟 46 85 71 85 46 16 85 71 90 46 71 71 16 16 90 85 85 71 90 90 16 公共计算机基础教研部
#define N 5 …… for(i=0; i<N-1; i++) { for(j=0; j<N-1-i; j++) if(grade[j] > grade[j+1]) temp = grade[j+1]; grade[j+1] = grade[j]; grade[j] = temp; } i=3 第4趟 16 46 85 71 16 46 46 85 46 90 71 71 71 16 85 46 16 85 90 85 71 90 90 16 公共计算机基础教研部
datatype arrayName[rowsize][colsize]; 6.3 二维数组的定义和引用 6.3.1 定义二维数组 datatype arrayName[rowsize][colsize]; int num[4][2]; 8*sizeof(int) 字节 4 X 2 = 8 公共计算机基础教研部
注意:我们可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组。 例如: int a[3][4]; 可以把a看作是一个一维数组,它有3个元素:a[0]、a[1]、a[2],每个元素又是一个包含4个元素的一维数组。 公共计算机基础教研部
二维数组的存储结构 short a[2][3]; 存放顺序:按行存放 先顺序存放第0行的元素 再存放第1行的元素 a[0][0] 公共计算机基础教研部
下标可以是整型表达式,如 a[2-1][2*2-1] 6.3 二维数组的定义和引用 6.3.2 引用二维数组的元素 二维数组元素的表示形式为: 数组名[下标][下标] 例如: a[2][3] 下标可以是整型表达式,如 a[2-1][2*2-1] 不要写成 a[2,3],a[2-1,2*2-1]形式 数组元素可以出现在表达式中,也可以被赋值 例如:b[1][2]=a[2][3]/2 公共计算机基础教研部
6.3 二维数组的定义和引用 6.3.2 引用二维数组的元素 在使用数组元素时,应该注意下标值应在已定义的数组大小的范围内。 6.3 二维数组的定义和引用 6.3.2 引用二维数组的元素 在使用数组元素时,应该注意下标值应在已定义的数组大小的范围内。 常出现的错误有: int a[3][4]; /* 定义a为3×4的数组 */ ┆ a[3][4]=3; 公共计算机基础教研部
二维数组的输入和输出 只能逐个对数组元素进行操作(字符数组例外) int a[2][3],i,j; 输入方法: 输入第i行第j列元素: scanf(“%d”,&a[i][j]); 输入整个数组元素: for (i=0;i<2;i++) for(j=0;j<3;j++) 输出方法: 输出第i行第j列元素: printf(“%d”,a[i][j]); 输出整个数组元素: for (i=0;i<2;i++) for(j=0;j<3;j++)
如何使两个数组的值相等 如何使两个二维数组的值相等? 通过双重循环赋值 int a[4][2]={1,2,3,4,5,6,7,8}; int b[4][2]; int i,j; for (i=0; i<4; i++) { for (j=0; j<2; j++) b[i][j] = a[i][j]; } 公共计算机基础教研部
6.3 二维数组的定义和引用 6.3.2 二维数组的初始化 可以用下面4种方法对二维数组初始化: 1.分行给二维数组赋初值。 6.3 二维数组的定义和引用 6.3.2 二维数组的初始化 可以用下面4种方法对二维数组初始化: 1.分行给二维数组赋初值。 例如: int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 2.可以将所有数据写在一个花括弧内,按数组排列的顺序对各元素赋初值。 例如:int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 公共计算机基础教研部
3.可以对部分元素赋初值。 例如: int a[3][4]={{1},{5},{9}}; 也可以对各行中的某一元素赋初值,如 int a[3][4]={{1},{0,6},{0,0,11}}; 1 0 0 0 5 6 0 0 0 0 0 0 1 0 0 0 5 0 0 0 9 0 0 0 1 0 0 0 0 6 0 0 0 0 11 0 也可以只对某几行元素赋初值。如: int a[3][4]={{1},{5,6}}; 公共计算机基础教研部
0 0 3 0 0 0 0 0 0 10 0 0 4.如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。 例如:int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};它等价于:int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 在定义时也可以只对部分元素赋初值而省略第一维的长度,但应分行赋初值。 例如:int a[][4]={{0,0,3},{},{0,10}}; 0 0 3 0 0 0 0 0 0 10 0 0 公共计算机基础教研部
6.3 二维数组的定义和引用 错误 int arr[ ][3] = { {1,2,3}, {4,5,6} }; 6.3 二维数组的定义和引用 int arr[ ][3] = { {1,2,3}, {4,5,6} }; int arr[2][ ] = { {1,2,3}, {4,5,6} }; 错误 公共计算机基础教研部
int a[][3]={{1,2,3},{4,5},{6},{0}}; 【例】以下程序的运行结果是什么? main() { int a[][3]={{1,2,3},{4,5},{6},{0}}; printf("%d,%d,%d\n",a[1][1],a[2][1],a[3][1]); } 1 2 3 4 5 0 6 0 0 0 0 0 结果:5, 0, 0 1 2 3 4 5 6 7 0 0 【例】若int a[ ][3]={1, 2, 3, 4, 5, 6, 7}, 则a数组的第一维大小是多少? 公共计算机基础教研部 51
二维数组程序举例 <例> 打印以下形式的数据: main() 1 0 0 0 0 { int a[5][5],i,j; 1 0 0 0 0 2 1 0 0 0 2 2 1 0 0 2 2 2 1 0 2 2 2 2 1 main() { int a[5][5],i,j; for(i=0;i<=4;i++) for(j=0;j<=4;j++) if(i==j) a[i][j]=1; else if(i>j) a[i][j]=2; else if(i<j) a[i][j]=0; for(i=0;i<5;i++) { printf(“\n”); for(j=0;j<5;j++) printf(“%4d”,a[i][j]); } 修改此例 0 0 0 0 1 0 0 0 1 2 0 0 1 2 2 0 1 2 2 2 1 2 2 2 2 给a数组赋值(符合规律的值) 分行输出 公共计算机基础教研部
应用示例: 下列程序的功能是显示如下图形,请填空。 【分析】这类题的元素值排列很有规律,所以一般要从分析行数 i、列数 j与元素值的关系着手。分析下图可知,当 i<j 时的各元素值均为0;而 i>=j时,元素值随行数 i 增加而增加,随列数 j 增加而减小,这样就很容易得出其元素值与 i,j 的关系是 i+1-j。 main() { int a[5][5],i,j; clrscr(); for (i=0;i<5;i++) { for (j=0;j<5;j++) { if ( 【1】 ) a[i][j]=0; else a[i][j]=【2】; printf("%3d",a[i][j]); } printf("\n"); 1 0 0 0 0 2 1 0 0 0 3 2 1 0 0 4 3 2 1 0 5 4 3 2 1 i<j i+1-j a[5][5]分析: a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24 a30 a31 a32 a33 a34 a40 a41 a42 a43 a44
二维数组程序举例 <例>打印输出杨辉三角形 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 main() { int a[6][6],i,j; for(i=0;i<6;i++) a[i][0]=a[i][i]=1; for(i=2;i<=5;i++) for(j=1;j<=i-1;j++) a[i][j]=a[i-1][j-1]+a[i-1][j]; { printf(“\n”); for(j=0;j<=i;j++) printf(“%4d”,a[i][j]); } 二维数组程序举例 <例>打印输出杨辉三角形 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 公共计算机基础教研部
main() { int a[6][6],i,j; for(i=0;i<6; i++) a[i][0]=a[i][i]=1; for(i=2;i<=5;i++) for(j=1;j<=i-1;j++) a[i][j]=a[i-1][j-1]+a[i-1][j]; for(i=0;i<6;i++) { printf(“\n”); for(j=0;j<=i;j++) printf(“%4d”,a[i][j]); } 1 1 1 i=2 i=1 i=2 1 1 2 1 1 i=3 3 3 1 1 a[2][1]=a[1][0]+a[1][1]; 1 1 当i=3时, j可以为1和2 36个随机值
main() { int a[6][6],i,j; for(i=0;i<6; i++) a[i][0]=a[i][i]=1; for(i=2;i<=5;i++) for(j=1;j<=i-1;j++) a[i][j]=a[i-1][j-1]+a[i-1][j]; for(i=0;i<6;i++) { printf(“\n”); for(j=0;j<=i; j++) printf(“%4d”,a[i][j]); } 1 1 1 1 1 2 1 1 3 3 1 4 6 4 1 1 5 10 10 5 1
【例】有一3×4矩阵,编程求其元素最大值并输出其行、列号。 main() { int i,j,x,y,max; int a[][4]={3,5,8,1,6,9,7,12,-6}; max=a[0][0]; for (i=0;i<3;i++) for (j=0;j<4;j++) if (a[i][j]>max) max=a[i][j]; x=i; y=j; } printf("max is a[%d][%d]=%d\n",x,y,max); 3 5 8 1 6 9 7 12 -6 0 0 0 要点:用两重循环遍历所有元素。 【讨论】 如果求最小值? 公共计算机基础教研部
举例 <例> 从键盘输入10名学生的《C程序设计》的考试分数,编程输出最高分。 公共计算机基础教研部
6.4 字符数组 6.4.4 字符串和字符串结束标志 Wang Li 如何让程序存储我的姓名? char a='W'; char b='a'; char c='n'; char d='g'; char e='L'; char f='i'; char name[15]={ 'W', 'a', 'n', 'g', 'L', 'i'}; 用字符数组 用字符串 用若干个字符 公共计算机基础教研部
6.4 字符数组 字符串常量是双引号括起的任意字符序列 "Hello World" "WangPing" "Please enter your full name:" "Hello \"Accp\"" 字符串常量中可以包含转义字符 H e l o W r d \0 字符串结束符 公共计算机基础教研部
h e l l o \0 6.4 字符数组 在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串 104 101 108 108 111 0 内存存放字符ASCII码 在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串 公共计算机基础教研部
6.4 字符数组 6.4.1 定义字符数组 定义方法与前面介绍的类似。例如: char c[10]; c[0]=′I′;c[1]=′ ′;c[2]=′a′; c[3]=′m′;c[4]=′ ′;c[5]=′h′;c[6]=′a′; c[7]=′p′;c[8]=′p′;c[9]=′y′; 公共计算机基础教研部
6.4 字符数组 6.4.2 字符数组的初始化 对字符数组初始化,可逐个字符赋给数组中各元素。 例如: char c[10]={‘I’,’a’,’m’,’h’,’a’,’p’,’p’,’y’} 公共计算机基础教研部
6.4 字符数组 6.4.2 字符数组的初始化 char c[10]={′c′,′ ′,′p′,′r′,′o′, 如果初值个数小于数组长度,则只将这些字符赋给数 组中前面那些元素,其余的元素自动定为’\0’。 char c[10]={′c′,′ ′,′p′,′r′,′o′, ′g′,′r′,′a′,′m′}; 公共计算机基础教研部
6.4 字符数组 6.4.2 字符数组的初始化 char c[]={′I′,′ ′,′a′,′m′,′ ′,′h′, 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。 char c[]={′I′,′ ′,′a′,′m′,′ ′,′h′, ′a′,′p′,′p′,′y′};数组c的长度自动定为10。 公共计算机基础教研部
定义和初始化一个二维字符数组 char diamond[5][5]={{′ ′,′ ′,*′},{′ ′,′*′,′ ′,′*′},{′*′,′ ′,′ ′,′ ′,′*′},{′ ′,′*′,′ ′,′*′},{′ ′,′ ′,′*′}} 公共计算机基础教研部
6.4 字符数组 6.4.3 引用字符数组的元素 <例> 输出一个字符串 #include <stdio.h> <例> 输出一个字符串 I a m b o y 1 2 3 4 5 6 7 8 9 #include <stdio.h> main() { char c[10]={'I',' ','a','m',' ','a',' ','b','o','y'}; int i; for(i=0;i<10;i++) printf("%c",c[i]); printf("\n"); } 公共计算机基础教研部
除了直接在定义时初始化,定义后赋值的方法有: 逐个元素赋值 a[0]=’A’; a[1]=’X’; 如果定义有 char a[10]; 除了直接在定义时初始化,定义后赋值的方法有: 逐个元素赋值 a[0]=’A’; a[1]=’X’; 以及从键盘输入,如scanf ,gets函数等。 公共计算机基础教研部
6.4 字符数组 6.4.5 字符数组的输入/输出 字符数组的输入输出可以有两种方法: 逐个字符输入输出。用格式符“%c”输入或输出一个字符。 将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串的输入输出。 公共计算机基础教研部
char c[]={″China″}; printf(″%s″,c); 例如 在内存中数组c的状态 公共计算机基础教研部
6.4 字符数组 W a n g \0 char name[10]; scanf("%s", name); Wang Li 使用 scanf 时,不能输入空格 printf("%s", name); Wang 格式描述串中使用转换字符串“%s” W a n g \0 公共计算机基础教研部
h e l l o 6.4 字符数组 <例> main( ) { char a[5]={‘H’,’e’,’l’,’l’,’o’}; printf(“%s”,a); } h e l l o 2 3 1 4 结果:Hello#-=* 用“%s”输出时,遇‘\0’结束 <例> main( ) { char a[ ]=“Hello”; printf(“%s”,a); } 结果:Hello 公共计算机基础教研部
6.4 字符数组 main() { char a[]={'h','e','l','\0','l','o','\0'}; <例> main() { char a[]={'h','e','l','\0','l','o','\0'}; printf("%s",a); } 输出:hel h e l \0 l o \0 数组中有多个‘\0’时, 遇第一个结束 公共计算机基础教研部
6.4 字符数组 【例】比较以下字符数组长度是否相同: char a[ ]=”ABCD”; char b[ ]= {“ABCD”}; char c[ ]={‘A’,’B’,’C’,’D’}; 【例】下列程序段的运行结果是: char a[5]={‘a’,’b’, ’\0’,’d’,’\0’}; printf(“%s”,a); 如果 printf(“%s”,a+1);结果是? 说明:%s的作用是输出一个字符串,直到遇到’\0’为止。 公共计算机基础教研部
注意: 在二维数组中,双下标引用——表示某行某列的某个元素 单下标引用——表示某行的字符串 注意: 在二维数组中,双下标引用——表示某行某列的某个元素 单下标引用——表示某行的字符串 【例】分析以下程序的运行结果: main() { char word[3][10]; int i; for (i=0;i<3;i++) scanf("%s",word[i]); printf("%s",word[i-2]); } 运行时,输入: 12345 abcdef ABCDEFG 结果:abcdef word[i]表示第i+1行word元素首地址(二维数组用单下标表示某行的字符串)
6.4 字符数组 6.4.6 字符串处理函数 用字符串处理函数gets/puts输入输出一个字符串 字符串输出函数puts 功能:向显示器输出字符串(输出完,换行) 说明:字符数组必须以‘\0’结束 字符串输入函数gets 格式:gets(字符数组) 功能:从键盘输入一以回车结束的字符串放入字符数组 中, 并自动加‘\0’ 说明:输入串长度应小于字符数组长度 公共计算机基础教研部
W a n g L i \0 char name[10]; gets(name); puts(name); 使用 gets函数允许输入空格 从键盘上读入一个完整的行,存入字符数组name。并用空字符'\0'取代行尾的换行符'\n'。 把字符数组中的字符串输出到显示器。 W a n g L i \0 公共计算机基础教研部
printf("\n 雇员姓名是:%s",name); printf("\n 雇员所属部门是:%s\n",dept); 使用puts函数输出字符串 printf("\n 雇员姓名是: "); puts(name); printf("\n 雇员所属部门是: "); puts(dept); 使用printf函数输出字符串 printf("\n 雇员姓名是:%s",name); printf("\n 雇员所属部门是:%s\n",dept); puts 函数完全可以由 printf 函数取代。 当需要按一定格式输出时,通常使用 printf 函数。 公共计算机基础教研部
示例 main() { char a[10]; gets(a); printf("%s\n",a+2); } 运行程序时,从键盘输入:abc defg 结果:c defg 公共计算机基础教研部
char str[10]; 一次性输入输出 scanf("%s",str); printf("%s",str); gets(str); 不能输入带空格的字符串 scanf("%s",str); printf("%s",str); 可以输入带空格的字符串 gets(str); puts(str); 公共计算机基础教研部
char str[10]; 一次性输入输出 scanf("%s",str); printf("%s",str); gets(str); 空格、回车或跳格(Tab)符作为输入数据的分隔符,因而不能被读入,输入遇到这些字符时,系统认为字符串输入结束 scanf("%s",str); printf("%s",str); gets(str); puts(str); 公共计算机基础教研部
6.4.6 字符串处理函数 字符串连接——strcat函数 strcat(str2, str1); str2必须足够大! H e l l o \0 \0 \0 \0 \0 \0 \0 C h i n a \0 H e l l o C h i n a \0 \0 公共计算机基础教研部
示例 #include "string.h" main() { char a[80]=”AB”,b[80]=”LMNP”; int i=0; strcat(a,b); puts(a); } 结果:ABLMNP 公共计算机基础教研部
6.4.6 字符串处理函数 字符串复制——strcpy函数 strcpy(目的字符串,源字符串); 字符串能否用=整体复制? str2 = str1; strcpy(str2, str1); 注意复制的方向! str2必须足够大! 公共计算机基础教研部
示例 main( ) { char a[ ]="abcde"; char b[10]; b="abcde"; b=a; } /*编译出错*/ 【讨论】编译出错原因何在? a,b都是两个数组定义时分配的内存存储单元首地址,是个常量,不能改变(不能赋值)。 公共计算机基础教研部
示例 #include “string.h” main( ) { char s[10],sp[ ]=”HELLO”; strcpy(s,sp); s[0]=’h’; s[6]=’!’; puts(s); } 【讨论】 结果为什么不是:hELLO! 如果让s[5]=’!’,结果又会如何? 结果: hELLO 公共计算机基础教研部
示例 #include “string.h” main( ) { char s1[20],s2[20 ]=”HELLO”; strcpy(s1, “perfect”); strcpy(s2, s1+3); puts(s1); puts(s2); } 结果: perfect fect 公共计算机基础教研部
#include <string.h> #include <stdio.h> void main() <例> strcpy与strcat举例 T r b o C + 1 2 3 4 5 6 7 8 9 u \0 24 ……. T r b o \0 1 2 3 4 5 6 7 8 9 u 24 ……. …... T r b o 1 2 3 4 5 6 7 8 9 u \0 24 ……. #include <string.h> #include <stdio.h> void main() { char destination[25]; char blank[] = " ", c[]= "C++", turbo[] = "Turbo"; strcpy(destination, turbo); strcat(destination, blank); strcat(destination, c); printf("%s\n", destination); } Turbo C++ 公共计算机基础教研部
示例 #include “string.h” main( ) { char s1[20],s2[20 ]=”HELLO”; strcpy(s1, “perfect”); strcat(s2, s1+3); puts(s1); puts(s2); } 结果: perfect HELLOfect 公共计算机基础教研部
if (strcmp(str2, str1) == 0) 6.4.6 字符串处理函数 字符串比较——strcmp函数 strcmp(字符串1,字符串2); 字符串能否用>,<,==比较大小? if (str2 == str1) if (strcmp(str2, str1) == 0) 公共计算机基础教研部
compare computer 6.4.6 字符串处理函数 字符串比较——strcmp函数 字符串是如何比较大小的? compare computer compare < computer 表示为 strcmp(str1, str2) < 0为真 当出现第一对不相等的字符时,就由这两个字符决定所在字符串的大小,返回其ASCII码比较的结果值 公共计算机基础教研部
示例 #include <string.h> main() { 从键盘输入: int i; BOOK char str[10],temp[10]="Control"; for ( i=0; i<4; i++) gets(str); if(strcmp(temp,str)<0) strcpy(temp,str); } puts(temp); 从键盘输入: BOOK CUT GAME PAGE 结果:PAGE 公共计算机基础教研部
#include <stdio.h> #include <string.h> main() { char username[15],pwd[15]; printf("\n 请输入用户名: " ); gets(username); printf("\n 请输入密码: "); gets(pwd); if((strcmp(username,"John")==0) && (strcmp(pwd,"123456")==0)) printf("\n 您已成功登录 \n "); else printf("\n 用户名和/或密码无效 \n "); } 请输入用户名: john 请输入密码: 123456 用户名和/或密码无效 请输入用户名:John 请输入密码: 123456 您已成功登录 公共计算机基础教研部
6.4.6 字符串处理函数 计算字符串长度——strlen函数 strlen(字符串); 不包括\0的实际字符的个数 char str[10] = {"China"}; printf("%d", strlen(str)); 打印结果是 5,6,还是10? C h i n a \0 \0 \0 \0 \0 不包括\0的实际字符的个数 公共计算机基础教研部
char a[ ]=”\t\r\\\0will\n”; printf(“%d,%d”,sizeof(a),strlen(a)); 以下程序段的运行结果是什么? char a[ ]=”\t\r\\\0will\n”; printf(“%d,%d”,sizeof(a),strlen(a)); 结果:10,3 <例>对于以下字符串,strlen(s)的值为: (1)char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’}; (2)char s[ ]=“\x69\082\n”; 答案:1 1 公共计算机基础教研部
6.4 字符数组 6.4.7 字符数组应用举例 <例> 输入一行字符,统计其中有多少个单词 输入:I am a boy. 预设两个变量:word=0, num=0; 当前字符=空格 是 否 未出现新单词,使word=0,num不累加 前一字符为空格(word==0),新单词出现, word=1,num加1 前一字符为非空格(word==1),未出现新单词,num不变 公共计算机基础教研部
例 输入:I am a boy. 当前字符 是否空格 word原值 新单词开始否 word新值 num值 I a m b o y 是 1 是 1 未 否 是 1 2 否 1 未 2 是 1 未 2 否 是 1 3 是 1 未 3 否 是 1 4 否 1 未 4 否 1 未 4 否 1 未 4 公共计算机基础教研部
输入一字符串给 string i=0 num=0 word=0 当((c=string[i])!=‘\0’) c=空格 真 假 word=0 word=1 num=num+1 i=i+1 输出:num word==0
#include <stdio.h> main() { char string[81]; int i,num=0,word=0; char c; gets(string); for(i=0;(c=string[i])!='\0';i++) if(c==' ') word=0; else if(word==0) { word=1; num++; } printf("There are %d words in the line\n",num); } 公共计算机基础教研部
练习 1. 打印以下形式的数据: 1 4 9 16 25 4 9 16 25 1 9 16 25 1 4 16 25 1 4 9 25 1 4 9 16 2. 从十个数中找出最小数,并将它插在第一个数之前。 公共计算机基础教研部
练习 3. 打印以下形式的数据: 0 0 0 0 1 0 0 0 1 2 0 0 1 2 2 0 1 2 2 2 1 2 2 2 2 4.将一个字符串中所有的空格符删去,例如:原来串a为”abc de fg”,删除后的串a变为”abcdefg”。 5.查找问题。 公共计算机基础教研部