main 存储在哪里? main 是关键字吗?我确实知道 main() 是一种方法,但我问的是“main”
Posted
技术标签:
【中文标题】main 存储在哪里? main 是关键字吗?我确实知道 main() 是一种方法,但我问的是“main”【英文标题】:Where is main stored & is main a keyword? I do know that main() is a method but I am asking about "main" 【发布时间】:2014-03-24 16:00:10 【问题描述】:我确实知道 C/C++ 和 Java 中使用的 main() 方法,但由于 main() 是用户定义的(因为 main() 中的代码是由用户定义的,所以它不能是预定义的方法)&在C / C ++中, main 不存储在头文件中,那么它究竟位于哪里,以便编译器首先在程序中搜索它?主要是关键字还是其他?我在某处听说它是用作关键字的属性,但我不确定。有人可以帮我吗? (我想知道 Java 和 C/C++ 的情况)
【问题讨论】:
您询问的是哪种语言?答案对于 C 和 C++(可能或多或少)相同,但对于 Java 却大不相同。 在 Java 的情况下“搜索”的不是 编译器,而是 JVM。对于 C 和 C++,它几乎是相似的,除了它不是编译器会寻找它,而是链接器。您可以在 C/C++ 中编译目标文件,而无需在其中包含 main()。 在 C/C++ 中,通常有一个“启动”子例程(可以用 C、汇编或其他语言编写)执行一些设置工作,然后调用main
。设置工作可能涉及调用初始化全局变量的子程序和调用全局变量的构造函数,并可能设置argc
和argv
参数。
在 Java 中,main
只是一个方法,唯一的特殊之处在于,当您执行 java SomeClass
时,JVM 会检查 SomeClass
以找到适当描述的 main
方法以调用。如果没有找到,那么java
命令会报错。编译器在这件事上没有发言权。
IIRC,已经有 C 的版本,其中 C 编译器“识别”main
并专门打包它。不过,这不在架构中,它只是一个实现细节。
【参考方案1】:
main
不是预定义的,但它是 预先声明的。在 C 中,您的代码链接到一个小型运行时库,该库构成您程序的true 起点。正是这个小型库进行了最少的堆栈设置,然后调用了一个名为main
的函数——它是硬编码的。您的代码运行是因为您提供了main
的定义。
Java 运行时执行类似的操作:虚拟机中的引导代码将调用作为输入提供的任何类的 main
方法。
【讨论】:
只是为了更加迂腐:在 C 中,main
的定义就像一个函数,但不允许调用它。运行时可能有一些时髦的调用方式。
这有多普遍?我对递归调用main
有模糊的回忆,尽管我确信如果它确实有效的话肯定是非标准的。
在“典型”操作系统(至少是 Unixy)中,运行时或多或少地对main()
进行正常调用;但它被允许做一些完全不同的事情。我记得一个案例(很久 以前,一些非 Unix 系统,可能是 DOS 或 Windows)调用 main()
失败了。是的,我记得有一个骗子向我展示了一个递归程序,除了main()
一次之外,它具有 no 函数。
谢谢 :) 但你能告诉我,主要的预声明在哪里?
libc
。它没有被声明太多,因为它是一个预期存在于最终完全链接的目标文件中的符号。【参考方案2】:
Main 不是 Java 中的关键字。当您尝试使用“java”命令执行 java 代码时,运行时将加载您尝试执行的公共类,然后调用该类中定义的 main 方法。运行时知道“main”是按照这种方式设计的要查找的方法。语言规范还要求应该有一个名为“main”的方法,它应该是公共的和静态的,并接受字符串数组作为参数,返回类型为 void。由于它是公共的和静态的,运行时可以调用该方法而无需实例化该类。
【讨论】:
【参考方案3】:C++11
只是引用标准:
3.6.1 主要功能
程序应包含一个名为 main 的全局函数,它是 指定程序的开始。是否由实现定义 一个独立环境中的程序需要定义一个主 功能。 [ 注意:在独立的环境中,启动和 终止是实现定义的;启动包含 使用静态的命名空间范围的对象执行构造函数 储存期限;终止包含析构函数的执行 对于具有静态存储持续时间的对象。 ——尾注]
实现不应预定义主要功能。这个功能 不得超载。它应该有一个 int 类型的返回类型,但是 否则它的类型是实现定义的。所有实现 应允许以下两个 main 定义:
int main() /* ... / 和 int main(int argc, char argv[]) /* ... */
在后一种形式中,argc 是传递给 程序运行的环境中的程序。如果 argc 是 非零这些参数应通过 argv[0] 提供 argv[argc-1] 作为指向以 null 结尾的初始字符的指针 多字节字符串 (ntmbs s) (17.5.2.1.4.2) 和 argv[0] 应为 指向代表名称的 ntmbs 的初始字符的指针 用于调用程序或“”。 argc 的值应为 非负的。 argv[argc] 的值应为 0。 [ 注意:它是 建议在之后添加任何其他(可选)参数 argv。 ——尾注]
函数 main 不得在程序中使用。联动 main 的 (3.5) 是实现定义的。定义 main 的程序 as 已删除或将 main 声明为 inline、static 或 constexpr 是 格式不正确。名称 main 没有保留。 [ 例子: 成员函数、类和枚举可以称为 main,也可以 其他命名空间中的实体。 —结束示例]
在不离开当前块的情况下终止程序(例如,通过 调用函数 std::exit(int) (18.5)) 不会破坏任何 具有自动存储持续时间的对象 (12.4)。如果调用 std::exit 在使用静态或静态对象销毁期间结束程序 线程存储持续时间,程序有未定义的行为。
main 中的 return 语句具有离开 main 函数的效果 (销毁任何具有自动存储持续时间的对象)并调用 std::exit 以返回值作为参数。如果控制达到 main结束没有遇到return语句,效果是 执行 return 0;
【讨论】:
【参考方案4】:是的。 Main 是 java 和 C 中的关键字。实现不应预定义 main 函数。此功能不得重载。它应该有一个 int 类型的返回类型,否则它的类型是实现定义的。所有实现都应允许 main 的两种定义。
【讨论】:
以上是关于main 存储在哪里? main 是关键字吗?我确实知道 main() 是一种方法,但我问的是“main”的主要内容,如果未能解决你的问题,请参考以下文章
C语言中的“main”可以用别的字母代替吗?比如“mai”或"ain"等。