static
static关键字在c语言中比较常用,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。
下面认识什么是变量,局部变量和全局变量的区别,静态局部变量和静态全局变量的区别
变量
1. 局部变量
普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。
普通局部变量存储于进程栈空间,使用完毕会立即释放。
#define _CRT_SECURE_NO_WARNINGS 1
//局部变量
#include<stdio.h>
int main()
{
int a;//定义局部变量a
printf("%d\n", a);
return 0;
}
如果不对a初始化的话,有些编译器会报警告
1>d:\test\2020_11_21\2020_11_21\11_21.c(6): error C4700: 使用了未初始化的局部变量“a”
2. 静态局部变量
静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
变量在全局数据区分配内存空间;编译器自动对其初始化其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束
//静态局部变量
#include<stdio.h>
int main()
{
static int a;//静态局部变量a
printf("%d\n", a);
return 0;
}
局部变量和静态局部变量的比较
#include<stdio.h>
void test()
{
int i = 0;//局部变量
i++;
printf("%d\n", i);
}
int main()
{
int i=1;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
#include<stdio.h>
void test()
{
static int i = 0;//静态局部变量
i++;
printf("%d\n", i);
}
int main()
{
int i = 1;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
结论:
同样的代码,其中一个用static修饰,两个代码的结果不同,说明了static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,直到程序结束
静态局部变量的效果跟全局变量有一拼,但是位于函数体内部,就极有利于程序的模块化了。
3 全局变量
全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。
普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。
//全局变量
#include<stdio.h>
int num = 10;//定义全局变量num
int main()
{
int a=0;//定义局部变量a
printf("%d\n", num);
return 0;
}
4 静态全局变量
静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。
在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用。
全局变量和静态全局变量比较
//全局变量
//test.c
int n = 100;//新建一个源文件,在其中定义一个n
//全局变量
#include<stdio.h>
int num = 10;//定义全局变量num
extern n;//告诉编译器从外部引入n
int main()
{
printf("%d\n", n);
printf("%d\n", num);
return 0;
}
//静态全局变量
//test.c
static int n = 100;//用static修饰
//全局变量
#include<stdio.h>
int num = 10;//定义全局变量num
extern n;//告诉编译器从外部引入n
int main()
{
printf("%d\n", n);
printf("%d\n", num);
return 0;
}
1>11_21.obj : error LNK2001: 无法解析的外部符号 _n
1>D:\test\2020_11_21\Debug\2020_11_21.exe : fatal error LNK1120: 1 个无法解析的外部命令
代码1正常,代码2会出现连接性错误
结论:
一个全局变量被staic修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用
函数
函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。其特性如下:
静态函数只能在声明它的文件中可见,其他文件不能引用该函数
不同的文件可以使用相同名字的静态函数,互不影响
非静态函数可以在另一个文件中直接引用,甚至不必使用extern声明
//函数
//test.c
int Add(int x,int y)//定义一个加法函数
{
return x + y;//返回x+y的值
}
#include<stdio.h>
int main()
{
printf("%d\n",Add(2, 3));
return 0;
}
//test.c
static int Add(int x,int y)//定义一个加法函数
{
return x + y;//返回x+y的值
}
#include<stdio.h>
int main()
{
printf("%d\n",Add(2, 3));
return 0;
}
代码1正常,代码2会出现连接性错误
结论:
一个函数被staic修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用
作用域:
作用域(scope),通常来说一段代码的名字并不总是有效/可靠的
而限定这个名字的可用性的代码范围就是这个名字的作用域。
1、局部变量的作用域是变量所在的局部范围
2.全局变量的作用域是整个工程
生命周期:
变量的生命周期是指变量的创建到变量的销毁之间的一个时间段
1.局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
2.全局变量的生命周期是:整个程序的生命周期。