【问题标题】:Why does this allow promotion from (char *) to (const char *)?为什么这允许从 (char *) 提升到 (const char *)?
【发布时间】:2009-04-19 23:31:51
【问题描述】:

鉴于 scanf 在 documentation from Microsoft 中有 (const char *) 以及对 this question 的答案,当我将 (char **) 提升为 (const char **) 时,到底发生了什么?

基本上为什么会编译?

#include <stdio.h>
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 <stdio.h>
void processargs(const char **p)
{ 
}
int main(int argc, char **argv)
{
    processargs(argv);          
    return 0;  
}

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

【问题讨论】:

  • 你不明白一件事:如果 T -> U 有效,那并不意味着 T* -> U* 有效。只是一个简单的: double a = 4; /* int -> double / int p;双 *dp = &p; / int* -> double* ?? */
  • 我这里没有改变类型...两个集合都是指针。
  • 请关闭另一个而不是这个...
  • '*' 的数量很重要。仔细查看palecek 对您上一个问题的回答。

标签: c


【解决方案1】:

char** -&gt; const char ** 很危险,因为您最终可能会意外修改底层的const 对象。

正确的写法是:

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

【讨论】:

  • 你可以这样使用 const 应该被宣传。我认为很多人都不知道您可以做到这一点。
【解决方案2】:

您可以增加访问限制,但不能减少它。从普通指针转到 const 指针很好,从 const 指针转到普通指针则不行。

第二个示例无法编译,因为您没有将指针转换为 const 指针,而是将指针从一种类型 (char*) 转换为另一种类型 (const char*)。例如,您可以将char** 更改为char* const*,但不能更改为const char**

【讨论】:

  • 好的,为什么第二个例子不能编译呢?
【解决方案3】:

检查这是否为您澄清:

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_mutable 的内容。

【讨论】:

    【解决方案4】:

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

    只需尝试(也许在编译器的帮助下)哪些操作可以使用char**,哪些操作可以使用const char**,并考虑是否以及哪些类型可以互换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2011-11-29
      相关资源
      最近更新 更多