函数(Function):是一段可以重复使用的代码。为了完成重复操作定义的函数,可以供其他程序或同一程序调用。函数是C语言的基本组成单位。
函数的优点;可以使程序简洁,易于维护,可以提高代码的重重率。
C语言的函数至多只能返回一个值,不能返回多个值。
形式参数(形参):数据类型 变量名,调用时具体传入的值为实际参数(实参),实参的类型,数量,顺序必须与形参相对于。形参是函数局部变量,只在该函数内部有效
函数的一个明显特征就是使用时带括号( )
,必要的话,括号中还要包含数据或变量,称为参数(Parameter)。参数是函数需要处理的数据。
返回值:很多函数都有返回值(Return Value)。返回值,就是函数的执行结果。返回值必须跟返回类型是同一类型,必须有return,若无,则报错。遇见return函数执行将终止。程序控制流将立即返回调用
函数体:描述当前函数具体需要完成的功能(函数要做的事情)
返回值类型:可以有返回值,也可以没有返回值(void)
如果无返回类型void,返回值类型(int,double,float,short,long,char..)。
返回值类型 函数名称 (参数)
{
//函数体;
返回值;
}
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~10的平方根和立方
int i;
double square,power;
for(i=1;i<=10;i++){
square =sqrt(i);//使用sqrt(x)函数计算x的平方根
}
power=pow(i,3);//使用pow(x,y)函数计算x的y次方
printf("%d的平方根是%.2lf,立方根是%.2lf ");//.2lf:double类型精确到小数点后两位
}
//floor()和ceil()函数
printf("----------floor()类型--------- ");//floor(x)--->不大于x的最大整数,不会四舍五入
printf("floor(12.1)=%f ",floor(12.1));//12
printf("floor(-12.1)=%f ",floor(-12.1));//-13
printf("floor(12.8)=%f ",floor(12.8));//12
printf("floor(-12.8)=%f ",floor(-12.8));//-13
printf("----------ceil()类型--------- ");//floor(x)--->不小于x的最大整数,不会四舍五入
printf("ceil(12.1)=%f ",ceil(12.1));//13
printf("ceil(-12.1)=%f ",ceil(-12.1));//-12
printf("ceil(12.8)=%f ",ceil(12.8));//13
printf("ceil(-12.8)=%f ",ceil(-12.8));//-12
//获取随机数
srand((unsigened)time(NULL))//设置随机种子,time(NULL);获取当时间距1970-01-01 00;00;00;00的秒数
for(i=0;i<10;i++){
printf("%d ",rand())//rand():伪随机数:产生的随机数0~32767之间
//产生一个0~99之间的随机数
printf("%d ",rand()%100);
}
示例2:使用随机实现人机猜拳大战
int userCount=0;//统计用户获胜的次数
int computerCount=0;//统计电脑获胜的次数
int user,computer;//用于保存人和电脑出的拳
char isContinue;//是否继续
srand((unsigned)time(NULL));
//人机猜拳大战 (0:剪刀,1:石头,2:布) y
do{
printf("*********************************** ");
printf("**********人机猜拳大战****************** ");
printf("*********************************** ");
computer =rand()%3;//产生随机0,1,2的随机数
print("请出拳:0代表剪刀,1代表石头,2代表布 ");
scanf("%d",&user);//让用户出拳//判断结果,人赢(user==0&&computer==2||user==1&&computer==0||user==2&&computer==1)
if((user==0&&computer==2)||(user==1&&computer==0||(user==2&&computer==1)){
printf("恭喜你赢了~~~~~~~~~~~~~~~~~~ ");
userCount++;//累加人赢的次数
}else if(user==computer){
printf("平局,真倒霉!!!");
}else{
printf("你真菜,输给了电脑");
computerCount++;//累加电脑赢的次数
}
}
printf("是否继续跟电脑决一雌雄?y代表继续,n代表退出 ");
fflush(stdin);//刷新缓冲区
isContinue=getchar();//获取输入的字符
}while(isContinue=='y');
printf("你赢了%d次,电脑胜了%d次 ",userCount,computerCount");
if(userCount>computerCount){
printf("经过您的不懈努力,终于战胜了电脑! ");
}else if(userCount==computerCount){
printf("你和电脑旗鼓相当,继续加油! ");
}else{
printf("你被电脑打败了,继续加油! ");
}
自定义函数:
无参数的定义:如果函数不接收用户传递的数据,那么定义时可以不带参数。
返回值类型 函数名(){
函数体
}
示例:计算1~100的和
int sum(){//sum为int类型,返回值也必须是int类型
int;
for(i=0;i<100;i++){
sum+=i;
}
return sum;//通过return返回,用来处理返回结果
}
注意:main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。
有参数的定义:如果函数需要接收用户传递的数据,那么定义时就要带参数。
自定义函数:
返回值类型 函数名称 (参数)
{
//函数体;
返回值;
}
示例:
int max(int a,int b);//有返回值,有参数 a和b为形式参数(形参)
int m;
if(a>b){
m=a;
}else{
m=b
}
return m;
}
int m=max(3,2);//调用 实际参数
示例:
#include <stdio.h>
//函数原形定义
void juxing();//计算矩形的面积
void sanjiaoxing();//计算三角形的面积
void main(){
//根据用户输入的代码(0代表矩形,1代表三角形,2代表圆)计算其面积
int code;
printf("请输入图形代码:0代表矩形,1代表三角形,2代表圆");
scanf("%d",&code);
if(code==0){
juxing();//通过函数名调用
}else if(code==1){
sanjiaoxing();
}
}
//计算矩形的面积
void juxing(){
int length,width,s;
printf("请输入矩形的长 ");
scanf("%d",&length);
printf("请输入矩形的宽 ");
scanf("%d",&width);
if(length>0&&width>0){
s=length*width;
printf("矩形的面积为%d ",s);
}else{
printf("您输入有误!长和宽必须大于零! ");
}
}
//计算三角形的面积
void sanjiaoxing(){
int bottom,height;
float s;
printf("请输入三角的底 ");
scanf("%d",&bottom);
printf("请输入三角形的高 ");
scanf("%d",&height);
if(bottom>0&&height>0){
s=bottom*height/2;
printf("三角形的面积为%f ",s);
}else{
printf("您输入有误!底和高必须大于零! ");
}
}
示例2:
编写一个函数void isTri(),判定用户输入的三个边长是否能组成三角形。
1.三边都要大于0
2.任意两边之和大于第三边
void isTri(){
int a,b,c;//定义三个变量
printf("请输入三角形的边长1:");//获取用户输入的三边长
scanf("%d",&a);
printf("请输入三角形的边长2:");
scanf("%d",&b);
printf("请输入三角形的边长3:");
scanf("%d",&c);
}
//判断三边长边长是否大于0;
if(a>0&&b>0&&c>0){
//判断二边之和是否大于第三边
if(a+b>c&&a+c>b&b+c>a){
printf("%d,%d,%d能组成三角形 ",a,b,c);
}else{
printf("你输入的边长不满足任意两边的和大于第三边的条件 ");
}
}else{
printf("你输入的边长有误!必须是整数 ");
}
void main(){
isTri();//调用
}
示例:编写一个函数int pieAdd(int n),计算1+2+3+……+n的值并返回。比如pieAdd(3)的返回值是1+2+3=6
int pieAdd(int n){
int i,sum=0;
for(i=1;i<=n;i++){
sum+=i;}
return sum;//返回值和返回类型对应
}
void main(){
int sum=pieAdd(5);//5实参要形参相对(类型,数量,顺序)
printf("累加为%d",sum);
}
示例:
写一个函数void rose(int n),判断某一个四位数是不是玫瑰花数(所谓玫瑰花数即该四位数各位数字的四次方和恰好等于该数本身。比如:1634=1^4+6^4+3^4+4^4
void rose(int n){
int ge,shi,bai,qian,sum;
ge=n%10;
//获取个位 //1234===>1234%10==>4
shi=n/10%10;
//获取十位 //1234==>1234/10==>123%10==>3
bai=n/100%10;
//获取百位 //1234==>1234/10==>123/10==>12%10==>2
qian=n%1000;
//获取千位 //1234/10==>123/10==>12/10==>1
sum=pow(ge,4)+pow(shi,4)+pow(bai,4)+pow(qian,4);
if(sum==n){
printf("%d是玫瑰花数 ",n)
}else{
printf("%d不是玫瑰花数 ",n);
}
void main(){
rose(1634);}//调用函数
}
函数的嵌套调用
使用递归实现计算N的阶乘
int factorinal(int a);//函数递归调用实现计算阶乘
void main(){
int sum=factorinal(5);
printf("5的阶乘为%d",sum);
}
//计算a的阶乘
int factorinal(int a)
{
if(a==1)
{
return 1;
}else{
return a*factorinal(a-1);
}
}
示例:
利用递归实现斐波那契数列: 1 1 2 3 5 8 13 21....
公式:f(n)=f(n-1)+f(n-2); n>2
古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月,后每个月又生一对兔子,假如兔子都不死,1年后总共有多少对兔子?
void main(){
int num =fibonacil(12);
printf("1年后有%d对兔子",num);
}
int fibonacil(int n){
if(n==1||n==2){
return 1;
}else{
return fibonacii(n-1)+fibonacii(n-2);
}
}