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

const char const*char[]编译器警告,c,arrays,pointers,char,constants,C,Arrays,Pointers,Char,Constants,我正在学习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[]) int mai

我正在学习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[])
int main(int argc, const char *argv[])
编译器不会抱怨这两个选项中的任何一个,如果我的想法是正确的,那么这两个选项都会产生相同的结果,因为*argv[]是指向数组的指针。我意识到如果argv不是数组,它们会有不同的含义,但我是否错了,它们会产生相同的结果,并且它们是正确的声明,而不是原始声明,在这个特定的情况下?

在这一行:

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

然而,
main
是特殊的:在这里使用
const
是非标准的。应该是:

int main(int argc, char *argv[])
编译器可能接受也可能不接受带有
const
的版本。它们是否接受由实现定义,这意味着编译器的文档应该有一个页面,说明它接受
main
的哪些签名。

在这一行:

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

然而,
main
是特殊的:在这里使用
const
是非标准的。应该是:

int main(int argc, char *argv[])
编译器可能接受也可能不接受带有
const
的版本。它们是否接受由实现定义,这意味着编译器的文档应该有一个页面,讨论它接受
main
的哪些签名

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

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

int main(int argc, const char *argv[])
int main(int argc, const char *argv[])
显然,您严重误解了
const
在参数定义中的工作方式。稍后我们将讨论这个问题,但首先我注意到,
main()
的允许签名是由标准指定的。允许实现支持其他签名,但符合“托管”实现要求支持的签名包括:

int main(void)

和等效物(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
,这是不兼容的

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

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

int main(int argc, const char *argv[])
int main(int argc, const char *argv[])
显然,您严重误解了
const
在参数定义中的工作方式。稍后我们将讨论这个问题,但首先我注意到,
main()
的允许签名是由标准指定的。允许实现支持其他签名,但符合“托管”实现要求支持的签名包括:

int main(void)

和等效物(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)
,我怀疑你的编译器会