zoukankan      html  css  js  c++  java
  • 你知道吗:char **p 和 const char **p 类型不相容

    char **p和const char **p是两种不相容的类型,因为它们是两种不同的类型。如果你理解这句话,可以不用往下看了。

    先看这个代码:

    1 foo(const char **p){ }
    2 
    3 void main(int argc, char **argv)
    4 {
    5    foo(arvg);
    6 }

    如果编译这段代码,编译器会发出一条警告消息:

    line 5:warning argument is incompatible with prototype

    (第5行:警告:参数与原型不匹配)。

    疑问是:实参char *s与形参const char *p是相容的(标准库中所有的字符串处理函数都是这个样子的),为什么实参char **argv与形参const char **p不相容呢?

    答案是,它们并不相容。

    在ANSI C标准中有这么一句话:每个实参都应该具有自己的类型,这样它的值就可以赋值给与它所对应的形参类型的对象(该对象的类型不能含有限定符)。

     

    这就是说参数传递过程类似于赋值。所以,除非一个类型为char **的值可以赋值给一个const char **类型的对象,否则肯定会产生一条诊断信息。要使以上赋值合法,必须满足下列条件之一:

          两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针所指向类型的全部限定符。

    正是这个条件,使得函数调用中实参char *能够与形参const char*匹配。

    1 char *cp;
    2 const char *ccp;
    3 ccp = cp;         //right
    4 cp = ccp;         //产生编译警告

            要想彻底理解为何char ** 与 const char **是不相容的,我们得先回顾一下const float *:它并不是一个有限定符的类型——它的类型是“指向一个具有const限定符的float类型的指针”,也就是说const限定符是修饰指针所指向的类型,而不是指针本身。

            类似的,const char **也是一个没有限定符的指针类型。它的类型是“指向有const限定符的char类型的指针的指针”。

            由于char **和const char **都是没有限定符的指针类型,但它们所指向的类型不一样(前者指向char*,后者指向const char*),因此它们是两种不同的类型,是不相容的。因此,类型为char **的实参与类型为const char **的形参是不相容的。它违反了上文黑体字所列出的约束。

            说明:在VC、VS里面编译第一个程序的话,0个warning,0个错误。在Linux下面用gcc编译的话,会给出实参和形参不相容的warning。 这是不是说明微软家的编译器不好呢?

            问题出自《C专家编程》一书。欢迎批评指正。

  • 相关阅读:
    noi 2011 noi嘉年华 动态规划
    最小乘积生成树
    noi 2009 二叉查找树 动态规划
    noi 2010 超级钢琴 划分树
    noi 2011 阿狸的打字机 AC自动机
    noi 2009 变换序列 贪心
    poj 3659 Cell Phone Network 动态规划
    noi 2010 航空管制 贪心
    IDEA14下配置SVN
    在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?
  • 原文地址:https://www.cnblogs.com/younes/p/1640373.html
Copyright © 2011-2022 走看看