函数
函数应该是为了完成某些功能而编写若干行代码的集合。可以供同一个程序或其他程序调用,或者可以称之为一个小程序,可以通过定义函数来将程序分块,当需要重复使用某段相同或相似的程序时就可以通过调用函数来节省代码,当然调用前要事先定义。这样既可以简化程序也方便修改,理解和维护程序。
之前一直在用的main()也是一个函数,其作为程序的入口是工程的主程序,或者说主函数。
同样的printf()也是函数,不过是c语言编译器的内置函数罢了,不需要自己定义可以直接调用。
一、内置函数的调用
内置函数 | 头文件 | 用途 |
double sqrt(double x) | math.h | 计算x的平方根 |
double pow(double x, double y) | 计算x的y次幂 | |
double ceil(double x) | 求不小于x的最小整数,并以double形式显示 | |
double floor(double x) | 求不大于x的最大整数,并以double形式显示 | |
int toupper(int x) | ctype.h | 如果x为小写字母,则返回对应的大写字母 |
int tolower(int x) | 如果x为大写字母,则返回对应的小写字母 | |
int rand(void) | stdlib.h | 产生一个随机数 |
void exit(int retval) | 终止程序 |
(调用内置函数时要现在程序前引用头文件)
例1:内置函数调用
#include <stdio.h> #include <stdlib.h> //引用rand函数头文件 void main() { int ai,player,aiScore=0,playerScore=0,deuce=0,i=0; char conti; printf("+----------------------------------------+\n"); printf("|****************************************|\n"); printf("|*************人机猜拳大战***************|\n"); printf("|****************************************|\n"); printf("+----------------------------------------+\n"); printf("=====输入0代表剪刀,1代表石头,2代表布====\n"); printf("\n游戏开始:\n"); do{ srand(i); //重置随机种子 确保每次随机都不一样 i++; ai=rand()%3; //取0~2随机数 printf("第%d回合请出拳:\n",i); scanf("%d",&player); printf("我出的是%d\n",ai); if(player==0&&ai==2||player==1&&ai==0||player==2&&ai==1){ printf("这局你赢了,技不如人,甘拜下风!\n"); playerScore++; }else if(ai==player){ printf("平局!\n"); deuce++; }else{ printf("对不起,这局我赢了!\n"); aiScore++; } fflush(stdin); //刷新缓存区避免取值错误 printf("输入y/n确定是否再战\n"); scanf("%c",&conti); }while(conti=='y'); if(aiScore<playerScore){ printf("技不如人,甘拜下风!你赢了!\n"); }else if(aiScore==playerScore){ printf("战平!\n"); }else{ printf("对不起,是我赢了!"); } printf("我们一共战了%d回合\n,你赢了%d回合,我赢了%d回合,平局%d回合",i,playerScore,aiScore,deuce); }
二、自定函数的定义和调用
1)函数定义的格式:
返回类型 函数名称(形式参数)
{
声明....
语句.....
.....
)
返回类型:函数返回值的类型,例如int,double,等等,但不能是数组;
如果指定的是void,说明函数无返回值;
(通俗的讲就是函数程序运行有没有个特定类型的结果)
函数名称:就是函数的标识符;
形式参数:可以有多个形式参数,每个形式参数都需要声明类型;
可以理解为给函数的初始参数;
可以没有;
{}中的内容就是函数的执行过程;
2)函数的调用:
调用函数直接在程序中输入 函数名+(形式参数)+;结尾,如果没有形参可以省略;
调用函数时要注意调用的函数定义应在调用函数前,如果在调用后定义则可以在主函数前声明所调用函数,形式同定义函数并加以;结尾
例2:函数的定义和调用
#include <stdio.h> // 编写一个函数int pieAdd(int n),计算1+2+3+……+n的值并返回。比如pieAdd(3)的返回值是1+2+3=6 int pieAdd(int n);//计算给定自然数1-n和的函数 void main() { int num; printf("请输入需要累加的自然数个数:"); scanf("%d",&num); printf("累加的结果为:%d\n",pieAdd(num));//在主程序中引入程序 } int pieAdd(int n){ int sum; sum = (1 + n) * n / 2; return sum; }
三、函数的几个特点
1)变量的作用域:
1.局部变量:在函数内声明的变量,其作用范围仅限于该函数内
主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。
允许在不同的函数中使用相同的变量名,它们代表不同的变量,分配不同的存放单元,互不相干,不会发生混淆。
复合语句中定义的变量,也是复合语句的局部变量。所谓复合语句,就是用{}包含起来的语句块。
2.全局变量:在任何函数外部声明的变量,叫全局变量。它的作用域是从声明时刻开始,到程序结束。
全局变量定义必须在所有的函数之外。
全局变量可加强函数模块之间的数据联系, 但是又使函数要依赖这些变量,因而使得函数的独立性降低。
在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,同名的全局变量不起作用。
例3:局部变量作用域
#include <stdio.h>
void m();
void main()
{
int a=1,b=2; { int a=3,b=4; printf("复合语句的变量a=%d,b=%d\n",a,b);//输出结果为a=3,b=4 } printf("main函数的变量a=%d,b=%d\n",a,b); //输出结果为a=1,b=2 m(); //输出结果为a=5,b=6
} void m() { int a=5,b=6; printf("m函数的变量a=%d,b=%d\n",a,b); }
例4:全局变量
#include <stdio.h> int sum=0;//全局变量 void addNumbers() { int sum;//局部变量 int num1,num2; printf("\n 请输入两个数:"); scanf("%d %d",&num1,&num2); sum=num1+num2; printf(" 子函数中 sum 的值是 %d \n",sum); } void main() { int sum=0;//局部变量 addNumbers(); printf("\n 主函数中 sum 的值是 %d \n ",sum); }
2)函数递归使用
函数递归就是利用函数可以相互调用的特点,在函数中调用函数本体从而到达循环的效果;
例子5:函数递归:
int factiral(int n)//计算阶乘 { if(n==1){ return 1; }else{ return n*factiral(n-1); } }