static是C语言的关键字,它有静态的意思
static的三种用法:
修饰局部变量
修饰全局变量
修饰函数
static修饰局部变量
我们先看一个程序:
void print() { int a = 0; a++; printf("%d\n", a); } int main() { int i = 0; while (i < 10) { print(); i++; } return 0; }
这个程序会输出10个1,原因是在主函数中每次调用print函数,print函数会输出a的值,但是a是一个局部变量,每次print函数调用结束后a就会被销毁,下次调用的时候还会创建一个a,所以每次打印a的值都是不变的
接下来我么用static修饰a
void print() { //修饰局部变量 static int a = 0; a++; printf("%d\n", a); } int main() { int i = 0; while (i < 10) { print(); i++; } return 0; }
这次运行程序,结果是打印从1~10
解释这个原因前,可以先了解一下内存:
内存可以粗口地分为3个区:栈区,堆区,静态区。
栈区存放局部变量、函数形参,堆区存放动态开辟的数据,静态区存放静态变量和全局变量
接下来解释原因:
普通的局部变量存放到栈区,这种局部变量进入作用域时创建,出作用域后就会被修改
被static修饰后的局部变量叫静态变量,这种变量存放到静态区中,而存在静态区中的变量,创建好后,直到程序结束后才会被销毁
本质上:static修饰改变了局部变量在内存中的存储位置,存储位置的改变,使得执行的效果不一样。
所以在上面的程序中,第一次调用print函数是就创建了一个静态变量a,即使在出print函数时这个变量也不会被销毁,仍保存着之前的值。
下一次再调用print函数时,函数中的static int a = 0;自动被跳过,执行下面的对a的值改变的操作
所以最后会打印出1~10
static修饰全局变量
一个全局变量已经有着静态变量的属性了,那为什么还要用static修饰?
其实,static修饰全局变量是用在跨文件的场景中
我们先在tes1函数中定义一个全局变量int num = 10;
如果想要在同项目的A文件中使用这B文件中的全局变量,我们需要在A文件中用关键字extern修饰声明一下这个变量,然后就可以使用了
如果我们将num用static修饰会发生什么呢?
可以看见,用static修饰后报错了
原因是:
全局变量本身就具有外部链接属性,在A文件中定义的全局变量在B文件中是可以通过链接使用
但如果全局变量被static修饰,这个外部链接属性就变为了内部链接属性,这个全局变量只能在自己所在源文件内部使用
static的修饰,会把外部链接属性变为内部链接属性,最终使得全局变量的作用域变小了
static修饰函数
其实static修饰函数是和static修饰全局变量类似的
我们在A源文件中一个函数,想要在B源文件中使用,只需要在B源文件中用extern声明外部函数,就可以在B文件中使用这个函数了
如果将sum函数用static修饰,会发生什么呢?
可以看到,也是会报错。
原因和static修饰全局变量相似:
函数本身具有外部链接属性,被static修饰后,外部链接属性变为内部链接属性,使得这个函数只能在自己所在的源文件中使用,其他源文件无法使用