C语言——用函数实现模块化程序设计

1 为什么要用函数

函数就是功能,每一个函数用来实现一个特定的功能。函数的名字反应其代表的功能
注:
1 一个C程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件,一个源程序文件可以作为多个C程序共用
2 一个源程序文件由一个或多个函数以及其他有关内容组成,一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译,而不是以函数为单位进行编译
3 C程序的执行是从main函数开始的,如果在main函数中调用其他函数在调用后流程返回main函数,在main函数中结束整个程序的运行
4 所有的函数都是平行的,即在定义函数时是分别进行的,是互相独立的
5 从用户使用的角度看,函数有两种:<1>库函数 <2>用户自己定义的函数用以解决用户专门需要的函数
6 从函数的形式看,函数分为两类:<1>无参函数。无参函数可以带回或不带回函数值,但一般不带回函数值<2>有参函数。

2 怎样定义函数

1 指定函数的名字,以便以后按名调用;
2 指定函数的类型,即函数返回值的类型;
3 指定函数的参数的名字和类型,以便在调用函数时向他们传递数据。对无参函数不需要这项
4 指定函数应当完成什么操作,也就是函数是做什么的,即函数的功能。

3 定义函数的方法

3.1 定义无参函数。如print_start
3.2 定义有参函数.如:int max(int x,int y){ int z; z=x+y; return(z);}
3.3 定义空函数;如:void sum{}

4 调用函数

一般调用形式:函数名(实参表列)

3种函数调用方式:
1 函数调用方式:把函数调用单独作为一个语句,如"printf_star();",这时不要求函数带回值,只要求函数完成一定操作
2 函数表达式:函数调用出现在另一个表达式中
3 函数参数:函数调用作为另一个函数调用时的实参

5 函数调用时的数据传递

5.1 形式参数和实际参数
在调用有参函数式,主调函数和被调函数之间有数据传递关系。
在定义函数式函数名后面括号中的变量名称为 “形式参数” 或“虚拟参数”
在主调函数中调用一个函数时,函数名后面括号中的参数称为 “实际参数”

5.2 实参和形参间的数据传递
在调用函数的过程中,系统会将实参的值传给形参,其中的数据传递称为 “虚实结合”

注:
1 实参可以是常量、变量或表达式
2 实参与形参的类型应相同或赋值兼容

6 函数调用的过程

1 形参在为调用之前不占内存存储单元,只有调用的时候系统才会给它分配内存单元;
2 当系统调用的时候,会将实参的值换递给形参;
3 函数调用期间,形参已经分配了临时的存储空间,即已经有值故而直接使用形参进行相关运算;
4 被调用的函数会通过return将值传递回调用函数里面;
5 当调用结束,给形参的存储空间自动释放。
注:实参向形参的数据传递是"值传递",单向传递,只能由实参传给形参,而不能由形参传给实参。实参和形参在内存中占有不同的存储单元,实参无法得到形参的值

7 函数的返回值

1 函数的返回值是从return中获取;
2 函数值的类型与函数定义有关;
3 在定义函数时指定的函数类型一般应该和return语句中的表达式一致即:函数类型决定返回值的类型。
4 对于不返回值的番薯,应当是定义函数为void类型(或称空类型)。

8 对被调用函数的声明和函数原型

函数声明一般形式有两种,分别为:
1 函数类型 函数名(参数类型1 参数名1,参数类型2 参数名2,…,参数类型n 参数名n);
2 函数类型 函数名(函数类型1,函数类型2,…,函数类型n);
注:
1 被调用的函数必须是已经定义的函数;
2 如果使用的是库函数,必须在开头调用#include指令,将有关的库函数所需的信息包含的文件夹中来
3 如果使用的是自己定义的函数,且函数的位置在调用它的函数后面,则需要在主函数中对被调用的函数进行声明。即:简概而论就是将定义的函数头放到主函数中

9 函数的嵌套调用

C语言的函数定义是互相平行,独立的,也就是说,在定义函数时,一个函数内不能在定义另一个函数,即不能嵌套定义,但可以嵌套调用函数,即再调用一个函数的过程中,又调用另一个函数

10 函数的递归调用

在调用一个函数的过程中又出现直接或间接调用该函数本身,称为函数的递归调用

11 数组作为函数参数

数组元素可以用作函数实参,但是不能用作形参。因为形参在函数调用时临时分配存储单元的,不可能为一个数组元素单独分配存储单元(数组是一个整体,在内存中占连续的一段存储单元)。在用数组元素做函数实参时,把实参的值传给形参,是“值传递”方式。数据传递的方向是从实参传到形参,单向传递

12 局部变量和全局变量

12.1 局部变量

在一个函数内部定义的变量只在本函数范围内有效,也就是说只有在本函数内才能引用它们,在此函数以外是不能使用这些变量的。在复合语句内定义的变量只在本复合语句范围内有效,只有在本复合语句内才能引用它们。在该复合语句以外是不能使用这些变量的,以上这些称为“局部变量”
注:
1 在主函数定义的变量,也只能在主函数内部使用,不能在其他函数中使用
2 不同函数中可以定义相同名字的变量,互不影响
3 形式参数也属于局部变量
4 在复合语句中(即程序块)定义的变量,生命周期在该复合语句结束的时候自动释放,因此也只能在复合语句中使用

12.2 全局变量

在函数内定义的变量是局部变量,而在函数之外定义的变量称为外部变量,外部变量是全局变量(也称全程变量)。全局变量可以为文件中其他函数所共用。它的有效范围从定义变量的位置开始到本源文件结束
注:
1 在函数内定义的变量是局部变量,在函数外定义的变量是全局变量
2 全局变量的生命周期是整个文件,因此若无必要则浪费系统存储单元空间
3 它会使函数的通用性降低,在划分模块要求将模块的“内聚性”强、与其他模块的“耦合性”弱,即尽量封闭
4 使用全局变量会降低程序的清晰性

13 变量的存储方式和生存期

13.1 动态存储方式和静态存储方式

变量的存储方式有两种不同的方式:静态存储方式和动态存储方式
静态存储方式:在程序运行期间由系统分配固定的存储空间的方式
动态存储方式:在程序运行期间根据需要进行动态的分配存储空间的方式
内存中供用户使用的存储空间的情况:
程序区;
静态存储区;
动态存储区。
数据分别放在静态存储区和动态存储区中。全局变量全部存放在静态存储区中
在C语言中每一个变量和函数都有两个属性:数据类型和数据的存储类别
C的存储类别包括4中:自动的,静态的,寄存器的,外部的

13.2 局部变量的存储类别

13.2.1 自动变量(auto变量)

在调用函数的时候,系统会自动分配这些变量的存储空间,并在函数调用结束的时候自动释放这些空间,这类变量称为自动变量。
自动变量一般用auto作为存储类别的声明,实际上,关键字auto可以省略,不写auto则隐含指定为“自动存储类别”。

13.2.2 静态局部变量(static局部变量)

有时希望函数的局部变量的值在函数调用结束后继续保持原值,即其占有的存储单元不被释放,在下一次在调用该函数时,该变量已有值(就是上一次调用结束时的值)。这时就应该指定该局部变量为"静态局部变量"
注:
1 静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不被释放
2 对静态局部变量是在编译时赋初值的,即只赋值一次,在程序运行时它已有初值
3 如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0或空字符’\0’
4 静态局部变量虽然生存周期长,但仍然是局部变量,其他函数不能引用它

13.2.3 寄存器变量(register变量)

一般对于使用非常频繁地变量定义为寄存器变量,因为寄存器的存储速度远远高于内存的存取速度,这样可以提高执行效率
注:3种局部变量的存储位置是不同的:自动变量存储在动态存储区:静态局部变量存储在静态存储区:寄存器变量存储在CPU中的存储器中

13.3全局变量的存储类别

13.3.1 在一个文件内扩展外部变量的作用域

外部变量的生存周期在它定义点到文件结束。它之前的部分不能引用它。可以使用extern进行外部变量声明,就可以从声明处之后引用该变量了。

13.3.2 将外部变量的作用域扩展到其他文件

在要调用外部变量的文件中用extern将外部变量的作用域扩展到本文件中来即可。

13.3.3 将外部变量的作用域限制在本文件中

当静态外部变量定义声明前加上static,则为限制只能用于本文件的外部变量
注:
1 你不要误以为对外部变量加static声明后才采取静态存储的方式(存放在静态存储区中),而不加static的是采取动态存储(存放在动态存储区中)
2 用static声明一个变量的作用是:
对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,其所分配的空间始终存在
对全局变量用static声明,则该变量的作用域只限于本文件模板(即被生命的文件中)

14 关于变量的声明和定义

一个函数一般由两部分组成:声明部分和执行部分
在声明部分出现的变量有两种情况:一种是需要建立存储空间的,另一种是不需要建立存储空间的。前者称为定义性声明,后者称为引用性声明
一般,把建立存储空间的声明称定义,不需要建立存储空间的声明称为声明

15 内部函数和外部函数

15.1 内部函数

如果一个函数只能被本文件中的其他函数所调用,它称为内部函数(静态函数)即:static 类型名 函数名(形参表);

15.2 外部函数

如果在定义函数时,在函数首部的最左端加关键字extern,则此函数是歪外部函数,可以被其他文件调用即:extern int fun (int a,int b);
因此当在定义的时候省略了extern,则默认为外部函数。前面所有使用的程序都是外部函数。
因此在调用此函数的其他文件中,需要对此函数做说明,即使在本文件中调用一个函数,也要用函数原型进行声明,因此每次将main函数放在文件最下面,可以省略声明,但为了严谨也应该进行声明

你可能感兴趣的:(1024程序员节,c语言,开发语言)