第七章 函数
第六节 变量的存储和引用,内部函数和外部函数
1. 变量的存储类别
从变量存在的时间(生存期)角度来划分,我们可以把变量分为:静态存储变量和动态存储变量,
从而引出了静态存储方式和动态存储方式
-
静态存储变量:在程序运行期间分配固定存储空间的变量,这种分配变量的方式就叫做静态存储方式
-
动态存储变量:在程序运行期间动态分配存储空间的变量,这种分配变量的方式就叫做动态存储方式
-
全局变量: 放在静态存储区中,程序开始执行的时候,给全局变量分配存储区,程序执行完毕后释放这些存储区.
在程序执行过程中,占据固定的存储单元,而不是动态的分配和释放 -
动态存储区中存放的数据
a) 函数形参,函数形参被看作是局部变量
b) 局部变量,函数内部定义的变量
c) 函数调用时现场的一些数据和返回地址等
一般来说,这些数据在函数调用开始时,分配内存空间,函数调用完毕,这些空间就被释放掉了,这些分配和释放就是动态的.
如果调用两次同一个函数,分配给此函数的局部变量等的存储空间地址就是不同的
2. 局部变量的存储方式
- 传统情形:
函数的局部变量:函数被调用时分配存储空间,函数执行完成后自动释放所占用的存储空间
#include <iostream>
void functionTest(){
int c = 4;
printf("c = %d\n", c);
c++;
return;
}
int main() {
functionTest();
functionTest();
functionTest();
return 0;
}
-
特殊情形:
局部静态变量:用static加以说明,能够保留原值,占用的存储单元不释放,在
下一次调用函数时,该变量的值,就是上一次该函数调用结束时的值 -
静态局部变量说明
a)在静态存储区内分配存储单元,程序运行期间不释放
b)局部静态变量在编译时赋予初值,只赋予一次初值,在程序运行的时候它已经有了初值,
以后程序调用时不再重新赋初值,而是调用上次函数结束后的值
c)定义局部静态变量时,如果不赋予初值,则编译器自动赋初值为0,而普通的局部变量,如果不赋初值,
则该普通局部变量是一个不确定的值.
d)虽然局部静态变量在函数调用结束后仍然存在,但其他函数是不能引用的
e)缺点:长期占用内存,降低程序可读性
f)结论:除非必要,否则不要多用局部静态变量
3. 全局变量的跨文件引用
-
extern:在引用该全局变量的头部,做一个外部变量说明,说明这里出现的变量是一个已经在其他文件中定义过的外部变量,
本文件不必为它分配内存,必须放在文件开头,所有函数的外部 -
在定义全局变量是前面增加static,则该全局变量只能在本文件中使用
4. 函数的跨文件调用
根据能够被其他源文件调用,将函数分为内部函数和外部函数
####内部函数:
只能被本文件中其他函数调用,定义内部函数的时候,在函数定义前边添加一个static,形式如下:
static 类型标识符 函数名(形参列表){…},
内部函数又称为"静态函数":使用内部函数,可以是函数只局限于所在文件
外部函数
如果一个函数定义,不使用static,就是外部函数,也可以添加extern,但是函数默认就是extern模式.
extern 类型标识符 函数名(形参列表){…},extern可以省略
在文件头部添加一个函数声明即可使用
5. static关键字用法总结
-
函数内部定义一个变量的时候使用static,则该变量会被保存在静态存储区,在编译的时候初始化,如果不进行初始化,该变量会被初始化为0,并且下次调用该函数时,该变量为上次调用结果的值
-
在全局变量之前添加static,导致该变量只能在本文件中使用,无法在其他文件中使用
-
在函数定义之前,增加static,导致该函数只能在本文件中被调用,无法在其他文件中被调用