返回

C语言进阶剖析——读懂const和volatile

后端

一、const 只读变量

const用于声明只读变量,一旦声明后,就不能再修改其值。这有助于提高代码的安全性,因为可以防止意外修改变量的值。

例如,我们可以使用const关键字声明一个常量PI,其值为3.1415926:

const double PI = 3.1415926;

现在,如果我们试图修改PI的值,编译器会报错:

error: assignment of read-only variable 'PI'

const关键字还可以用于声明常量数组。例如,我们可以使用const关键字声明一个名为days_in_month的常量数组,其中包含每个月的天数:

const int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

现在,如果我们试图修改days_in_month数组中的值,编译器会报错:

error: assignment of read-only location 'days_in_month[0]'

二、const 全局变量的分歧

const全局变量在C语言中引起了很多争论。一些程序员认为,const全局变量应该被视为常量,而另一些程序员则认为,const全局变量可以被修改。

事实上,const全局变量是可以被修改的,但只能在程序启动之前进行修改。一旦程序启动,const全局变量的值就不能再被修改。

例如,我们可以使用const关键字声明一个名为MY_GLOBAL_VARIABLE的全局变量,其值为10:

const int MY_GLOBAL_VARIABLE = 10;

现在,如果我们试图在程序启动后修改MY_GLOBAL_VARIABLE的值,编译器会报错:

error: assignment of read-only variable 'MY_GLOBAL_VARIABLE'

但是,如果我们试图在程序启动之前修改MY_GLOBAL_VARIABLE的值,编译器不会报错。例如,我们可以使用以下代码在程序启动之前修改MY_GLOBAL_VARIABLE的值:

#include <stdio.h>

const int MY_GLOBAL_VARIABLE;

int main() {
  MY_GLOBAL_VARIABLE = 20;
  printf("%d\n", MY_GLOBAL_VARIABLE);
  return 0;
}

输出结果为:

20

三、const 的本质

const关键字本质上是一种编译器指令,它告诉编译器将变量或函数参数视为常量。编译器会根据const关键字来生成相应的代码,以确保变量或函数参数的值不能被修改。

例如,当编译器遇到const变量时,它会将该变量的值存储在只读内存中。当编译器遇到const函数参数时,它会将该参数的值复制到一个临时变量中,然后将临时变量的地址传递给函数。这样,函数就无法修改参数的值。

四、const 修饰函数参数和返回值

const关键字还可以用于修饰函数参数和返回值。当const关键字修饰函数参数时,它表示该参数不能被函数修改。当const关键字修饰函数返回值时,它表示该函数的返回值不能被修改。

例如,我们可以使用const关键字修饰函数参数如下:

void my_function(const int x) {
  // x cannot be modified inside this function
}

现在,如果我们试图在函数my_function中修改x的值,编译器会报错:

error: assignment of read-only parameter 'x'

我们可以使用const关键字修饰函数返回值如下:

const int my_function() {
  return 10;
}

现在,如果我们试图修改函数my_function的返回值,编译器会报错:

error: assignment of read-only variable 'my_function()'

五、volatil