C++. 变量的存储说明符和cv-限定符. 简单复习

在C++中创建变量时,前面有时会有一些修饰符,这里总结一下。

大体分为两个类别:存储说明符和cv-限定符。

存储说明符

存储说明符有下面这些:

  • auto
  • register
  • static
  • extern
  • mutable

auto修饰符的变量时自动变量,如果变量没有任何修饰符,默认就是自动变量,其作用域在函数内部。

register修饰变量将创建一个寄存器变量,理念在于CPU访问寄存器中的值比访问普通存储在堆栈中的值速度要快,声明方法:

register int count_fast;

需要注意的是,编译器并不一定会满足将变量放在寄存器中的要求(有可能已被占用等等),而且寄存器中无内存地址,所以寄存器变量不能用地址操作符。

static修饰静态变量。要注意静态变量使用范围:

int global = 1000;// 在函数外声明,文件内外皆可使用
// 此时如果其他文件还想创建global同名变量,要么用extern声明(此时用的还是同一个,共享了变量),要么用static声明来隐藏这个大全局global(此时是新的变量)
static int one_file = 50;// 在函数外使用static声明,只在文件内各个函数可使用
void func (int n) {
  static int count = 0;// 在函数内用static声明,只能在函数内使用,但是无论函数是否执行,变量都存在,且多次调用时其值不会重新初始化,而是保持上一次的结果
  int lama = 0;// 普通变量,只能在函数内使用,函数不执行就不会存在
}

函数内创建与外部静态变量同名的变量时,将使用自己创建的,但是可以用::操作符表示使用外部的:

int global = 1000;
void func () {
  int global = 500;
  cout << global << endl;// 500
  cout << ::global << endl;// 1000
}

extern修饰的变量表示引用声明,假设文件1声明了一个外部变量,文件2要使用它,必须使用extern来修饰,因为不能创建两个同名的外部变量,如上文所述。

// file1.cpp
int global = 1000;

// file2.cpp
extern int global;

mutable修饰的变量,顾名思义,表示变量可变,那什么时候不可变呢?在下文要说的使用const修饰符修饰时,变量应该是不可变的,但是可能有这种用法:

struct person {
  char name[30];
  mutable int age;
};
const person me = {"Cloudox", 24};
strcpy(me.name, "Cloud");// 这是不允许的,因为结构体person的实例me是用const修饰的
me.age++;// 但这又是允许的,因为结构体person的成员age用mutable修饰了

cv-限定符

cv限定符只有两种:

  • const
  • volatile

这也是为什么它叫cv限定符,取首字母嘛。

const关键字上文已经说过了,很常用,表示变量的内存初始化后,程序不能对它进行修改了。

volatile修饰的变量时告诉程序,即使程序代码本身没有对变量的内存单元进行修改,它却也可能发生变化。

为什么会发生变化呢?因为假设你指针指向某个硬件位置,其中包含来自串行端口的时间或信息,这就有可能硬件本身改变它,而不是你程序去改变它。

那为什么要告诉程序它可能变化呢?因为假设编译器发现程序在几条语句中都使用了某个变量,那么为了优化,它不会让程序去查多次,而是缓存到寄存器中。这种优化是在变量本身不会被程序改变的前提下的,但是如果硬件改变了变量值,那就不能用这种优化了。因此volatile关键字实际上也就是告诉编译器,不要对这个变量做这种优化。

猜你喜欢

转载自blog.csdn.net/paradox_1_0/article/details/106074026