在 main 函数中重命名 argc 和 argv 是否安全?

许多程序使用标准名称来表示许多参数和字符串数组。主函数的原型类似于: int main(int argc, char *argv[]);。但是,如果为这些变量选择自定义名称,是否会破坏某些内容?

例如 int main(int n_of_args, char *args[]);

在编译器的上下文中,一切正常。这些变量对于 main 函数是局部的,因此它们可以有任何名称。简单的代码可以完美地构建和运行。但是这些名称可以由预处理器使用。那么,重命名这些参数是否安全呢?

我个人认为这些名字不好,因为它们看起来非常相似,只有一个字母不同。但是每个人都会出于某种原因使用它们。

6606 次浏览

是的。它是安全的,它看起来很奇怪,但它不会打破任何东西。

当然,您可以根据自己的喜好重命名这些参数 安全

int main(int wrzlbrnft, char* _42[]) {
}

名字是用沙子写的,它们对最终编译的代码没有任何影响。


唯一重要的是,声明和定义的参数类型实际上是匹配的。

main()函数的签名在本质上声明为

int main(int, char*[]);

如果您需要在实现中使用它们,实际上您需要为它们命名。如前所述,使用哪些名称实际上是不相关的。

是的,您可以根据需要重命名它们。它们只是函数参数名,仅此而已。

是的,它是安全的,只要您使用有效的变量名。它们是局部变量,因此它们的作用域不会超出 main函数。

根据 C 标准的第5.1.2.1节:

在程序启动时调用的函数名为 main 实现没有声明这个函数的原型 定义为返回类型为 int且没有参数:

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

或者使用两个参数(这里称为 argcargv,< strong > 尽管有 可以使用名称,因为它们是它们所在的函数的本地名称 声明:

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

或等价物; 或以其他实现定义的方式

也就是说,使用 argcargv以外的任何东西都可能会使阅读代码的人感到困惑,因为他们已经习惯了这些参数的常规名称。所以最好还是站在清晰的一边。

是的,使用不同的名字是安全的。

就我个人而言,我不会推荐它,但是,因为传统的 argcargv是如此广为人知和熟悉的其他 C 程序员谁可能会与您的代码工作。从长远来看,使用你自己的、特殊的、不同的名字会给你的读者带来更多的困惑和/或沮丧,而不会因为你更喜欢你的名字而拯救你。

“入乡随俗”

argcargv的名称实际上是在 C + + 11之前由 C + + 标准规定的,其中指出:

所有实施均应允许下列两种主要定义:

int main ()

还有

int main ( int argc , char * argv [])

接着讨论了 argcargv的要求。

所以从技术上讲,任何使用不同名称的程序都不符合标准,编译器可以拒绝它。当然,实际上没有编译器这样做。请参阅 在 comp.std.c + + 上的这个线程这个 C + + 03标准草案的3.6.1节。

几乎可以肯定,这只是一个疏忽,并在 C + + 11中进行了修改

所有实施均应允许

  • 返回 int
  • 返回 int的函数(int,指向 char的指针)

作为 main(8.3.5)的类型 第一个函数参数称为 argc,第二个函数参数称为 函数参数称为 argv,..。

就编译器而言,它是安全的。

唯一可能导致的问题就是混乱。阅读代码的人会希望这两个变量有自己的标准名称。你甚至可以这样做:

int main(int foo, char ** bar)
{
int argc;
float argv;

但我觉得我不需要告诉你这个练习有多糟糕。

根据 C 标准,是的,你可以重命名,没有什么会影响。正如我所理解的,在 C 语言中,默认的关键字/类型/令牌名称是用目的/用法定义的,所以它也是用同样的方式定义的名称

argc --> argument count


argv --> argument vector

这也是有意义的用法,所以你可以改为任何名称,除了 Reserved names

在 GCC 中,程序执行以函数名 main开始,它不依赖于他的参数。

当您为微控制器编写独立程序时,您不需要为名称 main而烦恼,您可以定义自己的 name并更改 Assembly 入口 _ 点来指向您的函数。它取决于控制器编译器和预定义控制器源代码的可用性。我在飞思卡尔控制器里,在代码战士的指挥下做过这个。

笔记:

最好遵循通用的标准/代码样式,使代码更加可见和可读

如果你不喜欢变量名,为什么不用宏 # 定义代替它们:

#define yourCounterName argc
#define yourVectorName  argv

你不会冒任何风险,并产生一个“干净的解决方案”。

我觉得每个人都很好地涵盖了技术 c + + 规则: 答案是肯定的。让我们抛开传统和事实,这1个特殊的函数是特殊的和标志性的,其中包含有效的点不改变这一基础。

很多时候,我觉得选择的哲学很少被讨论,因此我想就这个问题提供一个视角,因为我觉得这对于为什么这个问题被要求开始的原因很重要。

对我来说,这个问题涉及到在一般代码中表达英语的选择。你似乎被简短的描述所困扰,特别是,如果简短的描述落在相似的文本上。但是,在您的示例中,将 argn 更改为 n _ of _ args 只是实现了将一种简写形式更改为另一种形式的速记,而没有实际的附加值: 澄清或其他可见属性。

“数字”这个词已经被一个字母“ n”取代了。

如果你正在通过反短手的哲学来改变一个短手的名字,那么这样的东西似乎更合适:

Main (int argumentCount,char * * argumentVector)

我总是考虑两件事: 根据事物是什么和/或它们的隐含用法来命名。称之为 argumentVector 对我来说是多余的,因为双向间接 * * 隐含了矢量的属性。因此,对于如何编写代码,一个更好的长方法是: * * 参数。

有人会说,名为 argumentCount 的变量被声明为 int,Count 不能为负,但是可以有一个负的 int { unsign is better }。

同样,它是什么以及如何使用它在这种解释中发挥作用。如果是伯爵,那么我会假设它永远不会是负数。毕竟,你怎么可能有一个计数 -2苹果。我会说,你欠两个苹果。如果它是一个数字,那么我希望一个负的情况是可能的。这就是为什么额外的“ of”这个词对你可能很重要。此外,集合所引用的数字可能意味着一个特定的项,而不是集合本身的属性。Number = 5意味着一个特定的参数,而不是 numberOfArguments。

Main (int maxArgumentsIndex,char * * reference).

这消除了歧义。称之为索引可以消除负大小写歧义,还可以描述它是什么,以及如何使用它。它还暗示了英语的措辞,一个 max 是一个绝对的,并会感到奇怪的编写代码,修改这个值(它应该是常量)。“论点”在这里是有意义的,因为它是复数形式,描述了它是什么,以及它应该如何被使用。即使这样解释也可能是危险的,因为索引是 Count/NumberOf 的 -1。5个参数生成的 maxIndex 为4! !

任何其他的函数,我会完全使用:

Void 函数(const unsign int maxArgumentsIndex,const char * * 争论)

Not all situations merit long hand descriptors. In fact, some times a short hand yields more readability, in particular, in the case of writing math classes such as a Vec3f, Matrix, Quaternion, etc... I will almost always try to match the math language rather than the linguistic one. float x, y, z vrs. float xComponent and the like.

我明白所有这些都是一种风格的选择,但从长远来看,意识到这些选择真的会有所帮助。我保证,当数组不是以复数形式编写时,经验丰富的程序员会感到困扰,但话又说回来,main 是一种特殊的存在形式;)