C语言的指针相容问题char**和const char**

const char**无法赋char**的值,原因是指向的内容不相容。但是const char*却能赋char *的值(很多库函数就是这种形式),他们的指向内容却是相同的。why??
好像是什么相容性不可传递原理......郁闷啊
1楼,指针的内容是可变的。这个声明解释开是“声明一个指向一个指针的指针变量,这个指针变量指向一个只读的字符”。按照你的逻辑推演的话,const char *也就无法赋char *的值咯?

//char***也会出错,只有char *不出错,结论就是大于等于两重的指针都会出错。这就是编译器实现问题了,编译器就是这么干的,把本来合乎情理的东西弄成错误了,可能是微软出于某种安全性的考虑。但奇怪的是如下代码却是正确的:
const char **t;
char **a;
t = (const char **)a;
也就是说强制转化是没有问题的,必须保证赋给t的值和t在形式上的一致性。但是问题又出现了,下边的代码又有问题了:
char *const*t;
char **a;
*t = (char *const)*a;
即使进行了强制转化,a和t在形式上一致了,但是仍然错误。原因就是t是一个指向常指针的指针。所以,我们可以这么认为:对于道理上讲的通的东西,你可以经过强制转化赋值;对于语法上错误的赋值,无论怎么强制转化都是不起作用的。
下边是从网上看的关于常量指针的解释,讲的还是二重指针,可以推广到3重,4重,道理都是一样的。虽然对于解释这个问题,没有太大帮助,我觉得不错,分享一下。
#include <iostream>
#include <string>
using namespace std;
void test1(){
char **s; //s是数组的指针;
s = NULL;
s = new char*[4];
for (int i = 0; i < 4; ++i){
s[i] = new char[10];
strcpy(s[i], "test");
}
for (int i = 0; i < 4; ++i){
printf("%s\n", s[i]);
}
for (int i = 0; i < 4; ++i){
delete[] s[i];
}
delete[] s;
}

void test2(){
const char **s; //s是指向字符串常量的指针
s = NULL;
char b[4][10] = {"a","b","c","d"};
s = new const char*[4];
for (int i = 0; i < 4; ++i){
s[i] = b[i]; // OK
//s[i][0] = 'd'; //这句要报错,因为s[i]指向的是字符串常量
//即使b[i]字符串本不是常量(编译期间添加的属性)
}
for (int i = 0; i < 4; ++i){
printf("%s\n", s[i]);
}
delete[] s;
}

void test3(){
char * const * s; //s指向常量数组,数组的每一个元素是字符指针常量。
//数组的元素不可改,但数组元素指向的字符串可修改
s = NULL;// s不是常量
char a[4][10] = {"aa", "bb", "cc", "dd"};
char * const(b[4]) = {a[0], a[1], a[2], a[3]};
s = b;
for (int i = 0; i < 4; ++i){
s[i][1] = 'd'; //OK
//s[i] = NULL; //报错,因为s[i]是常量
printf("%s\n", s[i]);
}
}

void test4(){
const char * const * s; //s指向一个常量指针数组
//数组的每一个元素是字符指针常量,指向字符串常量(绕口令阿这是。。。)
s = NULL;// s不是常量
char a[4][10] = {"aa", "bb", "cc", "dd"};
char * const(b[4]) = {a[0], a[1], a[2], a[3]};
s = b;
for (int i = 0; i < 4; ++i){
//s[i][1] = 'd'; //报错,因为s[i][j]是常量
//s[i] = NULL; //报错,因为s[i]是常量
printf("%s\n", s[i]);
}
}

void test5(){
char a[4][10] = {"aa", "bb", "cc", "dd"};
const char * const(b[4]) = {a[0], a[1], a[2], a[3]};
const char * const * const s = b;
//s是一个常量指针,指向一个常量指针数组
//数组的每一个元素是字符指针常量,指向字符串常量(这才是绕口令!)
//s = NULL; //Error, s是常量
for (int i = 0; i < 4; ++i){
//s[i][1] = 'd'; //报错,因为s[i][j]是常量
//s[i] = NULL; //报错,因为s[i]是常量
printf("%s\n", s[i]);
}
}

int main(){
test1();
test2();
test3();
test4();
test5();
return 0;
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-12-09
这里涉及的问题挺复杂的,主要是因为const修饰符的问题。
1。比如const char* p 是指这个p本身是一个常量,他指向的是普通的char*变量,本身是常量,而char*就是普通的char*变量,所以指向内容是相同。
2。而const char** p 是指p指向的变量是常量的char**,然char**不是常量,他们的内容自然是不同的。
C有个标准,指向的内容必须一样,但本身变量是要向多限制过度的。比如普通的可以赋值给常量,但是常量不能赋值给普通变量,1提到的倒过来就不行。
有兴趣的话可以多写点代码,比如const char**, char* const * p, char** const p, const char* const * p,……等等,很多种组合,多写写就会有感觉了。本回答被网友采纳
第2个回答  2010-12-10
char *cp;
const char *ccp;
ccp=cp;
左操作数是一个指向有const限定符的char的指针。
右操作数是一个指向没有限定符的char的指针。
char类型与char类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(无),再加上自身的限定符(const)。
注意,反过来就不能进行赋值。
我可以帮助你,你先设置我最佳答案后,我百度Hii教你。
第3个回答  2010-12-10
char *cp;
const char *ccp;
ccp=cp;
左操作数是一个指向有const限定符的char的指针。
右操作数是一个指向没有限定符的char的指针。
char类型与char类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(无),再加上自身的限定符(const)。
注意,反过来就不能进行赋值。
第4个回答  2010-12-09
const char ** 表明指针中的内容是不可改变的,所以无法用char**对其进行赋值
反过来没有限制
相似回答