Download presentation
Presentation is loading. Please wait.
Published byΣάπφιρα Παπαϊωάννου Modified 6年之前
1
李祥 E-mail:tom_lx@126.com QQ:100756
2
目录 第八章 数组 1 简单学生成绩管理系统的开发 2 一维数组 3 多维数组 4 字符数组 5 数组作函数参数
3
知识点要求: 技能要求: 教学要求 1 字符数组的定义及引用 2 3 4 1 2 3 一维数组、多维数组的定义、初始化及使用 字符串处理函数
数组作函数参数 技能要求: 1 掌握数组在程序设计中的应用 2 掌握求数组元素最大值、排序等算法 3 理解数组名作函数参数
4
8.1 学生成绩管理系统的开发 任务描述: 开发一个简单的学生成绩管理系统,实现成绩的录入、平均分、最高分、排序与查询等功能。 任务要求:
(1)设计一个菜单界面。 (2)编写inputScore函数,实现学生成绩的录入。 (3)编写averageScore函数,求学生成绩的平均值。 (4)编写maxScore函数,求所有成绩中的最高分。 (5)编写queryScore函数,实现学生成绩的查询。 (6)编写sortScore函数,将学生成绩按从高到低进行排序。
5
8.1 学生成绩管理系统的开发 任务分析: (1)菜单的设计,前面已学习过,请同学先自行完成。
(2)要存储多名学生的成绩,用用前面学过的变量来存储,需要定义大批量的变量,这样会使程序的编写变得复杂。 C语言中引入了一个重要的数据结构—数组,用于解决类似于学生成绩这样大批量的数据处理问题。 (3)所有对成绩的管理其实就是对数组元素进行处理。
6
8.1 学生成绩管理系统的开发 涉及知识点 一维数组的定义 一维数组元素的引用 数组元素的平均值、最大值 数组元素的排序
7
8.2 一维数组 8.2.1一维数组的定义 定义形式: type array_name[n]; 数组名的命名规则和变量名相同 如:
类型符,指每个 元素的数据类型 数组名 常量或常量表达 式,指元素个数 定义形式: type array_name[n]; 数组名的命名规则和变量名相同 如: int a[10]; //定义整型数组a具有10个元素 float b[5]; //定义浮点数数组b具有5个元素 char c[20] //定义字符数组c具有20个元素
8
8.2 一维数组 注意数组元素下标数值的起始: 如: int a[10]; 该数组有10个元素,它们如下: 下标从0开始 下标到9结束
… a[7] a[8] a[9] 下标从0开始 下标到9结束
9
8.2 一维数组 常见的错误: ① float a[0]; //数组大小为0没有意义 ② int b(2)(3); //不能使用圆括号
③ int n=10, a[n]; //不能用变量说明数组大小
10
8.2 一维数组 2.一维数组在内存中的存放 一维数组: float mark[100]; mark[0] mark[1] mark[2]
86.5 92.0 77.5 52.0 94.0 低地址 高地址 每个数组元素占4个字节
11
8.2 一维数组 8.1.2 一维数组的初始化 数组的初始化: 在定义数组时直接给数组元素赋初值。 初始化方法:
从数组的第一个元素开始依次给出初始值表,表中各值之间用逗号分开,并用一对花括号将它们括起来。
12
根据花括号内元素个数系统自动确定中括号内省略的数值为10
8.2 一维数组 根据花括号内元素个数系统自动确定中括号内省略的数值为10 数组初始化的几种不种形式: 1)对全部数组元素赋予初值。如: int ndigit[10]={0,1,2,3,4,5,6,7,8,9}; 等价于: int ndigit[ ]={0,1,2,3,4,5,6,7,8,9}; 经上述初始化后,数组ndigit中的10个元素即ndigit[0]到ndigit[9]的值分别是0到9。
13
8.2 一维数组 数组初始化的几种不种形式: 2)对数组部分元素赋予初值。如: int fibonacci[20]={0,1};
这样数组中的前两个元素为0、1,而后18个元素皆为0。 3)数组元素初值都为0,可写成: int a[10]={0}; 等价于: int a[10]={0,0,0,0,0,0,0,0,0,0};
14
8.2 一维数组 4)字符数组的初始化,可用字符串来代替。如: char pattern[ ]= “the”; //数组大小为4 等同于:
不等同: char pattern[]={‘t’, ‘h’, ‘e’, }; //数组大小为3 注意:在对字符数组初始化时,为使程序能觉察到数组中存放的字符串的末尾,在内部表示中,编译程序要用'\0'来结束这个数组,也就是说字符'\0'是字符串的结束标志,它的ASCII码为0,输出时无内容。从而存储的长度比双引号之间的字符的个数多一个。
15
8.2 一维数组 8.1.3 一维数组元素的引用 引用方式: 数组名[下标] 例如先定义一个一维整型数组a有10个元素:
整型常量或 整型表达式 引用方式: 数组名[下标] 例如先定义一个一维整型数组a有10个元素: int a[10]; 然后对每一个元素即可引用,如: a[1]= 5; a[6]=a[1]+9; printf("%d" , a[6]);
16
8.2 一维数组 注意: 在定义数组并对其中各元素赋值后,就可以引用数组中的元素 只能引用数组元素而不能一次整体调用整个数组全部元素的值。
在引用一个数组元素前应该让该数组元素有确定值,否则引用会得到不确定的数据结果。
17
【例8.1】从键盘输入5个整数,保存到数组a中,再逆序输出。
void main() {int a0,a1,a2,a3,a4; scanf(“%d”,&a0); scanf(“%d”,&a1); scanf(“%d”,&a2); scanf(“%d”,&a3); scanf(“%d”,&a4); printf(“%d\n”,a4); printf(“%d\n”,a3); printf(“%d\n”,a2); printf(“%d\n”,a1); printf(“%d\n”,a0); } void main() { int a[5]; scanf(“%d”,&a[0]); scanf(“%d”,&a[1]); scanf(“%d”,&a[2]); scanf(“%d”,&a[3]); scanf(“%d”,&a[4]); printf(“%d\n”,a[4]); printf(“%d\n”,a[3]); printf(“%d\n”,a[2]); printf(“%d\n”,a[1]); printf(“%d\n”,a[0]); }
18
void main() {int a0,a1,a2,a3,a4; scanf(“%d”,&a0); scanf(“%d”,&a1); scanf(“%d”,&a2); scanf(“%d”,&a3); scanf(“%d”,&a4); printf(“%d\n”,a4); printf(“%d\n”,a3); printf(“%d\n”,a2); printf(“%d\n”,a1); printf(“%d\n”,a0); } void main() {int i, a[5]; for(i=0;i<5;i++) scanf(“%d”,&a[i]); for(i=4;i>=0;i--) printf(“%d”,a[i]); }
19
8.2 一维数组 【例8.2】 求斐波那契数列中前20个元素的值。 Fibonacci 数列公式: 已知: f0 = 0 f1 = 1
fn = fn-1 + fn-2 即:0, 1 , 1 , 2 , 3 , 5 , 8 , 13 ……
20
8.2 一维数组 解题思路: 用简单变量处理,不能在内存中保存这些数。
用数组处理,每个数组元素代表数列中的一个数,依次求出各数并存放在相应的数组元素中。 斐波那契数列可以表示成“F0,F1,F2,…”,其中除F0和F1以外,其他元素的值都是它们前两个元素值之和,即Fn=Fn-2+Fn-1,而F0、F1分别为0和1,这里的0、1、2…即对应数组元素的下标。为此,在程序中说明整型数组fibonacci[20],并依次存放斐波那契数列的前20个元素值。
21
#include <stdio.h>
void main( ) { int fibonacci[20],m,n; fibonacci[0]= 0; fibonacci[1]= 1; for(n=2;n<20;n++) fibonacci[n]=fibonacci[n-2]+fibonacci[n-1]; for(m=0;m<4;++m) //保证按4行输出 for(n=0;n<5;++n) //保证按一行输出5个数据 printf("%-6d",fibonacci[m*5+n]); //每个数据占6列,左靠齐 printf("\n"); //一行输出5个数据后换行 } return ;
22
8.2 一维数组 练习 完成学生成绩管理系统中主菜单函数和inputScore函数、averageScore函数的编写。 提示:
(1)学生人数使用宏来定义,这样便于根据实际情况修改学生的人数。 (2)用一维数组来存储学生的成绩。 (3)由于inputScore函数、averageScore函数都将使用该数组,因此可将一维数组定义为全局变量。
23
8.2 一维数组 【例8.3】 求一维数组中所有元素的最大值及该元素的下标。 解题思路: 采用“打擂台算法”
先找出任一人站在台上,第2人上去与之比武,胜者留在台上 第3人与台上的人比武,胜者留台上,败者下台 以后每一个人都是与当时留在台上的人比武,直到所有人都上台比为止,最后留在台上的是冠军
24
8.2 一维数组 【例8.3】 求一维数组(共10个元素)中所有元素的最小值及该元素的下标。 解题思路: 采用“打擂台算法”
先把a[0]的值赋给变量max max用来存放当前已知的最大值 a[1]与max比较,如果a[1]>max,则表示a[1]是已经比过的数据中值最大的,把它的值赋给max,取代了max的原值 以后依此处理,最后max就是最大的值
25
8.2 一维数组 for i=1 to 9 max=a[i] k=i a[i]>max 真 max=a[0] 输出:max,k 假
26
8.2 一维数组 记行号 记最大值 练习:完成maxScore函数的编写。 …… int i, k=0,max;
int a[10]={1,5,3,7,8,9,-2,4,1,-1}; max=a[0]; for (i=1;i<=9;i++) if (a[i]>max) { max=a[i]; k=i;} printf("max=%d\nk=%d\n",max,k); 记行号 练习:完成maxScore函数的编写。 记最大值
27
8.2 一维数组 【例8.4】从键盘任意输入10个数,按从小到大的顺序重新排列,然后输出。 对数排序的方法有多种,在这介绍两种: 冒泡法排序
选择法排序
28
8.2 一维数组 方法一:冒泡法(从小到大) 算法总体思想: 将每相邻的两个数进行两两比较,将小的数调到前面。 具体步骤见如下实例:
29
for(i=0;i<5;i++) if (a[i]>a[i+1]) { t=a[i];a[i]=a[i+1];a[i+1]=t; } a[0] a[1] a[2] a[3] a[4] a[5] 9 8 5 4 2 8 9 5 4 2 8 5 9 4 2 8 5 4 9 2 8 5 4 2 9 8 5 4 2 9 大数沉淀,小数起泡
30
for(i=0;i<4;i++) if (a[i]>a[i+1]) { t=a[i];a[i]=a[i+1];a[i+1]=t; } a[0] a[1] a[2] a[3] a[4] a[5] 8 5 4 2 9 5 8 4 2 9 5 4 8 2 9 5 4 2 8 9 5 4 2 8 9
31
for(i=0;i<3;i++) if (a[i]>a[i+1]) { t=a[i];a[i]=a[i+1];a[i+1]=t; } a[0] a[1] a[2] a[3] a[4] a[5] 5 4 2 8 9 4 5 2 8 9 4 2 5 8 9 4 2 5 8 9
32
for(i=0;i<2;i++) if (a[i]>a[i+1]) { t=a[i];a[i]=a[i+1];a[i+1]=t; } a[0] a[1] a[2] a[3] a[4] a[5] 4 2 5 8 9 2 4 5 8 9 2 4 5 8 9
33
for(i=0;i<1;i++) if (a[i]>a[i+1]) { t=a[i];a[i]=a[i+1];a[i+1]=t; } 2 4 5 8 9 a[0] a[1] a[2] a[3] a[4] a[5] 2 4 5 8 9
34
…… for(i=0;i<5;i++) if (a[i]>a[i+1]) { ……} for(i=0;i<4;i++)
for(j=0;j<5;j++) for(i=0;i<5-j;i++) if (a[i]>a[i+1]) { ……} …… for(i=0;i<1;i++) if (a[i]>a[i+1]) { ……}
35
int a[10]; int i,j,t; printf("input 10 numbers :\n"); for (i=0;i<10;i++) scanf("%d",&a[i]); for(j=0;j<9;j++) for(i=0;i<9-j;i++) if (a[i]>a[i+1]) {t=a[i];a[i]=a[i+1];a[i+1]=t;} printf("the sorted numbers :\n"); for(i=0;i<10;i++) printf("%d ",a[i]); printf("\n");
36
8.2 一维数组 方法二:选择法 算法思想是:(考虑10 个数)
先将10个数中最小的数与a[0]对换;再将a[1]到a[9]中最小的数与a[1]对换……每比较一轮,找出一个未经排序的数中最小的一个 共比较9轮
37
a[0] a[1] a[2] a[3] a[4] 小到大排序
38
程序段如下: int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(array[j]<array[k]) k=j; t=array[k]; array[k]=array[i]; array[i]=t; } 找最小值的下标
39
8.2 一维数组 练习: 选择一种排序算法,完成学生成绩管理系统中sortScore函数的编写。
40
8.2 一维数组 【例8.5】将十进制数转换成以指定数为基数的等值数。 解题思路: 指定基数的变化范围为2~16。
定义整型数组c存放变换结果,考虑到一些机器中以2为基数的长整数可达32位长度,与此相应的数组c的长度也被规定为32位。 数组c中存放转换结果,而且排列次序从低位到高位,在显示转换结果时则应从高位到低位。 在显示转换结果时,如果某一位的值在10~15范围内,则应显示英文字符’A’~’F’。
41
#include<stdio.h>
void main() {int d,r,c[32],i=0; printf("请输入十进制数:"); scanf("%d",&d); printf("请输入要转换的进制:"); scanf("%d",&r); do {c[i]=d%r;i++; d=d/r;} while(d!=0); printf("转换以后的数是:"); for (i--;i>=0;i--) if (c[i]<=9) printf("%d",c[i]); Else printf("%c",c[i]+55); return ; }
42
8.2 一维数组 思考题: 题目:把一个整数依序插入已排序的数组中,设数组已按从小到大的顺序排列。 如:定义a数组并进行初始化。
int a[10]={2,4,6,8,10,12,16,18,20}; 要求:通过键盘输入一个数9,按顺序插入到 数组中,数组元素输出: 2,4,6,8,9,10,12,16,18,20
43
8.2 一维数组 练习: 完成queryScore函数的编写,实现学生成绩的查询。 任务要求: (1)从键盘录入要查询的成绩。
(2)若存在1个以上的数组元素和要查找的成绩相同,则只输出第一个找到的元素在数组中的下标。 (3)若没有成绩和要查找的成绩相同,则输出“没有找到”信息。
44
8.3 多维数组 项目改进:基于二维数组的多门课程成绩管理系统的开发 任务描述 编写inputScore2函数,实现固定数量学生的成绩录入。
任务要求: (1)为简单起见,本任务要求将学生数量固定为3个,课程数量固定为4门。 (2)录入时,要求可以逐个学生逐门课进行录入。
45
8.3 多维数组 项目改进:基于二维数组的多门课程成绩管理系统的开发 解题思路: (1)定义一个用于存放学生成绩的二维数组;
(2)对于每个学生(外层循环),依次录入其4门课的成绩(内层循环)。 需解决的问题: 如何定义二维数组以及如何对二维数组进行遍历?
46
8.3 多维数组 任务实施 #include<stdio.h> int score[3][4];
void inputScore() { int i, j; //变量i代表行下标,j代表列下标 for(i = 0; i < 3; i ++) //遍历数组的每一行,依次处理每个学生 { printf("第%d个学生:\n", i+1); for(j = 0; j < 4; j++) { printf("输入第%d门课成绩:",j+1); scanf("%d", &score[ i ][ j ]); }
47
8.3 多维数组 二维数组的定义 类型说明符 数组名[常量表达式1][常量表达式2]; 如:int x[3][2];
类型说明符 数组名[常量表达式1][常量表达式2]; 列数 数组类型 行数 如:int x[3][2]; 表示x是二维数组,它有3行2列,x数组中的每个元素都具有整数类型。 x[0][0] x[0][1] 第一行 x[1][0] x[1][1] 第二行 x[2][0] x[2][1] 第三行
48
8.3 多维数组 二维数组元素的引用形式: 数组名 [下标][下标] 如: int b[4][5]; b[1][2]= a[2][3]/2;
整型常量或 整型表达式 二维数组元素的引用形式: 数组名 [下标][下标] 如: int b[4][5]; b[1][2]= a[2][3]/2; 注意: 下标值不能超出定义的范围。
49
8.3 多维数组 ① 给全部元素赋初值 二维数组的初始化 类型说明符 数组名[常量1][常量2]={初始化数据}; a)分行赋初值
如:int y[3][4]={{1,3,5,7},{2,4,6,8},{3,5,7,9}}; b)不分行 如:int a[3][4]={1,3,5,7,2,4,6,8,3,5,7,9}; 第二维长度 不能省略!
50
8.3 多维数组 ② 给部分元素赋初值 二维数组的初始化 如:int y[4][3]={{1},{2},{3},{4}};
int y[3][4] ={ {1},{5,6} }; 这些数据在内存中如何存放呢???
51
8.3 多维数组 二维数组元素在内存中的存储形式: 二维数组元素在内存中按行序优先存储,即当按照存储顺序存取元素时,最右边的下标变化最快 。
int a[3][4];
52
例如:int a[3][3]={ {1,2,3}, {4,5,6}, {7,8,9} };
地址 值 数组元素 3000H 3002H 3004H 3006H 3008H 300AH 300CH 300EH 3010H a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] a[2][0] a[2][1] a[2][2] 1 2 3 4 5 6 789
53
8.3 多维数组 注意:可把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组。 例如:int a[3][4];
a[0]、a[1]、a[2],每个元素又是一个包含4个元素的一维数组。
54
8.3 多维数组 三维数组的定义 如:int w[4][5][6];
类型说明符 数组名[常量表达式1][常量表达式2][常量表达式2] 如:int w[4][5][6]; 定义w是三维数组,其各维长度分别是4、5、6,数组的下标也是最右边的先变。
55
8.3 多维数组 【例8.6】将年月日转换成一年中的第几天。 解题思路:
把某月某日转换为这年的第几天,要考虑该年是否为闰年,由于二月份的天数因闰年和非闰年而异。把每月的天数存放在数组day_tab[2][13],其中day_tab [0][1-12]是非闰年各月的天数,数组中[1][1-12]是闰年各月的天数。
56
【例8.6】程序代码 #include <stdio.h> day_of_year(int year, int month, int day) { int i,leap; static int day_tab[2][13]= {{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; leap=(year%4==0&&year%100!=0|| year%400==0); // 闰年时leap=1,否则leap=0 for(i=0;i<month;++i) day+=day_tab[leap][i]; return(day); }
57
printf("input year,month,day: ");
【例8.6】程序代码 void main( ) { int year,month,day; printf("input year,month,day: "); scanf("%d,%d,%d" ,&year,&month,&day); printf("%d\n" ,day_of_year(year,month,day)); return ; }
58
8.3 多维数组 思考: 将一个二维数组行和列元素互换,存到另一个二维数组中。 即行变列,列变行:
a= 1 4 2 5 3 6 b= 即行变列,列变行: a[i][j]→b[j][i] (0≤i<2 0≤j<3)
59
8.3 多维数组 二维数组使用说明: 二维数组可以较方便地处理矩阵数据。
通常把二维数组理解成一个具有多行(第一维数值决定行数),每行上又有多列(第二维决定列数)的一个二维矩阵阵列。 也可以把二维数组想象成是一个一维数组(元素的个数由第一维决定),每个元素又是一个包含有多个元素的一维数组(元素的个数由第二维决定)。 二维数组元素的引用通常与一个双重循环有关,外层循环用来控制访问行,内层循环用来控制访问列。
60
8.3 多维数组 项目完善: 开发一个基于二维数组的多门课程成绩管理系统,实现多个学生多门课程成绩的录入、平均分、最高分、查询等功能。
任务要求: (1)设计一个菜单界面。 (2)编写inputScore2函数,实现学生成绩的录入。(已实现) (3)编写averageScore2函数,可按用户要求计算某门课程的平均成绩或某个学生所有课程的平均成绩。 (4)编写maxScore2函数,求出所有成绩中最高分。(二维数组所有元素求最大值)
61
8.4 字符数组 8.3.1 字符数组的定义与引用 字符数组:用来存放字符的数组称为字符数组。 用一个一维字符数组可以存放一个字符串;
用一个二维字符数组可以存放多个字符串, 由于二维字符数组的每一个元素都是一个字符串,所以二维字符数组也称为字符串数组。
62
8.4 字符数组 字符数组定义的一般格式: char 数组名[字符串数量][字符串最大长度]
说明: [字符串数量]部分如果没有,则表示只定义了一个一维字符数组。 例如: char str[4][10]; str有4个字符串,分别是str[0]、str[1]、str[2]、str[3],每个字符串的最大长度为9个字符,每个字符串最后一个下标变量存放'\0',它是空字符,对应的ASCII码为0,输出无内容,代表字符串结束。
63
8.4 字符数组 字符数组的初始化: 字符数组的初始化可按行进行。例如:
char str[4][10]={“Turbo C”, “Microsoft”, "FORTRANIV","PASCAL"}; 也可以使用赋值语句,例如给第一个字符串赋值: str[0][0]='T'; str[0][1]='u'; str[0][2]='r'; str[0][3]='b'; str[0][4]='o'; str[0][5]=' ';//空格字符 str[0][6]=‘C’; str[0][7]=‘\0’; 除初始化不允许对字符数组整体赋值。如下是错误的: str[0]="Turbo C";
64
8.4 字符数组 以下字符串的存放形式: char str[4][10]={“Turbo C”, “Microsoft”,
"FORTRANIV","PASCAL"}; T u r b o c \0 M i s f t F O R A N I V P S C L
65
8.4 字符数组 8.3.2 字符串处理函数 1. puts函数 形式: puts (字符数组/字符串常量)
作用:将一个字符串(以'\0'结束的字符序列)输出到显示器。
66
8.4 字符数组 puts函数输出的字符串中可包含转义字符: 例如:
static char str[]={"China\nBeijing″}; puts(str); 输出结果: China Beijing
67
8.4 字符数组 2. gets函数 形式:gets(字符数组)
作用:从终端输入一个字符串到字符数组,并且得到一个函数值,该函数值是字符数组的起始地址。函数调用如下: gets(str) 注意: 用puts和gets函数只能输入或输出一个字符串,不能写成: puts(str1,str2)或gets(str1,str2)。
68
8.4 字符数组 注意:使用以下字符串函数时,在程序开头用 #include <string.h> 3. strcat函数
作用:连接两个字符数组中的字符串,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。
69
8.4 字符数组 例如: char str1[30]={″People’s Republic of ″};
要足够大 例如: char str1[30]={″People’s Republic of ″}; char str2[]={″China″}; print(″%s″,strcat(str1,str2)); 输出: People′s Republic of China str1
70
8.4 字符数组 4. strcpy函数 形式:strcpy(字符数组1,字符数组2/字符串) 作用:将字符串2复制到字符数组1中。 例如:
static char str1[10],str2[]={“ China”}; strcpy(str1,str2); 执行后,str1的内容与str2相同:
71
8.4 字符数组 关于strcpy函数,要注意以下几点:
(1) 字符数组1必须定义得足够大,以便容纳被拷贝的字符串。字符数组1的长度不应小于字符串2的长度。 (2) 字符数组1必须写成数组名形式(如str1),“字符串2”可以是字符数组名,也可以是一个字符串常量。如 strcpy(str1, "China") (3) 拷贝时连同字符串后面的'\0'一起拷贝到字符数组1中。
72
8.4 字符数组 关于strcpy函数,要注意以下几点:
(4) 不能用赋值语句将一个字符串常量或字符数组直接赋给一个字符数组。如下面的赋值是不合法的: str2={"China"}; str1=str2; 如果用赋值语句,只能将一个字符赋给一个字符型变量或字符数组元素。如下面是合法的: char a[4],c1; c1='A'; a[0]='C';a[1]='h';a[2]='i';
73
8.4 字符数组 关于strcpy函数,要注意以下几点:
strcpy(str1,str2,2); 作用是将str2中前面2个字符拷贝到str1中去。
74
8.4 字符数组 5. strcmp函数 形式:strcmp (字符串1,字符串2) 作用:比较两个字符串的大小。 例如:
strcmp(str1,str2); strcmp(″China″,″Korea″); strcmp(str1,″Beijing″);
75
8.4 字符数组 比较的结果由函数值带回: (1) 字符串1==字符串2,函数值为 0 ;
(2) 字符串1>字符串2,函数值为 1 ; (3) 字符串1<字符串2,函数值为-1 。 注意:两个字符串比较,不能用以下形式: if(str1==str2) printf(″yes″); 只能用以下形式: if(strcmp(str1,str2)==0) printf(″yes″);
76
8.4 字符数组 6. strlen函数 形式:strlen (字符数组/字符串常量) 作用:测试字符串的长度。
函数值:字符串的实际字符个数(不包括′\0′)。如: static char str[10]={"China"}; printf("%d",strlen(str)); 输出结果不是10,也不是6,而是5。也可以直接测字符串常量的长度,如: strlen("China")
77
8.4 字符数组 7. strlwr函数 形式:strlwr (字符串) 作用:将字符串中大写字母换成小写字母。 8. strupr函数
作用:将字符串中小写字母换成大写字母。
78
8.4 字符数组 练习: 1.有一篇文章,共有3行文字,每行有80个字符,要求分别统计出其中英文大写字母、小写字母、数字、空格以及其他字符的个数。 2.从键盘输入一个字符串,删除其中的字母 a后输出。例如,输入字符串“abcaca”,输出 bcc。
79
8.5 数组作函数参数 数组作为函数参数时有两种形式: 数组元素作为函数的参数 数组名作为函数参数
80
8.5 数组作函数参数 8.5.1数组元素作函数参数 数组元素作为函数参数时,只是将该数组元素的值传给形参,以后形参的值有无变化和实参数组元素无关,即不影响实参数组元素,可以看作是一种单向传递。在使用时同普通变量作参数一样注意形参与实参类型的一致或兼容。
81
8.5 数组作函数参数 【例8.7】求部分数组元素的和 #include <stdio.h>
int fun(int i,int j,int k) { int sum; sum=i+j+k; i++; //i变化不会影响实参a[1] j++; //j变化不会影响实参a[2] k++; //k变化不会影响实参a[3] return(sum); }
82
8.5 数组作函数参数 void main( ) { static int a[5]={1,3,5,7,9}; int y;
y=fun(a[1],a[2],a[3]); //仅将a[1],a[2],a[3]的值传给形参i、j、k printf("%d\n" ,y); for (i=0;i<5;i++) printf("%d ",a[i]); return ; }
83
8.5 数组作函数参数 数组名作函数参数 数组名作函数参数时,是将实参数组的起始地址传递到被调函数对应的形参中,也就是说形参数组的起始地址和实参数组的起始地址是相同值,那么形参数组和实参数组就共用相同的存储空间,以后对形参数组元素的使用就是对实参数组元素的使用,即形参数组元素的变化会影响到实参数组元素,可以把这种传递看作是双向传递。
84
8.5 数组作函数参数 【例8.8】 有一个一维数组score,内放10个学生成绩,求平均成绩。 解题思路:
(1)用函数average求平均成绩,用数组名作为函数实参,形参也用数组名 (2)在average函数中引用各数组元素,求平均成绩并返回main函数
85
#include <stdio.h> int main() { float average(float array[10]); float score[10],aver; int i; printf("input 10 scores:\n"); for(i=0;i<10;i++) scanf("%f",&score[i]); printf("\n"); aver=average(score); printf("%5.2f\n",aver); return 0; } 定义实参数组
86
定义形参数组 float average(float array[10]) { int i; float aver,sum=array[0]; for(i=1;i<10;i++) sum=sum+array[i]; aver=sum/10; return(aver); } 相当于score[0] 相当于score[i]
87
8.5 数组作函数参数 几点说明: 1、用数组名作函数参数,应该在主调函数和被调函数分别定义数组。
2、实参与形参类型必须一致,如不一致,则出错。 3、在定义average函数时,声明数组的大小为10,但在实际上,指定其大小是不起任何作用的。 4、形参数组可以不指定大小,在定义数组时在数组名后面跟一个空的方括号,可再设一个形参,传递数组元素的个数。
88
8.5 数组作函数参数 强调: 数组名作参数时,不是把数组元素的值传递给形参,而是把实参数组的起始地址传递给形参数组,这样两个数组共占同一段内存,这与变量做函数参数的情况不相同的。 score[0] score[1] score[2] score[3] score[4] score array array[2] array[4] array[0] array[1] array[3]
89
8.5 数组作函数参数 在实际应用中,实参也可以是数组中某元素的地址 【例8.9】用函数sum_array( )求n个数之和
int sum_array(int a[],int n) { int i,total; for(i=0,total=0;i<n;i++) total+=a[i]; return total; }
90
8.5 数组作函数参数 调用函数sum_array( ),如有以下变量定义: int x[]={1,2,3,4,5}; int i,j;
则语句: i=sum_array(x,5); j=sum_array(&x[2],3); printf("i=%d\nj=%d\n",i,j); 将输出: i=15 j=12
91
8.5 数组作函数参数 实参传递给形参(数组)的是数据表开始地址,函数对形参数组元素的访问就是对实参数组元素的访问。如有必要,函数可以改变实参数组元素的值。 如: void init_array(int a[],int n,int val) { int i; for(i=0;i<n;i++) a[i]=val; } 如有以下数组定义: int a[10],b[100]; 以下语句的功能? init_array(a,10,1); init_array(b,100,2); 网络工程 12.3
92
8.5 数组作函数参数 练习: 编写一个函数mystrcpy(),将一个字符串中的元音字母复制到另一个字符串,然后在主函数中输出。
题目分析: (1)定义两个字符数组分别用来存放原字符串和元音字母字符串。 (2)函数的原型为: void mystrcpy(char a[ ],char b[ ])
93
8.5 数组作函数参数 项目完善 将简单学生成绩管理系统中存放学生成绩的全局数组改用局部数组,改用数组名作函数参数的形式实现。
94
8.5 数组作函数参数 8.5.3 多维数组作函数参数 当形参数组是多维数组时,除形参数组的第一维大小说明可省略外,其他维的大小必须明确指定。
95
8.5 数组作函数参数 函数sumatob()用于求一个有10列的二维数组各行10个元素之和并存于另一个数组中。
void sumatob(int a[][10],int b[],int n) { int i,j; for(i=0;i<n;i++) for(b[i]=0,j=0;j<10;j++) b[i]+=a[i][j]; }
96
8.5 数组作函数参数 【例8.10】编写函数yanghui,输出如下杨辉三角形。
提示:杨辉三角形的特点是第i行有i个数字,每行的第一个、最后一个数均为1,其余每一个数正好等于它一行的同一列和前一列数之和。 函数的原型为:void yanghui(int a[][N])
97
8.5 数组作函数参数 项目改进 将基于二维数组的多门课程成绩管理系统中存放学生成绩的全局数组改用局部数组,改用多维数组作函数参数的形式实现。
98
重点: 难点: 本章小结 1 2 3 1 2 数组的定义及数组元素的使用 求数组元素的最大值、排序等算法 数组作为函数参数 字符数组的应用
数组作为函数的参数
99
本章结束!
Similar presentations