1、const是C语言的一个关键字,它限定一个变量不允许被改变,尽管不可更改,但是它依然是变量,不是常量;使用const在一定程度上可以提高程序的安全性和可靠性。
2、当const和指针变量联合使用时,要分清楚,是对指针变量本身限定,还是对指针变量指向的数据限定:
(1)对指针变量本身限定:
int a = 3, b = 4;
int * const ptr = &a;//ptr的数据类型为int* const,即限定ptr不可变,但是*ptr是可变的
int* p = &b;
ptr = p;//错误,不能给const型变量赋值
*ptr = b;
p = ptr;
*p = *ptr;
(2)对指针变量指向的数据限定:
int a = 3,b = 4;
int const *ptr = &b;//ptr的数据类型为:const int *,即*ptr内容不可变,但是ptr可变;注意,使用const限定变量时,变量同时初始化,否则不合法
int *p = &a ;
int const *qtr;
p = ptr;//错误,无法从 const int *转换为 int*
qtr = ptr;//正确,同为cont int *类型
ptr = p;//正确,竟然可以从int*转换为const int*
(3)同时对指针变量本身和指针变量指向的数据使用const限定
int a = 3, b = 4;
int const * const ptr = &a;//ptr的数据类型:const int * const;即ptr本身和ptr指向的数据都不可改变
ptr = &b;//错误
*ptr = b;//错误
(4)对数组进行const限制
const int arr[10] = {0};
int *ptr;
ptr = arr;//错误,因为arr[10]为常量数组,否则,你就可以通过指针修改数组内容了;
综上:
(1)只有非const限制的地址才能赋给普通的指针变量,即把const型指针赋值给非const型指针变量是错误的(这是针对限制指针变量本身来说的);
(2)const限制的变量在做实际参数时,函数的形式参数也必须声明为const型,否则错误;反之,则不需要;
(3)将const型或非const型指针变量赋值给const型指针变量是合法的;
3、C专家编程中的一个例子:
(1)程序一
char ch = ’a‘,ch1 = ’b‘;
char const * ptr = &ch;
char * pt = &ch1;
ptr = pt;//将char*型指针变量赋值给const char*型指针变量是合法的
pt = ptr;//但是将const char*型指针变量赋值给char8指针变量是不合法的
(2)程序二
char const ** ptr;
char ** pt;
ptr = pt;// 无法从“char **”转换为“const char **”
pt = ptr;//无法从“const char **”转换为“char **”
*ptr = *pt;//正确,即将char*型指针变量赋值给const char*指针变量是合法的,和程序一相同
*pt = *ptr;//无法从“const char *”转换为“char *”
**ptr = **pt;//不能给限定的变量赋值
**pt = **ptr;//正确
书上的原题为
令人奇怪的是,尽管实参char** argv和形参const char**p不相容,但是实参char*s和const char *p是相容的;
<c专家编程>上的解释为:
(1)实参和形参不相容,这要看参数传递的约束条件:
每个实参都应该具有自己的类型,这样它的值就可以赋值给与它所对应的形参类型的对象(该对象的类型不能含有限定符);
这就说,参数传递过程类似于赋值;
(2)因此,接下来看赋值的约束条件:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针所指向类型的全部限定符;
这就是说,左边指针可以具有右边指针没有的限定符,同时包含右边指针所有的限定符;
这个条件使得函数调用中实参char*能够与形参const char*匹配;
合法的原因就是:
char* cp;
const char *ccp;
ccp = cp;
左操作数是一个指向有const限定符的char的指针;
右操作数是一个指向没有限定符的char的指针;
char类型与char类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(无),再加上自身的限定符;
反过来,就是错误的,因为cp = ccp时,左边操作数cp不包含右边操作数ccp所具有const限定符,所以是错误的;
(3)类似的,const char**也是一个没有限定符的指针类型,它的类型是指向有const限定符的char类型的指针的指针;由于char**和const char**都是没有限定符的指针类型,但它们所指向的类型不一样,前者指向char*,后者指向const char*,因此它们是不相容的。因此类型为char**的实参与类型为const char**形参是不相容的;
对此,我很不理解:
const char** 指向的是const限定符的char类型的指针,char**指向的是没有const限定符的char类型的指针,书中说,const char** 和char**指向的类型不同,因此不能相容;由此推理,const char* 和char*相容的话,二者指向的类型必能相容,但是:const char *指向的是由const限定符的char,char*指向的是没有const限定符的char,难道const char 和char就能相容么;
想不通啊????