关于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关键字,可以使他的存储类型由自动转变为静态。具有静态存储类型的变量在整个程序执行过程中一直存在。而不仅仅是它所在的代码块执行的时候存在。修改变量的存储类型并不修改变量的作用域,它只能在该代码块内部按名字访问。
注: 对于在代码块内部声明的变量,如果给他加上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时,输出结果为20. 那么volatile 有什么作用呢
volatile作用:
编译时不优化,执行时不缓存,每次需从内存中读出(保证内存的可见性)。