我不理解以下两种技术的区别:
int main(int argc, char* argv[]){;}
和
int main(int argc, const char* argv[]){;}
我知道 char*[]
和 const char*[]
之间的区别,但我想知道为什么有些情况下会选择使用后者。
是否存在需要更改命令行参数的用例?在添加 const
方面有什么最佳实践呢?
我不理解以下两种技术的区别:
int main(int argc, char* argv[]){;}
和
int main(int argc, const char* argv[]){;}
我知道 char*[]
和 const char*[]
之间的区别,但我想知道为什么有些情况下会选择使用后者。
是否存在需要更改命令行参数的用例?在添加 const
方面有什么最佳实践呢?
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
是不可变的? - Marcoargv
指向的参数、其指向的指针以及它们指向的字符串都不是不可变的。根据C 2018标准5.1.2.2.1第2条规定,“参数argc
和argv
以及argv
数组所指向的字符串应该可以被程序修改,并且在程序启动和终止之间保持最后存储的值。” - Eric Postpischilchar** argv
)是由C11标准定义的:
你可以认为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
andargv
, 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 atypedef
name defined asint
, or the type ofargv
can be written aschar ** argv
, and so on.
const char
与char
是“等效的”。然而,该标准还对参数做了如下规定:
因此,看起来
argc
和argv
参数以及argv
数组指向的字符串应该可以被程序修改,并且在程序启动和终止之间保留它们的最后存储值。
const
并不符合C标准。
这个答案详细介绍了是否可以修改main
参数。数组char **argv
在运行时分配,修改它不会影响任何程序执行。const
作为声明,主要是基于历史惯例。这个问题的答案详细说明了为什么可能会使用 const char **argv
而不是非 const
的版本。
int main(int argc, char *argv[])
的行为由C标准定义。而int main(int argc, const char *argv[])
的行为则没有,因为这两种类型不兼容,不能作为函数参数声明或参数类型互换。 - Eric Postpischil