c语言实验课件么哒第7章函数_第1页
已阅读1页,还剩74页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章 函

数1学习目标函数的概念、定义和调用函数参数的传递数组参数的传递

字符串参数的传递变量的作用域规则变量的存储类型C是模块化程序设计语言将一个大的程序按功能分割成一些小模块——称为子程序。C语言的子程序构造机制——函数。好处:层次清楚;函数相对独立,任务单一;函数可存于函数库中,供程序方便地调用它们;C语言程序一般是由大量的小函数而不是由少量的大函数构成,即所谓"小函数构成大程序"。一个C程序可由一个或多个源文件组成。一个源文件由一个或多个函数构成。一个C程序必须有并且只能有一个main函数。

C程序的执行总是从main函数开始,在main中结束主函数可以调用其它函数,其它函数可以相互调用。函数:C程序的最小单元简单函数举例main(){ printstar(

);printmessage(

);printstar(

);}void

printstar(){

printf(“*

*

*

*

*

*

*

*

*

*

*

*

*

*\n”);}void

printmessage(){

printf(“ How

do

you

do!\n”);}*

*

*

*

*

*

*

*

*

*

*

*

*How

do

you

do!*

*

*

*

*

*

*

*

*

*

*

*

*int

max(

int

x

,

int y

){

int

z;z

=

x

>

y

?

x

:

y

;return(

z

);}main(

){

int a=5,

b=9,

c;c

=max(

a,b);printf(“Max

=

%d”,c);}例:求最大值函数定义的一般形式数据类型函数名(形式参数表){说明部分语句}C函数只能有一个返回值。类型说明符用来指明返回值的类型。默认类型是整型。定义函数内部需要使用的变量语句部分实现函数的功能函数名的命名规则与所有的标识符一样形参表用来定义输入参数的类型和个数,必须是变量。可以为空(无参函数)int

max(int

x,int

y){ int

z;z

=

x

>

y

?

x

:

y;return(z);}void

printstar(){ printf(“*

* *

*

*

*

*\n”);}return语句标准形式return (表达式);或

return

表达式;功能结束本次函数调用并回到进行调用函数的语句,将表达式的值做为函数的返回值返回。函数的返回int

max(int

x,int

y){int

z;z

=

x

>

y

?

x

:

y;return(z);}void

printstar(){

printf(“*

* *

*

*

*

*\n”);}函数中可以有多个return语句,执行到哪一个return语句,就从哪一个return语句返回。return只能返回一个值,而不能返回多个值。 return(x,y);╳ 如明确没有返回值,则要定义成void型函数,即

“无类型”。void

printstar(){

printf(“*

*

*

*

*

*

*

*

*

*

*\n”);

}return(表达式);语句中的表达式值的类型应与定义函数时函数的类型一致。如果不一致,以定义函数时规定的函数类型为准进行类型转换。例如:int

fun(){return

10;int

a

=

5;return

a;}该函数只能返回10例:定义函数,用来求两个实数的和。float

add(float

x,

float

y){

float

z;z=x+y;return(z);}已知条件:两个实数求: 这两个数的和max(float

x,

float

y){floatz;z=x>y?x:y;return(z);}main(){float

a,b;floatc;scanf("%f,%f",&a,&b);c=max(a,b);printf("Max

is

%f\n",c);}例:函数返回值类型转换不指定函数类型的函数,按整型处理4.5,6.3

Max

is

6函数调用的一般形式无参函数:函数名(

);有参函数;函数名(实参表列);实参可以是常量、变量或表达式printstar();int

max(int

x,int

y){

int

z;z

=

x

>

y

?

x

:

y;return(z);}void

printstar(){

printf(“*

* *

*

*

*

*\n”);}c=max(5

,

8);c=max(a

,

b);函数语句printstar();表达式方式函数调用出现在表达式中,函数的返回值参加表达式的运算。c=5*max(a,b);3.作为函数的参数printf(“max=%d”,

max(a,b)

);c=max(k,max(i,j));函数的调用方式void

printstar(){printf(“*

* *

*

*

*

*\n”);}int

max(int

x,int

y){

int

z;z

=

x

>

y

?

x

:

y;return(z);}int

max(

int

x,

int y

){

int

z;z

=

x

>

y

?

x

:

y

;return(

z

);}main(

){

int a=5,

b=9,

c;c

=

max(

a

,

b

);printf(“Max

=

%d”

,

c);}例:求最大值函数的原型声明int

max(int

x

,int

y){int

z;z

=

x

>

y

?

x

:

y;return(z);}根据C语言的规定在主调函数中,要对被调函数作声明。函数的声明又称作函数原型。函数类型

函数名(参数1的类型

参数1名,参数2的类型

参数2名┅);函数类型函数名(参数1的类型,参数2的类型,┅┅);int

max(int

x

,

int y

)

;int

max(int, int)

;可以省略形参的名称函数原型必须和被调函数实际的定义一致。例:输出数字金字塔18main(

){int

num;void

pyramid(int

n);printf(“请输入金字塔的层数:");scanf(“%d”,

&num);pyramid(num);}void

pyramid(int

n){int

i

,

j;for(i

=

1;

i

<=

n;

i++){ for(

j

=

1;

j

<=

n-i;j++)printf("

");for(

j

=

1;

j

<=

i;

j++)printf("%d

"

,

i

);请输入金字塔的层数:5}}printf("\n");122333444455555float

area

(float

r);main(

){

float

s,ra;scanf(“%f

”,&ra);s

=

area(ra);printf(“area

is:%f

”,

s);}float area

(float

r){

return

3.14*r*r;

}main(

){

float

area

(floatr);float

s,ra;scanf(“%f

”,&ra);s

=

area(ra);printf(“area

is:%f

”,s);}float area

(float

r){

return

3.14*r*r;

}函数的声明的位置如果在所有函数定义之前,对程序中的函数原型进行了声明,则在各个主调函数中不必再对被调用函数进行声明。int max(int

x

,

int

y);double min(double

x

,

double

y);echoline();voidmain(){…}int max(int

x

,

int

y){…}double min(double

x

,

double

y){…}void echoline(

){…}推荐推荐被调函数定义在前主调函数定义在后则在主调函数中无须再对被调函数进行声明float area

(

float r

){

return 3.14*r*r

;

}main(

){float

a,ra;scanf(“%f

”,&ra);a=

area(ra);printf(“area

is:%f

,

a);}被调函数出现在主调函数之前,不必函数说明例:判断1777和1991是否为素数?题目分析:定义一个函数prime用来判断一个整数是否为素数定义函数头部由函数prime的功能可知其形式参数为整型函数prime应该有返回值(整型),并能表明判断结果:0:否,

1:是int

prime(int

n)3)定义函数体素数:

函数返回1非素数:函数返回04)main函数,两次调用函数prime即可,避免代码重复。24#include

"math.h"int

prime(

int n

){

int

k

,

i

,

result=1;k

=

sqrt(n);for(i

=

2;

i

<=

k;

i++)if(n%i

=

=

0){

result

=

0;break

;}return

result;}main(

){int a

=

1777,

b

=

1991;if(prime(a)==1)printf("%d是素数\n",a);elseprintf("%d不是素数\n",a);if(prime(b)==1)printf("%d是素数\n",b);elseprintf("%d不是素数\n",b);}1777是素数1991不是素数调用库函数时,在文件开始的#include“*.h”就是说明被调函数的原型。stdio.hstring.hmath.hstdlib.h例:编写函数求1+2+3+…+n(前n个自然数的和),主函数中输入n,然后调用该函数求和,再输出结果。int

he(int

n){int

i;int

nhe=0;for(i=1;

i<=n;

i++)nhe+=i;return(nhe);}int

he(int

n);main(

){int

n

,

sum;printf(“please

input

n:”);scanf(“%d”,

&n);sum=he(n);printf(“sum=%d”,

sum);}形式参数和实际参数

形参:定义函数时,函数名后括号内的变量。

实参:调用函数时,函数名后括号内的表达式。形式参数与实际参数的关系形参与实参类型一致,个数相同。若形参与实参类型不一致,自动按形参类型转换。参数传递方式函数间的参数传递例:比较两个数并输出大者int

max(int

x,int

y);main(){int

a,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf("Max

is

%d",c);}int

max(int

x,int

y){

int

z;z=x>y?

x:y;return(z);}main函数

变量

a5变量b10105swap(a,

b);形参

x

swap函数temp=x;10变量x=y;

temp

55

y=temp;形参y无参返回main(

){ int

a

=

5,

b

=

10;printf("before

a=%d,

b=%d

\n",

a,

b

);swap(

a,

b

);printf("after

a=%d,

b=%d

\n",

a,

b

);}swap

(

int

x

,

int

y

){inttemp;temp

=

x;x

=

y;y

=

temp;}一.表达式或简单变量传递方式(复制数据)单向值传递方式方式:函数调用时,为形参分配单元,并将实参的值复制到形参中调用结束,形参单元被释放,实参单元仍保留并维持原值特点:形参与实参占用不同的内存单元单向值传递(形参的改变并不影响实参)参数传递方式形式参数为地址(指针),调用时实际参 数为地址:&变量或其它地址形式特点–实参和形参必须是地址常量或变量。–形参与实参指向同样的存储单元。二.地址方式传递参数数组作为函数的参数数组元素名作函数实参----值传递数组元素a[0]、a[1]……,是简单变量。数组名作函数参数----地址传递数组名表示数组在内存中的起始地址。形参应该是指针变量,接受实参传给的地址。数组元素作函数实参:值传递求数组中最大的数组元素main(

){

int i

,

c

,

a[7]

=

{

5

,

6

,

9

,

3

,

7

,

10

,

4

}

;c

=

a[0]

;for

(

i

=

1

;

i

<

7

;

i

++

) c=max

(

c

,

a

[

i

]

)

;printf(

“The

biggest

number

is

%d”

,

c)

;}int max(

int x

,

int y

){

return (

x>y?

x

:

y

)

;}数组名作为参数:地址传递形式参数中数组在内存中已分配一块连续的空间形式参数只是与实际参数数组公用一块内存空间形式参数中数组长度没有意义数组长度也作为形式参数int

fun(

int

a[],int

n

)下语句:)如在main函数有如int

fun(int

a[6]{}int

b[6],c;c=fun(b);地址传递float aver

(int b[

]);main(){

float

avg;int

a[10]={1,3,4,5,6,7,8,9,10,11};avg=aver

(

a

)

;printf(“average

is

%f”,

avg);}float aver

(

int b[]

){

int

i

,

sum=0;for(i=0;

i<10;

i++)sum=sum+b[i];return

(sum/10.0);}数组名作函数参数:地址传递例:求数组的平均值aa[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]134567891011b例:求数组中元素的最大值36#define

N

10float

max(float

a[], int

n);main(

){

float

array[N],

max;int

i;printf(“请输入%d个实数:\n”,

N);for(i

=

0;

i

<

N;

i++)scanf(“%f”,

&array[i]);max

=

max(array,

N);printf(“最大的数组元素值是%.2f\n",max);}float

max(float

a[],

int

n){int

i;float

max;max

=

a[0];for(i

=

1

;

i

<

n

;

i++)if(a[i]

>

max)max

=

a[i];return

max;}例:比较两个数组的大小比较两个数组a和b的大小,比较规则为:①用m,n和k记录两个数组对应元素的比较结果如果a[i]>b[i],m++;否则,如果a[i]=b[i],k++;否则n++结果②如果m>n,数组a大于b;否则如果m<n,数组a小于b;否则数组a等于b。3738main(){int

a[N], b[N],

cmp,

i;printf("请输入数组1:%d个整数:\n",

N);for(i

=

0;

i

<

N;

i++)scanf(“%d”,

&a[i]);printf("请输入数组2:%d个整数:\n",

N);for(i

=

0;

i

<

N;

i++)scanf(“%d”,

&b[i]);cmp

=cmp(a

,

b,

N);if(cmp>0)

printf("数组1大于数组2\n");else

if(cmp

<

0)

printf("数组1小于数组2\n");else

printf("数组1等于数组2\n");}#define

N

5int

cmp(int

a[],

int

b[],

int

length){int

i,

result, m

,n,k;m=n

=k

=0;for(i

=0;

i

<

length;

i++)if(a[i]

>

b[i])

m++;else

if(a[i]

<

b[i])

n++;else

k++;if(m

>

n) result

=

1;else

if(m

<

n) result

=

-1;else result

=

0;return

result;}result=m-nfloat

aver(int p[]

,

int n

);main()例:求数组的平均值{int

a[10]={1,3,4,5,6,7,8,9,10,11};int

b[5]={77,68,9,25,10};int avga

,

avgb;avga=aver(

a

,

10

);avgb=aver(

b

,

5

);printf(“%d,%d",

avga,

avgb);}float aver

(int

p[],

int

n){

int i

,

sum=0;

for

(i=0;

i<n;

i++)sum=sum+p[i];return

(sum*1.0/n);}10987654321互换的数组元素的下标关系:两者之和为n-1;若一个为a[i],另一个为a[n-1-i]12345678910a[0]

1

2n-3

n-2

n-1例:编写函数将数组中各元素位置对调,并调用该函数。a[n]例:求一维数组的最大值、最小值和平均值。int

formax(int

b[] ,

intn){int

i,max=b0];for(i=0;i<10;i++)if(max<b[i])

max=b[i];return

max;}int

formin(int

b[] ,

intn){int

i,min=b[0];for(i=0;i<10;i++)if(min>b[i])

min=b[i];return

min;}float

foraver(int

b[] ,

intn){int

i,sum=0; float

aver;for(i=0;i<10;i++)

sum+=b[i];return

sum/(float)n;}int formax(int

b[], int

n);int formin(int

b[], int

n);float

foraver(int

b[], int

n)

;main(){

int

a[10]={1,2,3,4,5,6,7,8,9,10}int

max,min;float

aver;max=formax(a,

10);min=

formin

(a,

10);aver=foraver(a,

10);printf("%d,%d,%f",max,min,aver);}例:学生成绩排名42#define

M

5#define

N

5/*学生人数*//*成绩科数*/void

sort_score(

float

score[

][N], float

ave[

]

);main(

){

floatscore[M][N]

={{

80.0,

85.0,

78.0,

97.0,

68.0

},{

90.0,

97.0,

89.0,

88.0,

92.0

},{

60.0,

75.0,

79.0,

95.0,

56.0

},{

98.0,

61.0,

78.0,

99.0,

68.0

},{

80.0,

89.0,

98.0,

97.0,

88.0

}

};float ave[M];

int i

,

j

;43sort_score(

score

, ave

);for(i=0;

i<M;

i++){printf("第%d名学生的平均成绩为:%.2f\n",

i+1,

ave[i]);for(j=0;j<N;

j++)printf(“%10.2f

,

score[i][j]);printf("\n");}}【例7-9】编写函数实现学生成绩按平均分排名,学生成绩存储在一个二维数组中。44void sort_score(

float

score[

][N], float

ave[

]

){float sum,

temp;int i,

j,

k;for(i

=

0;

i

<

M;

i++){sum

=

0;for(j

=

0;

j

<

N;

j++)sum

=

sum

+

score[i][j];ave[i]

=

sum/N;}45for(i

=

0

;

i

<

M-1

;

i++)for(j

=

i+1

;

j

<

M

;

j++){if(ave[i]<ave[j])/*分析i=0;j=1*/{temp

=

ave[i];

ave[i]

=

ave[j]; ave[j]

=

temp;for(k

=

0;

k

<

N;

k++){temp

=

score[i][k];score[i][k]

=

score[j][k];score[j][k]

=

temp;}}}}当形式参数是多维数组时,只能忽略第一维的长度,后面的维数必须书写,46如:sort_score(float

score[][N],

float

ave[])N不能忽略字符串是以一维字符数组形式存放的,所以字符串的传递与一维数组的传递方式相同。字符串传递给函数时,一般采用地址传递方式把字符串的首地址传递给函数。这时函数的形式参数应该是字符型指针。字符串参数的传递例:定义求字符串长度的函数,在主函数中调用int slen(char

s[]){

int

n=0;while(s[n]!=’\0’)n++;return(

n);}main(){

char

str1[20]=“1234”;int

len;len=slen(str1);len=slen(“goodnight”);}例:用函数调用将字符串a复制到字符串b中。Iamateacher\0a

p1b

p2Iamateacher\050#include

"stdio.h"#include

"string.h"#define

N

80void copy_string(char

from[],

char

to[]);void

main(void){

chara[N],

b[N];printf("请输入一串字符串:\n");gets(a);copy(a

,

b);puts(b);}字符串复制void

copy(char

from[], char

to[]){int

i;for(i

=

0;from[i]

!=

'\0';

i++)to[i]

=

from[i];to[i]

=

'\0';}函数的嵌套调用在调用一个函数的过程中,又调用另一个函数。a(int i

,

int j

);b(double

x

,

double

y);intdoublemain(){

a

(

m

,

n

)

;

}int a(

int

i

,

int

j

){

b

(

x

,

y

);

}double

b(

double

x

,

double

y

){

}函数的嵌套调用main函数{

…………调用函数a;……}函数a{

…………调用函数b;……}函数b{

………………}sum+=jc(i);jc*=i;main(

){

int n=10,

he;he=jcsum(

n)

;printf("%d",he);}int jcsum(

int

n){

int i,

sum=0;for(i=1;

i<=n;

i++)return

sum;}int

jc(int

n){

int

i,

jc=1;for(i=1;

i<=n;

i++)return

jc;}求1~10的阶乘之和例:计算数组元素的均方差【例7-11】编写函数计算数组元素的均方差。方差等于数组中所有元素与其平均值的平方和,它描述的是数据波动的情况,均方差等于方差的平方根。54#include

"stdio.h"#include

"math.h"#define

N

10float

average(float

a[],

int

n);float

variance(float

a[],

int

n,

float

ave);float

rms(float

a[],

int

n);main(

){float

x[N],

var;int

i;printf("输入%d个数值:\n",N);for(i=0;i<N;

i++)scanf("%f",

&x[i]);var

=

rms(x,

N);printf("这些数值的均方差为:%.4f\n",

var);}【例7-11】编写函数计算数组元素的均方差。方差等于数组中所有元素与其平均值的平方和,它描述的是数据波动的情况,均方差等于方差的平方根。55float

average(floata[],

int

n){int

i;

float sum

=

0.0;for(i

=

0;

i

<

n;

i++)sum

=

sum

+

a[i];return

sum/n;}float

variance(floata[], int

n, float

ave){inti;

float

var;var

=0.0;for(i

=

0;

i

<

n;

i++)var

=

var

+

pow((a[i]

-ave)

,2

);return

var;}【例7-11】编写函数计算数组元素的均方差。方差等于数组中所有元素与其平均值的平方和,它描述的是数据波动的情况,均方差等于方差的平方根。56float

rms(float

a[],

int

n){int

i;float

ave,var;ave

=

average(a,

n);var

=

variance(a,

n,

ave);var

=

sqrt(var);return

var;}输入10个数值:1.0

2.0

3.0

4.0

5.0

6.0

7.0

8.0

9.0

10.0这些数值的均方差为:9.0830C语言可以在不同的位置定义变量。函数体内部:局部变量。函数头中的形式参数:属于局部变量。所有函数的外部:全局变量。定义在不同位置的变量,作用的范围也不同。局部变量在函数内部定义的变量,只能在该函数中使用,称为“局部变量”。float f1(int

a){ int

b

,c;…….}char

f2(int

x,int

y){

int i

,

j;……}main(){ int

i

,

m

,

n;…….}a,b,c有效x,y,i,j有效i,m,n有效max(intx,inty){intz;if(x>y)

z=x;else

z=y;return(z);}1、main函数内部定义的变量也只能在main函数内部使用。但它2、不同的函数中可以使用相同的变量名,们占据不同的内存单元,是不同的变量。3、形参也是局部变量,作用范围在定义它的函数内。局部变量的说明

main(){

int

a,b;a=3;b=4;printf("main:a=%d,b=%d\n",a,b);sub();printf("main:a=%d,b=%d\n",a,b);}sub(){

int

a,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}说明 不同函数中同名变量,占不同的存储单元baba4367main:a=3,b=4sub:a=6,b=7main:a=3,b=4二、全局变量在函数外部定义的变量称作外部变量(全局变量)全局变量作用域是从定义变量开始到本源文件结束。在一个函数内部,既可以使用本函数定义的局部变量,也可以使用在此函数前定义的全局变量。局部变量与其它变量重名时,局部优先;即局部变量起作用,全局变量不起作用。

int i,j;

/*外部变量*/float f1(

int a

){ int

b

,

c;i=5;……

}float a,b;

/*外部变量*/float f2(

int x

,

int

y){

int x1

,

y1;…

}main(

){

int

m

,

n;a=0;}a,b的作用域i,j的作用域全局变量的作用域int

a=5;main(){ printf("a=%d",

a);a=10;printf("a=%d",

a);sub();printf("a=%d",

a);}sub(){a=20;printf("a=%d",

a);}a=5a=10a=20a=20inta=3,b=5;main(){

int

a=8;printf("a=%d,b=%d",a,b);sub();}sub(){printf(“a=%d,b=%d”,a,b);}a=8,

b=5a=3,

b=5例:全局变量与局部变量同名,则全局变量被屏蔽?编制一个函数,求数组的最大值和最小值,主函数调用它。void maxmin(

float a[],

int

n);float

Max ,

Min

;void

main(

){ float

a[10]={

9,4,7,9,10,6,8,2,6,4};maxmin(

a,

10);printf(“max=%f,min=%f”,Max,Min

);}v{oid maxmin(

float a[],

int

n)int i

;ax=Min=a[0]

;or

(

i=1;

i<n;

i++)全局变量使得函数间多了一种传递数据的方式应尽量少使用全局变量,因为:全局变量在程序全部执行过程中占用存储单元M

降低了函数的通用性、可靠性,可移植性

f

降低程序清晰性,容易出错{

if(

a[i]

>

Max

) Max=a[i]

;else

if(

a[i]

<

Min) Min=a[i]

;}}66#define

N

10float

array[N];/*全局变量*/float

max_array();void

main(void){

float

max;int

i;printf("请输入%d个实数:\n",N);for(i=0;i<N;

i++)scanf("%f",&array[i]);max

=

max_array();printf("数组中最大元素是:%.2f",max);}float

max_array(){int

i;float

max;max

=

array[0];for(i

=

1;i

<

N;

i++)if(array[i]

>

max)max

=

array[i];return

max;}变量的存储类型规定了该变量数据在内存中的存储区域(数据段或堆栈段)。在不同存储区域存储的数据,有不同的生存期。有些变量的生存期是短暂的,变量会被反复地建立和撤消,还有些变量虽然在离开了说明它们的函数时暂时无法访问到它的数据,可一旦又调用该函数,那些数据还在。在C语言中变量有四种存储类型,属于有两种存储期:自动存储期和静态存储期,它们分别是:auto----自动型。

register----寄存器型。

static----静态型。

extern----外部参照型。一、自动变量 定义格式:auto

类型说明符 变量

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论