03 函数 作用域
函数方便复用
1. 把加法 写成 add函数
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main(void)
{
int result = add(3, 5);
printf("%d\n", result);
return 0;
}
| 部分 | 含义 |
|---|---|
前面的 int | 返回一个整数 |
add | 函数名 |
int a, int b | 接收两个整数,叫作参数 |
执行到 return,当前函数立即结束。返回类型是 void 时表示不返回数据;参数写 void 表示不接收参数。
2. 先声明 后调用
上面的 add 写在 main 前面,编译器已经认识它。如果想把函数实现{}放在后面,需要先写一条声明:
int add(int a, int b); // 声明:提前告诉编译器张啥样
-
声明只有函数的名字、参数和返回类型,末尾有分号;
-
定义则带有
{ },里面是真正执行的代码。
3. 作用域 生存期
对变量的使用而言,我们需要从以下两个角度去分析它:
| 名称 | 定义 |
|---|---|
| 作用域 | 代码中哪些位置可以使用这个变量 |
| 生存期 | 程序运行时,这个变量存在多久 |
3. 局部变量 全局变量
局部变量:定义在函数内部或某个 { } 代码块中的变量,只能在对应范围内使用。
全局变量:定义在所有函数外面的变量,可以供多个函数使用。
int total = 0; // 全局变量
void record(void)
{
int step = 1; // 局部变量
total += step;
}
从作用域 生存期角度去分析:
-
局部变量作用域在内层
{ }中,离开这一层代码块时生命周期就结束,不必等整个函数返回。 -
全局变量作用域在全部文件,生存期一直到程序结束,但若要在其他
.c文件中使用,还需要相应的extern声明。 -
给局部变量加上
static,不改变作用域,但生存期会一直存在到程序结束。
for (int i = 0; i < 3; i++){} 中定义的 i,也只在这个 for{} 范围内有效。
4. static静态局部变量
连续调用三次 count_calls(),看看加不加 static 有什么区别。
不加 static:每次重新开始
void count_calls(void)
{
int count = 0;
count++;
printf("%d\n", count);
}
每次调用都会创建本次的 count,执行 count = 0 的初始化,加 1 后输出。函数返回时,这个变量的生命周期结束,所以下一次仍从 0 开始,三次输出为 1、1、1。
加上 static:保留上次的值
void count_calls(void)
{
static int count = 0;//加上static
count++;
printf("%d\n", count);
}
count 只初始化一次。函数返回后,它仍然存在,下一次调用会接着上次的值加 1,三次输出为 1、2、3。
| 对比 | int count = 0; | static int count = 0; |
|---|---|---|
| 初始化 | 每次调用时初始化 | 程序启动前初始化一次 |
| 函数返回后 | 本次变量的生存期结束 | 变量继续存在,保留当前值 |
static 延长了这里局部变量的生存期,但没有扩大它的作用域,函数外仍然不能直接用这个 count。
写一个返回较大值的函数
补全 max2 函数,返回两个整数中较大的一个。在 main 中分别用 12、7 和 -3、5 调用它,并输出结果。
示例输出
12
5
提示
函数只负责比较参数并 return,打印结果放在 main 中。
参考代码
#include <stdio.h>
int max2(int a, int b)
{
if (a > b) {
return a;
}
return b;
}
int main(void)
{
printf("%d\n", max2(12, 7));
printf("%d\n", max2(-3, 5));
return 0;
}