C主函数中,const char*[]与char*[]的区别。

4

我不理解以下两种技术的区别:

int main(int argc, char* argv[]){;}

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

我知道 char*[]const char*[] 之间的区别,但我想知道为什么有些情况下会选择使用后者。

是否存在需要更改命令行参数的用例?在添加 const 方面有什么最佳实践呢?


1
唯一的区别在于 const char 不允许您修改数据。例如,argv[0][0] = 'X'; 在这种情况下会引发编译器错误。 - Sven Nilsson
@SvenNilsson:那不是唯一的区别。int main(int argc, char *argv[]) 的行为由C标准定义。而int main(int argc, const char *argv[]) 的行为则没有,因为这两种类型不兼容,不能作为函数参数声明或参数类型互换。 - Eric Postpischil
2个回答

6

int main(int argc, char *argv[]) 是根据 C 2018 标准中的 5.1.2.2.1.1,在托管环境下声明 main 的一种定义方式。而 int main(int argc, const char *argv[]) 则不是。

在适当的情况下,使用const来指示指向对象不会更改是一个好习惯,但必须正确使用。类型为 char *[]const char *[] 的参数声明或参数类型不兼容且不能互换。如果使用 const char *argv[] 声明 main,则其行为未被 C 标准定义。

至于为什么规定声明应该是 char *argv[] 而不是 const char *argv[],这部分是历史原因,也因为某些处理命令行参数的技术可以直接修改参数。


char *argv[] 是一种定义声明的方式,对吗?我以为应该是 const char **argv,因为 argv 是不可变的? - Marco
4
@marco-a说:argv指向的参数、其指向的指针以及它们指向的字符串都不是不可变的。根据C 2018标准5.1.2.2.1第2条规定,“参数argcargv以及argv数组所指向的字符串应该可以被程序修改,并且在程序启动和终止之间保持最后存储的值。” - Eric Postpischil
真有趣!我今天学到了新东西。我一直以为它是不可变的(可能是因为修改用户输入的不良习惯)。 - Marco

2
第一个参数(char** argv)是由C11标准定义的:

It shall be defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }`

or equivalent¹⁰) or in some other implementation-defined manner.

¹⁰Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.

你可以认为C11标准中定义的const charchar是“等效的”。然而,该标准还对参数做了如下规定:

argcargv参数以及argv数组指向的字符串应该可以被程序修改,并且在程序启动和终止之间保留它们的最后存储值。

因此,看起来const并不符合C标准。 这个答案详细介绍了是否可以修改main参数。数组char **argv在运行时分配,修改它不会影响任何程序执行。
关于为什么不使用 const 作为声明,主要是基于历史惯例。这个问题的答案详细说明了为什么可能会使用 const char **argv 而不是非 const 的版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接