zoukankan      html  css  js  c++  java
  • 【C语言】02-函数

    一、函数的分类

    前面已经说过,C语言中的函数就是面向对象中的"方法",C语言的函数可以大概分为3类:

    1.主函数,也就是main函数。每个程序中只能有一个、也必须有一个主函数。无论主函数写在什么位置,C程序总是从主函数开始执行

    2.开发人员自定义的函数,可有可无,数目不限

    3.C语言提供的库函数,例如stdio.h中的输出函数printf()和输入函数scanf()


    二、函数的声明和定义

    虽说C中的函数类似于Java中的方法,但在使用上还是有区别的。

    1.在Java中,每个方法的定义顺序没有限制,在前面定义的方法内部可以调用后面定义的方法

    复制代码
    1 public void test() {
    2      int c = sum(1, 4);
    3  }
    4  
    5  public int sum(int a, int b) {
    6      return a + b;
    7  }
    复制代码

    第1行定义的test方法可以调用在第5行定义的sum方法

    2.在标准C语言中,函数的定义顺序是有讲究的,默认情况下,只有后面定义的函数才可以调用前面定义过的函数

    复制代码
    1 int sum(int a, int b) {
    2      return a + b;
    3  }
    4  
    5  int main()
    6  {
    7      int c = sum(1, 4);
    8      return 0;
    9  }
    复制代码

    第5行定义的main函数调用了第1行的sum函数,这是合法的。如果调换下sum函数和main函数的顺序,在标准的C编译器环境下是不合法的(不过在Xcode中只是警告,Xcode中用的是GCC编译器)

    3.如果想把其他函数的定义写在main函数后面,而且main函数能正常调用这些函数,那就必须在main函数前面作一下函数的声明

    复制代码
     1 // 只是做个函数声明,并不用实现
     2  int sum(int a, int b);
     3  
     4  int main()
     5  {
     6      int c = sum(1, 4);
     7      return 0;
     8  }
     9  
    10  // 函数的定义(实现)
    11  int sum(int a, int b) {
    12      return a + b;
    13  }
    复制代码

    我们在第2行做了sum函数的声明,然后在第6行(main函数中)就可以正常调用sum函数了。

    函数的声明格式:

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

    可以省略参数名称,比如上面的sum函数声明可以写成这样:

    int sum(int, int);

    只要你在main函数前面声明过一个函数,main函数就知道这个函数的存在,就可以调用这个函数。究竟这个函数是做什么用,还要看函数的定义。如果只有函数的声明,而没有函数的定义,那么程序将会在链接时出错。

    4.在大型的C程序中,为了分模块进行开发,一般会将函数的声明和定义(即实现)分别放在2个文件中,函数声明放在.h头文件中,函数定义放在.c源文件中

    下面我们将sum函数的声明和定义分别放在sum.h和sum.c中

    sum.h文件

    sum.c文件

    然后在main.c中包含sum.h即可使用sum函数

    其实sum.h和sum.c的文件名不一样要相同,可以随便写,只要文件名是合法的

    运行步骤分析:

    1> 在编译之前,预编译器会将sum.h文件中的内容拷贝到main.c中

    2> 接着编译main.c和sum.c两个源文件,生成目标文件main.obj和sum.obj,这2个文件是不能被单独执行的,原因很简单:

    * sum.obj中不存在main函数,肯定不可以被执行

    * main.obj中虽然有main函数,但是它在main函数中调用了一个sum函数,而sum函数的定义却存在于sum.obj中,因此main.obj依赖于sum.obj

    3> 把main.obj、sum.obj链接在一起,生成可执行文件

    4> 运行程序

    说到这里,有人可能有疑惑:可不可以在main.c中包含sum.c文件,不要sum.h文件了?

    大家都知道#include的功能是拷贝内容,因此上面的代码等效于:

    这么一看,语法上是绝对没有问题的,但是绝对运行不起来,在链接时会出错。原因:编译器会编译所有的.c源文件,这里包括main.c、sum.c,编译成功后生成sum.obj、main.obj文件,当链接这两个文件时链接器会发现sum.obj和main.obj里面都有sum函数的定义,于是报"标识符重复"的错误。

    有人可能觉得分出sum.h和sum.c文件的这种做法好傻B,好端端多出2个文件,你把所有的东西都写到main.c不就可以了么?

    • 没错,整个C程序的代码是可以都写在main.c中。但是,如果项目做得很大,你可以想象得到,main.c这个文件会有多么庞大,会严重降低开发和调试效率。
    • 要想出色地完成一个大项目,需要一个团队的合作,不是一个人就可以搞的定的。如果把所有的代码都写在main.c中,那就导致代码冲突,因为整个团队的开发人员都在修改main.c文件,张三修改的代码很有可能会抹掉李四之前添加的代码。
    • 正常的模式应该是这样:假设张三负责编写main函数,李四负责编写一系列的自定义函数,张三需要用到李四编写的某个函数,怎么办呢?李四可以将所有的函数声明在一个.h文件中,比如lisi.h,然后张三在他自己的代码中包含lisi.h文件,接着就可以调用lisi.h中声明的函数了,而李四呢,可以独立地在另外一个文件中(比如lisi.c)编写函数的定义,实现那些在lisi.h中声明的函数。这样子,张三和李四就可以相互协作、不会冲突。

    三、函数的形参和实参

    在定义函数时,函数名后面的()中定义的变量称为形式参数(形参);在调用函数时传入的值称为实际参数(实参)。

    复制代码
    // b是test函数的形参(形式参数)
    void test(int b) 
    { b = 9; // 改变了形参b的值 } int main() { int a = 10; printf("函数调用前的a:%d ", a); test(a); // a是test函数的实参(实际参数) printf("函数调用后的a:%d", a); return 0; }
    复制代码

    如果是基本数据类型作为函数的形参,那是简单的值传递,将实参a的值赋值给了形参b,相当于

    int a = 10;
    int b = a;
    b = 9;

    a和b是分别有着不同内存地址的2个变量,因此改变了形参b的值,并不会影响实参a的值。

    上述代码的输出结果为:

    关于函数的补充

    C程序由函数构成。函数是C程序的基本单位。程序的全部工作都是由各个函数分别完成。被调用的函数可以是系统提供的库函数,也可以是用户根据需要自己编制设计的函数。C的函数相当于其他语言中的子程序。

    一个较大的程序一般应分为若干个程序模块,每一个模块用来实现特定的功能。

    一个C程序可由一个主函数和若干个其他函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用多次。

    在程序开发中,常将一些常用的功能模块编写成函数,放在公共函数库中供大家选用。程序设计人员要善于利用函数,以减少重复编写程序段的工作量。

    一个C程序的说明

    一个C程序由一个或多个程序模块组成,每一个模块作为一个源程序文件。对于较大程序,一般不希望把所有内容全放在一个文件中,而是将它们分别放在若干个源文件中,再由若干个源程序文件组成一个C程序。这样写便于分别编写、分别编译,提高调试效率。一个源程序文件可以由多个C程序公用。

    一个源程序文件由一个或多个函数以及其它内容(命令行、数据定义等)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译,而不是以函数为单位进行编译。

    C程序的执行是从main函数开始的,如果在main函数中调用其他函数,在调用后流程返回到main函数,在main函数中结束整个程序的运行

    所有函数都是平行的,即在定义函数时是分别进行的,是互相独立的。一个函数并不从属与另一个函数,即函数不能嵌套定义。函数可以互相调用,但不能调用main函数,main函数由系统调用

  • 相关阅读:
    PHP filter_input_array() 函数
    pt-query-digest 用法
    [SDOI2017]苹果树
    C# json 转 xml 字符串
    C# json 转 xml 字符串
    C# double 好用的扩展
    C# double 好用的扩展
    win10 uwp 使用 Microsoft.Graph 发送邮件
    win10 uwp 使用 Microsoft.Graph 发送邮件
    Sublime Text 安装中文、英文字体
  • 原文地址:https://www.cnblogs.com/haijiabei/p/4838018.html
Copyright © 2011-2022 走看看