在main函数中重命名argc和argv是否安全
Is it safe to rename argc and argv in main function?
许多程序对许多参数和字符串数组使用标准名称。主要功能的原型看起来像:int main(int argc, char *argv[]);
。但是,如果我为这些变量选择自定义名称,我会破坏一些东西吗?
例如int main(int n_of_args, char *args[]);
在编译器的上下文中,一切都很好。这些变量是main函数的局部变量,所以它们可以有任何名称。简单的代码构建和运行都非常完美。但这些名称可能会被预处理器使用。那么重命名这些参数安全吗?
PS就我个人而言,我觉得这些名字很糟糕,因为它们看起来很相似,只有一个字母不同。但每个人都出于某种原因使用它们。
是的,只要使用有效的变量名,它是安全的。它们是局部变量,所以它们的作用域不会超出main
函数。
来自C标准第5.1.2.2.1节:
程序启动时调用的函数名为
main
。这个实现没有声明该函数的原型。它应该定义为返回类型为int
且无参数:int main(void) { /* ... */ }
或具有两个参数(此处称为
argc
和argv
,尽管有可以使用名称,因为它们是所在函数的本地名称声明):int main(int argc, char *argv[]) { /* ... */ }
或同等产品;或者以某种其他实现定义的方式
也就是说,使用argc
和argv
之外的任何东西都可能会让其他阅读代码的人感到困惑,因为他们习惯了这些参数的传统名称。所以最好还是站在聪明的一边。
名称argc
和argv
实际上是C++标准在C++11之前强制要求的。声明称:
所有实施都应允许以下两个主要定义:
int main ()
和
int main ( int argc , char * argv [])
并对CCD_ 12和CCD_。
因此,从技术上讲,任何使用不同名称的程序都不符合标准,编译器可以拒绝它。当然,实际上没有编译器这样做。请参阅comp.std.c++上的此线程,或本c++03标准草案的第3.6.1节。
这几乎可以肯定只是一个疏忽,并在C++11中进行了更改,改为
所有实施均应允许
- ()返回CCD_ 14和
- 返回
int
的函数(int
,指向char
的指针的指针)作为
main
(8.3.5)的类型。在后一种形式中,为了说明,第一个函数参数称为argc
,第二个函数参数称为argv
,…
当然,您可以根据的喜好安全地重命名这些参数
int main(int wrzlbrnft, char* _42[]) {
}
名字是用沙子写的。它们对最终编译的代码没有任何影响。
唯一重要的是,声明和定义的参数类型实际上是匹配的。
main()
函数的签名本质上声明为
int main(int, char*[]);
如果您需要在实现中使用它们,实际上您需要命名它们。如前所述,使用哪些名称实际上是无关紧要的。
是。它很安全,看起来很奇怪,但不会打碎任何东西。
是的,使用不同的名称是安全的。
不过,就我个人而言,我不建议使用它,因为传统的argc
和argv
对于其他可能使用过您的代码的C程序员来说是如此广为人知和熟悉。从长远来看,使用自己的、特殊的、不同的名字会在读者中引起更多的困惑和/或沮丧,因为你更喜欢自己的名字。
"入乡随俗。"
是的,您可以根据需要重命名它们。它们只是函数参数名称,仅此而已。
我觉得每个人都很好地涵盖了技术c++规则:答案是肯定的。让我们抛开传统,抛开这个1特殊功能是特殊的和标志性的这一事实,它包含了不在此基础上改变的有效点。
很多时候,我觉得选择的哲学很少被讨论,因此我想对这件事提供一个视角,因为我觉得这对为什么要求这样做很重要。
对我来说,这个问题涉及到用代码表达英语的一般选择。你似乎会被短手的描述所困扰,尤其是如果短手的文字看起来相似的话。然而,在您的示例中,将argn更改为n_of_args只完成了将一种类型的速记更改为另一种形式的速记,而没有实际的附加值:澄清或其他可见属性。
单词"number"已替换为字母"n"。
如果你通过反短手的哲学来更改短手的名字,那么这样的东西可能看起来更合适:
main(int argumentCount,char**argumentVector)
我总是考虑两件事:根据事物的本质和/或其隐含用法来命名事物。称它为argumentVector对我来说是多余的,因为作为向量的属性是由双向间接性**暗示的。因此,我将如何编写代码的一个更好的长手是:**参数。
有人会说,名为argumentCount的变量被声明为int,Count不能为负数,但可以为负数int{unsigned is better}。
同样,它是什么以及如何使用它在这种解释中发挥作用。如果它是一个计数,那么我认为它永远不会是负数。毕竟,你怎么能有一个计数为-2的苹果呢。我想说,你欠两个苹果。如果它是一个数字,那么我希望有可能出现阴性病例。这就是为什么额外的单词"of"对你来说可能很重要。这一点,也许还有集合所指的数字,意味着一个特定的项,而不是集合本身的属性。Ie:argumentsNumber=5表示一个特定的参数,而不是numberOfArguments。
main(int maxArgumentsIndex,char**arguments)。
这消除了歧义。将其称为索引可以消除大小写的歧义,还可以描述它是什么,以及如何使用它。它还暗示了英语措辞中的max是绝对的,如果编写修改这个值的代码(它应该是const),会感觉很奇怪。"arguments在这里是有意义的,因为它是复数,描述了它是什么,以及它应该如何使用。即使这样解释也可能很危险,因为Index是Count/NumberOf的-1。5个参数产生的maxIndex为4!!
任何其他功能,我都会完全使用:
void函数(const unsigned int maxArgumentsIndex,const char**自变量)
并不是所有的情况都值得用长手描述。事实上,有时短手会产生更高的可读性,尤其是在编写Vec3f、矩阵、四元数等数学类的情况下……我几乎总是试图匹配数学语言,而不是语言语言。浮动x,y,z vrs。float xComponent等。
我知道这一切都是一种风格选择,但从长远来看,意识到这些选择确实会有所帮助。我保证,当数组不是以复数形式编写时,经验丰富的程序员会感到烦恼,但话说回来,main是一种特殊的存在散文;)
根据C标准,可以重命名,不会有任何影响。正如我所理解的,在C语言中,默认的Keyword/types/token名称是根据目的/用法定义的,因此以相同的方式定义名称
argc --> argument count
argv --> argument vector
这在用法上也是有意义的,所以你可以更改为任何名称,除了Reserved names
在GCC中,程序执行从函数名main
开始,这与他的参数无关。
当您为微控制器编写独立程序时,您不需要为名称main
而烦恼,相反,您可以定义自己的name
,并将Assembly entry_point更改为指向您的函数。这取决于控制器编译器和预定义控制器源代码的可用性。我在Code warrior下的Freescale控制器中做过这件事。
我的注意事项:
最好遵循通用标准/代码样式,使代码更可见和可读。
就编译器而言,这是安全的。
这可能造成的唯一问题是混乱。阅读代码的人会期望这两个变量有它们的标准名称。你甚至可以做这样的事情:
int main(int foo, char ** bar)
{
int argc;
float argv;
但我不认为我需要说明这将是多么糟糕的做法。
如果你不喜欢变量名,为什么不用宏#define:代替它们呢
#define yourCounterName argc
#define yourVectorName argv
您不会冒任何风险,生产出"清洁的解决方案"。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 为什么我的for循环不能正确获取argv
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 检查 argv[i] 是否存在C++
- 在main函数中重命名argc和argv是否安全
- 在int main中的argv[]是否应该总是char*类型(如果使用argv则为char**类型)?
- 如何读取char argv输入并解析(检查)它是否为非整数