一、
先看这段代码,编译的话会报错
foo(const char **p){}
main(int argc,char **argv)
{
foo(arvg);
}
错误原因简单来说就是参数类型不匹配。
那么为什么 char * *argv 类型的参数不能 传递给 const char **p?这是本文要解释的问题。
而事实上,
char *cp;
const char *ccp;
ccp = cp;
这样却是符合要求的。(即char * 可以传递给 const char *)
Why?
二、
先说一个概念,参数的传递类似于赋值,而赋值的条件要满足:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具备右边指针所指向类型的全部限定符。
通过类型限定符可以修改声明中的类型,类型限定符有 const、volatile、restrict 和 _Atomic。声明中可使用多个类型限定符,它们的顺序没有限制。
先看这个为什么可以吧:
char *cp;
const char *ccp;
ccp = cp;
根据赋值的条件:
- 左操作数 ccp 是一个
指向有 const 限定符的指针
。(const直接修饰指针本身) - 右操数 cp 是一个
指向没有限定符的 char 的指针
。 - 由于 char 类型与 char 类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(无),再加上自生的限定符(const)。
注意,如果反过来赋值 cp = ccp; 则会报错
再说 char * *argv 类型的参数不能 传递给 const char **p,即:
char **cp;
const char **ccp;
ccp = cp; //报错
错误!
同样,看左右参数限定符
- 左操作数 ccp 是
指向一个具有const 限定符的char类型的指针
的指针。(这里const 修饰的是 指针指向的类型。) - 右操作数 cp 是
指向一个char类型指针
的指针 - 由于 char * * 和 const char ** 都是没有限定符的指针类型。但是它们所指向的类型不一样(相当于一个是 int 型指针,一个是 char 型指针),因此它们是不相容的。
总结:
char *cp;
const char *ccp;
cp = ccp;报错是因为限定符原因
char **cp;
const char **ccp;
cp = ccp; 报错是因为 修饰符类型不同
三、
参考书本内容