首页 理论教育C语言无返回值函数库函数实现流水灯控制

C语言无返回值函数库函数实现流水灯控制

【摘要】:② 无返回值函数:此类函数用于完成某项特定的处理任务,执行完成后不向调用者返回函数值。C语言提供了极为丰富的库函数,这些库函数又可从功能角度进行以下分类。习惯上把调用者称为主调函数。根据图4-40,P0端口连接8位LED灯,利用标准库函数实现流水灯的控制。

使用函数是实现结构化程序设计思想的重要方法。结构化程序设计思想的重点之一就是模块化,即把一个复杂的、较大的程序划分成若干个模块,每个模块完成一个特定的功能,各个模块通常由不同的人来编写和调试,模块之间相互独立,靠参数的传递实现模块之间进行联系,从而把一个复杂的问题“分而治之”,这种方法便于组织人力共同完成比较复杂的任务。

一个C语言程序是由若干个函数构成的,C语言中的所有函数都是一个独立的程序模块。一个C程序总是从main函数开始执行,调用其他函数后,流程仍将返回到main函数,最后在main函数中结束程序的运行。其他函数也可以相互调用,同一函数可以被一个或多个函数调用任意次。但是main()函数是系统调用的,不能被其他函数调用。

4.6.1 函数的分类与定义

C源程序是由函数组成的。函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能。C语言不仅提供了极为丰富的库函数,还允许用户建立自己定义的函数。用户可把自己的算法编成一个个相对独立的函数模块,然后用调用的方法来使用函数。由于采用了函数模块式的结构,C语言易于实现结构化程序设计。

在C语言中可从不同的角度对函数分类。

(1)从函数定义的角度看,函数可分为库函数和用户定义函数两种。

① 库函数:由C系统提供,用户无须定义,也不必在程序中做类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。

② 用户定义函数:由用户按需要写的函数。

(2)C语言的函数兼有其他语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。

① 有返回值函数:此类函数被调用执行完后将向调用者返回一个执行结果,称为函数返回值。如数学函数即属于此类函数。由用户定义的这种要返回函数值的函数,必须在函数定义和函数说明中明确返回值的类型。

② 无返回值函数:此类函数用于完成某项特定的处理任务,执行完成后不向调用者返回函数值。这类函数类似于其他语言的过程。由于函数无须返回值,用户在定义此类函数时可指定它的返回为“空类型”,空类型的说明符为“void”。

(3)从主调函数和被调函数之间数据传送的角度看,又可分为无参函数和有参函数两种。

① 无参函数:函数定义、函数说明及函数调用中均不带参数。主调函数和被调函数之间不进行参数传送。此类函数通常用来完成一组指定的功能,可以返回或不返回函数值。

② 有参函数:也称为带参函数。在函数定义及函数说明时都有参数,称为形式参数(简称为形参)。在函数调用时也必须给出参数,称为实际参数(简称为实参)。进行函数调用时,主调函数将把实参的值传送给形参,供被调函数使用。

(4)C语言提供了极为丰富的库函数,这些库函数又可从功能角度进行以下分类。

字符类型分类函数:用于对字符按ASCII码分类:字母、数字、控制字符、分隔符、大小写字母等。

② 转换函数:用于字符或字符串的转换;在字符量和各类数字量(整型,实型等)之间进行转换;在大、小写之间进行转换。

③ 目录路径函数:用于文件目录和路径操作。

④ 诊断函数:用于内部错误检测。

⑤ 图形函数:用于屏幕管理和各种图形功能。

⑥ 输入输出函数:用于完成输入/输出功能。

接口函数:用于与DOS,BIOS和硬件的接口。

⑧ 字符串函数:用于字符串操作和处理。

⑨ 内存管理函数:用于内存管理。

⑩ 数学函数:用于数学函数计算。

日期和时间函数:用于日期、时间转换操作。

进程控制函数:用于进程管理和控制。

其他函数:用于其他各种功能。

以上各类函数不仅数量多,而且有的还需要硬件知识才会使用,因此要想全部掌握则需要一个较长的学习过程。应首先掌握一些最基本、最常用的函数,再逐步深入。

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

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

【实训4.7】根据图4-40,P0端口连接8位LED灯,利用标准库函数实现流水灯的控制。

分析:在标准库函数中提供了循环移位和延时等操作函数,这些函数的原型声明包含在头文件intrins.h中。利用将字符型数据按照二进制循环左移的库函数实现8位流水灯控制。

库函数 crol (a,n)的功能:变量a循环左移n位操作,n=1时即向左移动一位,最高位数据移至最低位,如图4-55所示。使用循环移位函数可以更简洁地完成流水灯显示操作。

图4-55 循环左移操作示意图

利用标准库函数实现流水灯控制的源程序:

流水灯控制小结:前面介绍了多种方法进行流水灯控制的程序编写。各种控制方法的实现具有不同的特点,请大家仔细分析对比一下它们的优缺点。

通过前面这些不同的控制方法,表明单片机控制的特点如下:

(1)单片机控制是数字控制

(2)控制对象不变(硬件结构不变)的情况下,存在多种控制方案,应选择最优的控制方案。

4.6.2 函数的定义

C语言规定,程序中所有函数,必须遵循“先定义,后使用”的原则。C语言编译系统提供的库函数是由编译系统事先定义好的,程序设计者不必自己定义,只需利用#include命令把有关的头文件包含到文件中即可。例如,实训4.7中用到的 crol (a,n)、 nop ()等,就必须在本文件的开始部分定义如下命令:

函数定义就是确定一个函数完成一定的操作功能,函数定义的一般形式如下:(www.chuimin.cn)

其中:

(1)函数类型说明:指出函数中return 语句返回的值的类型,它可以是C语言中任意合法的数据类型,如int,float,char等。如果不加函数类型说明符,C语言默认返回值的类型是整型。函数也可以没有返回值,这时函数类型应说明为void类型。

(2)函数名:是用户给函数起的名称,它是一个标识符,是函数定义中不可缺少的部分,函数名后的一对圆括号是函数的象征,即使没有参数也不能省略。

(3)形式参数列表:是写在圆括号中的一组变量名,形式参数之间用逗号分隔。形式参数称为形式的(或虚参数,简称虚参),是因为形参没有固定的值,形参的值只有函数被调用时由调用函数的实参提供。C语言中的函数允许没有形式参数,当没有形式参数时,园括号不能省略。

① 无参数传递的延时函数定义举例。

② 有参数传递的延时函数定义举例。

其中,形式参数ms被指定为unsigned int型。main()主调函数调用延时函数时,形式参数必须换成实际参数确定延时函数具体的延时时间。

(4)用{}括起来的部分称为函数体,由说明部分和语句组成。在函数体中可以定义各种变量,在函数中定义的变量只有在该函数内使用。函数体中的语句规定了函数执行的操作,体现了函数的功能,在函数体内通常包含return语句。函数体中可以既无变量定义,也无语句,但一对花括号是不可省略的。例如:

这是一个空函数,不产生任何操作,但它是一个合法的函数。

4.6.3 函数调用

函数调用就是在一个函数主体中调用另外一个已经定义的函数,前者为主调函数,后者为被调函数。

函数调用的格式如下:

实际参数:主调函数中调用带有形参的函数时,函数名后面括号中的参数(可以是表达式)称为实际参数(简称实参);如果有多个实参,要用“,”间隔开;实际参数与形式参数顺序对应,个数相同,类型应匹配。例如,

实际参数200在形式参数unsigned int的数值范围内。

如果调用无参函数,则“实际参数表”可以没有,但括号不能省略。

调用函数时,被调函数必须是已经存在的函数(是库函数或用户自定义的函数)。函数调用要注意以下几种情况。

(1)如果被调函数的函数定义在主调函数之后,则需要在主调函数中对被调函数进行声明。函数声明是一个说明语句,必须在结尾加分号。函数声明的一般格式如下:

函数声明是向编译系统说明函数的相关信息,包括函数名、函数返回值类型、形式参数类型、形式参数个数及排列顺序,以便在编译系统对函数进行检查。

例如,前面源程序中的函数声明:

(2)如果程序要使用C51标准函数库,则在程序的开始处要用#include预处理的命令声明被调函数所在函数库。例如,源程序中要调用左移函数 crol ()时,须添加如下预处理:

(3)如果被调用的函数不是标准库函数,在本文件中也没有定义,而是在其他文件中定义的,调用时需要使用关键字“extern”进行函数原型说明。如任务4.4的延时函数的定义若在另外一个文件中,则函数声明时需要进行如下说明:

函数的“定义”和“声明”之间的区别。

① 函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。

② 函数声明的作用则是把函数名字、函数类型、以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。它不包含函数体。

③ 如果被调函数的定义出现在主调函数之前,可以不必加声明。

④ 如果在文件的开头(在所有函数之前)已对本文件中所调用的函数进行了声明,则在各函数中不必对其所调用的函数再做声明。

4.6.4 函数的返回值

函数的返回值是通过函数调用使主调函数得到的确定值。函数的返回值只能在函数体中,通过return语句返回给主调函数。

return 语句的一般形式为:或者为:

对于不带返回值的函数,在函数体中不得出现return语句。

函数的返回值属于某一个确定的类型,在函数定义时指定函数返回值的类型。该语句有以下用途:

(1)它能立即从所在的函数中退出,返回到调用它的程序中去。

(2)返回一个值给调用它的函数。