自定义函数
函数的作用
一个拥有上万行代码的程序,如果全部写在main()函数中,调试和修改会变得非常困难。因此,我们需要将程序中一些完成某些功能的代码变成子程序,既可以反复调用,还可以使得的整个程序实现模块化,维护起来更方便。在C语言中,函数就是子程序。
函数的定义
函数定义在main()函数的{}之外,因为main()也只是一个函数,只不过约定整个程序从它开始执行。函数的定义格式如下:
返回类型 函数名([类型 参数1,类型 参数2......]){
函数代码
}
函数无返回类型的可以写void,最简单的函数定义如下:
void ppp(){
printf("hello");
}
这个函数的功能是向屏幕输出一个 hello
函数的调用
函数没有调用时不会执行的(main()函数除外),函数的调用格式如下:
函数名([参数1,参数2......]);
例如:ppp();
函数的定义要写在调用之前,不然编译会报错。或者在调用之前先声明一下,函数的声明格式如下:
返回类型 函数名([类型 参数1,类型 参数2......]);函数传递参数
设置函数参数的作用
调用函数时传递参数可以使得函数的功能更灵活,以下函数实现输出指定个数的 hello 字符串。
void ppp(int a){
int i;
for(i-0;i<a;i++) printf("hello");
}
调用时:
ppp(10);
ppp(20);
课堂练习
编写函数,输出一个‘*’字符组成的矩形,要求可以通过函数参数设置矩形的宽高。
函数的返回类型
调用函数结束后可以返回一个值,这个返回值的类型需要在定义函数时声明,例如:下面的函数用来比较两个整数,返回较大者。
int max(int a,int b){
if(a>b) return a;
else return b;
}
return语句的作用
执行return语句可以结束一个函数的执行,直接返回调用处,同时可以选择返回一个数值。返回类型为void的函数,可以用return;终止调用。
带返回值的函数可以参与表达式运算,例如: a=10+max(30,35);
课堂练习
1、输入两个整数,输出它们的最大最大公约数,要求编写一个取两个整数的最大公约数的子函数。
2、输出1~100之间的所有质数,要求编写函数判断一个数是否为质数。
变量的作用域
局部变量
- 在{}内定义的变量只在{}范围内有效
- 函数的参数也是局部变量
- 复合语句内也可以定义局部变量。
- 当局部变量与全局变量重名时,局部变量优先。
全局变量
在函数之外定义的变量为全局变量,可以为当前源文件中所有的函数共用(在变量定义之前定义的函数不能使用它,编译会报错)。全局变量建议用大写字母命名,以区分局部变量。
声明外部变量extern
全局变量理论上可以被所有源文件中所有函数所共用,但是如果在一个源文件中要使用另一个源文件中的全局变量,需要用extern声明一下该变量,告诉编译器这个变量在别的原文件中。
变量的生存周期
函数中定义的局部变量或数组,随着函数的运行结束,变量的存储空间将被释放。
静态变量static
在函数中,在变量的定义前面加上static关键词,声明此变量为静态变量,则该变量不会随着函数的结束而消失,下次调用该函数时静态变量还是保留上一次的值。将数组作为函数参数
将主函数的数组作为参数传入子函数,传入的是数组的地址,在子函数中使用的将会是同一个数组。例如:
int ppp(int a[]){
a[0]=10;
}
递归调用
主函数可以调用子函数,子函数还可以再调用其他子函数,调用层次没有限制。函数还可以调用自己,这就叫递归调用,递归调用科技解决很多复杂问题,但是要设计好结束条件,以免出现无限次调用造成资源耗尽程序非法终止。
课堂练习
在有序的一维数组中实现二分法查找。
#include<stdio.h>
int ppp(int a[],int i,int j,int x){
if(i<0||j>12) return -1;
if(a[(i+j)/2]==150) return (i+j)/2;
else if(a[(i+j)/2]<150) return ppp(a,(i+j)/2+1,j,x);
else return ppp(a,i,(i+j)/2-1,x);
}
void main(){
int a[]={2,8,12,57,60,78,82,90,105,112,150,183,192};
printf("%d",ppp(a,0,12,150));
}