一直以来,我认为const就是用来简单修饰一个常量的,类似于宏定义中的宏替换一样,一个常量就是在程序运行过程不能修改。后来再次接触const关键字时,也没理解的很透彻,今天算是第三次再看const关键字,也算是把之前的理解做了一个总结归纳。
const修饰一个变量为常量,比如const int a = 2; 说a就是一个常量,a的值不能被修改,其实这里的不能修改是指在一定意义上的不能修改,说的明白一些,就是不能通过a来修改,但是事实上通过一些其他方式a的值还是可以被修改的。如下这个程序:
- #include<stdio.h>
- int main(int argc,char *argv[])
- {
- const int a=3;
- int *p=(int*)&a;
- *p=100;
- printf(“%d”,a);
- return 0;
- }
其中通过指针变量p来进行间接访问并对其修改,实现了修改a的值。
有些C语言的书上这样写道:“const就是用来声明一个只读关键字的”,其实仔细理解一下,就是不能通过变量名来对其直接进行修改,但是可以通过指针变量进行间接访问并进行修改,上面的程序就是一个很好的例子。
再比如下面这个程序:
- int integerArray[10]={0};
- const int* pointer=integerArray;
其中声明了一个指向只读内容的指针pointer,它在这里是一个指向常量的指针变量,pointer指向的内容不可以变,但是pointer的指向可以变,也就是不能通过修改pointer的指向内容来修改它所指向的值。如下这样的表述:
- *(pointer+1)=2;
这样的表述是非法的,因为不能通过pointer来修改其指向的值。不过这里的不可变也并不是绝对意义的并不可变,看了下面的程序你就会理解这种意义的不可改变。
- #include<stdio.h>
- int main(int argc,char *argv[])
- {
- int array[10]={0};
- const int *pointer=array;
- int *pointer1=(int*)pointer;
- pointer1[0]=1;
- printf(“%d”,array[0]);
- return 0;
- }
其中不能通过pointer指针变量来修改其指向的值,但是把pointer这个指针变量赋给pointer1这个指针变量,通过pointer1进行间接访问操作就可以对其指向的值进行改变。
说到这里,就说完指向常量的指针变量。接下来就是指向变量的指针常量了,指针常量就是指针的指向不能被改变,也就是说在声明时就必须指针常量进行初始化,否则丢失了这一次初始化的机会就无法对其直接进行赋值。
注意我这里说的不是能直接进行赋值,也就是说可以间接来对其进行赋值。从上面指向常量的指针修改常量的值得来启发,我们可以采用如下的方法唉修改这个指针常量。
- #include<stdio.h>
- int main(int argc,char *argv[])
- {
- int a=2;
- int* const p;
- int **p1=(int**)&p;
- *p1=&a;
- printf(“%d”,*p);
- return 0;
- }
其实这个程序的思路来源于通过一个指针变量来修改一个指向常量的指针,既然可以那么修改,那么修改一个指针常量的值,就可以通过一个二级指针来对一级指针的指向进行修改,就类似于之前通过一级指针来对一个值来进行修改一样,这样的降级思维理解起来非常有意思,类似于之前对多维数组的降级使用一样的。
如果上面的两个const使用都理解的话,下面这个声明我们应该一看就懂:
- cont int* const p;
就是上面的两种声明的组合:指向常量的常指针就是指向常量的指针与常指针的复合。
最后附上《Effective c++》Item21提供的一个理解:
如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。
这里就是我对C语言中const的理解,至于C++中的const我暂时没有去仔细复习,不过c++是一门面向对象的编程语言,其使用应该和类以及对象有关系,不过最基本理论也就是上面的几句话。暂时先把C语言中的理解透彻了,至于C++在以后应该不会是一个难事。