C语言--一个实参与形参赋值引发的思考

首先来看一段代码:

#include<stdio.h>

void foo(const char **p) {  }

void main(int argc, char **argv) 
{
    foo(argv);

    return ;
}

我们对这段代码进行编译,发现它报出了警告:

test.c: In functionmain’:
test.c:14:9: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
     foo(argv);
         ^
test.c:10:6: note: expected ‘const char **’ but argument is of type ‘char **’
 void foo(const char **p) {  }
      ^

一般来说,对程序运行结果没有影响的警告我们会进行忽略,但是这个程序很短,非常易读,所以我们并不认为程序中有引发警告的bug,但是它却爆出了警告,这就耐人寻味了。

要想了解这个问题,我们需要阅读ANSI C标准。

如果你对上面的代码所论述的问题还没有那么清楚,请思考如下代码的运行结果:

#include<stdio.h>

void main(int argc, char **argv) 
{
    char *cp;
    const char *ccp;
    ccp = cp;
    cp = ccp;
}

你觉得两个赋值语句有什么不同?emmmm,事实是cp = ccp会爆出警告。

我们来阅读一下ANSI C的标准吧~

要使上述的赋值形式合法,必须满足下列条件之一:

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

好了,我们可以对先对第二个代码进行分析了:

cp是一个指向char类型的指针,无限定符;ccp是一个指向char类型的指针,有限定符。所以当ccp为左操作数的时候,它含有右边指针(无)所指向类型的全部限定符。因此没有警告,反之cp = ccp有警告。

那么我们来分析一下第一个代码:

argv是一个指向char*类型的指针,p是指向一个const char*的指针,foo(argv)相当于是执行了p = argv的赋值操作,而它们根本就是不相容的类型,所以也会产生一条诊断信息。

所以对于这种细微的东西,了解之后会发现原来是很有趣的一件事情。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值