------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
C语言回顾-函数
一、函数的概念、分类
1、函数的概述
C源程序是由函数组成的,实际程序往往由多个函数组成。函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能。
C语言不仅提供了极为丰富的库函数,还允许用户建立自己定义的函数。
用户可把自己的算法编成一个个相对独立的函数模块,然后用调用的方法来使用函数。
可以说C程序的全部工作都是由各式各样的函数完成的,所以也把C语言称为函数式语言。
2、函数的分类
1)从函数定义的角度看,函数可分为库函数和用户自定义函数两种。
库函数:由C系统提供,用户无须定义,也不必在程序中作类型说明,只需要在程序前包含有该函数原型的头文件即可在程序中直接调用。
用户定义函数:由用户按需要写的函数。对于用户自定义函数,不仅要再程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能拿使用。
2)C语言的函数兼有其他语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。
有返回值函数:
此类函数被调用执行完成后将向调用者返回一个执行结果,称为函数返回值。
由用户定义的这种要返回函数值的函数,必须在函数定义和函数说明中明确返回值的类型。
无返回值函数:
此类函数用户完成某项特定的处理任务,执行完成后不像调用者返回函数值。
由于函数无序返回值,用户再定义此类函数时可指定它的返回位“空类型”,空类型的说明符为 void。
3)从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。
无参函数:
函数定义、函数说明及函数调用中均不带参数。
主调函数和被调函数之间不进行参数传送。
有参函数
也称为带参函数。在函数定义及函数说明是都有参数,称为形式参数(简称形参)。在函数调用时也必须给出参数,称为实际参数(简称实参)。进行函数调用时,主调函数将把实参的值传送给形参,供被调函数使用。
4)C语言提供了极为丰富的库函数。
3、自定义函数的书写格式
用户定义函数:由用户自己写的函数。
对于用户自定义函数,不仅要再程序中定义函数本身,而且在主程序中需声明,然后才能使用。
函数定义到使用分三步:
1、声明 2、定义函数 3、调用函数。
函数的基本格式:
返回值类型 函数名称(函数参数){
函数体;
}
二、无参无返回值函数定义
1、无参无返回值
一般形式:
void 函数名(){
声明部分
语句
}
void 无返回值函数:此类函数用于完成某项特定的处理任务,执行完后不向调用者返回执行结果,这类函数类似于其他语言的过程;由于函数无返回值,用户再定义此类函数时可指定其函数返回值位“空类型”。
void printLine(){
printf("---------------\n");
}
三、无参有返回值函数定义
一般形式:
返回值类型 函数名(){
声明部分
语句
return 返回值类型变量或常量;
}
其中返回值类型和函数名称位函数头。
返回值类型指明了本函数的返回值类型。函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少。
{ }中的内容称为函数体。在函数声明不封,是对函数体内使用到的变量的类型说明。
在很多情况下都不要求无参函数有返回值,此时函数类型符可写为void。
int sum(){
int num1,num2;
int result = 0;
printf("请输入两个数,中间用\",\"隔开。\n");
scanf("%d,%d",&num1,&num2);
result = num1 + num2;
return result;
}
四、有参无返回值函数定义
一般形式:
void 函数名(形式参数表列){
声明部分
语句
}
形式参数表列表的格式:类型 变量名,类型 变量2,······
思考&实现
输入一个数n,打印n条线。
void printLineN(int n){
for (int i = 0; i<n; i++) {
printf("-------------------\n");
}
}
五、有参有返回值函数定义
一般形式:
返回值类型 函数名(形式参数表列){
声明部分
语句
return 返回值类型变量或常量;
}
有参函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数,他们可以是各种类型的变量,个参数之间用逗号隔开。
在进行函数调用时,主调函数将赋予这些形式参数实际的值。形参既然是变量,必须在形参表中给出形参的类型说明。
注意:定义函数时注意函数名不能重复。
思考&实现
1)通过函数实现求出两个数中的最大值的功能。
int max(int x,int y){
//方法一
if (x>y) {
return x;
} else {
return y;
}
}
int max_1(int x,int y){
//方法二:三目运算符。
return x>y?x:y;
}
六、函数的参数
函数的参数分为形参和实参两种。
形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。
1、形式参数介绍和使用
定义函数的时候,函数名后面小括号中的参数,简称为形参
注意:
1)形参定以后并不会立即分配存储空间,在函数调用的时候才会真正的分配存储空间
2)如果有多个形参,可以用逗号分隔
3)形式参数是什么类型的数据,那么实际参数也必须是什么样的类型
4)形参的类型可以不同
5)函数内部不可以定义与函数形参同名的变量,因为形参与函数的代码是一个代码块
2、实际参数介绍和使用
调用函数的时候,函数名后面小括号中的参数,简称实参。
实参可以是变量,也可以是常量,也可以是表达式。
实参出现在主调函数中,进入被调函数后,实参变量也不能使用。
形参和实参的功能是作述职的传递。
发生函数调用时,主调函数把实参的值传递给被调函数的形参从而实现主调函数向被调函数的数据传送。
七、函数的参数传递过程
1、形参变量只有在被调用时才分配内存单元。在调用结束时,即刻释放所分配的内存单元。
因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。
2、实参可以是常量、变量、表达式、函数等。
无论实参是何种类型的量,在进行函数调用是,它们都必须具有确定的值,以便把这些值传送给形参。
3、实参和形参在数量上,类型上。顺序上应严格一致,否则会发生类型不匹配等错误。
4、形参的值在函数内部可以被修改,但是不会影响主调函数中实参的值。
八、函数的返回值及注意事项
1、函数的返回值
函数的值(或称函数返回值)是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值。
2、使用注意事项
1)函数的值只能通过return语句返回主调函数。
return语句的一般形式为:
return 表达式;
或者是: return (表达式);
return 常量; return 0;
return 表达式; return a=5;
2)如果return的值和函数定义的类型不一致,以函数的返回值类型为准。
九、函数的声明
在主调函数中调用某函数之前应对该被调函数进行说明(声明),这与使用变量之前要先进行变量说明是一样的。
在主调函数中对被调函数作说明的目的是使编译系统指导被调函数返回值的类型,以便在主调函数中按此种类型对返回值作相应地处理。
一般形式是:
返回值类型 被调函数名(类型 形参,类型 形参···);
返回值类型 被调函数名(类型,类型···);
例如:
int max( int a, int b);
int max(int , int);
函数声明的注意事项:
1)如果被调函数的返回值是int类型,此时可以不再声明
2)如果被调函数写在了主调函数之前,此时可以不声明被调函数。
十、函数的调用
函数调用的一般形式:
函数名(实际参数表);
对无参函数调用时则无实际参数表。
实际参数表中的参数可以是常量、变量或其他构造类型数据及表达式。
各实参之间用逗号分隔。
函数调用的注意事项:
1)函数表达式
m= max(34,10) + 10;
2)函数调用作为另外一个函数的实参
m=max(max(56,426),120);
3)函数的嵌套调用
思考&实现
从键盘输入三个整型数字,找出最大值。
#include <stdio.h>
int max(int x,int y){
//方法一
if (x>y) {
return x;
} else {
return y;
}
}
int max_1(int x,int y){
//方法二:三目运算符。
return x>y?x:y;
}
int main(int argc, const char * argv[]) {
int x,y,m,n;
printf("请输入两个数求最大值:\n");
scanf("%d%d",&x,&y);
m=max(x, y);
n=max_1(x, y);
printf("两个数的最大数是:%d\n",m);
return 0;
}
十一、函数应用:打印图形
思考&实现
1、写一个函数打印一条横线
2、打印自定义行数的横线
#include <stdio.h>
int main(int argc, const char * argv[]) {
void printLineN(int n);
int n = 0;
printf("请输入你要打印的行数:\n");
scanf("%d",&n);
printLineN(n);
return 0;
}
void printLine(){
printf("---------------\n");
}
void printLineN(int n){
for (int i = 0; i<n; i++) {
printLine();//由于printLine在printLineN之前,所以不用声明。
}
}
十二、函数应用:数字计算
思考&实现
1、写一个函数求三个数的和
2、写一个函数求三个数的平均值
#include <stdio.h>
int sum(int x,int y,int z){ //注意:int x中间的空格不能省略
return x+y+z;
}
float avg(int x,int y,int z){
return sum(x, y, z)/3.0f;
}
int main(int argc, const char * argv[]) {
int m=0;
float n =0.0f;
m = sum(56, 44, 27);
n = avg(56, 44, 27);
printf("三个数的和是%d\n",m);
printf("三个数的平均数是%.2f",n);
return 0;
}
十三、递归函数概述及构成条件
1、递归函数概述及用法
一个函数在它的函数体内调用它自身称为递归调用。
这种函数称为递归函数。
C语言允许函数的递归调用。在递归调用中,主调函数又是被调函数。执行递归函数将反复调用其自身,每调用依次就进入新的一层。
为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。
一个递归有两个阶段:
1)递推阶段:缩小问题的规模
2)回归阶段:回归计算
2、递归函数构成条件
1)自己调用自己
2)存在一个条件能够让递归结束
3)问题的规模能够缩小
思考&实现
有5个人做在一起,问第5个人多少岁?他说比第4个人大两岁。问第4个人岁数,他说比第3个大两岁。问第3个人,又说比第2个人大两岁。问第2个人,说比第1个人大两岁。最后问第1个人,他说10岁。请问第5个人多大?
#include <stdio.h>
int getAge(int n){ //有n个人。
int age;
if (n==1) {
age = 10;
} else {
age=getAge(n-1)+2;
}
return age;
}
int main(int argc, const char * argv[]) {
int age;
age = getAge(5);
printf("age = %d",age );
return 0;
}
3、递归的应用举例
思考&实现1
用递归法求N的阶乘
int jieCheng(int n){
int ji;
if (n==1) {
ji = 1;
} else {
ji = jieCheng(n-1)*n;
}
return ji;
思考&实现2
实现x的y次方,比如2的3次方=8,3的4次方=81
要求用递归来实现
int xy(int x,int y){
int cf;
if (y==1) {
cf = x;
} else {
cf = xy(x, y-1)*x;
}
return cf;
}