黑马程序员——C语言基础---函数

                                                                         ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------

一、函数的概念、分类 

1、函数的概述 

C源程序是由函数组成的。虽然在前面各章的程序中大都只有一个主函数main(),但实用程序 往往由多个函数组成。函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能。  

C语言不仅提供了极为丰富的库函数(如Turbo C,MS C都供了三百多个库函数),还允许用户建立自己定义的函数。 用户可把自己的算法编成一个个相对独立的函数模块,然后调用的方法来使用函数。可以说C程序的全部工作都是由各式各样的函数完成的,所以也把C语言成为函数式语言。 

2、函数的分类 

在C语言中可从不同的角度对函数分类。 

1) 从函数定义的角度看,函数可分为库函数和用户定义函数两种。 

stdio.h stdlib.h  

库函数:由C系统提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该 函数原型的头文件即可在程序中直接调用。

用户定义函数:由用户按需要写的函数。对于用户自定义函数,不仅要在程序中定义函数本 身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。  

2) 语言的函数兼有其它语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。  

有返回值函数:此类函数被调用执行完后将向调用者返回一个执行结果,称为函数返回值。 如数学函数即属于此类函数。由用户定义的这种要返回函数值的函数,必须在函数定义和函数说 明中明确返回值的类型。 

无返回值函数:此类函数用于完成某项特定的处理任务,执行完成后不向调用者返回函数值。 这类函数类似于其它语言的过程。由于函数无须返回值,用户在定义此类函数时可指定它的返回 为“空类型”,空类型的说明符为“void”。  

3) 从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。 

无参函数:函数定义、函数说明及函数调用中均不带参数。主调函数和被调函数之间不进行 

参数传送。此类函数通常用来完成一组指定的功能,可以返回或不返回函数值。 

有参函数:也称为带参函数。在函数定义及函数说明时都有参数,称为形式参数(简称为形 

参)。在函数调用时也必须给出参数,称为实际参数(简称为实参)。进行函数调用时,主调函数将 把实参的值传送给形参,供被调函数使用。 

4) C语言提供了极为丰富的库函数,这些库函数又可从功能角度作以下分类。 

字符类型分类函数:用于对字符按ASCII码分类:字母,数字,控制字符,分隔符,大小 写字母等。 

转换函数:用于字符或字符串的转换;在字符量和各类数字量(整型,实型等)之间进行 转换;在大、小写之间进行转换。 

目录路径函数:用于文件目录和路径操作。 

诊断函数:用于内部错误检测。 

图形函数:用于屏幕管理和各种图形功能。 

输入输出函数:用于完成输入输出功能。 

接口函数:用于与DOS,BIOS和硬件的接口。 

字符串函数:用于字符串操作和处理。 

内存管理函数:用于内存管理。 

数学函数:用于数学函数计算。 

日期和时间函数:用于日期,时间转换操作。 

进程控制函数:用于进程管理和控制。 

其它函数:用于其它各种功能。  

在C语言中,所有的函数定义,包括主函数main在内,都是平行的。也就是说,在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定义。但是函数之间允许相互调用,也允许嵌套调用。习惯上把调用者称为主调函数。函数还可以自己调用自己,称为递归调用。  

main 函数是主函数,它可以调用其它函数,而不允许被其它函数调用。因此,C程序的执行总是从main函数开始,完成对其它函数的调用后再返回到main函数,最后由main函数结束整个程 序。一个C源程序必须有,也只能有一个主函数main。  

3、自定义函数的书写格式 

用户定义函数:由用户自己写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而 且在主程序中需声明,然后才能使用。  

函数定义到使用分三步:1、声明。2、定义函数。3、调用函数。 

函数的基本格式:  

返回值类型 函数名称(函数参数)

{

函数体; 

二、函数的分类

1、无参无返回值 

一般形式如下: 

void 函数名()

{

    声明部分 //定义局部变量 语句

}

Void 无返回值函数:此类函数用于完成某项特定的处理任务,执行完后不向调用者返回执行结 果,这类函数类似于其他语言的过程;由于函数无返回值,用户在定义此类函数时可指定其函数 返回值为“空类型”

<span style="font-size:14px;">#include <stdio.h>
/**
 *  定义一个无参无返值函数
 *
 */
void print_line(){
    printf("-----------------\n");
}
int main(int argc, const char * argv[]) {
    //调用函数
    print_line();   
    return 0;
}</span>

2、无参有返回值函数定义 

一般形式如下: 

返回值类型 函数名()

{

    声明部分

    语句

}

return 返回值类型变量或常量;

//返回给主调函数

其中返回值类型和函数名称为函数头。 返回值类型指明了本函数的返回值类型。函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少。 

{}中的内容称为函数体。在函数体中声明部分,是对函数体内部所用到的变量的类型说明。 

在很多情况下都不要求无参函数有返回值,此时函数类型符可以写为void。

<span style="font-size:14px;">#include <stdio.h>
/**
 *  无参有返回值的函数
 *
 *  @return int类型
 */
int sum(){
    //1、定义变量
    int num1,num2;
    int result=0;    
    //2、提示用户输入两个数
    printf("请输入两个数,用\",\"分隔\n");    
    //3、接收用户输入的两个数
    scanf("%d,%d",&num1,&num2);   
    //4、进行计算
    result = num1 + num2;    
    //5、返回计算的结果
    return result;
}
int main(int argc, const char * argv[]) {
    // 从键盘上输入两个数,计算他们的和
    int s = sum();
    printf("s = %d\n",s);
    return 0;
}</span><span style="font-size:12px; font-family: SimSun; background-color: rgb(255, 255, 255);"> </span>

3、有参无返回值函数定义

一般形式如下: 

void 函数名(形式参数表列)

{

    声明部分

    语句

}

形式参数表列表的格式:类型 变量名,类型 变量2,.......

<span style="font-size:14px;">#include <stdio.h>
/**
 *  有参数无返回值类型的函数
 *  功能:打印n条线
 */
int n = 10;
//                定义了一个整形变量 n,n也称之为形参变量名
void print_line_n(int n){
    //n的作用域:从定义的位置开始,到函数的"}"结束
    for (int i=0; i<n; i++) {
        printf("--------------\n");
    }
}
int main(int argc, const char * argv[]) {   
    print_line_n(5);    
    return 0;
}</span>

4、有参有返回值函数定义 

一般形式如下: 

返回值类型 函数名(形式参数表列)

{

    声明部分

    语句

    return 返回值类型变量或常量;

}

有参函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数,它们可以是各种类型的变量,各参数之间用逗号间隔。在进行函数调用时,主调函数将赋予这些形式参数实际的值。形参既然是变量,必须在形参表中给出形参的类型说明  

注意:定义函数时注意函数名不能重复

<span style="font-size:14px;">#include <stdio.h>
//定义了两个形式参数(形参) 分为int类型的x和int类型的y
int max(int x,int y){   
    //用if的方式判断
    if (x>y) {
        return x;       
    }else{   
        return y;
    }
    printf("xxxxoooo");
}
int max1(int x,int y){   
    return x>y?x:y;    
}
int main(int argc, const char * argv[]) {
    //求两个数的最大值,用函数实现
    int m = max1(12, 38);
    printf("m = %d\n",m);
    return 0;
}</span>

三、函数的参数 

1、形式参数介绍和使用 

定义函数的时候,函数名后面小括号中的参数,简称形参。 

形式参数是什么样类型的数据,那么实际参数也必须是什么样的类型 

函数内部不可以定义与函数形参同名的变量,因为形参与函数的代码是一个代码块 

2、实际参数介绍和使用 

   调用函数的时候,函数名后面小括号中的参数,简称实参

实参出现在主调函数中,进入被调函数后,实参变量也不能使用。

形参和实参的功能是作数值的传递。

发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。

<span style="font-size:14px;">#include <stdio.h>
float max(int x,float y){
    //int x;
    return  x>y?x:y;
}
int main(int argc, const char * argv[]) {   
    float m = max(30, 83.4f);
    printf("m = %f\n",m);   
    return 0;
}</span>

四、函数的参数传递过程 

1、函数的参数传递过程 

1)形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。  

2)实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得 确定值。  

3)实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配的错误。

<span style="font-size:14px;">#include <stdio.h>
int sum(int x,int y){
    x = 10,y=20;
    return  x+y;
}
int main(int argc, const char * argv[]) {
    //          double
    double d1 = 4.5,d2 = 56.3;
    int d = sum(d1, d2);
    printf("%d\n",d);    
    return 0;
}</span>

五、函数的返回值及注意事项 

1、函数的返回值  

函数的值(或称函数返回值)是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值。  

2、使用注意事项 

1) 函数的值只能通过return语句返回主调函数。return语句的一般形式为: 

return 表达式;

或者为:

return (表达式);

该语句的功能是计算表达式的值,并返回给主调函数。在函数中允许有多个return语句,但每次调用只能有一个return 语句被执行,因此只能返回一个函数值。 

2) 函数返回值的类型和return实际返回的值类型应保持一致。如果两者不一致,则以return实际类型为准,自动进行类型转换。  

3) 如函数值为整型,在函数定义时可以省去类型说明。 也就是说如果没有指定返回类型,那么C语言默认是int的类型(开发中不要省略返回值类型) 

4) 不返回函数值的函数,可以明确定义为“空类型”,类型说明符为“void”。 为了使程序有良好的可读性并减少出错, 凡不要求返回值的函数都应定义为空类型。

<span style="font-size:14px;">#include <stdio.h>
//sum相对main被调函数
//int sum(int x,int y){
//
//    float b = 3.4f;  //float
//    return b;        //float
//}
sum(int x,int y){   
    return x+y;
}
//main 相对 sum 是一个主调函数
int main(int argc, const char * argv[]) {   
    printf("sum = %d\n",sum(34, 12));
    return 0;
}<span style="font-family: SimSun; background-color: rgb(255, 255, 255);"> </span></span>

六、函数的声明

1、函数的声明

在主函数调用函数之前应该对该被调用函数进行声明(声明),这与使用变量之前要先进行变量说明是一样的。

在主调函数中对被调函数作说明的目的是使编译系统知道被调函数返回值的类型,以便在 

主调函数中按此种类型对返回值作相应的处理。 

其一般形式为: 

返回值类型 被调函数名( 类型 形参, 类型 形参... ); 

或为: 

返回值类型 被调函数名( 类型, 类型...); 

如: 

int max( int a, int b );

int max( int, int );

注意:

1) 如果被调函数的返回值是整型时,可以不对被调函数作说明,而直接调用。这时系统将自动对被调函数返回值按整型处理。 

2) 当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数再作说明而 直接调用。 

3) 普通的函数声明

<span style="font-size:14px;">#include <stdio.h>
//全局的方法声明
void test1();
void test3();
int main(int argc, const char * argv[]) {
    //函数test1的声明
    int max(int x,int y);
    //调用test1()
    test1();
    test3();
    //调用max并保存max函数返回的值,到m中
    int m = max(45, 23);   
    m = sum(45, 23);
    printf("m = %d\n",m);  
    return 0;
}
void test2(){    
    printf("我是test2!\n");
    test3();    
}
void test1(){    
    printf("我是test1!\n");
    //void test2();
    test2();    
}
int max(int x,int y){
    return x>y?x:y;
}
int sum(int x,int y){
    return x+y;
}
void test3(){
     printf("我是test3!\n");  
}</span><span style="font-family: SimSun; background-color: rgb(255, 255, 255);"><span style="font-size:14px;"> </span><span style="font-size:12px;"> </span></span>

七、函数的调用

1、函数的调用 

C语言中,函数调用的一般形式为:  

函数名(实际参数表);  

对无参函数调用时则无实际参数表。 实际参数表中的参数可以是常数,变量或其它构造类型数据及表达式。 各实参之间用逗号分隔。 

1) 函数表达式 

函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数 是有返回值的。 

int z=0;

z = max(23, 80)+1; 

2) 函数语句 

函数调用的一般形式加上分号即构成函数语句。 

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

3) 函数实参 

函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因 此要求该函数必须是有返回值的。  

printf("%d\n",max(20, 30)); 

4)函数名不能和变量名同名 

2、函数的嵌套调用 

C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用。即在被调函数中又调用其它函数。这与其它语言的子程序嵌套的情形是类似的。

<span style="font-size:14px;">#include <stdio.h>
int max(int x,int y){
    return  x>y?x:y;  //34
}
int sum(int x,int y){
    return x+y;
}
int main(int argc, const char * argv[]) {    
    //1、实参是整型常量
    int a  =58,b=12;
    int m = max(34,12);
    //2、实参是变量
    m = max(a, b);    
    //3、实参可以是一个表达式
    m = max(a+3, b+5);
    m = max(a=100, b++);    
    //函数调用的注意事项
    //1) 函数表达式
    m = max(34, 10)+10;   
    //2)函数调用作为另外一个函数的实参  
    m = sum(max(56, 438),120);    
    //3)函数的嵌套调用
    m = max(max(56, 438),120);
    // 3个数最大值?    
    //4)函数名不能和变量名同名
    //int max = max(4,23);    
    printf("m = %d\n",m);
    return 0;
}</span>

八、递归函数概述及构成条件 

1、递归函数概述及用法 

一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。C语言允许函数 的递归调用。在递归调用中,主调函数又是被调函数。执行递归函数将反复调用其自身,每调用一次就进入新的一层。  

这个函数是一个递归函数。但是运行该函数将无休止地调用其自身,这当然是不正确的。为了防 止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满 足某种条件后就不再作递归调用,然后逐层返回。

2、递归函数构成条件 

1)自己调用自己 

2)存在一个条件能够让递归结束 

3)问题的规模能够缩小 

<span style="font-size:14px;">#include <stdio.h>
void test1(){
    printf("什么是幸福?当别人饥饿的时候,我吃肉不biaji嘴!\n什么是浪漫?明知道她不喜欢你,还送他999朵玫瑰\n什么是浪费?明知道她喜欢你,你还送她999朵玫瑰!\n");   
    test1();  //这就是递归调用   
}
//定义一个函数
//计算年龄的方法
int getAge(int n){
    int age;
    //如果 n == 1  年龄是10
    if (n==1) {
        //n==1 表示第一个人,他的年龄是10
        age = 10;
    }else{
        //如果不是第一个人,当前这个人得年龄 = 前一个人(n-1)得年龄+2
        age = getAge(n-1)+2;
    }
    return age;
}
int main(int argc, const char * argv[]) {    
    int age = getAge(5);
    printf("age = %d\n",age);    
    return 0;
}</span>
                                                                          ------- Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值