【问题标题】: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++

标签: c argv argc


【解决方案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。它包含环境变量。


    资源:

    【讨论】:

    • 程序名和传递给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,而是 StackOverflow,一个我们通过回答他们的问题来帮助人们的社区,不要将它们重定向到手册、常见问题解答或 lmgtfy 链接。
    • 上面已经回答了这个问题。然而,C FAQ 仍然值得一读,恕我直言。但它在其许可证中声明未经许可不得复制。因此链接。只是为了完整起见。
    【解决方案7】:

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

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

    【讨论】:

      【解决方案8】:

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

      【讨论】:

        猜你喜欢
        • 2020-11-03
        • 2011-07-08
        • 2014-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-08
        • 2014-04-23
        相关资源
        最近更新 更多