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

104

可能的重复问题:
main()函数的参数是什么?
int argc和char *argv[]是什么意思?

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

我不明白这是什么意思。如果我们在程序中没有使用这些参数,为什么要使用它们?为什么不只用 int main()

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


1
请注意,如果您不打算使用命令行参数,则定义函数int main(void)int main()是完全允许的(也很明智)。在C99或C11中,返回类型(int)是强制性的;如果您没有指定代码遵循哪个版本的C标准,编译器有时仍然可以让您省略它。另请参见在C和C++中main()应该返回什么? - Jonathan Leffler
8个回答

131

main函数的参数argcargv用于向程序传递参数,最常见的方式是使用老旧的终端,用户可以键入cat file。在这里,单词cat是一个程序,它将文件输出到标准输出(stdout)。

程序接收argc中的参数数量和argv参数列表。在上面的例子中,argument count将是两个(程序名称计为第一个参数),而argument vector将包含[catfilenull],其中最后一个元素是空指针。

通常,您会像这样编写:

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 的第三个参数,其中包含程序的 环境变量 向量。还有其他变体的 main 函数参数列表,但我不会在此详细介绍,因为这是非标准的。
另外,变量的命名只是一种约定,没有实际意义。遵循这种约定是一个好习惯,可以避免混淆他人,但同样地,定义 main 为其他名称也是合法的。
int main(int c, char **v, char **e) {
   // code
   return 0;
}

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


如果我没错的话,argc 的最小可能值为1,argv [0] 包含字符串 ./mymainprogramargv [1]NULL。我的问题是: 1: argc 可以容纳的最大值是多少? 2: 添加到 argv[] 中的这些字符串是什么? - phougatv
1
@barnes - 最大值取决于操作系统。在Win32中,命令行本身的长度限制为32K,因此argc的实际限制为16K。 - Jesse Chisholm
1
@barnes:旧的DOS系统命令行参数限制为127字节,虽然现在不太重要,但这是我记得的一个有趣的事实 ^_^ - Frank
@alastair 同意,以编程方式启动进程基本上没有限制,而在 shell 中输入命令则有。Frank 所指的是 DOS 上的 COMMAND shell,它将其限制为 127 字节,而不是接收程序。同样,在 Win32 的 CMD shell 中也只有有效的 16K。 - Jesse Chisholm
1
char **envp 作为第三个参数不是 POSIX 标准的一部分。请参考此线程 - ben
显示剩余2条评论

71

这些是用于向您的程序传递参数的,例如从命令行调用程序时。

$ 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

使用一些字符到数字的转换函数,例如atol()(链接在这里),可以将char字符串"2"、"8"等转换为数字。


16

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

这样一来,当启动您的应用程序时,您就可以使用参数(如-version)以不同的方式进行操作。

但是,在C中,您也可以将 int main(void) 作为原型。

第三个原型(较少知道和非标准的)具有第三个参数,即 envp,其中包含环境变量。


资源:


程序的名称与传递给main()的参数有什么关系? - user379888
1
@Potatoswatter,@You,我更新了我的答案,明确说明envp不是标准的。@fahad,通常第一个参数是应用程序的名称,这样你就可以知道你的应用程序是如何被调用的。 - Colin Hebert
仅从其名称,你如何知道它被称为什么? - user379888
@fahad,我的意思是“应用程序的名称是什么”。例如,这可以用于打印错误消息,如“非法选项...用法:applicationName [-v]”。 - Colin Hebert
在*nix操作系统中,不同的“程序”可以是指向相同可执行文件的符号链接——知道它是如何调用的使得可执行文件根据被称为什么而表现出不同的行为。我认为这方面的一个经典例子是busybox实用程序 - 同一文件就像成百上千个其他实用程序(可能只实现每个实用程序最常使用的功能)一样运行,作为一个可执行文件在许多情况下都非常有优势... - SlySven

3

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


int main() 只在 C++ 中有效。在 C 中,您需要像这样放置一个 void:int main(void)。C 风格的 int main(void) 在 C++ 中也是有效的,尽管在 C++ 中不鼓励使用它。 - Ultimater
@Ultimater 我很确定 int main() 在C语言中也是有效的。它声明了一个变参函数。 - Navin
@Navin 许多C++编译器在遇到C代码时非常宽容,因为C++允许int main()int main(void)都可以编译通过,但是一个C编译器,特别是旧的C编译器,不支持C++风格的int main()。我上过一门关于C/C++的课程,强调了可移植性,如果你的作业应该用C语言编写,而你给出了int main()声明,他的作业检查器会抱怨,甚至无法编译,除非我们在截止日期前重新提交,否则我们会失去作业分数。 - Ultimater

1

argc 是程序在运行时接收到的命令行参数的数量,而 argv 则是一个字符数组的数组(更确切地说,是 C 字符串的数组),其中包含这些参数。如果您知道自己不需要命令行参数,则可以将主函数声明为接受 void 参数:

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

根据标准,这是main定义的唯二原型,但有些编译器也允许返回类型为void。更多信息请参见维基百科


从技术上讲,int main() 是一个可以接受任意多个参数的函数,而 int main(void) 则不接受任何参数,因此后者更为正确。 - You
2
不,在一个定义中,int main()是一个不带参数的函数。在一个不是定义的声明中,它是一个带有未指定参数的函数。这是n1256中的6.7.5.3/14,或者n794中的6.5.5.3/10。提问者正在询问一个定义。 - Steve Jessop

1

2
但这不是comp.lang.c,这是StackOverflow,一个社区,在这里我们通过回答问题来帮助人们,而不是将他们重定向到手册、FAQ或lmgtfy链接。 - Mark Elliot
1
问题已经在上面得到了回答。然而我认为 C FAQ 仍值得一读。但它在许可证中规定未经许可不得复制。因此提供链接,只是为了完整起见。 - cschol

0

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

这使您有机会对传递给程序的参数做出反应。如果您不期望任何参数,则可以使用 int main


0

您可以使用参数运行应用程序,例如app -something -somethingelseint argc表示这些参数的数量,char *argv[]是一个包含传递给应用程序的实际参数的数组。这样,您就可以在应用程序内部处理它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接