1、函数的概述
什么是函数?
函数是实现特定功能的代码块
为什么使用函数?
1)可以提高代码的复用性
2)降低程序复杂度
3)改进性能(函数内去调用汇编执行某些操作)
4)隐含变量和操作等
2、函数的分类和书写格式
函数的分类
从函数定义的角度看,函数可分为库函数和用户定义函数两种。
库函数:有C系统提供,用户无须定义,也不必在程序总做类型说明,只需在程序前包含有改函数原型的头文件即可在程序中直接调用。printf,scanf等函数均属此类。
用户定义函数:由用户按需要写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。
C语言 提供了极为丰富的库函数,这些库函数又可从功能角度作以下分类。
字符类型分类函数:用于对字符按ASCII码分类:字母,数字,控制字符,分隔符,大小写字母等。
转换函数:用于字符或字符串的转换;在字符量和各类数字量(整型,实型等)之间进行转换;在大、小写之间进行转换。
目录路径函数:用于文件目录和路径操作。
诊断函数:用于内部错误检测。
图形函数:用于屏幕管理和各种图形功能。
接口函数:用于与DOS,BIOS和硬件的接口。
字符串函数:用于字符串操作和处理。
内存管理函数:用于内存管理。
数学函数:用于数学函数计算。
日期和时间函数:用于日期,时间转换操作。
进程控制函数:用于进程管理。
其他函数:用于其他各种功能。
自定义函数的书写格式
由用户自己写的函数,也叫用户定义函数。我们不仅在程序中要实现函数的功能还要在使用函数之前进行声明。
函数定义到使用分三步:1、声明函数 2、定义(实现)函数 3、调用函数
声明就是对函数进行一个说明,告诉编译器有这么样一个函数,需要传递那些数据什么数据类型。
实现就是把特定的功能用代码表达出来。
调用就是使用函数。
函数的基本格式:
返回值类型 函数名称(数据类型 变量名1,数据类型 变量名2,...){
函数体;
return 对应类型的结果;
}
函数的格式说明:
返回值类型:返回结果的数据类型。
函数名:这段功能代码的名字,符合标识符命名规则即可。
参数列表:
参数列表中可以有0-N个参项,参数项之间,连接。
形式参数:函数上定义的参数,作用在于接收实际参数的数据。
数据类型:参数的数据类型。
参数名:变量名
函数体:就是完成功能的代码
return:结束函数,如果函数不需要有返回值,则不需要return
返回值:功能的结果,由return带给调用者。
变量的作用域
可以在任何代码的起始处定义变量。变量值存在于他们的块中,他们在声明的时候创建,在定义他们的块结束的时候,该变量就不存在了,这个程序代码块就是变量的作用域。
演示:
块中定义变量。
函数也是一个块,其内部声明的变量,可以叫做局部变量,在其他函数内不能使用。
主函数也是一个块。
所有函数外边定义的变量叫做全局变量。
局部变量
定义说明:在函数内部的变量,也称内部变量。其作用域仅限于函数内,离开该函数后再使用这种变量表达对应的意义就是非法的。
局部变量注意事项:
1)主函数中定义的变量也只能在其自身中使用,不能再其他函数中使用。同时,主函数中也不能使用其他函数中定义的变量。因为主函数也是一个函数,它与其他函数是平行关系。
2)形参变量是属于被调函数的局部变量。
3)允许在不同的函数中使用相同的变量名,他们代表不同的对象,分配不同的地址单元,互不干扰,也不会发生混淆。
全局变量
对于全局变量还有以下几点说明:
1)外部变量定义必须在所有函数之外,且只能定义一次。
2)在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。
其原因是存储在不同的片区。
代码区 函数diamante
静态存储区 全局变量、静态变量
堆区(Heap) 动态内存
栈区(Stack) 局部变量、函数形参等
3)如果外部变量定义在某函数下面,则要使用该外部变量的时候一定要进行说明
外部变量说明的一般格式为:
extern 类型说明符 变量名,变量名,……;
4)在整个程序内,可以出现多次外部变量的说明,但是外部变量在说明的时候不能再赋初始值。
外部变量在定义时就已经分配了内存单元,外部变量定义可作初始赋值,在说明的时候只是表明在函数内要使用某外部变量。
5)外部变量可加强函数模块之间的数据了联系,但是又使函数要依赖这些变量,因而使得函数的独立性降低。从模块化程序设计的观点来看这是不利的,因此在不必要时尽量不要使用全局变量。
函数的声明
调用某函数之前对该函数进行声明。
目的是使编译系统知道被调函数返回值类型,以便在主调函数中按此种类型对返回值作相应的处理。
其一半格式为:
返回值类型 被调函数名(类型1 形参名1,类型2 形参名2...);
或为:
返回值类型 被调函数名(类型,类型...);
如:
int max(int a, int b);
int max(int,int);
C语言中,函数调用的一般格式为:
函数名(实际参数表);
注意:
1)函数的声明可以写到主调函数里面也可以写到外面。
2)当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数再作说明,而直接调用。
3)如果被调函数的返回值是整型时,可以不对被调函数作说明,而直接使用,即使在主调函数下面也可以直接使用。这时系统自动对被调函数返回值按整型处理。(建议不要省略)
实际参数介绍和使用
实际参与操作的数据。调用函数的时候,函数名后面小括号中的参数,即为实际参数,简称实参。实参出现在主调函数中。形参和实参的功能是做数据的传递。从主调函数中把数据传过来,被调函数用对应的形参去接。
注意:
1)实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,他们都必须具有确定的值,以便把这些值传送给形参。
2)实参和形参在数量上,类型上,顺序上严格一致,否则会发生不匹配的错误。
3)形参的值在函数内部可以被修改,但是不会影响主调函数中实参的数据。
形式参数介绍和使用
定义函数的时候函数名后面小括号中的参数,简称形参,用来接收实际运算数据或者数据地址。
注意:
1)如果多个形参,可以用逗号分隔。
2)形参的类型可以不相同。如int max(int a ,int b , float c);
3)形式参数是什么样类型的数据,那么实际参数也必须是什么样的类型,否则会产生错误会丢失数据。
4)形式参数出现在函数定义中,作用域是函数体,离开该函数则不能使用。
5)函数内部不可以定于与函数形参同名的变量,因为形参与函数的代码是一个代码块。
6)形参定义后,并不会立即分配存储空间,在函数调用的时候才会真正的分配存储空间。
函数的返回值及注意事项
函数的返回值是一个结果,就是函数执行完特定操作之后得到的那个,需要给主调函数返回的结果。
使用注意事项:
1)当前情况下的函数的值只能通过return语句返回主调函数。
return语句的一般格式为:
return 表达式;
或者为:
return (表达式);
该语句的功能是计算表达式的值,并返回给主调函数。
2)在函数中允许有多个return语句,但每次调用只能有一个return语句被执行,因此只能返回一个函数值。
3)函数返回值类型和return实际返回值的类型应保持一致。如果两者不一致,则获取return后表达式的值,自动进行类型转换。
4)如函数值为整型,在函数定义时可以省去类型说明。也就是说如果没有指定类型,那么C语言默认是int类型。(开发中不要省略返回值的类型)
5)不反悔函数值的函数,可以明确定义为 空类型 ,类型说明符为void,为了使程序有良好的可读性并减少出错,凡不要求返回值的函数都应定义为空类型
函数的调用
C语言中,函数的调用一般格式为:
函数名(实际参数表)
参数列表可以不写,对无参函数调用时则无实际参数表,实际参数表中的参数可以是常数,变量或其它构造类型数据及表达式,各实参之间用都好分隔。
使用注意事项:
1)函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数是由返回值的。
int z = 0;
z=add(23+70)+1;
2)函数调用的一般形式加上分号即构成函数语句。
printf("%d\n",n);
scanf("%d",&m);
3)做函数实参
函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是由返回值的。
printf("%d\n",add(20,30));
4)C语言中函数之间是平行的,不能嵌套定义,但是函数之间也可以互相调用(嵌套调用),习惯上把调用者成为主调函数,还有函数自己调用自己的叫递归调用。
5)main函数是主函数,C程序的执行总是从main函数开始,完成对其他函数的调用后再返回main函数,最后由main函数结束整个程序。
6)一个C源程序必须有,也只能有一个主函数main,它可以调用其他函数,而不允许被其他函数调用。