目录
前言:
1.变量作用域
2.代码执行顺序
3.易错点
4.思维导图
我们是先定义函数,再调用函数。完成了函数的定义以后,我们就可以开始调用函数了,让我们来回顾一下:
调用函数分为两部分,一部分是函数名,一部分是函数参数。
我们定义了一个只有一个参数的函数AddThree()
,然后我们调用一下它:
int a=10;
int b;
b=AddThree(a);
printf("%d\n",n);
1.函数名 AddThree
2.函数参数,整型变量 a
以及有两个参数的函数AddTwoNumber()
:
int num_c;
num_c = AddTwoNumber(10, 20);
printf("%d\n", num_c);
1.函数名 AddTwoNumber
2.第一个函数参数,整型常量 10
3.第二个函数参数,整型常量 20
4.分隔两个参数的逗号
对于同一个函数,我们可以使用不同的参数来调用它,这样就会得到不同的返回值。
比如下面的两次调用,分别得到的是不同的返回值,一次是30,一次是140。
这也是函数的一个特性,函数定义只有一次,函数调用可以有很多次。
1.1
在函数定义中,我们有时候会定义一些变量,这些变量只能在函数内部“生效”,函数外部的代码无法直接访问(修改,读取)这些变量。
同样的,函数外部定义的变量,我们也无法在函数内部用代码直接去访问(读取和修改)它们。
1.2
这种机制叫做变量的作用域,也就是变量“生效”的地方,不同地方定义的变量,作用域各有不同,在变量作用域以外的地方访问它,代码会报错。
例如:
int AddThree(int num_a)
{
int num_b;
num_b = num_a + 3;
return num_b;
}
int main(){
int num_c = 10;
int num_d;
num_d = AddThree(num_c);
printf("%d\n", num_d);
printf("%d\n", num_b);
}
1.函数内部定义的变量 int num_b
2.函数外部定义的变量 int num_c = 10 int num_d
3.函数外部的代码访问函数外部的变量num_d,能够正常访问 printf("%d\n", num_d)
4.函数外部的代码访问函数内部的变量num_b,无法正常访问 printf("%d\n", num_b)
1.3
需要注意的是,这个函数的外部,包括其他函数,比如我们在函数A中定义的变量,就无法在函数B中访问;以及在函数B中定义的变量,也无法在函数A中访问。
我们可以看到不同的变量的不同作用域,这是函数内部和外部的区别
这是两个函数之间的区别。
2.1
之前我们已经学过了三种代码执行顺序了他们分别是:
顺序执行——从上到下顺序执行。
判断语句如(if,if-else)的执行顺序——判断执行,又叫判断分支,或者选择执行。
循环(for循环,while循环)涉及的代码执行顺序——循环执行。
在函数定义和调用的代码中,我们也能感受到,它的执行顺序和上面三种都不太一样。
这里就涉及到新的代码执行顺序——跳转执行:
2.2
我们知道所有C程序的代码执行都是从main函数开始的,然后默认从上往下执行。
比如这样:
int main(){
int num_a = 5;
float flo_b = 10.0;
char cha_c = 'a';
printf("%d\n", num_a);
printf("%f\n", flo_b);
printf("%c\n", cha_c);
}
1.C语言启动,进入main函数 int main() {}
2.顺序执行,定义整形变量 int num_a = 5
3.顺序执行,定义浮点型变量 float flo_b = 10.0
4.顺序执行,定义字符型变量 char cha_c = 'a'
5.顺序执行,打印整形变量 printf("%d\n", num_a)
6.顺序执行,打印浮点型变量 printf("%f\n", flo_b)
7.顺序执行,打印字符型变量 printf("%c\n", cha_c)
当我们调用函数的时候,代码执行顺序首先会从调用函数的地方跳转到函数定义的内部;
然后再函数内部执行,最后又从return的地方返回到函数外部调用函数的地方。
这里面就涉及到一个跳转到函数定义内部的过程,这就是跳转执行的顺序。
2.3
我们来看看一个跳转执行的代码顺序:
int AddThree(int num_a)
{
int num_b;
num_b = num_a + 3;
return num_b;
}
int main(){
int num_c = 10;
int num_d;
num_d = AddThree(num_c);
printf("%d\n", num_d);
}
1.从main函数开始 int main(){
2.顺序执行,定义一个整型变量 int num_c = 10
3.顺序执行,定义一个整型变量 int num_d
4.顺序执行到函数调用,准备跳转到函数内部 AddThree(num_c)
5.跳转执行,到函数内部 int AddThree(int num_a)
int AddThree(int num_a)
{
int num_b;
num_b = num_a + 3;
return num_b;
}
int main(){
int num_c = 10;
int num_d;
num_d = AddThree(num_c);
printf("%d\n", num_d);
}
6.顺序执行函数内部的代码 int num_b
7.继续顺序执行 num_b = num_a + 3
8.函数执行完毕,返回值到函数外部 return num_b
9.回到函数调用处 num_d = AddThree(num_c)
10.继续顺序执行 printf("%d\n", num_d)
2.4
我们来梳理一下跳转执行的顺序:
1、调用函数
2、函数定义的内部
3、return返回到函数调用处
如果一个函数的返回类型是void
,以及函数体内部没有关键字return。
这时候函数内部,执行完所有代码以后,仍然会跳转到调用函数的地方,只不过没有返回值。
在C语言中,使用一对花括号 {} 可以创建一个块级作用域。在块级作用域内定义的变量只在该作用域内可见。
注意,块级作用域可以嵌套:
内部作用域可以访问外部作用域中的变量,
而外部作用域无法访问内部作用域中的变量。
最后我想说的是:
在撰写这篇文章时,我参考了《白纸编程》这个app的观点和思想,我要感谢他们对我的启发和帮助。