C语言 第七章 函数
第七章 函数
C
源程序有函数组成:一个main函数
和若干个其他函数组成,main函数
调用其他函数
函数概述
参数
0多个,有的函数有1多个参数,有的函数没有参数
返回值
0~1个,有的函数有1个返回值,有的函数没有返回值
函数分两种
系统函数
又称为标准函数或库函数,如sqrt()
, fabs()
, rand()
…
需要包含对应的头文件才能调用: #include <xxx.h>
自定义函数
我们自己编写的函数,需要定义后才能调用
函数的定义
1 | 函数的返回值类型 函数名(参数类型1 参数1, 参数类型2 参数2 ...) |
函数的调用
调用就使用,对有参数的函数,还要同时给出参数
1 |
|
形式参数(简称形参)
在函数定义头部中的参数,在函数未被调用时,此参数无具体值。1
2
3
4
5// 这里的a,b就是形参
void max(int a, int b)
{
...
}
实际参数(简称实参)
调用函数时给出的具体参数,是有具体的值。1
2// 这里的1,2就属于实参
max(1,2);
函数的返回值
return
调用返回
函数的好处
程序功能被细分为若干函数,每个函数负责一个小功能,main函数负责调度、指挥个函数的工作。
有return语句 | 无return语句 | |
---|---|---|
有返回值的函数(名前非void) | 返回表达式的值,函数结束,返回系统默认值,函数结束 | 函数中语句执行结 束后(执行到最后的}),返回系统默认 值,函数结束 |
无返回值的函数(名前有void) | 函数结束(无返回值) ;return 表达式 这是错误的 | 函数中语句执行结 束后(执行到最后 的 } ),函数结束(无返回值) |
函数的声明
C语言是按照顺序编译,所以要将其他函数放在main函数前面
1 | void fun() |
也可提前定义函数,避免出错,注意:在文件头部声明函数的时候,只可省略形参名,
;
不可省
1 |
|
递归
函数直接或间接的自己调用自己,称为递归。
递归程序,结构简练,可读性强。但执行时其时间和空间上的开销都比较大。
为防止自调用无休止的进行,在函数内必须设置调用终止的条件,否则程序将无法终止,被称为死递归。
递归的分析方法
与嵌套调用类似。
尽管每次调用的都是资深(同一函数),弹药把每次所调用的函数都看作是不同的函数,这些函数都具有相同的参数、返回值和语句。
经典题型
求阶乘1
2
3
4
5int recursion(int loop)
{
if(loop == 1 || loop == 0)return 1;
return loop*recursion(loop-1);
}
函数的作用域和存储类别
变量的作用域
局部变量
只在本函数内有效
若未赋初值,值为随机数
不同函数中可使用同名变量,形参和实参也可同名(形参也是函数内的变量)
在复合语句中定义变量(只在复合语句“块”内有效)
全局变量
全局变量在函数外定义的变量、
作用域:从变量定义处开始,到本程序文件末尾均有效(其中所有函数都能用)。
初始值自动为0。
全局变量可在多个函数中同时起作用,应尽量少用或不用全局变量。
不同存储类别的变量的特点
变量定义前加 | auto | static | register |
---|---|---|---|
存储位置 | 内存动态存储区 | 内存静态存储区 | CPU寄存器(没在内存) |
作用域 | 所在函数内,或所在复合语句 { } 内有效 | 同auto | 同auto |
生存期 | 离开函数或{ }就消失 | 永久保留 | 同auto |
初值 | 随机数,初值重新赋值 | 值为0,初值只赋一次 | 同auto |
编译预处理
宏定义,只会替换文本,不会计算
1 |
|
先预处理,再编译;预处理部分不编译
预处理阶段将宏定义字符串替换1
2
3
4
5
6
7
语句为
s=3*M + 4*M;
预处理后
s=3*(y*y+3*y) + 4*(y*y+3*y)1
2
3
4
5
6
7
8
9
10
11
12
13
14
main()
{
printf("%d", 2*N);
}
// 预处理后
main()
{
printf("%d", 2*3+5 );
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 此例为错误示例
main()
{
printf("%d", 2*N);
}
// 预处理后,这种情况是错的,不能这么写
main()
{
printf("%d", 2*3+5; );
}1
2
3
4
5
6
7
8
9
10
11
12
main()
{ PRINT
}
// 预处理后
main()
{ printf("*");
}
头文件
预处理后会将头文件替换掉
1 |
c源程序 -> 预处理 -> 编译 -> 运行