购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

任务5
函数与编译预处理

1.函数

一个较大的程序通常由多个程序模块组成,每个模块用于实现一个特定的功能。在程序设计中,模块的功能是用子程序来实现的。在C语言中,子程序的作用是由函数来完成的。函数是C语言中的一种基本模块,一个C语言程序由一个主函数和若干个函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次,同一工程中的函数也可以分放在不同文件中一起编译。

从使用者的角度来看,函数有两种,即标准库函数和用户自定义函数。标准库函数是由C编译系统的函数库提供的,用户无须自己定义这些函数,即可直接使用它们;用户自定义函数是由用户根据自己的需要编写的函数,用于解决用户的特殊需求。

从函数的形式看,函数有3种,即无参函数、有参函数和空函数。无参函数被调用时,主调函数并不将数据传送给被调函数,一般用于执行指定的一组操作;无参函数可以带回或不带回函数值,但一般以不带回函数值的居多。有参函数被调用时,在主调函数与被调函数之间有参数传递,即主调函数可以将数据传给被调函数使用,被调函数中的数据也可以带回来供主调函数使用。空函数的函数体内无语句,是空白的;调用空函数时,什么工作都不做,不起任何作用;定义空函数的目的并不是为了执行某种操作,而是为了以后程序功能的扩充。

1) 函数定义的一般形式

(1)无参函数的定义形式如下:

其中,返回值类型标识符指明本函数返回值的类型;函数名是由用户定义的标识符;“()”内没有参数,但该括号不能少,或者括号里加关键字“void”;“{}”中的内容称为函数体语句。在很多情况下,无参函数没有返回值,所以函数返回值类型标识符可以省略,此时函数类型符可以写为“void”。例如:

(2)有参函数的定义形式如下:

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

在此定义了一个min函数,返回值为一个整数型(int)变量,形参为j和k,也都是整数型变量。int n语句定义n为一个整数型变量,通过if条件语句,将最小的值传送给变量n。return n的作用是将n的值作为函数值带回到主调函数中,即n的返回值。

(3)空函数的定义形式如下:

调用该函数时,实际上什么工作都不用做,它没有任何实际用途。例如:

2 函数的返回值 调用函数时,通过主调函数的实参与被调函数的形参之间进行数据传递来实现函数间的参数传递。在被调函数的最后,通过return语句返回函数,将被调函数中的确定值返回给主调函数。return语句一般形式如下:

函数返回值的类型一般在定义函数时用返回类型标识符来指定。在C语言中,凡不加类型说明的函数,都按整数型来处理。如果函数值类型的return语句中表达式的值不一致,则以函数类型为准,自动进行类型转换。

对于不需要有返回值的函数,可以将该函数定义为“void”类型(或称“空类型”)。这样,编译器会保证在函数调用结束时不使用函数返回任何值。为了使程序减少出错,保证函数的正确调用,凡是不要求有返回值的函数,都应该将其定义为void类型。例如:

3 ) 函数的调用 在C语言程序中,函数可以相互调用。所谓函数调用,就是在一个函数体中引用另外一个已经定义了的函数,前者称为主调函数,后者称为被调函数。

(1)函数调用的一般形式如下:

对于有参数型的函数,如果包含了多个实参,则应将各参数之间用逗号分隔开。主调函数的实参数量与被调函数的形参数量应该相等,且类型保持一致。实参与形参按顺序对应,逐一传递数据。

如果调用的是无参函数,则实参列表可以省略,但是函数名后面必须有一对括号。

(2)函数调用的方式。

函数语句调用:在主调函数中将函数调用作为一条语句,并不要求被调函数返回结果数值,只要求函数完成某种操作,例如:

函数表达式调用:函数作为表达式的一项出现在表达式中,要求被调函数带有return语句,以便返回一个明确的数值参与表达式的运算。例如:

作为函数参数调用:在主调函数中将函数调用作为另一个函数调用的实参。例如:

2.编译预处理

编译预处理是C语言编译器的一个重要组成部分,C语言提供的预处理功能有3种,即宏定义、文件包含和条件编译。

1 ) 宏定义 宏定义命令为#define,其作用是用一个简单易读的字符串来代替另一个字符串。宏定义可以增强程序的可读性和维护性。宏定义分为不带参数的宏定义和带参数的宏定义。

(1)不带参数的宏定义的一般形式为

其中,“#”表示这是一条预处理命令;“define”表示为宏定义命令;“标识符”为所定义的宏名;“字符串”可以是常数、表达式等。例如:

它的作用是指定用标识符(即宏名)PI代替“3.1415926”字符串,这种方法使用户能以一个简单的标识符代替一个长的字符串。当程序中出现3.1415926这个常数时,就可以用PI这个字符代替,如果想修改这个常数,只需要修改这个宏定义中的常数即可,这就是增加程序的维护性的体现。

(2)带参数的宏定义:带参数的宏在预编译时不仅要进行字符串替换,还要进行参数替换。带参数宏定义的一般形式为

带参数的宏调用的一般形式:

例如:

2 ) 文件包含 所谓“文件包含”处理,是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件中。在C语言中,“#include”为文件包含命令,其一般形式为

例如:

上述程序的文件包含命令的功能是将reg52.h、absacc.h和intrins.h文件插入该命令行位置,即在编译预处理时,源程序将reg52.h、absacc.h和intrins.h这3个文件的全部内容复制并分别插入到该命令行位置。

3 条件编译 通常情况下,在编译器中进行文件编译时,会对源程序中所有的行都进行编译(注释行除外)。如果程序员只想使源程序中的部分内容在满足一定条件才进行编译,可通过“条件编译”对一部分内容指定编译的条件来实现相应的操作。条件编译命令有以下3种形式。

(1)第1种形式:

其作用是,当标识符已经被定义过(通常是用#define命令定义),则对程序段1进行编译;否则,编译程序段2。如果没有程序段2,本格式中的“#else”可以没有。程序段1可以是语句组,也可以是命令行。

(2)第2种形式:

其作用是,当标识符没有被定义,则对程序段1进行编译;否则,编译程序段2。这种形式与第1种形式的作用正好相反,在书写上也只是将第1种形式中的“#ifdef”改为“#ifndef”。

(3)第3种形式:

其作用是,如果常量表达式的值为逻辑“真”,则对程序段1进行编译;否则,编译程序段2。可以事先给定一定的条件,使程序在不同的条件下执行不同的功能。 zc5pROkojYLSgTmcGh+iUOcoTr84D1PK/dZ1BfFbOex9cnwHPcyJcJ/I2AhNmSfJ

点击中间区域
呼出菜单
上一章
目录
下一章
×