static、const和关键字volatile

关于static修饰变量或函数

    在介绍static之前,先看下static修饰全局变量和局部变量的题。

#include<iostream>
using namespace std;

static int m;
void fun1()
{
	static int n = 0;
	n++;
	printf("n = %d\n",n);
} 

void fun2()
{
	m = 0;
	m++;
	printf("m = %d\n",m);
}
int main()
{
	int i;
	for(i = 0; i < 10; i++)
	{
		fun1();
	} 

	for(i = 0; i < 10; i++)
	{
	    fun2();
	}

	system("pause");
	return 0;
}

 运行结果:
     从运行结果可以看出,被static修饰的变量存储属性会发生改变,但被static修饰的全局变量和局部变量又有什么不同。这里先介绍下,变量的存储位置。
  变量的存储位置
变量的缺省存储类型取决于它的申明位置。
    1. 凡是在任何代码块之外的声明的变量总是存储于静态内存中。不属于堆栈内存,这类变量称为静态变量。静态变量在函数运行之前创建。
    2.  在代码块内部声明的变量的缺省存储类型是自动的,存储于堆栈中。
     注: 对于在代码块内部声明的变量,如果给他加上static关键字,可以使他的存储类型由自动转变为静态。具有静态存储类型的变量在整个程序执行过程中一直存在。而不仅仅是它所在的代码块执行的时候存在。修改变量的存储类型并不修改变量的作用域,它只能在该代码块内部按名字访问。
    3.  寄存器变量:register 关键字。
   static总结:
    1. static修饰变量
       static修饰全部变量,改变的是链接属性,将外部链接属性变为内部链接属性。即不能在其他源文件中被访问         static修饰局部变量,改变的是存储类型,从自动变量变为静态变量,同时影响了生命周期。变量的属性和作用域不受影响。
    2. static修饰函数  改变的是链接属性,将外部链接属性变为内部链接属性

对于上面的程序,由于m是被static修饰的全局变量,所以它的存储类型并不改变,每次调用fun2()时,首先将m赋值为0,所以最后m的结果为1. 在调用fun1()时,由于n时被static修饰的局部变量,它的存储类型由自动变量变为静态变量,每次创建n时,由于静态区中已经存在n, 所以并不影响n的值,所以n最后的输出结果为1-10.

const和关键字volatile

const定义常量
    在 C 语言中,当 const 修饰一个标识符的时候我们说,这个标识符依然是一个变量,但是它具有常属性,不能被直接改变  。
    
    在C++中,const修饰的标识符就是常量
const修饰变量时的优化处理

    在这里可以看到num的值修改了,但输出结果并没有改变,这是怎么回事呢?
这里编译器在编译期间,对代码做了优化处理。当编译器看到num被const修饰时,从语义上,num是不希望被修改的值,优化时就将num的值存放寄存器中(提高访问的效率),使用时直接从寄存器取,所以即使内存中的值改变,寄存器也感知不到,所以输出结果为10. 

当对代码做修改时,会出现什么情况呢?


当加上volatile时,输出结果为20. 那么volatile 有什么作用呢
volatile作用:
     编译时不优化,执行时不缓存,每次需从内存中读出(保证内存的可见性)。
 
 

猜你喜欢

转载自blog.csdn.net/smile_zhangw/article/details/81060336