c笔记之函数.docx

上传人:b****9 文档编号:25710768 上传时间:2023-06-11 格式:DOCX 页数:33 大小:21.64KB
下载 相关 举报
c笔记之函数.docx_第1页
第1页 / 共33页
c笔记之函数.docx_第2页
第2页 / 共33页
c笔记之函数.docx_第3页
第3页 / 共33页
c笔记之函数.docx_第4页
第4页 / 共33页
c笔记之函数.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

c笔记之函数.docx

《c笔记之函数.docx》由会员分享,可在线阅读,更多相关《c笔记之函数.docx(33页珍藏版)》请在冰豆网上搜索。

c笔记之函数.docx

c笔记之函数

函数

一个C程序可由一个主函数和若干个子函数组成。

每个子函数完成一个特定的功能(功能相对独立的程序段)。

用户角度分类

标准函数,即库函数

自定义函数

函数形式分类

无参数函数

有参数函数

函数定义一般形式

类型说明函数名([形式参数说明])

{

函数体

}

形式参数说明

类型说明变量名[,类型说明变量名。

]

1.一个C程序可以分为若干个函数

2.每个程序有且只能有一个主函数(main),其他函数都是“子函数”

3.子函数可以相互调用,但主函数不能被调用

4.一个C源程序由一个或多个文件构成,一个源程序文件是一个编译单位

各函数间的信息的往来是由参数传递和返回语句实现的。

函数的参数:

调用时,实参值传给形参;

仅与位置有关,与名字无关;

注意二者的个数、类型。

形式参数和实际参数

1.定义参数时,必须说明形参的类型。

形参只能是变量或数组。

2.函被调用前,形参不占用内存;函数调用结束后,形参所占有的内存也将被回收。

3.实参可以是常量、变量或表达式。

4.实参与形参的类型必须一致。

字符型和整型可以互相匹配。

5.C语言中实参对形参的数据传递是“值传递”,即单向传递。

它仅由参数的对应位置确定,与名字无关。

实参形参传递方式

常量、变量、表达式、变量传递(单向)

数组元素

数组名数组传递组首地址(“双向”)--〉共享同一个存储空间

eg1:

#include

intsum(inta,intb)

{

a=a+b;

b=a+b;//无效语句

returna;

}

main()

{

inta=1,b=3,c;

c=sum(a,b);//a,b值不变

printf("Sumof%d,%dis%d\n",a,b,c);

}

eg2:

#include

intmax(intx,inty)

{

intz;

z=(x>y)?

x:

y;

returnz;

}

main()

{

inta,b,c;

scanf("%d%d",&a,&b);//输入:

空格或换行隔开

c=max(a,b);

printf("Maxis%d\n",c);

}

eg3:

函数返回值

#include

intmax(intx,inty)

{

//intz;

//z=(x>y)?

x:

y;

//returnz;

//if(x>y)

//returnx;

//else

//returny;

return(x>y)?

x:

y;

}

main()

{

inta,b,c;

scanf("%d%d",&a,&b);//输入:

空格或换行隔开

c=max(a,b);

printf("Maxis%d\n",c);

}

eg4:

按从右往左的顺序,计算实参各个表达式的值。

#include

intf(inta,intb)

{

intc;

printf("a=%d,c=%d\t",a,b);

if(a>b)c=1;

elseif(a==b)c=0;

elsec=-1;

returnc;

}

intmain()

{

inti=2,p;

p=f(i,i);//a=2,c=20

printf("%d\n",p);

i=2;

p=f(++i,i);//a=3,c=30

printf("%d\n",p);

i=2;

p=f(i++,i);//a=2,c=3-1

printf("%d\n",p);

i=2;

p=f(i,++i);//a=3,c=30

printf("%d\n",p);

i=2;

p=f(i,i++);//a=3,c=21

printf("%d\n",p);

}

函数的调用

1.先定义,再使用

#include

floatf(floatx)

{

return2*x*x+3*x+1;

}

main()

{

floatx;

scanf("%f",&x);

printf("y=%f\n",f(x));

}

2.如果被调函数的定义在主调函数之前,可以先给出原形说明。

原形说明

类型说明函数名(参数类型[变量名],

参数类型,...);变量名可写可不写

#include

floatf(float);//原形说明

main()

{

floatx;

scanf("%f",&x);

printf("y=%f\n",f(x));

}

floatf(floatx)

{

return2*x*x+3*x+1;

}

3.调用库函数

#include

#include

floatf(float);

main()

{

floatx,y;

scanf("%f",&x);

y=sin(x*3.1415926/180);

printf("sin(%f*3.1415926/180)=%f\n",x,y);

}

函数的嵌套调用

一个函数又调用另一个函数

注意点:

返回到主调函数的调用处

参数传递是单向的

eg:

#include

voidb(intx);

voida(intx)

{

x+=11;

b(x);

printf("a_sub:

%d\n",x);

}

voidb(intx)

{

x+=22;

printf("b_sub:

%d\n",x);

}

main()

{

intx=0;

a(x);

printf("main:

%d\n",x);

}

/*

b_sub:

33

a_sub:

11

main:

0

--------------------------------

*/

eg1:

用弦截法求方程的根。

x*x*x-5*x*x+16*x-80=0

#include

#include

floatf(floatx)

{

return((x-5)*x+16)*x-80;

}

floatxpoint(floatx1,floatx2)//求弦截点x的坐标

{

return(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));

}

floatroot(floatx1,floatx2)//求区间(x1,x2)上的根

{

inti;

floatx,y,y1;

y1=f(x1);

do

{

x=xpoint(x1,x2);

y=f(x);

if(y*y1>0)

{

y1=y;

x1=x;

}

else

{

x2=x;

}

}while(fabs(y)>0.00001);

returnx;

}

main()

{

floatx,x1,x2,y1,y2;

do

{

printf("inputx1,x2:

");

scanf("%f%f",&x1,&x2);

y1=f(x1);

y2=f(x2);

}while(y1*y2>0);//是否存在根

x=root(x1,x2);

printf("arootis%f\n",x);

}

eg2:

mn!

编写求C=------------的程序。

nm!

(n-m)!

分析:

重复三次求阶乘的运算,只是每次的值不同。

#include

floatfac(intk)//求阶乘

{

floatt=1;

inti;

for(i=2;i<=k;i++)

t*=i;

returnt;

}

main()

{

floatc;

intm,n;

printf("inputm,n:

");

scanf("%d%d",&m,&n);

c=fac(n)/(fac(m)*fac(n-m));

printf("%d!

/(%d!

*(%d-%d)!

)=%.0f\n",n,m,n,m,c);

}

/*

inputm,n:

58

8!

/(5!

*(8-5)!

)=56

--------------------------------

*/

函数的递归调用

是指在调用一个函数时又直接或间接地调用了函数本身。

直接递归调用

eg:

intf(intx)

{

inty,z;

...注意:

这两个递归都无法结束。

z=f(y);因此应含有某条件控制

...递归调用结束。

}

间接递归调用

eg:

intf1(intx)

{

inty,z;

...

z=f2(y);

...

}

intf2(intt)

{

intu,v;

...

v=f1(u);

...

}

eg1:

有5个人坐在一起,问第5个人多少岁?

答,比第4个人大2岁。

第4个人说他比

第3个人大2岁,第3个人比第2个人大2岁,第3个人比第2个人大2岁,第2个人

比第1个人大2岁,问第1个人时回答是10岁。

那么第5个人到底多大?

#include

intage(intn)

{

intc;

if(n==1)c=10;//递归结束条件

elsec=age(n-1)+2;//相当于数据结构“栈”

returnc;

}

main()

{

printf("%d\n",age(5));

}

eg2:

求阶乘n!

(n>0)

①循环法

floatfac(intn)

{

floatf=1;

if(n>1)

for(i=2;i<=n;i++)

f*=i;

elsef=-1;

returnf;

}

②递归法

递归公式:

n!

=1(n=0,1)

n*(n-1)!

(n>1)

#include

floatfac(intn)

{

floatf;

if(n>1)f=fac(n-1)*n;

elseif(n==0||n==1)f=1;

elsef=-1;

returnf;

}

main()

{

intn;

floaty;

printf("inputaintegernumber:

");

scanf("%d",&n);

y=fac(n);

if(y<0)

printf("error:

%d<0\n",n);

else

printf("%d!

=%.0f",n,y);

}

数组作为函数的参数

1.数组元素做函数实参

eg:

求5个任意整数中的最大数。

#include

intmax(intx,inty)

{

return(x>y?

x:

y);

}

main()

{

inta[5],i,m;

printf("enter5integers:

\n");

for(i=0;i<5;i++)

scanf("%d",&a[i]);

m=a[0];

for(i=0;i<5;i++)

m=max(m,a[i]);

printf("maxis%d\n",m);

}

2.一维数组作为函数的参数

函数的形参是数组,对应的实参必须是数组名。

1.实参数组与形参数组的类型必须一致。

2.用数组名做参数时,传递的是数组的首地址。

因此形参数组也可以不指定大小。

但需另设一个参数,传递数组元素的个数。

3.数组做函数参数时,形参数组和实参数组共享同一内存单元。

如果形参数组的元素的值被修改,实参数组的元素的值也就被改变了。

eg1:

求5个任意整数中的最大数。

#include

#defineN5

intmax(intx[N])

{

inti,m;

m=x[0];

for(i=0;i

if(m

m=x[i];

returnm;

}

main()

{

inta[N],i;

printf("enter5integers:

\n");

for(i=0;i

scanf("%d",&a[i]);

printf("maxis%d\n",max(a));

}

形参数组不指定大小,另设一个参数传递数组元素的个数。

#include

#defineN5

intmax(intx[],intn)

{

inti,m;

m=x[0];

for(i=0;i

if(m

m=x[i];

returnm;

}

main()

{

inta[N],i;

printf("enter5integers:

\n");

for(i=0;i

scanf("%d",&a[i]);

printf("maxis%d\n",max(a,N));

}

eg2:

用比较法排序(从大到小)

#include

#defineN5

voidsort(intx[],intn)

{

inti,j,t;

for(i=0;i

for(j=i+1;j

if(x[i]

{

t=x[i];

x[i]=x[j];

x[j]=t;

}

}

main()

{

inta[N],i;

printf("enter5integers:

\n");

for(i=0;i

scanf("%d",&a[i]);

sort(a,N);//a是数组名,传递数组的首地址

printf("enterthearray:

\n");

for(i=0;i

printf("%d",a[i]);

}

3.多维数组作为函数的参数

如果形参是多维数组,可以省略第一维的大小,但不能省略其他维的大小。

eg:

有一个3×4的矩阵,求最大元素的值。

#include

intmax(intx[][4])

{

inti,j,m;

m=x[0][0];

for(i=0;i<3;i++)

for(j=0;j<4;j++)

if(m

m=x[i][j];

returnm;

}

main()

{

staticinta[3][4]={{1,3,5,7},{2,4,6,8},{15,13,17,5}};

printf("maxis%d\n",max(a));

}

局部变量与全局变量

局部变量(多用)

在函数内定义的变量;形参也是局部变量;作用域为本函数。

局部变量只在自己的范围内有效。

如果局部变量的有效范围有重叠,则有效范围小的优先。

1.在一个函数内部定义的变量

2.函数的形式参数

3.在某个复合语句中定义的变量

全局变量/外部变量(少用)

在函数之外定义的变量(外部/全程变量)是全局变量

有效范围:

从定义变量的位置开始到源文件结束

1.利用全局变量可以在传递数据

利用全局变量可以减少函数的参数。

2.应尽量少使用全局变量。

3.如果全局变量与局部变量同名,则全局变量优先。

eg:

有5个学生的学习成绩,求平均分、最高分和最低分。

分析:

用一个函数返回三个数据,除了用函数值外,可以借助于全局变量。

#include

#defineN5

floatmax=0,min=0;

floataverage(floatscore[],intn)

{

inti;

floatsum=score[0];

max=min=score[0];

for(i=1;i

{

sum=sum+score[i];

if(max

if(min>score[i])min=score[i];

}

returnsum/n;

}

main()

{

floatavg,score[N];

inti;

for(i=0;i

scanf("%f",&score[i]);

avg=average(score,N);

printf("max:

%f,min:

%f,average:

%f\n",max,min,avg);

}

变量的存储类别

静态存储方式:

编译时分配空间,在程序运行期间占有固定存储空间(static变量、全局变量)

动态存储方式:

程序执行时动态分配存储空间(auto变量、register变量、形参)

若没有指定存储方式,默认动态存储方式auto变量。

eg:

#include

intsub()

{

staticinty=1;//保留值

y++;

returny;

}

main()

{

intj;

for(j=1;j<=10;j++)

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

printf("\n");

}

/*

234567891011

--------------------------------

*/

1.变量的动态存储和静态存储

变量的划分

⑴全局变量与局部变量:

按变量的作用域

局部变量:

1.自动变量

2.静态局部变量

3.寄存器变量

4.形式参数

全局变量

⑵静态存储变量和动态存储变量:

按变量的存储类别,即生存期

动态存储:

1.自动变量

2.寄存器变量

3.形式参数

静态存储:

1.静态局部变量

2.全局变量

⑶按变量的存放位置:

动态存储区:

1.自动变量

2.形式参数

静态存储区:

1.静态局部变量

2.全局变量

寄存器:

--寄存器变量

(内存中供用户使用的存储空间包括:

程序区

静态存储区:

编译时分配空间

动态存储区:

执行时分配空间)

变量或函数的属性:

数据类型:

1.整型、2.字符型...

存储类别:

1.自动型auto

2.静态型static

3.寄存器register

4.外部型extern

2.局部变量的存储类别

⑴自动变量

存储在动态存储区,用auto说明--〉通常,将auto省略

eg:

intfunc1(inta)形参a,变量b、c都是自动变量。

{调用该函数时,系统给它们分配

autointb,c=3;存储空间,函数调用结束时自动

...释放存储空间

}

⑵局部静态变量

占用静态存储区,用static说明

1.局部静态变量属于静态存储类别。

在程序整个运行期间都不释放存储空间。

2.局部静态变量在编译时赋初值(仅赋一次初值)。

3.如果定义局部静态变量时没有赋初值,编译时会自动赋初值。

4.局部静态变量只能在定义它的函数内被使用。

(它存在但不能被其他函数使用)

eg:

打印1到5的阶乘。

#include

floatfac(intn)

{

staticfloatf=1;

f=f*n;//f=1,1,2,6,24

returnf;

}

main()

{

intj;

for(j=1;j<=5;j++)

printf("%d!

=%.0f\n",j,fac(j));

}

/*

1!

=1

2!

=2

3!

=6

4!

=24

5!

=120

--------------------------------

*/

⑶寄存器变量(了解)

存储在寄存器中,用register说明

1.计算器的寄存

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1