C++ C/C++;主要功能';s参数?
在C/C++中,主函数接收C++ C/C++;主要功能';s参数?,c++,c,parameters,location,main,C++,C,Parameters,Location,Main,在C/C++中,主函数接收char*类型的参数 int main(int argc, char* argv[]){ return 0; } argv是一个char*数组,指向字符串。这些绳子在哪里?它们是在堆上、堆栈上还是在其他地方?它们具有编译器的魔力,并且依赖于实现 虽然您可以访问实际参数,但我认为它们的实际位置根本不重要。参数列表是流程环境的一部分,类似于(但不同于)环境变量。这些参数与任何其他函数的参数没有区别。 如果体系结构的调用序列需要参数通过堆栈,则它们位于堆栈上。如果像on
char*
类型的参数
int main(int argc, char* argv[]){
return 0;
}
argv
是一个char*
数组,指向字符串。这些绳子在哪里?它们是在堆上、堆栈上还是在其他地方?它们具有编译器的魔力,并且依赖于实现 虽然您可以访问实际参数,但我认为它们的实际位置根本不重要。参数列表是流程环境的一部分,类似于(但不同于)环境变量。这些参数与任何其他函数的参数没有区别。
如果体系结构的调用序列需要参数通过堆栈,则它们位于堆栈上。如果像on一样,x86-64某些参数进入寄存器,这些参数也会进入寄存器。通常不知道它们在哪里
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char **foo;
char *bar[] = {"foo", "bar"};
(void)argv; /* avoid unused argv warning */
foo = malloc(sizeof *foo);
foo[0] = malloc(42);
strcpy(foo[0], "forty two");
/* where is foo located? stack? heap? somewhere else? */
if (argc != 42) main(42, foo); else return 0;
/* where is bar located? stack? heap? somewhere else? */
if (argc != 43) main(43, bar); else return 0;
/* except for the fact that bar elements
** point to unmodifiable strings
** this call to main is perfectably reasonable */
return 0;
/* please ignore memory leaks, thank you */
}
#包括
#包括
int main(int argc,char*argv[]){
char**foo;
char*bar[]={“foo”,“bar”};
(void)argv;/*避免未使用的argv警告*/
foo=malloc(sizeof*foo);
foo[0]=malloc(42);
strcpy(foo[0],“四十二”);
/*foo在哪里?堆栈?堆?其他地方*/
如果(argc!=42)main(42,foo);否则返回0;
/*酒吧在哪里?堆垛?堆?其他地方*/
如果(argc!=43)main(43,bar);否则返回0;
/*除了bar元素
**指向不可修改的字符串
**这个对main的调用非常合理*/
返回0;
/*请忽略内存泄漏,谢谢*/
}
这个问题的答案取决于编译器。这意味着它不在C标准中处理,因此任何人都可以按照自己的意愿实现它。这是正常的,因为操作系统也没有一个通用的、被接受的、标准的方法来启动和完成进程
让我们想象一个简单的,为什么不呢
进程通过某种机制接收命令行中写入的参数。argc只是一个int,编译器将引导函数作为程序进程(运行时的一部分)的入口点推送到堆栈中。实际值是从操作系统获取的,可以写入堆的内存块中。然后构建argv向量,并将其第一个位置的地址推入堆栈
然后调用必须由程序员提供的函数main(),并保存其返回值以供以后(几乎中间)使用。堆中的结构被释放,为main获得的退出代码被导出到操作系统。进程结束。正如
pmg
所提到的,当递归调用main
时,参数指向的位置取决于调用方。在最初调用main
时,答案基本相同,只是“调用者”是C实现/OS
在UNIX-y系统上,
argv
指向的字符串、argv
指针本身以及进程的初始环境变量几乎总是存储在堆栈的最顶端。它实际上是编译器依赖性和操作系统依赖性的组合main()
与任何其他C函数一样,是一个函数,因此两个参数argc
和argv
的位置将遵循平台上编译器的标准。e、 g.对于大多数以x86为目标的C编译器,它们将位于返回地址和保存的基指针上方的堆栈上(记住,堆栈向下增长)。在x86_64上,参数在寄存器中传递,因此argc
将位于%edi
中,argv
将位于%rsi
中。编译器生成的主函数中的代码然后将它们复制到堆栈中,这就是后面引用的位置。这样寄存器就可以用于main
的函数调用
argv指向的
char*
s块以及实际的字符序列可以在任何地方。它们将从某个操作系统定义的位置开始,并可能被链接器生成的预编译代码复制到堆栈或其他地方。您必须查看exec()
的代码和链接器生成的汇编程序预编译,才能找到答案。以下是C标准()的说明:
5.1.2.2.1程序启动…
2如果已声明,则主功能的参数应符合以下要求 约束条件:
- argc的值应为非负。
- argv[argc]应为空指针。
- 如果argc的值大于零,则数组成员argv[0]到
argv[argc-1]应包含指向给定字符串的指针
程序启动前主机环境定义的实现值。这个
目的是向程序提供程序启动前确定的信息
来自托管环境中的其他位置。如果主机环境无法
为字符串提供大写和小写字母,实现
应确保以小写形式接收字符串。
- 如果argc的值大于零,则argv[0]指向的字符串
表示程序名;如果
程序名在主机环境中不可用。如果argc的值为
大于1时,argv[1]通过argv[argc-1]指向的字符串
表示程序参数。
- 参数argc和argv以及argv数组指向的字符串应 可由程序修改,并在程序之间保留其最后存储的值 启动和程序终止。