const char const * char []编译器警告

时间:2016-02-17 19:00:30

标签: c arrays pointers char const

我正在学习C并且仍然有点绿色,但我正在学习一些课程,并且我收到编译器警告有关重复的' const'声明说明符。

违规行是;

int main(int argc, const char const *argv[])

除非我严重误解了const在参数定义中的工作方式,否则因为argv是一个我需要使用的数组;

int main(int argc, const char const **argv)

或者

int main(int argc, const char *argv[])

编译器不会抱怨这些选项中的任何一个,如果我的思路正确,两者都应该产生相同的结果,因为* argv []是一个指向数组的指针。我意识到如果argv不是一个数组,它们会有不同的含义,但是我错了它们会产生相同的结果,并且它们是正确的声明,而不是原始声明,在这种特殊情况下?

3 个答案:

答案 0 :(得分:3)

在这一行:

int main(int argc, const char const *argv[])
你曾两次写const。一般来说,这是C标准允许的,但无论如何你的编译器似乎都是友好和警告的。您可以忽略或禁用此警告,也可以删除其中一个const

但是,main很特别:此处使用const是非标准的。它应该是:

int main(int argc, char *argv[])

编译器可能会也可能不会接受const的版本。它是否是实现定义的,这意味着编译器的文档应该有一个页面,讨论它接受的main签名。

答案 1 :(得分:1)

  

除非我严重误解了const在参数定义中的工作方式,否则因为argv是一个我需要使用的数组

int main(int argc, const char const **argv)
     

或者

int main(int argc, const char *argv[])

显然,你严重误解了const在参数定义中的工作方式。我们稍后会谈到这一点,但首先我发现main()的允许签名是由标准指定的。允许实现支持其他签名,但符合,#34;托管"实现需要支持:

int main(void)

int main(int argc, char *argv[])

和等价物(C2011,5.1.2.2.1)。因此,无论所有其他考虑因素如何,都支持这些签名,并且不需要支持不等价的签名,例如const限定符。

然后回到数组​​参数的问题。假设你有一个数组...

int a[4];

...你要传递给一个函数。从技术上讲,你不能这样做。在几乎所有的上下文中,特别是当它们作为函数参数出现时,数组值衰减到指针。您可以传递这样的指针,这确实很常见,但您无法传递数组本身。数组的元素类型(包括完全相同的限定符)是结果指针值的目标类型。此外,不能是const - 这是类型的属性。因此,编写

非常好
int a[4];
int f(int *);

f(a);

此外,请注意,您提出的方法签名都将参数argv声明为指向const char的指针。该类型与指向char的指针不兼容。如果你想声明argv本身不能改变(虽然这样做是不必要的),那么你可以把它写成

int main(int argc, char ** const argv)

,我怀疑你的编译器会接受。如果您想声明argv数组中的指针无法通过argv更改,那么那就是...

int main(int argc, char * const *argv)

......这也很有可能被接受。但是,您实际尝试编写的内容将argv元素的内容声明为const,并且这些内容不兼容。

答案 2 :(得分:1)

const适用于其左边的内容,除非左边没有任何内容,否则它适用于其右边的内容。宣言:

int main(int argc, const char const *argv[])

将两个const应用于相同的char标识符,因此警告。

如果你想说argv是一个指向常量字符的非常量指针数组,请使用:

const char * argv[]

如果你想说argv是一个常量字符常量指针数组,请使用:

const char * const argv[]

argv参数的正确声明只是char* argv[]char** argv。根本不使用const个说明符。具体的编译器可能允许const变体,但标准没有定义。