1、static
定义全局静态变量、定义局部静态变量、定义静态函数
全局静态变量:
1、内存分配在数据区,生存期为程序运行期间
2、如果没有进行初始化,默认为0
3、作用域局限于一个源文件内,无法被源程序的其他源文件使用
和全局变量比较
区别在第三点,全局变量的文件作用域可以通过 extern 关键字在源程序的其他源文件进行声明,而被其他源文件使用
局部静态变量:
1、内存分配在数据区,生存期为程序运行期间
2、同上
3、作为局部变量作用域局限于函数块内,
和局部变量比较
区别在1、2点
1、内存分配在栈区,生存期为函数执行期间
2、不初始化值不确定
#include <stdio.h>
void fun();
int main(void)
{
for(int i = 0; i < 10; i++)
{
fun();
}
return 0;
}
void fun()
{
static int i;
++i;
printf("fun函数被调用%d次\n",i);
}
就像这样,因为 局部静态变量的生存期间为整个程序执行期间,所以作为局部变量却可以保存上一次修改之后的值,也可以再次被修改并保存值。
静态函数:
只能在本文件内被调用,无法被其他文件调用
2、volatile
每次访问volatile修饰的变量是都会到对应的内存地址中重新读取。volatile表明变量的值可能随时被外部改变,因此对这些变量的存取不能缓存到寄存器,每次使用都要重新读取。
例如,外设端口寄存器的值,多线程环境下被几个线程共享的变量,一个中断服务程序中修改的供其他程序检测的变量。
3、register
建议计算机把数据保存到寄存器中,当某个变量被频繁读写,如果可以的化,应该把器保存在cpu的寄存器中,从而加快存取速度
1、register变量必须是能被cpu寄存器所接受的类型。
2、只是建议,编译器不一定会则会么做
3,由于有可能被放在寄存器中,因此不能用用取地址运算符
4、只有局部变量和形参可以作为register变量
5、优化的编译系统可能自动识别使用频繁的变量保存在cpu内存中
4、const
1、修饰变量为常量(#define也可以定义常量)
2、修饰函数的参数,表示在函数体内不饿能修改参数值
3、修饰函数返回值,一般修饰的是返回值为指针的函数,该返回值因此也只能赋值给被const修饰的指针。修饰非指针类型是没有意义的。因为返回值是临时变量,在函数调用结束后变量的生命周期也就结束了,因此使用const修饰是没有意义的。