C语言函数¶
约 1903 个字 232 行代码 7 张图片 预计阅读时间 9 分钟
在C语言中,函数就是一个完成某项特定的任务的一小段代码
C语言包括两类函数,一是库函数,二是自定义函数
库函数¶
标准库和头文件¶
C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSIC规定了⼀些常用的函数的标准,被称为标准库。而不同的编译器厂商根据ANSI提供的C语言标准就给出了⼀系列函数的实现,这些函数就被称为库函数
库函数相关头文件:库函数头文件查询
库函数的查询¶
C/C++官方的链接:https://zh.cppreference.com/w/c/header
cplusplus.com:https://legacy.cplusplus.com/reference/clibrary/
库函数文档中的一般格式(以qsort函数为例)¶
1.函数原型
2.函数功能介绍
3.参数和返回类型说明
4.代码举例
5.代码输出
6.相关知识链接
自定义函数¶
自定义函数语法形式¶
C | |
---|---|
1 2 3 4 5 6 7 8 |
|
ReturnValueType
是用来表示函数计算结果的类型,有时候返回类型可以是void
,表示什么都不返回,如果不写任何返回类型(包括void
),则默认返回类型是int
,但是不建议不写返回类型name
是为了方便使用函数;函数有了名字方便调用,所以函数名尽量要根据函数的功能起的有意义。- 函数的参数可以是
void
(也可以不写任何内容) ,明确表示函数没有参数。如果有参数,要交代清楚参数的类型和名字,以及参数个数。 {}
括起来的部分被称为函数体,函数体就是完成计算的过程
形式参数和实际参数¶
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
实际参数¶
实际参数就是真实传递给函数的参数
形式参数¶
如果只是定义了 Add 函数,而不调用函数, Add 函数的参数 x和 y 只是形式上存在的,不会向内存申请空间,不会真实存在的,所以称为形式参数。形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形式的实例化。
形式参数和实际参数的关系¶
形参和实参各自是独立的内存空间,形参是实参的⼀份临时拷贝。所以对形参的修改不影响实参,并且实参和形参可以重名
return
语句¶
return
后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执行表达式,再返回表达式的结果return
后边也可以什么都没有,直接写return;
这种写法适合函数返回类型是void
的情况return
返回的值和函数返回类型不⼀致,系统会自动将返回的值隐式转换为函数的返回类型return
语句执行后,函数就彻底返回,后边的代码不再执行- 如果函数中存在
if
等分分支的语句,则要保证每种情况下都有return
返回,否则会出现编译错误
数组类型作为函数形参¶
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
- 函数的形式参数要和函数的实参个数匹配
- 函数的实参是数组,形参也是可以写成数组形式的
- 形参如果是一维数组,数组大小可以省略不写
- 形参如果是二维数组,行可以省略,但是列不能省略
- 数组传参,形参是不会创建新的数组的,即可以使用
void
返回类型 - 形参操作的数组和实参的数组是同一个数组,即改变形参数组等于改变实参数组
嵌套调用和链式访问¶
嵌套调用¶
嵌套调用就是函数之间的互相调用
代码实例
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
链式访问¶
所谓链式访问就是将⼀个函数的返回值作为另外⼀个函数的参数就是函数的链式访问
代码实例
C | |
---|---|
1 2 3 4 5 6 7 8 |
|
函数定义与函数声明¶
函数的调用一定要满足,先声明后使用;
函数的定义也是一种特殊的声明,如果函数定义放在调用之前,那么则不需要再声明
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Note
一般情况下,函数的声明、类型的声明放在头文件(.h
)中,函数的实现是放在源文件(.c
)文件中
作用域和生命周期¶
作用域¶
作用域是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效(可用)的,而限定这个名字的可用性的代码范围就是这个名字的作用域
- 局部变量的作用域是变量所在的局部范围
- 全局变量的作用域是整个工程(项目)
生命周期¶
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。
- 局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域生命周期结束
- 全局变量的生命周期是:整个程序的生命周期,程序结束时,全局变量销毁
static
和extern
关键字¶
static
关键字¶
static
关键字用来:
- 修饰局部变量
- 修饰全局变量
- 修饰函数
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
代码1的test
函数中的局部变量i
是每次进入test
函数先创建变量(生命周期开始)并赋值为0,然后++
,再打印,出函数的时候变量生命周期将要结束(释放内存)
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
代码2中,我们从输出结果来看,i
的值有累加的效果,其实test
函数中的i
创建好后,出函数的时候不会销毁,重新进入函数也就不会重新创建变量,直接上次累积的数值继续计算
extern
关键字¶
extern
是用来声明外部符号的,如果一个全局的符号在A源文件中定义的,在B源文件中想使用,就可以使用 extern
进行声明然后使用
C | |
---|---|
1 2 3 4 5 |
|
函数默认是具有外部链接属性,具有外部链接属性,使得函数在整个工程中只要适当的声明就可以被使用
C | |
---|---|
1 2 3 4 5 |
|
被 static
修饰后变成了内部链接属性,使得函数只能在自己所在源文件内部使用,不可被同一工程中的其他文件访问
Note
若想在整个工程中使用add
函数(变量也是如此),不能用static
修饰,并且在其他文件中需要用extern
修饰(没有声明文件声明时)
如果想在整个工程中使用一个全局变量,当这个变量在头文件中,否则如果有多个文件包含时一定不要给初始值,否则会被报错为重定义;如果在一个源文件声明一个变量,在其他源文件中需要使用时,则可以使用extern
实现只声明并且给初始值
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
函数递归¶
函数递归中的递就是递推的意思,归就是回归的意思
递归限制条件¶
- 递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。
- 每次递归调用之后越来越接近这个限制条件
代码实例:
C | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|