一、如何理解const

一般普通的变量可以作为左值,像 int a = 10; a = 20;

但const修饰的变量不能够再作为左值(左值简单理解为等号左边的值)!!!一般来说,初始化完成后,不能够再被修改!!!(也就是说const int b = 20;这样初始化后,不可再对b进行修改。初始化的时候是可以去修改的,即让b = 20, 但是初始化过后,b=30❌这样再去修改就错误了。)

初始化过后不能修改,这是我们对const最初的一个理解。

 

const只是在语法上限制不能够修改,但可以对其内存进行操作从而进行修改的,比如:用指针重写内存的内容

 

二、C/C++中const的区别(笔试题)

(1)C语言中的const

1、在C语言中,const修饰的变量可以不用初始化,不用初始化也可以编译成功,但是如果你不初始化,你就没有机会再给它一个合法的值了,因为const修饰的变量不能作为左值。

虽然可以不用初始化,但是我们最好初始化一下。

比如:const int a;  (一开始没初始化,是可以的)

   a = 20;❌  (但是后面就不能再赋值了,因为const修饰的变量a不能作为左值)

所以在C语言中,const修饰的量不叫常量,叫常变量,常变量可以理解为除了不能作为左值,跟普通的变量没什么区别,一样不能够定义数组。

const int N = 20;

int a[N];  // 在C语言中,这样是错误的

 

2、C语言,用指针修改内存:

void main() {
      const int a = 20;
      
      int *p = (int *) &a;    // 用指针p指向变量a所在内存
      *p = 30;  // 通过指针的解引用,将a的内存值改为30
      
      printf("%d %d %d", a, *p, *(&a));    // 不管是输出哪种表达式,访问的都是a这块内存
}
输出的结果:30 30 30

 

(2)C++中的const

1、C++中,const修饰的变量必须初始化(不初始化的话编译会报错),叫做常量,能够用来定义数组。

const int N = 20;

int a[N];  // 在C++中,这样是对的,是可以的

2、C++,用指针修改内存:

void main() {
      const int a = 20;
      
      int *p = (int *) &a;    // 用指针p指向变量a所在内存
      *p = 30;  // 通过指针的解引用,将a的内存值改为30
      
      printf("%d %d %d", a, *p, *(&a));    // 不管是输出哪种表达式,访问的都是a这块内存
}
输出的结果:20 30 20

 

3、为什么在C和C++中同一段程序出现不同的结果呢?

其实这也就是C和C++中const的区别导致的:在两种语言中,const的编译方式不同,C语言中,const修饰的变量是当做一个变量来生成编译指令的。

C++中,编译器在编译时,将所有出现const常量名字的地方,都替换成了常量的初始值。如下图所示:

chown函数 修改为system分组_数组

 

最后输出a,但是却没有输出30,,输出a是20,是因为是输出的20跟a的内存没有关系,编译的时候,a早就被替换掉了(这也是C++里面const的变量要进行初始化的原因,不初始化,拿什么替换?!)。

至于a的内存上的值有没有改成30呢?改了!!用指针p修改了!!p指向的是a的内存,所以最后输出30。

另外,* 和 & 会互相抵消,*(&a) 就是a。 

 

4、C++中,const修饰的变量a如果用一个变量b去初始化,而不是用一个常量(或者说立即数)去初始化,(变量的值是多少是在运行时才知道,所以编译时替换的话,最多也是用b替换,但是b在编译时是不确定的,如果定义数组用到b的话,那就会报错,所以就不进行替换了)所以此时const修饰的变量a又叫常变量,跟C语言中的就一样了,就不能够再定义数组了,不能够作为左值了。

chown函数 修改为system分组_赋值_02