黑马程序员——函数

时间:2022-08-27 11:08:14

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

一、函数概念

功能相对独立的代码段

二、函数的分类

分类:1.库函数和用户定义函数

        2.有返回值和无返回值

        3.有参函数和无参函数

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

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

三、函数的格式

    基本格式:  返回值类型    函数名(函数参数){函数体}

    函数头:返回值类型    函数名(函数参数)

    函数按照参数和返回值可分为:

    1.无参无返回值

      格式:void 函数名(){语句}

    2.无参有返回值

      格式:返回值类型 函数名(){语句;return 返回值类型变量或常量(返回给主调函数)}

    3.有参无返回值

      格式:void 函数名(形式参数){语句}

    4.有参有返回值

       格式:返回值类型 函数名(形式参数){语句;return 返回值类型变量或常量}

四、形式参数和实际参数

1.形式参数

在定义函数时,函数名后面的小括号()中定义的变量称为形式参数,简称形参

特点:1)形参定义后,并不会立即分配空间,在调用时才会真正分配空间。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。

      2)在被调函数中不能定义和形参同名的变量

2. 实际参数

在调用函数时传入的值称为实际参数,简称实参

特点:1)实参出现在主调函数中,实参变量不能在被调函数中使用。在被调用时必须是确定的值。

      2)实参与形参类型需一致,否则精度丢失。

      3)函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。形参的值在函数内部可以被修改,不会影响主调函数中实参的值,但是主调函数中的实参必须有数值。

五、函数的返回值

概念:被调函数返回给主调函数的值。

注意事项:1.函数返回值,用到一个关键字“return”。

          2.return(常量/变量/表达式) 括号可省略。

          3.返回值类型和函数定义的返回值类型不一致时,以定义的为准。

六、被调用函数的声明

在主调函数中对被调函数作说明的目的是使编译系统知道被调函数返回值的类型,以便在主调函数中按此种类型对返回值作相应的处理。

其一般形式为:
        类型说明符  被调函数名( 形参); 

注意:1.如果返回值是整型,可以不用声明,即类型省略。

      2.如果被调函数在主调函数之前,可以不用声明。

七、函数的调用

一般形式:函数名(实际参数表);

实参可以是整型常量:int m=max(34,56);

             变量:int a=34,b=56;

                    int m=max(a,b);

            表达式: int a=75,b=23;

                       1)int m=max(a+1,b+1);

                       2)int m=max(a=100,b++);

注意:1.m=max(34,45)+10 该形式也是对的。

      2.函数调用作为另外一个函数的实参,自身也可。

            m=sum(max(24,23),90);

      3.函数名不能与变量同名。

函数的嵌套,例如:计算s = 22! + 32!

 1 #include <stdio.h>
 2 
 3 long f1(int p){
 4     int k;
 5     long r;
 6     long f2(int);
 7     k=p*p;
 8     r=f2(k);
 9     return r;
10 }
11 
12 long f2(int q){
13     long c=1;
14     int i;
15     for(i=1;i<=q;i++)
16         c=c*i;
17     return c;
18 }
19 
20 int main(void){
21     int i;
22     long s=0;
23     for (i=2;i<=3;i++)
24         s=s+f1(i);
25     printf("\ns=%ld\n",s);
26 
27     return 0;
28 }

在程序中,函数f1和f2均为长整型,都在主函数之前定义,故不必再在主函数中对f1和f2加以说明。在主程序中,执行循环程序依次把i值作为实参调用函数f1求i2值。在f1中又发生对函数f2的调用,这时是把i2的值作为实参去调f2,在f2 中完成求i2!的计算。f2执行完毕把C值(即i2!)返回给f1,再由f1返回主函数实现累加。

八、递归函数

1.概念

一个函数在他的函数体调用本身称为递归函数。

2.构成条件

1)存在自己调用自己

2)存在一个可以结束递归函数的条件

3)有一个使要解决的问题规模缩小的规律,即使问题化为一小步来解决

例如:

 1  #inside <stdio.h>
 2 int main(){
 3   getage(5);
 4    return 0;
 5 }
 6  int getage(int i){
 7     int age;
 8     if(i==1){
 9    age=10;
10     }else{
11     age=getage(i-1)+2;
12    }return age;
13  }

黑马程序员——函数

当递推至if为真时,系统会进行出栈操作,并迭代计算出先前压栈进入内存的数值,当迭代计算完毕,递归结束。

3.优缺点

优点:问题规模能够缩小,且有规律,代码会比较简洁。

缺点:耗用内存大。

 九、#include指令

  #include指令:预处理指令。所谓预处理,就是在编译之前做的处理,预处理指令一般以 # 开头。

 #include指令文件包含命令的格式:

   1.#include “ ”

    包含一个用户定义的文件,可以是头文件,也可以是普通文件,如“a.TXT”。

    搜索顺序:1)在当前文件所在路径下查找

              2)第一步没有,则在编译器include路径下查找

              3)第二步没有,则在系统include路径下查找

              4)第三步没有,系统报错

   2.#include < >

   包含一个系统(编译器自带)的头文件。

   搜索顺序:1)第一步没有,则在编译器include路径下查找

             2)第二步没有,则在系统include路径下查找

             3)第三步没有,系统报错

十、模块化编程

1.概念

把功能相似的函数封装到不同的文件中。

2.实现条件

1)文件名.c

   此文件为C语言源文件,函数定义放在.c源文件中。

2)文件名.h

   此文件C语言函数库中的一个头文件,里面声明了一些常用的输入输出函数。

3.优点

1)使用时,只需包含.h的文件即可,源文件则对外隐藏

2)可以把功能细化为多个模块

3)避免代码冲突,节约编程时间