为什么这允许从(char *)升级到(const char *)?

鉴于scanf在Microsoft的文档中有(const char *)以及这个问题的答案,当我为(char **)促销(const char **)做同样的事情时,会发生什么?

基本上为什么要编译?

#include  int main(int argc, char **argv) { char szArray[50]; int i = 0; strcpy(szArray,"10"); /* the following code is upcasting the (char *) to (const char *) */ sscanf(szArray,"%d",&i); return 0; } 

为什么不编译呢?

 #include  void processargs(const char **p) { } int main(int argc, char **argv) { processargs(argv); return 0; } 

两者似乎都在向指针做同样的事情!

char** -> const char **很危险,因为你最终可能会意外地修改底层的const对象。

写下你想要的正确方法是:

 void processargs(const char * const *p) { } 

你被允许增加访问限制,你不能减少它。 从普通指针到const指针很好,从const指针到普通指针不是。

第二个例子没有编译,因为你没有将指针转换为const指针,你正在从指针转换为一个类型( char* )到另一个类型( const char* )。 例如,您可以将char**更改为char* const* ,而不是const char**

检查这是否为您澄清:

 char * a_mutable = /*...*/; const char * a_constant = /*...*/; char **pointer_to_mutable = &a_mutable; /* ok */ const char **pointer_to_constant = &a_constant; /* ok */ pointer_to_constant = pointer_to_mutable; /* oops, are you sure? */ *pointer_to_constant = a_mutable; /* valid, but will screw things around */ 

最后一行是有效的,因为pointer_to_constant是指向常量字符的可变指针的可变指针,但它会破坏事物,因为你将a_constant指向a_mutable 。 这就是为什么不允许你使pointer_to_constant接收pointer_to_constant的内容。

你的第一个例子是有效的,因为你将char* rvalues转换为const char* ,这是正常的(基本上是因为你不能分配给rvalues)。 第二个没有,因为(非常量)指针的目标始终是左值。

只是尝试(可能借助于编译器)您可以使用char**执行哪些操作,这些操作使用const char** ,并考虑是否以及哪些类型可以互换。