七、C语言之用函数实现模块化程序设计

7.1 为什么要用函数?

首先有一个问题:为什么要用函数?如果程序功能较多,并都在main函数中实现,就会使得程序冗长且复杂,不易理清,增大阅读以及后续维护难度。同时如果要多次实现某一功能,则需要多次编写相同代码,使得程序过于冗长,不精练。

模块化即一个功能或多个功能组成一个模块,当需要什么功能,则使用什么模块,好比就是组装电脑,当需要主板,则装上主板,需要电源,则插上电源。需要注意的是:主函数可以调用其他函数,其他函数之间可以相互调用。

注意:函数即是功能,每一个函数实现一个特定的功能,函数的名字应反应其代表的功能。

当定义的函数在main函数之后,而main函数要调用该函数,在这种情况下,则需在main函数之前或main函数中调用该函数之前对该函数进行函数声明(函数声明:将有关函数的信息:返回值类型、函数参数类型及个数、函数名称告知编译系统,在编译系统进行编译时知道是函数)。

说明:

(1)一个C程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件(一个源程序文件是一个编译单位),对于较大的程序,则由若干个源程序文件组成一个C程序。这样便于编写和编译,提高调试效率。

(2)所有函数均是平行的,一个函数并不从属于另一个函数。函数不能嵌套定义,但是可以嵌套调用。

7.2 怎样定义函数?

对于变量以及函数来说,都是先定义后使用。定义的作用在于让编译系统知道,函数名字叫什么,函数返回值类型是什么,函数参数类型以及个数是哪些?

定义函数:函数名、函数返回值类型、函数参数类型以及个数、函数体(具体实现什么功能):函数体包括声明部分和语句部分,声明部分包括对调用函数的声明以及对使用变量的定义。

函数:从用户的角度看,函数分为库函数以及自己定义的函数;从函数的形式看,分为有参函数和无参函数。

函数可分为内部函数和外部函数,如果一个函数只能在本文件中被其他函数所调用,它称为内部函数,在定义内部函数时添加static关键字,内部函数又称为静态函数。外部函数为在函数首部添加关键字extern或在定义时省略extern,默认为外部函数,可供其他文件调用。

注意:在需要调用此函数的其他文件中,需要对此函数作声明,不要忘记,即使在本文件中调用一个函数,也要用函数原型进行声明。声明=让编译器认识。

7.3 如何调用函数?

举例:

print_star(); //调用无参函数

c = max(a,b); //调用有参函数

注意:函数调用不一定需要有分号,如果作为函数表达式或函数参数,函数调用本身是不必有分号的。

函数调用时数据传递:

首先确认形式参数和实际参数的不同:形式参数是指函数定义时函数名后面括号中变量称为形式参数(形参);在调用函数时,函数名后面括号中的参数称为实际参数(实参);实际参数可以是常量、变量或表达式。

数据传递方向为:实参传递至形参。

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

函数调用过程:

(1) 定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元,在发生函数调用时,形参被临时分配内存单元。

(2) 调用结束,形参单元被释放。注意:实参单元仍保留并维持原值,没有改变。实参向形参的数据传递是值传递,单向传递,只能由实参传给形参,而不能由形参传给实参。实参和形参在内存中占有不同的存储单元。

函数的返回值:

(1)函数的返回值是通过函数中的return语句来获得的。

(2)函数类型决定返回值的类型。

(3)对于不带返回值的函数,应当用定义函数为“void类型”(空类型)

函数的嵌套调用:在调用一个函数过程中,又调用另一个函数。

函数的递归调用:直接或间接的调用该函数本身。

7.3.1 数组作为函数参数

数组名也可以作实参和形参,传递的是数组第一个元素的地址。

(1)数组元素作函数实参。数组元素不可作为形参,原因在于形参是在调用时临时分配存储单元的,不可能为一个数组元素单独分配存储单元(数组是一个整体,在内存中占连续的一段存储单元)。

(2)数组名作函数参数。数组名作函数实参时,向形参(数组名或指针变量)传递的是数组首元素的地址。

(3)多维数组名作函数参数。多维数组名作实参、形参时,同样代表数组首元素的地址。形参中二维数组中第一维大小可省略,第二维大小不可省略。

7.3.2 局部变量和全局变量

对于变量,可从两个方面进行梳理,一个是作用域、一个是存在性。

对于作用域来说:可分为局部变量和全局变量。

定义变量,有三种情况

(1)在函数开头定义;

(2)在函数内的复合语句内定义;

(3)在函数的外部定义;

局部变量:函数内定义、复合语句内定义。主函数定义的变量只在主函数中有效,主函数不能使用其他函数定义的变量。不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰。形参也属于局部变量。复合语句中定义的变量,离开该复合语句该变量就无效,系统会把它占用的内存单元释放。

全局变量(首字母大写):函数之外定义。全局变量可以被本文件中其他函数所调用。它的作用域为从定义变量的位置到本文件结束。设置全局变量的作用在于增加函数之间数据联系的渠道,通过函数调用能得到一个以上的值。

变量的存储方式和生存期

从存在性角度看,存储方式可分为静态存储方式(程序运行期间由系统分配固定的存储空间)以及动态存储方式(根据需要动态的分配存储空间)。

对于局部变量,可分为static定义的静态局部变量、自动变量(auto)、寄存器变量。

静态局部变量是在编译时赋初值的,只赋初值一次,在程序运行时,它已有初值,该静态局部变量会保留上次函数调用结束时的值。对于自动变量,则是在函数调用时赋初值的,每调用一次函数重新给一次初值。在定义静态局部变量不赋初值的话,编译时自动赋初值为0或‘\0’。而对于自动变量来说,其值不确定。对于静态局部变量,其他函数不能进行引用,只能被本函数引用。

对于全局变量,存放在静态存储区中。有时程序设计人员想要扩展外部变量的作用域,有以下几种情况。

1、在一个文件内扩展外部变量的作用域:在引用之前用extern扩展作用域。

2、将外部变量的作用域扩展到其他文件:在一个文件中定义该变量,在需要引用该变量的文件中用extern对该变量作外部变量声明。

3、将外部变量的作用域限制在本文件中: 在定义外部变量时,加一个static声明。即静态外部变量。

注意:对局部变量使用static,称为静态局部变量,静态局部变量存放在静态存储区。程序运行期间不释放。同时静态局部变量不可被其他函数引用。而对全局变量使用static表示只在本文件中使用,存放区域仍然为静态存储区。

你可能感兴趣的:(AUTOSAR,电驱,C语言,c语言)