细谈const char ** 与 char ** 的区别 .

           摘自:http://blog.csdn.net/piaojun_pj/article/details/6132399

 

[c-sharp] view plain copy print ?
  1. #include "stdafx.h"  
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. int main(int argc, char* argv[])  
  6. {  
  7.     const char ** p0=NULL;  
  8.     char ** p1=NULL;  
  9.     p0=p1;  
  10. }  
  11. // error C2440: “=”: 无法从“char **”转换为“const char **”  

      程序出现了错误,很明显是类型转换时类型不匹配(const char ** 和 char **)。为了较详细的分析这个问题,我们先看看下面这个程序。

[c-sharp] view plain copy print ?
  1. #include "stdafx.h"  
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. int main(int argc, char* argv[])  
  6. {  
  7.     const char * p0=NULL;  
  8.     char * p1=NULL;  
  9.     p0=p1;  
  10. }  

 

     毫无疑问,这个典型的程序成功的运行了。p0是指向有const限定符的char类型的指针,也就是p0指向const char类型,而p1指向char类型的指针,即p1指向char。所以,比较p0和p1就是比较const char 和 char。众所周知,const char是绝对不能用char来赋值的,即const char c1= char c2。但是指向const char类型的指针p0却可以用指向char类型的指针p1赋值,即p0=p1。这个类型转换还有一个明显的特征就是const char类型是char类型的const形式。这里我们由程序总结出这样一个规律:
     const type * p1;
     type * p2;
     p1=p2;
注意:两个'type'表示相同的类型(int ,char,char*...... )。

      让我们再回到最初的那个问题——const char ** p0和 char ** p1的区别。首先,根据《C陷阱与缺陷》中的“大嘴原则”(编译器会从左至右尽可能的将最长的字符串组合成一个有意义的标识),p0是指向“const char *” 的指针,p1是指向“char *”的指针。你可能会这样想,const char * 不正是 char * 的const形式吗?但是人的第一直觉往往是错的,不要相信自己的眼睛,用心去分析。const char * 是一个指针类型,它指向const char类型,而char * 也是一个指针,它指向char类型。哈哈,我想你已经恍然大悟了,const char * 和 char *根本就是两个不同类型的指针,换句话说,const char * 根本就不是 char * 的const形式。你现在一定在想“char * 的const形式是什么?它与const char * 有什么不同?”,如果你没有这样想,我先在这里道歉,请原谅我的自大,呵呵。char * p的const形式就是char * const p。如果你已经明白了,那么请忽视我接下来的罗里罗嗦。const char * p表示p指向const char 类型,也就是说p这个指针本身并不是const的,p是可以作为左值的(可以被多次赋值),只是p指向的变量是const的(p不可以通过解引用*p去修改p指向的变量)。明白了原理之后,我们编写一个测试程序试一下。

[c-sharp] view plain copy print ?
  1. #include "stdafx.h"  
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. int main(int argc, char* argv[])  
  6. {  
  7.     // const char ** 的赋值过程   
  8.     const char c1='x';  
  9.     const char * p0=&c1;  
  10.     const char ** p1=&p0;  
  11.     // char ** 的赋值过程   
  12.     char c2='y';  
  13.     char * p2=&c2;  
  14.     char ** p3=&p2;  
  15.     char * const * p4=p3;// 注意:char * const * 就是char ** 的赋值兼容类型   
  16. }  

上面讨论的错误经常发生在函数传参的时候,例如:

[c-sharp] view plain copy print ?
  1. #include "stdafx.h"  
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. void const_test(const char ** p)  
  6. {  
  7.     cout<<"I am in finction const_test."<<endl;  
  8. }  
  9.   
  10. int main(int argc, char* argv[])  
  11. {  
  12.     char c='x';  
  13.     char * p1=&c;  
  14.     char ** p2=&p1;  
  15.     const_test(p2);  
  16. }  
  17. // error C2664: “const_test”: 不能将参数1 从“char **”转换为“const char **”  

正确的函数参数类型写法是这样的。

[c-sharp] view plain copy print ?
  1. #include "stdafx.h"  
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. void const_test(char * const * p)  
  6. {  
  7.     cout<<"I am in finction const_test."<<endl;  
  8. }  
  9.   
  10. int main(int argc, char* argv[])  
  11. {  
  12.     char c='y';  
  13.     char * p1=&c;  
  14.     char ** p2=&p1;  
  15.     const_test(p2);  
  16. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值