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

来源:互联网 发布:双色球中奖算法 编辑:程序博客网 时间:2024/05/29 07:23

首先来看一段代码:

#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的赋值操作,而它们根本就是不相容的类型,所以也会产生一条诊断信息。

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