C语言之函数

时间:2021-08-19 23:18:32

函数:为了完成某一项功能而编写的代码的集合。

C语言中的函数可以分为内置和自定函数。

内置函数:C语言中已经定义过的函数,不需要

声明,可以直接调用。

常见的内置函数:

函数名

类库

说明

double sqrt(double x)

math.h

计算x的平方根

double pow(double x int y)

计算x的y次方

int ceil(double x)

返回不小x的最小整数

int floor(double x)

返回不大x的最大整数

int  toupper(int x)

ctype.h

转大写

int  tolower(int x)

转小写

rand()

stdlib.h

返回一个[0,32767]之间随机数

示例1:

int i;

double x=1.34;

for(i=1;i<=10;i++){

printf("%d的平方根为%0.2f,立方为:%0.0f\n",i,sqrt(i),pow(i,3));

}

printf("---ceil函数---\n");

printf("%lf\n",ceil(x));

printf("---floor函数---\n");

printf("%lf\n",floor(x));

示例2:

//产生10个[1,3]随机数

int i;

long l = time(NULL);//返回当前时间距1970-1-1 00:00:00(元年)经历的总秒数

//printf("%ld",l);

srand(l);//使用srand设置随机种子:随机种子不相同的情况下,rand()产生的随机数不相同

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

printf("%d\t",rand()%3+1); //rand()产生[0,32767]一个伪随机数

}

示例3: //实现"人机猜拳大战" 0代表剪刀, 1代表石头,2代表布

规则采用7局4胜制

1.获取用户输入的出拳(0,1,2)

2.让电脑尝试一个[0,2]之间的随机数

3.判断当局输赢:

人胜: 人==0&&电脑==2   人==1&&电脑==0  人==2&&电脑==1

平局:人==电脑

电脑胜: 电脑==0&&人==2   电脑==1&&人==0  电脑==2&&人==1

4.评判最终结果:count1(人)>count2(电脑)

int user,computer;//声明两个变量用于保存用户和电脑的出拳

int count1=0,count2=0,i;//统计人和电脑所有各种胜利的局数

printf("*************************************************\n");

printf("*************郑州尚学堂人机猜拳大战**************\n");

printf("*************************************************\n");

for(i=1;i<=7;i++){

printf("\n\n第%d局开始:\n",i);

printf("请出拳(0代表剪刀;1代表石头;2代表布):\n");

scanf("%d",&user);//获取用户出拳

//获取电脑出拳(产生一个[0,2]之间的一个随机)

srand((unsigned)time(NULL)); //设置随机种子

computer =  rand()%3;//rand()-->[0,32767];

if(user<0||user>2){

printf("您的出拳有误,请从新输入!\n");

}else{

if((user==0&&computer==2)||(user==1&&computer==0)||(user==2&&computer==1)){

count1++;//为用户计分

printf("第%d局,用户胜!\n",i);

}else if(user==computer){

printf("第%d局,平局!\n",i);

}else {

count2++;//为电脑计分

printf("第%d局,电脑胜!\n",i);

}

}

}

printf("\n*****************比赛结果*******************\n");

//评判最终结果

if(count1>count2){

printf("比分%d VS %d,最终结果:用户胜!\n",count1,count2);

}else if(count1==count2){

printf("比分%d VS %d,最终结果:平均!\n",count1,count2);

}else{

printf("比分%d VS %d,最终结果:电脑胜!\n",count1,count2);

}

示例4:生成一个4位随机数作为验证码,有字母和数字组成。

分析:   1、创建一个数组用于保存字母,数组

2、生成4个[0,length-1]随机数作为访问数组的下标

char cs[]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'};

int i,index;

printf("验证码为:\n");

//设置随机种子

srand((unsigned)time(NULL));

for(i=0;i<4;i++){

index = rand()%36;//获取[0,35]随机数

printf("%c",cs[index]);

}

printf("\n");

自定义函数:

必须直接或间接在main中调用,否则该自定义函数不会被执行。

返回值类型 函数名(参数类型 参数名,参数类型 参数名...)

{

//函数体;

return  返回值;

}

返回值类型:用于定义当前函数所返回值的类型;

函数名:为函数体中代码起一个名称,命名需要满足标识符的命名规则。

参数类型:类似于声明变量的数据类型,用于限定当前参数的类型。

函数体:为了完成某些功能的代码集合。

函数的调用:在C语言中通过函数名进行调用,一旦该函数被调用了,将执行函数体中的代码。

函数原型说明在形式上与函数头部类似,最后加一个分号。原型说明中参数表里的参数名可以不写(只写参数类型)。

示例:

#include <stdio.h>

//声明函数的原型:参数名可以省略

void printRectangle();

void printfTriangle();

void  printTriangle2(int rows);

int getRand();

int getMax(int a,int b);

void main()

{

/*

int chioce;

printf("请输入图形代码:1代表打印矩形,2代表打印三角形\n");

scanf("%d",&chioce);

switch(chioce){

case 1:

printRectangle();//利用函数名调用该函数

break;

case 2:

printfTriangle();

break;

}*/

//  printTriangle2(7);

// int n = getRand();//无参数,有返回值。

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

int m = getMax(3,2);

printf("m=%d",m);

}

//无参数无返回值类型

//打印矩形

void printRectangle()

{

int i,j;

for(i=0;i<4;i++){

for(j=0;j<8;j++){

printf("*");

}

printf("\n");

}

}

//无参数无范围值

//打印三角形

void printfTriangle()

{

int i,j;

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

{

for(j=0;j<=i;j++){

printf("*");

}

printf("\n");

}

}

//无返回值,有参数

//打印指定行数的三角形

/* 定义函数时,参数为形式参数;调用函数时具体传入的值称为实际参数*/

void  printTriangle2(int rows)

{

int i,j;

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

{

for(j=0;j<=i;j++){

printf("*");

}

printf("\n");

}

}

/*

有返回值,无参数.

返回值:在函数内部使用return关键可以将值返回,C语言中只能返回一个值;返回值要和返回值的类型相匹配。

*/

//生成一个[1,6]之间随机数

int getRand()

{

int num;

srand((unsigned)time(NULL));

num = rand()%6+1;//获取一个[1,6]之间的随机数

return num;

}

//有返回值,有参数

int getMax(int a,int b)

{

/*

int max;

if(a>b){

max=a;

}else{

max=b;

}*/

int max = a>b?a:b;

return max;

}

函数的嵌套调用:在一个函数中调用其他的函数。 只有当被调用的函数执行结束后,程序才会继续向下执行本函数的代码。

示例

#include <stdio.h>

void m1();

void m2();

void areaRect();

void areaTri();

void testReturn();

/*

函数的嵌套调用:在一个函数中调用其他的函数。 只有当被调用的函数执行结束后,程序才会继续向下执行本函数的代码。

*/

void main()

{

/*

printf("main....begin....\n");

m1();//调用了m1()函数

printf("main....end....\n");

*/

int select;

while(1){//0代表假,非0代表真

printf("请选择您要计算的图形代码:\n");

printf("0代表退出,1代表长方形, 2代表三角形,3代表圆\n");

scanf("%d",&select);

if(select==0){

//break;//跳出循环;

//exit(0);//终止程序

return;

}else if(select==1){

areaRect();//计算长方形的面积

}else if(select==2){

areaTri();//计算三角形的面积

}else if(select==3){

//计算圆形的面积

}else{

printf("您输入的代码编号有误,请重新输入[0,3]之间的代码!\n");

}

}

printf("谢谢使用,再见!\n");

//testReturn();

}

void m1(){

printf("m1().....begin.....\n");

m2();//调用m2()函数

printf("m1().....end.....\n");

}

void m2(){

printf("m2()....begin....\n");

printf("m2()....end....\n");

}

//1.计算长方法的面积

void areaRect(){

int width,length,area;

printf("请输入长方形的长:\n");

scanf("%d",&length);

printf("请输入长方形的宽:\n");

scanf("%d",&width);

if(width>0&&length>0){

area=length*width;

printf("长方形的面积为:%d\n",area);

}else{

printf("长方形的长和宽必须是正整数!\n");

}

}

//2.计算三角形的面积

//1.计算长方法的面积

void areaTri(){

float bottom,height,area;

printf("请输入三角形的底:\n");

scanf("%f",&bottom);

printf("请输入三角形的高:\n");

scanf("%f",&height);

area = bottom*height/2;

printf("三角形的面积为:%0.2f",area);

}

/*

返回值:

语法: return 表达式或值;

1.函数中最多只能返回一个值,不能返回多个。

2.函数的返回值必须与函数声明时的返回值类型相匹配。

3.程序执行的过程中,如果遇到return关键字,将返回到函数的被调用处(结束当前的方法)。

*/

void testReturn(){

printf("return......before....");

return ;

printf("return......after....");

}

函数的递归调用:函数自身调用自身,类似循环。在编写递归程序时需要注意递归的条件,避免死循环发生。

示例: 利用递归实现阶乘

int factorial(int a)

{

if(a==1){

return 1;

}else{

return a*factorial(a-1);//递归调用

}

}

示例2: 利用递归实现斐波那契数列

古典问题:兔子问题,有1对兔子,从第3个月开始每月可以生一对小兔子,小兔子三个月之后又可以每月生1对小兔子...

第12个月总共有多少对兔子?

斐波那契数列

1 1 2 3 5 8 13 21....

f(n)=f(n-1)+f(n-2)  n>2

int fibonacci(int n)

{

if(n==1||n==2){

return 1;

}else{

return fibonacci(n-1)+fibonacci(n-2);

}

}

示例3:汉诺塔

#include <stdio.h>

void Hanoi(int n, char a,char b,char c);

void Move(int n, char a, char b);

int count;

/*

void main()

{

int n=3;

printf("请输入汉诺塔的层数:\n");

Hanoi(n, 'A', 'B', 'C');

}

*/

/*

分析:

当只有一个盘子的时候,只需要从将A塔上的一个盘子移到C塔上。

当A塔上有两个盘子是,先将A塔上的1号盘子(编号从上到下)移动到B塔上,

再将A塔上的2号盘子移动的C塔上,最后将B塔上的小盘子移动到C塔上。

当A塔上有3个盘子时,先将A塔上编号1至2的盘子(共2个)移动到B塔上(需借助C塔),

然后将A塔上的3号最大的盘子移动到C塔,最后将B塔上的两个盘子借助A塔移动到C塔上。

当A塔上有n个盘子是,先将A塔上编号1至n-1的盘子(共n-1个)移动到B塔上(借助C塔),

然后将A塔上最大的n号盘子移动到C塔上,最后将B塔上的n-1个盘子借助A塔移动到C塔上。

第一个参数n:代表盘子的个数

第二个参数a:代表源杆

第三个参数b:代表中间杆

第四个参数c:代表目标杆

*/

void Hanoi(int n, char a, char b, char c)

{

if (n == 1)//当盘子的个数为1,直接将源杆上的盘子移动至目标杆

{

Move(n, a, c);

}

else

{

Hanoi(n - 1, a, c, b);//先将初始塔(源杆)的前n-1个盘子借助目的塔(目标杆)移动到借用塔(中间杆)上

Move(n, a, c);//将剩下的一个盘子移动到目的塔(目标杆)上

Hanoi(n - 1, b, a, c);//将最后将借用塔(中间杆)上的n-1个盘子移动到目的塔上

}

}

/*

第一个参数n:代表要移动的盘子

第二参数a:源杆

第三个参数b:目标杆

*/

void Move(int n, char a, char b)

{

count++;//记录所移动步数

printf("第%d次移动 Move %d: Move from %c to %c !\n",count,n,a,b);

}

局部变量和全局变量

局部变量:在函数内声明的变量,其作用范围仅限于该函数内

局部变量的作用域范围:仅限于当前变量所在那对"{}"之中。

局部变量需注意以下几点:

1.主函数中定义的变量也只能在主函数中使用,不能在其它

函数中使用。

2.允许在不同的函数中使用相同的变量名,它们代表不同的

变量,分配不同的存放单元,互不相干,不会发生混淆。

3.复合语句中定义的变量,也是复合语句的局部变量。所谓

复合语句,就是用{}包含起来的语句块。

void main(){

int sum=0;

addNumbers();

printf("main函数中sum=%d\n",sum);

int a=1,b=2;

{

int a=3,b=4;

printf("复合语句中的a=%d,b=%d\n",a,b);

}

printf("main函数中的a=%d,b=%d\n",a,b);

m1();

}

void addNumbers()

{

int num1,num2,sum;

printf("请输入两个整数:\n");

scanf("%d %d",&num1,&num2);

sum = num1+num2;

printf("addNumbers函数中sum=%d\n",sum);

}

void m1(){

int a=5,b=6;

printf("m1函数中a=%d,b=%d\n",a,b);

}

全局变量:定义在函数外部的变量。 全局变量的作用域:从变量声明到程序结束,所有的函数都可以共享。

注意:

1.全局变量应该声明在所有函数的外部。

2.全局变量可以实现多个函数共享数据。

3.如果全局变量和局部变量同名,以局部变量的值为准(全局变量不起作用)。

示例:

int sum=0;//全局变量

void main()

{

int sum = 6;//局部变量

printf("main函数中sum=%d\n",sum);

add();

printf("main函数中sum=%d\n",sum);

}

void add()

{

//int sum=0;//局部变量

int a,b;

printf("请输入两个整数:\n");

scanf("%d %d",&a,&b);

sum = a+b;//当前全局变量与局部变量同名时,全局变量不起作用

printf("add函数中sum=%d\n",sum);

}

示例5:  举行"尚学堂杯选秀大赛",参赛选手演出结束后,将有10名评委进行打分

评分规则:去掉一个最高分,去掉一个最低分,求平均分,该平均分为选手最终得分。

#include <stdio.h>

void printMenu();

void getScore();

float calcAvg();

float scores[10];// 用于保存评委的打分

void main()

{

printMenu();//打印菜单

getScore(); //获取评委打分

float result = calcAvg();//计算平均分(最终得分)

printf("您的最终得分为:%0.2f\n",result);

}

//打印菜单

void printMenu(){

printf("******************************\n");

printf("*******尚学堂杯选秀大赛*******\n");

printf("******************************\n");

}

//获取评委打分,并将评委的打分保存到数组中

void getScore(){

int i;

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

printf("请%d号评委打分:\n",i+1);

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

}

printf("评委打分完毕,结果正在紧张统计中.....\n");

}

//计算最终得分:去掉一个最高分和一个最低分计算平均分

float calcAvg(){

float sum,avg;

float max=scores[0];//假设第一个为最高分

float min=scores[0];//假设第一个为最低分

int i;

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

sum+=scores[i];//计算总分数

if(scores[i]>max){//获取最高分

max=scores[i];

}

if(scores[i]<min){//获取最低分

min=scores[i];

}

}

avg=(sum-max-min)/8;//计算平均分

return avg;

}