C语言 函数
一、函数
1.1 什么是函数
函数:完成特定功能的程序段
维基百科对函数的定义:子程序
1.在计算机科学中,子程序是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具有相对独立性。
2.一般会有输入参数并有返回值,提供了对实现过程的封装和细节的隐藏。
1.2 C语言中函数分类
函数主要分为两大类:库函数和自定义函数
库函数:编译器提供的可在C源程序中调用的函数。库函数又分为两类,一类是C语言标准规定的库函数,一类是编译器特定的库函数(如:MSVC编译器提供的scanf_s函数)。由于版权原因,库函数的源代码一般不可见,但在头文件中可以看到它对外提供的接口)
使用库函数需要引用对应头文件: #include <文件名>
库函数参考手册网址:
http://www.cplusplus.com/
自定义函数:程序员根据需要编写的函数,也是本文谈论的重点
二、函数定义与声明
2.1函数的定义
函数的定义:一个函数的具体实现
语法:
返回类型 函数名(形参列表){
功能代码;
}
返回类型:一个函数执行完后可以返回特定的值给主程序,返回类型就是指定返回值的数据类型,如果不需要返回值,此时写上void。如果有返回值,在功能代码部分必要要有return语句;
函数名:一个标识符,应该尽量使用能表明函数功能的名字,比如一个求和的函数可以使用sum命名
形参列表:什么是形参后面会讲到,这里先理解成参数列表。指需要传入到函数内的参数,当不要参数时为空,需要参数时要写上参数类型和参数名
功能代码:大括号内是函数的功能代码,是函数功能具体的实现代码
return: 终止当前函数执行,并返回return后面的值(类型必须与返回类型相同)。如果函数中没有return语句,那么只有遇到函数反大括号才会结束函数的执行
1 | //定义了一个求两值相加和的函数,函数返回类型是int,所以只能求整数相加。 |
1 | //定义了一个打印函数,函数没有返回值,不需要传入参数,函数名为print |
2.1函数的声明
1 |
|
函数声明:
1.告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但是具体是不是存在,函数声明决定不了
2.函数的声明一般在函数使用之前出现,要满足先声明后使用
3.函数声明一般要放在头文件内
4.函数定义出现在函数调用(使用)之前,可以省略函数声明
1 |
|
函数声明语法: 返回类型 函数名(参数列表);
1 |
|
三、写函数小技巧
写函数时候,首先要了解需求,即这个函数是干什么的、要解决什么问题。是否需要返回值,如果需要返回值类型是怎样的。是否需要传入参数。要做到高内聚低耦合。
3.1判断质数的函数
分析:质数就是只能被1和本身整除的数字。如果被其他数字整除就不是质数。假设一个数n,那在
[2,n-1]的范围内用n对它们取余数都必须不等于0。但是我们可以继续优化,减少计算。我们对n开平方根。那么范围可以是[2,√n]。另外如果是1或2那么本身就是质数所以不需要计算。
1 |
|
输入
1 | 4 |
输出
1 | 4不是质数 |
3.2 求第n个斐波那契数
分析:斐波那契数列为: 1、1、2、3、5、8、13……,从第三个数开始,每个数的值等于前两个斐波那契数相加的值
f(x) = 1 [1,2]
f(x) = f(x-2) + f(x-1) x>2
1 |
|
输入
1 | 7 |
输出
1 | 第7个斐波那契数为:13 |
四、函数调用
函数的调用就是函数的使用。函数调用通过使用函数调用运算符构成函数调用表达式实现。函数调用操作符是 ( ),函数调用表达式的一般形式:
函数名(参数列表);
函数没有参数时,( )内为空就行
4.1实参与形参
实参:函数调用操作符中的参数称为实际参数,简称实参,每个实参前面没有类型说明符,传入实参类型与个数必要与对应函数定义里面的相同
形参:函数定义中()内的参数叫做形式参数,简称形参。形式参数只有在函数调用的过程中才会分配内存空间。形参在函数调用完成后就会自动销毁。因此形参只会在函数中有效。本质上形参只是实参的一份临时拷贝
1 |
|
4.2传值调用与传址调用
以下通过这个案例演示
1 |
|
输出
1 | a与b交换前:a=10 b=20 |
我们可以发现,调用swap函数,a和b的值却没有交换。这是因为此时我们是传值调用。
传值调用:形参和实参分别占用不同的内存区域,对形参的改变不会影响实参


我们可以发现,实参a和b 与 形参x和y占用不同内存地址,通过传入实参a、b对形参x、y赋值后,实参a、b和形参x、y就没有任何关系了,所以对x、y的值的修改并不会影响实参a和b
传址调用:把函数外部创建变量的内存地址传递给函数的形参。这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是通过函数内部可以操作函数外部的变量
1 |
|
输出
1 | a与b交换前:a=10 b=20 |

简单来说,如果传入的是变量的地址就是传址调用,否则就是传值调用。当需要在函数内部改变外部变量的值时要使用传址调用
4.3嵌套调用和链式访问
嵌套调用:函数和函数之间可以根据实际的需求进行组合,即在函数内部调用另外一个函数
1 |
|
输出
1 | 欢迎访问我的博客 |
链式访问:把一个函数返回值作为一个函数的参数
1 |
|
输出
1 | 100 |
函数可以嵌套调用,但是不能嵌套定义(不能在一个函数内定义另外一个函数)