一.在C语言中static的作用
1.修饰局部变量,改变了变量的声明周期,这种变量长期存在于该函数当中(其作用域并不发生改变)
int foo(){
static int i = 1; // (1)
//int i = 1; // (2)
i += 1;
return i;
}
如果要明白修饰局部变量的这个用法我们首先要了解c/c++中的内存分布和static所处的位置
对于一个完整的程序,在内存中的分布情况如下:
1.栈区: 由编译器自动分配释放,像局部变量,函数参数,都是在栈区。会随着作用于退出而释放空间。
3.堆区:程序员自己分配并释放的区域,像malloc,calloc,realloc,new…
3.全局数据区(静态区):全局变量和静态便令的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束释放。
4.代码区
它存在的意义就是随着第一次函数的调用而初始化,却不随着函数的调用结束而销毁(如果把以上的(1)换成(2),那么i就是在栈区分配了,会随着foo的调用结束而释放
那么第二个问题也就浮出水面了,它是在第一次调用进入(1)的时候初始化,且只初始化一次,也就是你第二次调用foo(),不会继续初始化,而会直接跳过。
那么它跟定义一个全局变量有什么区别呢,同样是初始化一次,连续调用foo()的结果是一样的,但是,使用全局变量的话,变量就不属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
那么我们总结一下,静态局部变量的特点
(1)该变量在全局数据区分配内存(局部变量在栈区分配内存);
(2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化(局部变量每次函数调用都会被初始化);
(3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0(局部变量不会被初始化);
(4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,也就是不能在函数体外面使用它(局部变量在栈区,在函数结束后立即释放内存);
2.修饰全局变量,改变了变量的作用域,使得变量只能在自己的源文件内部使用。
(也就是说改变了他的连接属性)
3.修饰函数,使得函数只能在自己源文件内部使用(改变的也是链接属性)
//file a.c
#include <stdio.h>
void fn()
{
printf("this is non-static func in a");
}
//file b.c
#include <stdio.h>
extern void fn(); //我们用extern声明其他文件的fn(),供本文件使用。
void main()
{
fn();
}
修饰函数和修饰全局变量具有类似的功能。
1.静态函数(全局变量)不能被其它文件所用;
2.其它文件中可以定义相同名字的函数(全局变量),不会发生冲突;
总结:
1.一种是修饰变量,一种是修饰函数,所以说是两种
2.静态全局变量和修饰静态函数的作用是一样的,一般合并为一种。