int main( const int argc , const char[] const argv)
作为Effective C++第3条所述“尽可能使用const”,我开始思考“为什么不将这些‘常量’参数设置为
const
”?在程序中是否存在修改
argc
值的情况?int main( const int argc , const char[] const argv)
const
”?argc
值的情况?getopt
,实际上确实操作argv[]
,所以它也不能被设置为const
。getopt
的原型表明它不会修改argv[]
但可能会修改指向的字符串,但Linux手册指出getopt
重新排列其参数,并且他们似乎知道自己在做坏事。 Open Group的手册没有提到这种排列。)argc
和argv
上放置const
并没有多大好处,而且会使一些老派编程实践失效,例如:// print out all the arguments:
while (--argc)
std::cout << *++argv << std::endl;
我已经用C语言编写了这样的程序,我知道我不是唯一的。我从某个地方复制了示例。
const
添加到argv
中,而不会影响任何C函数所能做的事情。此外,getopt
声明为int getopt(int argc, char * const argv[], const char *optstring);
。在这里,“const”不是顶层的,但是它声明指针是const
,承诺不修改它们(尽管它们指向的字符串可能会被修改)。 - Cheers and hth. - Alfchar* const* ___argv
,但实际接口遵循const char **
。这样很容易混淆。我混淆了[]
和*
相对于const
的优先级。请原谅我的错误。 - Joe Zgetopt()
知道它不遵循标准,因为它会注意 POSIXLY_CORRECT
环境变量以使其正确地运行。特别是,POSIX 不会对参数进行置换,并且不会在第一个非选项参数之后查找选项。 - Jonathan LefflerC标准(ISO/IEC 9899:2011)如下所述:
5.1.2.2.1程序启动
¶1 在程序启动时调用的函数名为
main
。实现不声明此函数的原型。它应该定义为具有整数返回类型和没有参数的函数:
int main(void) { /* ... */ }
或者使用两个参数(这里被称为argc
和argv
,尽管可以使用任何名称,因为它们是在声明它们的函数中本地的):
int main(int argc, char *argv[]) { /* ... */ }
10)或以其他实现定义的方式。
¶2 如果它们被声明,main
函数的参数应遵守以下约束:
argc
的值必须为非负数。argv[argc]
必须是空指针。argc
的值大于零,则数组成员 argv[0]
到 argv[argc-1]
(含)必须包含指向字符串的指针,这些指针在程序启动前由主机环境赋予实现定义的值。目的是为了向程序提供从托管环境中其他位置确定的信息。如果主机环境无法提供同时具有大写和小写字母的字符串,则实现必须保证字符串以小写形式接收。argc
的值大于零,则由 argv[0]
指向的字符串表示程序名称;如果程序名称不可从主机环境获得,则 argv[0][0]
必须是空字符。如果 argc
的值大于 1,则由 argv[1]
到 argv[argc-1]
指向的字符串表示程序参数。argc
和 argv
以及 argv
数组指向的字符串必须可由程序修改,并在程序启动和程序终止之间保留它们的最后存储值。10)因此,int
可以被定义为 int
的 typedef 名称替换,或者将 argv
的类型写成 char **argv
等等。
请注意最后一个要点。它说 argc
和 argv
都应该是可修改的。它们不一定需要被修改,但可能会被修改。
QApplication(argc,argv)
构造函数被定义为引用argc
(http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html#QApplication)。这让我感到惊讶。 - HostileFork says dont trust SEargc
通常不是一个常量,因为main()
函数的签名早于const
。
由于argc是一个堆栈变量,改变它不会影响除了你自己的命令行处理以外的任何东西。
当然,如果您愿意,可以将其声明为const
。
在形式参数上使用顶层 const
不是函数类型的一部分。您可以随意添加或删除它:它只影响函数实现中对参数的使用。
因此,对于 argc
,您可以自由添加 const
。
但是对于 argv
,如果使字符数据为 const
,就会改变函数签名。这意味着它不是标准的 main
函数签名之一,并且将不必被识别为 main
函数。所以,这不是一个好主意。
不使用标准的 main
参数的一个好理由是,在 Windows 中,它们无法表示带有国际字符文件名等实际程序参数。这是因为在 Windows 中,它们按照非常强的惯例编码为 Windows ANSI。在 Windows 中,您可以通过 GetCommandLine
API 函数实现更可移植的参数访问功能。
总之,没有什么阻止您向 argc
添加 const
,但在 argv
上使用最有用的 const
将给您提供一个非标准的 main
函数,很可能不会被识别为这样的函数。令人欣慰的是(以一种讽刺的方式),有很好的理由不使用标准的 main
参数来编写可移植的严肃代码。简单地说,它们只支持旧的 ASCII,只有英文字母。
main
签名可以正常工作,并且您可以接收任意Unicode参数。 - R.. GitHub STOP HELPING ICEC
语言。在C语言历史上不存在const
。const
,因为const
的作用仅限于编译时。
const
关键字,之前它并不属于 C 的一部分。 - Jonathan Leffler因为argc
是一个局部变量(在C++中不是引用或其他东西),并且由于main
的特殊地位意味着向后兼容性的花招赋予它巨大的自由度,而没有强制应用程序将其设置为const的必要性。
main() {}
int main() {}
main() { return 0; }
main(int argc, char* argv[]) { return 0; }
int main(const int argc, const char** argv) { /* no return*/ }
这些以及其他许多变体都可以在广泛的C和C++编译器上编译。
因此,归根结底,argc并非不是const,只是它不必是,但如果您想使其成为const,那么它可以是。
main(const int argc, const char* argv[]) { return 0; }
http://ideone.com/m1qc9c,这是一个C++示例。
main(const int argc) {}
const
的好理由是编译器实现不知道您将对main函数的参数执行什么操作,它只知道必须给您这些参数。const
,哪些参数会被您的函数修改。const
,然后如果您有理由更改它们(例如递减索引以搜索数组),您就必须创建本地非const
变量,并将const
参数的值复制到这些变量中。这会导致繁琐的工作和额外的LOC,没有真正的好处。一个不错的静态分析器会发现您是否未修改参数的值,并建议您将参数声明为const
。
argc
声明为const
。 - Oliver Charlesworth--argc
- Aniket Ingeconst
作为传值参数并不能获得任何好处的说法。可以参考以下链接:https://dev59.com/Bmoy5IYBdhLWcg3wMLOj#8714278 和 https://dev59.com/iXVD5IYBdhLWcg3wBWvd#117557。 - leonbloy