存储关键字 -- auto static extern register volatile
程序运行起来电脑会为该程序分配一个进程。
进程里面会将空间分为5部分:
代码区 ---- 存储代码的
常量区 ---- 常量数据
全局数据区/静态数据区 --- 全局变量 / 静态变量
栈区 --- 局部变量 --- 函数运行的时候开空间,运行结束销毁空间
堆区 --- 动态申请空间 --- 人为申请 人为释放
至于变量存在那个区域具体看如何定义。
auto:自动 -- 默认 ,不写存储关键字
全局变量 --- 全局数据区
局部变量 --- 栈区
static:--- 静态 --- 静态变量 --- 静态数据区
static可以修饰局部变量
静态局部变量-- 静态数据区 --- 程序运行的整个期间空间一致存储,不会被销毁。
-- 访问的时候还是只能在定义它的函数内部访问
-- static变量的初始化只会初始化一次,下一次再遇到初始化语句略过
eg:
流水灯
#include<stdio.h>
// 流水灯函数
void led_flash(void)
{
static int num = 1;
printf("%d灯亮~~~~~~~\n",num);
num++;
if(num > 5)
{
num = 1;
}
}
int main()
{
while(1)
{
led_flash();
sleep(1);
}
return 0;
}
static也可以修饰全局变量
static还可以用来修饰函数
static 修饰全局变量和函数作用:变量和函数只能在当前文件使用,不能被别的文件引用。
extern --- 用于声明变量或者函数
------- 开放变量和函数给外部使用
// 声明这个变量a
extern int a;
变量的声明必须加extern,因为编译器没有办法区分是变量定义还是变量声明,为了区分加extern的就是变量声明,不加extern的就是变量定义。
函数的声明加不加extern都可以,因为编译器很好区分函数的定义和函数的声明,有函数头{函数体} -- 函数定义 ,没有{函数体}就是函数声明。
register --- 寄存器
CPU和内存几乎比较频繁的时候可以将变量定义为寄存器变量。
register int i;
for(i=1;i<1000000000;i++)
{
printf("%d",i);
}
注意:
寄存器是由有限的,如果有空闲的寄存器,寄存器变量就可以存在寄存器中,
如果没有空闲寄存器,这个变量还是会被基座内存变量。
编译器很多都做一些优化操作,如果检测到你的变量在程序运行的时候,需要CPU进行频繁的IO操作,并且有空闲的寄存区,也会将它提升为寄存器变量。
volatile --- 可变的,易变的
--- 编译器针对某一个程序会做优化,会忽略掉一些程序的执行。
示例代码:
#include<stdio.h>
void delay(void)
{
volatile int i,j;
for(i=0;i<100000;i++)
{
for(j=0;j<100000;j++);
}
}
int main()
{
printf("33333333\n");
delay();
printf("44444444\n");
return 0;
}
volatile的作用:告诉CPU我这个变量是易变的,每次操作都需要重新从内存中获取变量后再运行,不能省略这个步骤,
一般:中断 多线程。