第四章 数组和函数Word格式.docx
《第四章 数组和函数Word格式.docx》由会员分享,可在线阅读,更多相关《第四章 数组和函数Word格式.docx(41页珍藏版)》请在冰点文库上搜索。
i<
10;
i++)/*此循环语句用来对数组元素逐个赋值*/
a[i]=i;
/*将循环变量i的值赋值给a[i]*/
i++)/*此循环语句用来逐个输出数组元素的值*/
printf("
a[%d]=%d\n"
i,a[i]);
/*双撇号里除了%d外均为普通字符原样输出*/
}
程序分析与解释:
本程序实现的功能是在程序运行过程中对数组a中的元素赋值,然后逐个输出数组元素的值。
运行结果如图4-1所示。
图4-1程序运行结果
4.1.3一维数组的初始化
1.定义数组的同时对全部数组元素初始化。
此时可以不用指明数组的长度。
定义一个含有10个元素的int型数组a,并对其全部元素赋初值:
inta[10]={0,1,2,3,4,5,6,7,8,9};
或者
inta[]={0,1,2,3,4,5,6,7,8,9};
经过初始化后,a[0]=0,a[1]=1,a[2]=2,a[3]=3,a[4]=4,
a[5]=5,a[6]=6,a[7]=7,a[8]=8,a[9]=9。
2.定义数组的同时对部分数组元素初始化。
此时必须指明数组元素的长度。
定义了一个含有5个元素的int型数组a,并只对其前3个元素赋初值,后2个元素值为0。
inta[5]={1,2,3};
经过初始化后,a[0]=1,a[1]=2,a[2]=3,a[3]=0,a[4]=0。
4.1.4一维数组程序举例
【例4-2】输入一组学生的成绩,统计成绩的最高分、最低分和平均分。
floatscore[10],max,min,avg,sum;
inti;
/*定义循环变量i*/
printf("
inputtenpoints:
"
);
i++)/*对数组元素赋值,即输入成绩*/
{
scanf("
%f"
&
score[i]);
}
/*假设a[0]既是最大值又是最小值,sum初值为a[0]*/
max=min=sum=score[0];
for(i=1;
i++)/*从下标1开始提取数组元素的值*/
sum=sum+score[i];
/*数组元素的值逐个相加*/
if(score[i]>
max)/*找出最高分*/
max=score[i];
if(score[i]<
min)/*找出最低分*/
min=score[i];
avg=sum/10;
/*计算平均分*/
printf("
max=%f\nmin=%f\navg=%f"
max,min,avg);
定义一个一维整型数组score,数组的长度为10,用来存放10个同学单科的成绩。
其中,max表示最高分,min表示最低分,avg表示平均分,sum表示总分。
假设数组元素a[0]既是最大值用max表示,又是最小值用min表示,每次从数组中提取一个元素分别和max、min比较,如果值比max大则赋值给max,如果比min小就赋值给min。
运行结果如图4-2所示:
图4-2程序运行结果
4.2二维数组
二维数组的数组元素可以看作是排列为行列的形式(矩阵)。
二维数组也用统一的数组名来标识,第一个下标表示行,第二个下标表示列。
下标均从0开始。
二维数组可以看作是数组元素为一维数组的数组。
4.2.1二维数组的声明
声明二维数组的一般格式如下:
类型说明符数组名[下标1][下标2];
inta[2][3];
/*表示声明了一个有2行3列的二维数组a*/
✧元素下标应为整型常量或整型表达式。
✧二维数组定义中的第1个下标表示该数组具有的行数,第2个下标表示该数组具有的列数,两个下标之积是该数组具有的数组元素的个数。
✧二维数组的存放规律是“按行排列”。
即先存放第一行的元素,再存放第二行的元素。
✧二维数组中的每个数组元素的数据类型均相同。
4.2.2二维数组的引用
二维数组引用的一般格式如下:
二维数组名[下标1][下标2]
声明一个2行3列的二维数组。
此时,共有2×
3=6个数组元素。
元素分别是:
a[0][0],a[0][1],a[0][2],a[1][0],a[1][1],a[1][2]
4.2.3二维数组的初始化
1.分行给二维数组所有元素赋初值。
inta[2][3]={{1,2,3},{4,5,6}};
经过初始化后,
a[0][0]=1,a[0][1]=2,a[0][2]=3,A[1][0]=4,a[1][1]=5,a[1][2]=6。
2.不分行给二维数组所有元素赋初值。
inta[2][3]={1,2,3,4,5,6};
3.给二维数组所有元素赋初值,二维数组第一维的长度可以省略,但第二维的长度不能省。
inta[][3]={1,2,3,4,5,6};
等价于:
4.对部分元素赋初值
inta[2][3]={{1,2},{4}};
a[0][0]=1,a[0][1]=2,a[0][2]=0,A[1][0]=4,a[1][1]=0,a[1][2]=0。
4.3.4二维数组的应用
【例4-3】假设有三个同学,每个同学均选修了四门课程,统计出计算每个同学的平均分。
inta[3][4],i,j,sum=0;
floatavg;
/*初始化数组,每行存放一个学生的成绩,共3行*/
3;
i++)
for(j=0;
j<
4;
j++)/*该行中的每列存放一门成绩*/
scanf("
%d"
a[i][j]);
for(j=0;
j++)/*统计该学生的总成绩*/
sum=sum+a[i][j];
avg=sum/4.0;
/*计算该学生的平均分*/
avg%d=%f\n"
i,avg);
/*该学生的平均分输出后总成绩清零,继续统计下一个同学的总分*/
sum=0;
本程序中定义了一个3行4列的数组a,每一行存放一个同学的成绩,每一行中的4列分别存放该同学的4门课程的成绩。
循环变量i用来控制行数,循环变量j用来控制列数。
运行结果如图4-3所示:
图4-3程序运行结果
4.3字符型数组
存放字符型数据的数组我们称为字符型数组。
其中每个数组元素存放的值都是单个字符。
4.3.1字符型数组的声明
字符数组的定义与前面介绍的数值数组相同,只是数据类型为char。
charc[10];
/*声明一个char型数组c,由10个元素组成*/
4.3.2字符型数组的引用
引用方法与前面介绍的相同。
定义字符数组c,数组长度是5。
charc[5];
/*5个元素分别是c[0],c[1],c[2],c[3],c[4]*/
【例4-4】从键盘输入字符对字符数组赋值。
charc[5];
inti;
/*每循环一次,从键盘输入一个字符赋值给数组元素c[i]*/
5;
scanf("
%c"
c[i]);
i++)/*逐个输出数组元素的值*/
printf("
c[%d]=%c\n"
i,c[i]);
程序在运行过程中对数组元素赋值,并逐个输出数组元素的值。
输出格式如图4-4所示。
图4-4程序运行结果
4.3.3字符型数组的初始化
1.定义数组的同时对全部元素赋初值。
此时可以不用指定数组的长度。
定义一个字符型数组c,由5个元素组成,并对其全部元素赋初值。
charc[5]={‘H’,’e’,’l’,’l’,’o’};
或
charc[]={‘H’,’e’,’l’,’l’,’o’};
经过初始化后,c[0]=’H’,c[1]=’e’,c[2]=’l’,c[3]=’l’,c[4]=’o’。
2.定义数组的同时对部分元素赋初值。
此时必须指明数组的长度。
则未被赋值的元素自动定为空字符,即’\0’。
charc[5]={‘y’,’e’,’s’};
经过初始化后,c[0]=’y’,c[1]=’e’,c[2]=’s’,c[3]=’\0’,c[4]=’\0’。
4.3.4字符串
C语言没有提供字符串变量(存放字符串的变量),对字符串的处理常常采用字符数组实现。
C语言规定以在字符数组中加以’\0’(ASCII码为0的字符)作为字符串结束标志。
字符串结束标志占用一个字节。
它不执行任何操作。
可以用字符串的方式对数组作初始化赋值。
charc[6]={‘H’,’e’,’l’,’l’,’o’,’\0’};
可写为:
charc[6]={"
Hello"
};
或去掉{}写为:
charc[6]="
;
经过初始化后,c[0]=’H’,c[1]=’e’,c[2]=’l’,c[3]=’l’,c[4]=’o’,c[5]=’\0’。
字符数组c在内存中占用空间6个字节,如图4-4所示:
H
e
l
o
\0
图4-4字符数组c的存储
而在数组s中:
chars[]={‘H’,’e’,’l’,’l’,’o’};
字符数组s在内存中占用空间5个字节,如图4-5所示:
O
图4-5字符数组s的存储
✧用字符串方式赋值比用字符逐个赋值要多占一个字节,用于存放字符串结束标志’\0’。
4.3.5字符串的输入输出
1.以字符常量的形式对字符数组进行输入输出,使用格式符“%c”,此时系统不会自动在最后一个字符后加’\0’。
参见例4.3。
2.以字符串的形式对字符数组进行输入输出。
采用“%s”格式符来实现。
chars1[]=”Hello”;
此时系统会自动在最后一个字符后加’\0’。
字符数组s1在内存中的占用空间6个字节,如图4-6所示:
图4-6字符数组s1的存储
输出以上字符数组s1:
printf(“%s”,s1);
输出结果为:
Hello
✧字符串结束标识符号’\0’不输出。
✧格式化输入输出字符串,输入输出项是要求字符数组的首地址,即字符数组名。
scanf(“%s”,c);
从键盘输入:
字符数组c存放的字符串为’’Hello”,此时系统自动在最后一个字符后面加入’\0’。
✧按照%s格式格式化输入字符串时,输入的字符串中不能有空格(空格,Tab),否则空格后面的字符不能读入,scanf函数认为输入的是两个字符串。
charc[20];
HelloWorld
此时字符数组c存放的字符串为”Hello”,而不是字符串”HelloWorld”。
4.3.6字符串常用函数
C语言为我们提供了丰富的字符串处理函数。
下面介绍几种常用的字符串处理函数。
1.字符串输出函数puts
格式:
puts(字符数组名);
功能:
从字符数组的起始地址开始,依次将存储单元中的字符输出到控制台,直到遇到字符串结束标志(’\0’)为止。
charc[10]=”Hello”;
puts(c);
输出:
2.字符串输入函数gets
gets(字符数组名);
从键盘输入一个字符串(可包含空格),直到遇到回车符,并将字符串存放到指定的字符数组中。
gets(c);
此时,字符数组c中存放的字符串是”Hello”。
3.判断字符串的长度的函数strlen
strlen(字符数组名或字符串常量)
统计字符串的长度(不包括“字符串结束标志\0”),并将其作为函数值返回。
printf(“%d”,strlen(c));
输出结果:
5
4.字符串连接函数strcat
strcat(s1,s2)
将s2为首地址的字符串连接到s1字符串的后面。
从s1原来的’\0’(字符串结束标志)处开始连接。
注意s1要有足够的存储控件,以确保连接字符串后不越界。
chars1[20]="
s2[6]="
World"
strcat(s1,s2);
HelloWorld
5.字符串复制函数strcpy
strcpy(s1,s2)
将s2为首地址的字符串复制到s1为首地址的字符数组中。
注意s1要有足够的存储空间,以确保复制字符串后不越界。
chars1[20]="
strcpy(s1,s2);
%s"
s1);
输出结果为:
World
6.字符串比较函数strcmp(s1,s2)
strcmp(s1,s2)
将s1,s2为首地址的两个字符串进行比较,比较的结果由返回值表示。
当s1==s2,函数的返回值为:
0;
当s1<
s2,函数的返回值为:
负整数;
(绝对值是ASCII码的差值)
当s1>
正整数;
字符串之间的比较规则:
从第一个字符开始,对两个字符串对应位置的字符按ASCII码的大小进行比较,直到出现出现第一个不同的字符,即由这两个字符的大小决定其所在串的大小。
printf("
strcmp(s1,s2));
-15
7.字符串大小写转换函数
strlwr(字符串)
strupr(字符串)
strlwt函数的功能是将字符串中的所有大写字母转换为小写字母。
Strupr函数的功能是将字符串中的所以小写字母转换为大写字母。
%s\n"
strlwr("
));
strupr("
hello
HELLO
4.3.7字符串应用实例
【例4-5】由键盘任意输入一个字符串和一个字符,要求从该字符串中删除所指定的字符。
程序如下:
#include<
stdio.h>
chars1[100],c1;
inti,j;
gets(s1);
/*读入一个字符串,赋值给字符数组s1*/
delete?
/*提示*/
c1);
/*输入要删除的字符,用c1表示*/
for(i=0,j=0;
s1[i]!
=’\0’;
i++)/*逐个提取数组元素的值*/
if(s1[i]!
=c1)
/*旧数组元素的值赋值给新数组元素s1[j]*/
s1[j]=s1[i];
j++;
/*新数组元素下标增1*/
s1[j]='
\0'
/*新数组元素末加字符串结束标识符\0’*/
puts(s1);
根据给定的字符,删除字符数组中指定的字符。
j表示新数组元素的下标,i表示删除前数组元素的下标。
如图4-7中数组s1中存放字符串“HelloWorld”,当输入给定字符’o’,即删除字符串中的字符’o’时,从第一个元素开始逐个比较数组元素的值是否是’o’,如果不是则把此数组元素a[i]的值赋值给新数组元素a[j]。
新数组中存放的字符串为”HellWrld”。
运行结果如图4-5所示:
图4-5程序运行结果
4.4函数
4.4.1函数概述
C语言的程序由函数组成,函数是C语言程序的基本单位。
C语言程序的结构如图4-6所示。
在每个程序中,主函数main是必须的,它是所有程序的执行起点,main函数只调用其它函数,不能为其它函数调用。
如果不考虑函数的功能和逻辑,其它函数没有主从关系,可以相互调用。
所有函数都可以调用库函数。
程序的总体功能通过函数的调用来实现。
图4-6C程序结构图
可从不同的角度对函数分类。
1.从定义的角度把函数分为两类:
(1)库函数
库函数即标准函数,由系统提供,无须用户定义,也不必在程序中作类型说明,用户可以直接使用它们。
库函数如:
printf、scanf、getchar、putchar、gets、puts。
(2)用户自定义函数
由用户自己定义的函数。
用来实现某一特定的功能。
它不仅要在程序中定义,而且必须在调用它的函数模块中进行类型说明。
2.从函数的返回值角度可分为两类:
(1)有返回值函数
(2)无返回值函数
3.从主调函数和被调函数之间数据传送的角度可分为两类:
(1)无参函数
(2)有参函数
4.4.2函数定义
同变量一样,调用用户自定义函数之前必须先对其进行定义。
函数定义的一般格式如下:
类型说明符函数名(参数列表)
声明部分
语句序列
1.无参数无返回值函数定义。
下列函数实现任意输入两个数x和y,输出其中的最大值。
voidmax()
intx,y;
scanf(“%d%d”,&
x,&
y);
if(x>
y)
printf(“%d”,x);
else
printf(“%d”,y);
}
注意如果函数没有返回值,则其类型为空。
C语言规定空类型用“void”表示。
2.无参数有返回值函数定义。
下列函数实现任意输入两个数x和y,返回其中的最大值。
intmax()/*函数返回值为int型*/
intx,y;
returnx;
returny;
注意
✧函数返回值类型也称为函数类型。
函数通过return语句返回计算结果,即函数值,有返回值的函数中至少应含一个return语句。
函数返回值可以是任何有效类型,默认为整型(int)。
✧在定义函数是对函数值说明的类型一般应该和return语句中的表达式类型一致。
✧return语句可以包含表达式。
此时,则返回表达式的值。
3.有参数无返回值函数定义。
voidmax(intx,inty)/*两个参数x和y,均为整型*/
{
printf(“%d”,x);
printf(“%d”,y);
✧参数列表是一些用于接受数据的变量的定义,用逗号分隔。
当函数被调用时这些变量依次接收从主调函数传来的值。
这些用于接受数据的变量也称为形式参数,简称为形参。
✧定义有参数的函数中,必须对形式参数进行类型说明。
✧也可以用如下形式定义形式参数:
voidmax(x,y)
intx,y;
语句序列
4.有参数有返回值函数定义。
intmax(intx,inty)
✧在定义函数时对函数值说明的类型一般应该和return语句中的表达式类型一致。
✧如果函数值的类型和return语句中表达式的类型不一致,则以函数类型为准。
对数值型数据,可以自动进行类型转换。
✧函数类型决定返回值类型。
5.空函数定义。
max(){}
说明空函数什么功能也不实现,只是为了以后扩充函数功能时补充的。
4.4.3函数调用
在一个函数中可以调用同一个软件项目里另外一个库函数或自定义函数。
函数每调用一次实质就是执行一次函数内的代码。
习惯上将函数的调用者称为主调函数,把被调用的函数称为被调函数。
main函数是主函数,它可以调用其它函数,而不允许被其它函数调用。
因此,C程序的执行总是从main函数开始,完成对其它函数的调用后再返回到main函数,最后由main函数结束整个程序。
函数调用的一般格式如下:
函数名(实参表);
函数调用时传给函数的参数称为实际参数,简称为实参。
函数的形参和实参遵守如下规则:
✧形参只能是变量,并且在被调用时才分配内存单元,调用一旦结束,即刻释放所分配的内存单元。
因此,形参只在函数内部有效。
函数调用结束返回主调函数后则不能再使用该形参变量。
✧实参可以是常量、变量、表达式、函数等,在进行函数调用时,实参必须具有确定的值,以便把这些值传送给形参。
因