C/C++主函数的参数在哪里?

rem*_*inn 58 c c++ parameters location program-entry-point

在C/C++中,main函数接收类型的参数char*.

int main(int argc, char* argv[]){
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

argv是一个数组char*,并指向字符串.这些字符串在哪里?它们是堆,堆栈还是其他地方?

Stu*_*Stu 31

它们是编译器魔术,并且依赖于实现.

  • +1:这非常接近你将得到的非超详细的答案...... (12认同)
  • 一定要喜欢它似乎总是提升"诙谐"的非答案,而不是那些实际提供有用信息,背景或例子的人. (7认同)
  • 啊,请不要亲自接受,我真的不是要打击你或你的答案.我想我应该在我之前的评论中更谨慎地说 - 对不起.我只是想知道为什么这种答案倾向于得到最多的赞成而不是更全面(通常更有用)的答案更详细地解释情况 - 即使完整的解释不像这里那样可行. (2认同)

Joh*_*ode 28

这是C标准(n1256)所说的:

5.1.2.2.1程序启动
...
2如果声明它们,函数的参数应遵守以下约束:

  • argc的值应为非负值.

  • argv [argc]应为空指针.

  • 如果argc的值大于零,则数组成员argv [0]argv [argc-1]包含指向字符串的指针,在程序启动之前由主机环境给出实现定义的值.目的是在程序启动之前从托管环境中的其他地方向程序提供信息.如果主机环境不能提供大写和小写字母的字符串,则实现应确保以小写形式接收字符串.

  • 如果argc的值大于零,则argv [0]指向的字符串 表示程序名称 ; 如果程序名不能从主机环境获得,则argv [0] [0]应为空字符.如果argc的值大于1,则argv [1]通过argv [argc-1]指向的字符串 表示程序参数.

  • 参数argcargv以及argv数组指向的字符串应该可由程序修改,并在程序启动和程序终止之间保留它们最后存储的值.

最后一个项目符号是存储字符串值的最有趣的文件.它没有指定堆或堆栈,但它确实要求字符串是可写的并且具有静态范围,这对字符串内容可能位于何处设置了一些限制.正如其他人所说,具体细节将取决于实施情况.


Jer*_*myP 17

它实际上是编译器依赖和操作系统依赖的组合. main()是一个函数,就像任何其他C函数,所以这两个参数的位置argcargv将遵循平台上的编译器的标准.例如,对于大多数针对x86的C编译器,它们将位于返回地址上方的堆栈上以及保存的基指针(堆栈向下增长,请记住).在x86_64上,参数在寄存器中传递,因此argc将进入%ediargv将进入%rsi.编译器生成的main函数中的代码然后将它们复制到堆栈中,这是后面引用指向的位置.这样寄存器就可以用于函数调用main.

char*argv指向的块和实际的字符序列可以在任何地方.它们将在某个操作系统定义的位置启动,并且可以通过链接器生成到堆栈或其他位置的前导码复制.您将不得不查看exec()链接器生成的代码和汇编器前导码以查找.

  • "main()是一个函数,就像任何其他C函数一样"不在c ++中,从另一个函数调用它是非法的,即使它被声明为返回int,你实际上也不需要返回任何东西 (3认同)

Bal*_*arq 8

这个问题的答案是编译器依赖的.这意味着它不符合C标准,因此任何人都可以按照自己的意愿实施.这是正常的,因为操作系统也没有通用的标准方法来启动进程并完成它们.

让我们想象一个简单的,为什么不是场景.

该进程通过某种机制接收在命令行中写入的参数.然后argc只是一个int,它被编译器放入的引导函数推送到堆栈,作为程序进程的入口点(运行时的一部分).实际值是从操作系统获得的,并且可以写在堆的内存块中.然后构建argv向量,并将其第一个位置的地址也推入堆栈.

然后调用必须由程序员提供的函数main(),并保存其返回值以供稍后(几乎中间)使用.释放堆中的结构,并将为main获取的退出代码导出到操作系统.该过程结束.