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

时间:2016-04-29 18:51:14

标签: c++ c main

许多程序对许多参数和字符串数组使用标准名称。 main函数的原型如下:HWND console_name =FindWindow(null,"my_process_console"); if(console_name){ ShowWindow(console_name,SW_SHOW); } 。但如果我为这些变量选择自定义名称,我会破坏一些东西吗?

E.g。 int main(int argc, char *argv[]);

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

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

10 个答案:

答案 0 :(得分:117)

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

来自C standard的第5.1.2.2.1节:

  

程序启动时调用的函数名为main。该   实现声明此函数没有原型。它应该   使用返回类型int定义并且没有参数:

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

或有两个参数(此处称为argcargv尽管如此   可以使用名称,因为它们是它们所在的函数的本地名称   声明):

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

或同等的;或者以其他一些实现定义的方式

话虽这么说,使用除argcargv以外的任何内容可能会使读取您的代码的其他人混淆这些参数的常规名称。因此,最好在犯罪方面犯错。

答案 1 :(得分:37)

在C ++ 11之前,名称argcargv实际上是由C ++标准强制执行的。它说:

  

所有实现都应允许以下两个主要定义:

int main ()
     

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

继续讨论argcargv的要求。

从技术上讲,任何使用不同名称的程序都不符合标准,并允许编译器拒绝它。当然,没有编译器实际上这样做了。请参阅this thread on comp.std.c++this C++03 draft standard的第3.6.1节。

这几乎肯定只是一种疏忽,而且在C ++ 11中有所改变,而后者则说是

  

所有实施都应允许两者

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

作为main的类型(8.3.5)。在后一种形式中,出于以下目的   第一个函数参数称为argc,第二个函数参数称为argv   函数参数称为function getInnerHTML($tag, $id=null, $nodeValue = false){ if(empty($this->site))return 'Error: Missing $this->source, use setSource() first'; $this->loadHTML($this->source); $tmp = $this->getElementsByTagName($tag); $ret = null; $i = 0; foreach ($tmp as $v){ if($id !== null){ $attr = explode('=',$id); if($v->getAttribute($attr[0])==$attr[1]){ if($nodeValue == true){ $ret .= trim($v->nodeValue); }else{ $ret .= $this->innerHTML($v); } } }else{ if($nodeValue == true){ $ret .= trim($v->nodeValue); }else{ $ret .= $this->innerHTML($v); } } if(++$i > 4) break; } return $ret; } ,...

答案 2 :(得分:28)

当然,您可以根据需要安全地重命名这些参数

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

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

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

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

 int main(int, char*[]);

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

答案 3 :(得分:15)

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

答案 4 :(得分:7)

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

就个人而言,我不推荐它,因为传统的argcargv是如此广为人知,并且对于可能使用您的代码的其他C程序员来说都很熟悉。从长远来看,使用你自己的,特殊的,不同的名字会让你的读者感到更加困惑和/或沮丧,因为你更喜欢你的名字。

"在罗马时,像罗马人那样做。"

答案 5 :(得分:5)

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

答案 6 :(得分:3)

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

很多时候,我觉得这些选择的哲学很少被讨论,因此我希望提供一个关于这个问题的观点,因为我觉得这个问题的起因很重要。

对我来说,这个问题涉及一般在代码中表达英语的选择。你似乎对简短的描述感到困扰,特别是如果简短的手上有相似的文字。在您的示例中,将argn更改为n_of_args只会将一种类型的短手更改为另一种形式的速记,而不会添加任何实际值:澄清或其他可见属性。

'数字'已经被一封字母取代了。

如果你是通过反短手的哲学改变一个简短的名字,那么这样的事情似乎更合适:

  

main(int argumentCount,char ** argumentVector)

我总是考虑两件事:根据事物和/或隐含用法命名事物。将它称为argumentVector对我来说是多余的,因为作为向量的属性是双间接**所暗示的。因此,如何编写代码的更好的长手是:**参数。

有人会说名为argumentCount的变量被声明为int而Count不能为负数,但你可以使用负数int {unsigned更好}。

同样,它是什么以及如何使用它来解释这个问题。如果它是一个伯爵,那么我认为它永远不会是负面的。毕竟,你怎么能有-2个苹果的数量。我会说,你吃了两个苹果。如果是一个数字,那么我认为可能会出现负面情况。这就是为什么附加单词'对你来说很重要。那个,也许一个集合所引用的数字意味着一个特定的项目,而不是一个集合本身的属性。即:argumentsNumber = 5意味着一个特定的参数,但不是numberOfArguments。

  

main(int maxArgumentsIndex,char ** arguments)。

这消除了歧义。将其称为索引可消除负面情况模糊,并描述它是什么,以及如何使用它。它还暗示了英语的措辞,max是绝对的,并且会觉得奇怪的编写代码来修改这个值(它应该是const)。 '参数'这里有意义,因为它是复数,描述它是什么,以及它应该如何使用。即使以这种方式解释也可能是危险的,因为索引是Count / NumberOf的-1。 5个参数产生的maxIndex为4 !!

任何其他功能,我会完全使用:

  

void function(const unsigned int maxArgumentsIndex,const char **   参数)

并非所有情况都值得长手描述。事实上,有时候一只简短的手会产生更多的可读性,特别是在编写数学类如Vec3f,Matrix,Quaternion等的情况下......我几乎总是试图匹配数学语言而不是语言语言。浮动x,y,z vrs。 float xComponent等。

我理解所有这些都是一种风格选择,但从长远来看,意识到这些选择确实会有所帮助。我保证经验丰富的程序员在数组不是以复数形式编写时会受到打扰,但是再次,主要是存在的特殊散文;)

答案 7 :(得分:2)

根据C标准,是的,你可以重命名,没有任何影响。据我所知,在C语言中,默认的关键字/类型/令牌名称是按目的/用途定义的,因此它以相同的方式定义名称

argc --> argument count

argv --> argument vector

这在使用方面也有意义,因此您可以更改为任何名称 Reserved names

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

当您为微控制器编写独立程序时,您无需为名称main而烦恼,而是可以定义自己的name并更改Assembly entry_point以指向您的函数。它取决于控制器编译器和预定义控制器源代码的可用性。我在Code-warrior下的飞思卡尔控制器中做过这个。

我的注意事项:

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

答案 8 :(得分:0)

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

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

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

但我不认为我需要说出这种做法有多糟糕。

答案 9 :(得分:-1)

如果您不喜欢变量名称,为什么不用宏#define替换它们:

#define yourCounterName argc
#define yourVectorName  argv 

您不会冒任何风险并制作一个清洁的解决方案"。