存储类型 数据类型 变量名;
- C语言的存储类型:
- 常见的有
const、static、extern、auto、register、volatile
;
- 关于const关键字,详见本人原创博客,这里不再赘述,
链接:
https:
- 静态存储区的存储:
- 1.
data 段
:存放初始化
的全局变量和静态变量
;
- 2.
bss 段
:存放未初始化
的全局变量和静态变量
;
- 其中bss段在程序执行之前会被系统
自动清0
;
- static关键字:
- static常用于修饰变量;
- static的作用:
- 延长局部变量的生命周期:
static修饰
的静态局部变量
只执行初始化1次
,使得局部变量的生命周期
原本从离的最近的花括号结束,在static修饰后,延长至整个程序结束
;
- 限制作用域:
- 1.static修饰的
全局变量
,只能在本源文件
中访问,即便是extern外部声明
也不可以
;
- 2.static修饰的
函数
,只能在本源文件
中调用;
- static 修饰的变量:
- 其存放在
全局数据区
的静态变量区
,包括全局静态变量
和局部静态变量
,都在全局数据区
分配内存,其在初始化时,自动初始化为 0
;
- 特别注意:
- 1.static修饰的
局部变量
在主函数执行之前
,就已经分配好了;
- 2.在功能函数中,static修饰的局部变量
只是一个声明
,多次调用时,也不会重新赋值
;
- 3.static修饰的局部变量仍是局部变量,
作用域还是离的最近的花括号
;
- 测试代码:
#include <stdio.h>
void func1(){
int x = 1;
static int y1 = 5;
x++;
y1++;
printf("x = %d\n",x);
printf("y1 = %d\n",y1);
}
void func2(){
static int y = 1;
int x1 = 5;
y++;
x1++;
printf("y = %d\n",y);
printf("x1 = %d\n",x1);
}
int x1 = 999;
static int y1 = 666;
int main(int argc, char const *argv[])
{
int x2;
static int y2;
printf("x1 = %d\n",x1);
printf("y1 = %d\n",y1);
puts("--------------------------------");
printf("x2 = %d\n",x2);
printf("y2 = %d\n",y2);
puts("--------------------------------");
func1();
puts("********************************");
func1();
puts("********************************");
func1();
puts("--------------------------------");
func2();
puts("********************************");
func2();
puts("********************************");
func2();
return 0;
}
x1 = 999
y1 = 666
--------------------------------
x2 = 0
y2 = 0
--------------------------------
x = 2
y1 = 6
********************************
x = 2
y1 = 7
********************************
x = 2
y1 = 8
--------------------------------
y = 2
x1 = 6
********************************
y = 3
x1 = 6
********************************
y = 4
x1 = 6
- extern关键字:
- extern修饰的变量或者extern修饰的函数是在其他源文件中定义的,即在一个源文件中,若要使用其他源文件中所定义的变量或者函数,需要使用extern关键字声明;
- 测试代码:
#include <stdio.h>
int a = 4;
int b = 5;
int my_mul(int x,int y){
return x * y;
}
#include <stdio.h>
extern int a;
extern int b;
extern int my_mul(int,int);
int main(int argc, char const *argv[])
{
printf("my_mul = %d\n",my_mul(a,b));
return 0;
}
my_mul = 20
- auto关键字:
- 除了
全局变量
和static的变量
,定义变量时,省略存储类型的变量,默认都是auto修饰
的;
- register关键字:
register修饰
的是寄存器类型
的变量,被处理器执行的效率是最高的
;
- CPU在取数据时,优先级为:寄存器 > 高速缓存(
cache
)> 内存空间;
- 由于中央处理器的寄存器的
个数是有限
的,所以把所有的变量都定义成寄存器变量是不现实
的;
- 特别注意:
- register关键字修饰的变量是
不能取地址
的;
- 总结:
- 实际开发中,一般情况不用,了解即可;
- 测试代码:
#include<stdio.h>
int main(int argc, const char *argv[]){
register int k = 999;
printf("k = %d\n",k);
return 0;
}
k = 999
- volatile关键字:
- 主要作用是,防止编译器优化,要求CPU每次取数据,必须在内存中取;
- 常见的使用场景:
- 1.多线程访问同一个变量;
- 2.寄存器处于中断的状态;