关于'main(int argc,char *argv [])'[重复]

Posted

技术标签:

【中文标题】关于\'main(int argc,char *argv [])\'[重复]【英文标题】:Regarding 'main(int argc, char *argv[])' [duplicate]关于'main(int argc,char *argv [])'[重复] 【发布时间】:2011-04-23 07:38:35 【问题描述】:

可能的重复:What are the arguments to main() for?What does int argc, char *argv[] mean?

每个程序都以main(int argc, char *argv[]) 定义开始。

我不明白这是什么意思。如果有人能解释为什么我们在程序中不使用这些参数,我会很高兴?为什么不只是:int main()

程序的名称是*argv[]argc 的元素之一,是*argv[] 中的参数个数的计数吗?发送到*argv[] 的其他参数是什么?我们如何发送它们?

【问题讨论】:

请注意,如果您不打算使用命令行参数,那么定义函数int main(void)int main() 是完全允许的(并且非常明智)。返回类型(int)在 C99 或 C11 中是强制性的;如果您不指定代码遵循哪个版本的 C 标准,编译器有时会让您忽略它。另见What should main() return in C and C++。 【参考方案1】:

main 的参数 argcargv 被用作向程序发送参数的一种方式,可能最熟悉的方式是使用良好的终端,用户可以在其中键入 @ 987654329@。这里cat这个词是一个程序,它获取一个文件并将其输出到标准输出(stdout)。

程序接收argc 中的参数数量和argv 中的参数向量,在上面的argument c中,数量将是两个(程序名称算作第一个参数)并且 argument vector 将包含 [cat,file,null]。而最后一个元素是空指针。

通常,你会这样写:

int  // Specifies that type of variable the function returns.
     // main() must return an integer
main ( int argc, char **argv ) 
     // code
     return 0; // Indicates that everything went well.

如果您的程序不需要任何参数,则以以下方式编写main-函数同样有效:

int main() 
  // code
  return 0; // Zero indicates success, while any 
  // Non-Zero value indicates a failure/error

在 C 语言的早期版本中,在 main 之前没有 int,因为这是暗示的。今天,这被认为是一个错误。

在兼容 POSIX 的系统(和 Windows)上,可以使用第三个参数 char **envp,其中包含程序 environment variables 的向量。 main 函数的参数列表的进一步变体存在,但我不会在这里详细说明,因为它是非标准的。

另外,变量的命名是约定,没有实际意义。坚持这一点总是一个好主意,这样您就不会混淆其他人,但将main 定义为同样有效

int main(int c, char **v, char **e) 
   // code
   return 0;

对于第二个问题,有几种方法可以向程序发送参数。我建议您查看 POSIX 标准的exec*()family of functions,但使用system("command arg1 arg2") 可能更容易,但使用system() 通常不受欢迎,因为它不能保证在每个系统上都能正常工作。我自己没有测试过;但是如果没有bashzsh 或其他在*NIX 系统上安装的shell,system() 将失败。

【讨论】:

如果我没记错的话,argc 的最小可能值是 1,argv[0] 包含字符串 ./mymainprogram,而 argv[1]NULL。我的问题是 - 1:argc 可以容纳的最大值是多少? 2: 这些添加到argv[] 的字符串是什么? @barnes - 最大值取决于操作系统。在 Win32 中,命令行本身的长度限制为 32K,因此argc 的实际限制为 16K。 @barnes:旧 DOS 的命令行参数限制为 127 个字节,这并不是说它不再重要,而是我碰巧记得的一个有趣的事实^_^ @JesseChisholm 我意识到这已经很老了,但值得一提的是,该限制适用于启动其他 Cygwin 进程的 Cygwin 进程(它们将 argv 直接传入此类情况)。另外,我一直在研究a way to bypass the Windows limit。 char **envp 作为第三个参数不是 POSIX 标准的一部分。看到这个thread【参考方案2】:

这些用于将参数传递给您的程序,例如在调用程序时从命令行传递参数

$ gcc mysort.c -o mysort

$ mysort 2 8 9 1 4 5

上面,程序mysort是用一些命令行参数执行的。在main( int argc, char * argv[]) 内部,这将导致

Argument Count, argc = 7 

因为有 7 个参数(计算程序),并且

Argument Vector, argv[] =  "mysort", "2", "8", "9", "1", "4", "5" ;

以下是一个完整的例子。

$ cat mysort.c
#include <stdio.h>
int main( int argc, char * argv [] ) 
    printf( "argc = %d\n", argc );
    for( int i = 0; i < argc; ++i ) 
        printf( "argv[ %d ] = %s\n", i, argv[ i ] );
    


$ gcc mysort.c -o mysort

$ ./mysort 2 8 9 1 4 5
argc = 7
argv[ 0 ] = ./mysort
argv[ 1 ] = 2
argv[ 2 ] = 8
argv[ 3 ] = 9
argv[ 4 ] = 1
argv[ 5 ] = 4
argv[ 6 ] = 5

[char 字符串“2”、“8”等可以使用一些字符到数字的转换函数转换为数字,例如atol()(link)]

【讨论】:

【参考方案3】:

使用argc(参数计数)和argv(参数向量),您可以在启动应用程序时获取传递参数的数量和值。

这样,当您的应用程序启动时,您可以使用参数(例如-version)以不同的方式运行。

但您也可以使用int main(void) 作为 C 中的原型。

还有第三个(鲜为人知且非标准的)原型,其第三个参数是envp。它包含环境变量。


资源:

Wikipedia - Main function, C and C++

【讨论】:

程序名和传递给main()的参数有什么关系? @Potatoswatter,@You,我更新了我的答案,明确表示 envp 不是标准的。 @fahad,通常第一个参数是应用程序的名称,这样你就可以知道你的应用程序是如何被调用的。 光看名字,你怎么知道它叫什么? @fahad,我的意思是“应用程序是如何命名的”。例如,这可用于打印错误消息,例如“Illegal option... usage: applicationName [-v]” 在 *nix 操作系统中,不同的“程序”成为同一个可执行文件的符号链接并非不可能 - 知道它是如何被调用的,可以使该可执行文件根据其被调用的内容而表现出不同的行为。这方面的一个经典示例是我认为busybox 实用程序 - 同一个文件的行为就像字面上数百个其他实用程序(可能在“缩减”或仅实现每个实用程序最常用的功能) ) 作为一个可执行文件,在许多情况下都是有利的......【参考方案4】:

argc 表示传递给程序的参数数量。 char* argv[] 是传递的参数。 argv[0] 始终是程序名称本身。我不是 100% 确定,但我认为 int main() 在 C/C++ 中有效。

【讨论】:

int main() 仅在 C++ 中有效。在 C 中,您需要像这样放置一个 void:int main(void)。 C 风格的 int main(void) 在 C++ 中也有效,但不鼓励在 C++ 中使用它。 @Ultimater 我很确定int main() 在 C 中也有效。它声明了一个可变参数函数。 @Navin 许多 C++ 编译器在遇到 C 代码时非常宽容,因为 C++ 允许 int main()int main(void) 进行编译,但是 C 编译器,肯定是较旧的 C 编译器,不支持C++ 风格int main()。我参加了一门非常强调可移植性的 C/C++ 课程,如果你的作业应该用 C 编写并且你给了它一个 int main() 声明,他的作业检查器会抱怨,甚至不会编译它,我们除非我们在截止日期前重新提交,否则作业会被扣分。【参考方案5】:

argc 是在运行时提供给程序的命令行参数的数量,argv 是包含这些参数的字符数组(更确切地说,是 C 字符串数组)。如果您知道您不需要命令行参数,则可以在采用 void 参数时声明您的 main,而不是:

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

这是根据标准为main 定义的仅有的两个原型,但一些编译器也允许返回类型为void。更多关于这个on Wikipedia。

【讨论】:

从技术上讲,int main() 是一个带有任意多个参数的函数,而 int main(void) 正好采用零个参数,因此后者更正确。 不,在定义中,int main() 是一个不带参数的函数。在不是定义的 declaration 中,它是一个采用未指定参数的函数。这是 n1256 中的 6.7.5.3/14,或 n794 中的 6.5.5.3/10。提问者在询问定义。【参考方案6】:

comp.lang.c FAQ 处理问题

“main() 的正确声明是什么?”
Question 11.12a。

【讨论】:

...但这不是 comp.lang.c,而是 ***,一个我们通过回答他们的问题来帮助人们的社区,不要将它们重定向到手册、常见问题解答或 lmgtfy 链接。 上面已经回答了这个问题。然而,C FAQ 仍然值得一读,恕我直言。但它在其许可证中声明未经许可不得复制。因此链接。只是为了完整起见。【参考方案7】:

argc 是命令行参数的数量,argv 是表示命令行参数的字符串数组。

这使您可以选择对传递给程序的参数做出反应。如果您不期待,不妨使用int main

【讨论】:

【参考方案8】:

您可以使用app -something -somethingelse 等参数运行您的应用程序。 int argc 表示这些参数的数量,char *argv[] 是一个数组,其中实际参数被传递到您的应用程序中。这样您就可以在应用程序中使用它们。

【讨论】:

以上是关于关于'main(int argc,char *argv [])'[重复]的主要内容,如果未能解决你的问题,请参考以下文章

关于int main(int argc, const char * argv[])的理解

关于int main(int argc,char* argv[])详解

main (int argc,char *argv[]) 或main (int argc,char **argv)区别

int main(int argc, char* argv[]) 和 int main(int argc, char** argv) [关闭]

int main(int argc,char *argv[])与int main(int argc,char **argv)区别?

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