static
作用:
static最主要功能是隐藏,其次因为static变量存放在静态存储区,具备持久性和默认值为0
①隐藏作用,可以在不同的文件中定义同名变量和同名函数。
②对于变量来说,保持变量持久,静态数据区的变量会在程序刚刚运行时就完成初始化,也是唯一一次初始化;储存在静态数据区,静态存储区只有两种变量(全局变量和static静态变量)。
③默认初始化为0x00,和全局变量一样的属性,减少程序员的工作量。
实例:
看上面两个程序,static 修饰的变量再函数多次调用的时候只会被赋初值一次
此时a存储在了静态数据区
const
作用
①对变量加以限定不能被修改,常量必须在定义的时候同时被初始化。
②const和指针一起使用,
const int *p1;
int const *p2;
int *const p3;
在三种情况中,第三种指针是只读的,p3本身的值不能被修改;
第一二种情况,指针所指向的数据是只读的,p1,p2的值可以修改,但指向的数据不能被修改。
③const和函数形参一起使用
使用const单独定义变量可以用#define命令替换,const通常放在函数形参中。
如果形参是一个指针,为了防止在函数内部修改指针指向的数据就可以用const来限制。
volatile
编译器优化: 内存访问速度远远比不上cpu处理的速度,为了提高性能,从硬件上引入高速缓存cache,加速对内存的访问。
编译优化的方法有:
将内存变量缓存到寄存器;
调整指令顺序充分利用CPU指令流水线。
作用
因为访问寄存器要比访问内存单元要快的多,编辑器会作减少存取的优化。
当使用volatile声明函数变量的时候,系统总是重新从它所在的内存读取数据。遇到这个关键字声明的变量,编译器对访问该变量的代码不再进行优化,从而提供对特殊地址的稳定访问; 如果不使用valatile,编译器将对所声明的语句进行优化,以免出错。
注意:
参考自: volatile详解(任何人都能懂的那种)-CSDN博客
volatile对应的变量可能在你的程序本身不知道的情况下发生改变
比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量你自己的程序,是无法判定何时这个变量会发生变化
还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。
对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,**而不会利用cache当中的原有数值,**以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况
extern
作用
①函数内定义的变量为局部变量,函数外定义的变量为全局变量,为静态存储方式,生存周期为整个程序,有效范围为定义变量的位置开始到本源文件结束。
如果在定义前想要引用该全局变量,则应该加上 extern作为 “外部变量声明”。
多个源文件的工程想要引用一个源文件的外部变量也只许引用变量的文件中加入extern关键字加以声明,但是可以在引用的模块内修改其变量的值,慎用。
②extern “C”: C++代码调用C语言代码。在C++的头文件中使用。
sizeof
作用:
sizeof 在 编译阶段处理,作用为取得一个对象(数据类型或数据对象)的长度(即占用内存的大小,以1字节为单位)。
特殊对象
①指针可以看做变量的一种,32位操作系统sizeof 指针都为4,例子:
int *p;
sizeof(p) =4;
sizeof(*p) = sizeof(int )=4;
②对于静态数组,sizeof可以直接计算数组大小,例:
int a[10];
char b[ ]= “hello”;
Sizeof (a) = 4 * 10 =40;
Sizeof (b) = 6; (求字符串长度时要加上字符串结束符/0)
③数组作为函数形参时候,数组名当做指针 使用,例:
Void fun (char p[ ])
{
Sizeof (p) ; //结果为4
}
sizeof 与 stelrn 的区别:
sizeof 是操作符, strlen为函数;
sizeof 可以使用类型作为参数,如int char;
strlen只能使用 char*做参数且以\0为结尾
sizeof 为数组时候,不退化, 传递给strlen时数组会被退化成指针;