存储类型:
1.auto 自动
局部变量默认的存储类型,储存在栈中。
2.static 静态
可修饰局部变量、全局变量和函数。
在修饰变量时,只能在初次定义时初始化一次(储存在.data),若没有初始化则程序运行前内核将之初始化为0(储存在.bss),储存在静态区,整个程序运行期间不释放。在修饰局部变量时,作用域为当前函数,在修饰全局变量时,作用域为当前文件。
在修饰函数时,此函数只能在当前文件内调用。
3.extern 外部定义
可修饰变量和函数。
在修饰变量时,表示被修饰的变量是在其他地方已经定义过的全局变量。
在修饰函数时,表示被修饰的函数是在其他地方已经定义过的(函数默认是全局的),这样做省去因添加头文件而增加的其他不必要的函数,加速预处理阶段。
4.register 寄存器
表示把被修饰的变量放入到寄存器中,不必每次再从内存中读取,省去指令周期提高效率,适用于需要频繁调用的变量。值得说的是,编译器可以选择依旧把该变量存在内存中,由于寄存器没有地址,所以不能取址。
类型限定符
1.const 常量(c90)
可修饰静态变量、指针和数组,在变量初次定义时使用,表示被修饰的变量的值为只读。
当修饰静态变量时,const放在变量类型前后均可。被修饰的静态变量可赋值给其他静态变量。
当修饰指针时,const放在 * 前,表示不能修改指针指向的地址中的值(*指针的值),const放在 * 后,表示不能修改指针指向的地址(指针的值)。被修饰的指针(在 * 前)不可赋值(指针的值)给其他未被const修饰的指针(自然不可以)。
当修饰数组时,const放在数组类型前。被修饰的数组可赋值给其他数组,被修饰的数组不可将地址赋值给其他未被const修饰的指针(自然不可以)。指向该数组的指针可进行++或--操作。
2.volatile 易变(c90)
表示每次都必须从内存中重新读取被修饰的变量的值,避免因优化原因导致程序读取寄存器中的旧值而产生错误。用时放在类型前,如 volatile int *p
3.restrict 限制(c99)
只能修饰指针,受限指针指向的对象不允许除该指针以外的其他任何方式访问。用时放在变量名前,* 后,如 int * restrict p
4._Atomic 原子(c11)
表示对被修饰的变量的访问具有原子性,即同时只能有一个线程访问该变量,用于公共资源实现互斥。用时放在类型前,如 _Atomic int a