【问题标题】:Can main() return structure?main() 可以返回结构吗?
【发布时间】:2013-06-23 16:14:09
【问题描述】:

昨天面试有人问我一个问题,main可以回复struct吗? 我不知道有人能告诉我这是否可能,如果可以,为什么?

【问题讨论】:

  • 为什么我在接受采访时从来没有收到这么简单的问题? :)

标签: c struct main


【解决方案1】:

main 只能在 C 中返回 int 值(至少对于托管实现)。

【讨论】:

  • @VarunChhangani exit(a);main 中的return a; 是等价的。
  • exit 和从 main 中返回并不完全相同。如果您调用exitatexit 处理程序可以从main 函数的初始调用和尚未返回的任何其他函数调用访问自动存储持续时间对象。如果您从mainreturn,则这些对象的生命周期已经结束,您无法从atexit 处理程序访问。此外,如果您在任何具有自动存储持续时间的缓冲区的流上调用了setbufsetvbuf,则从main 返回会调用UB,但调用exit 不会。
  • @R.. +1 有趣的点,但为什么标准明确说它们是等价的? (5.1.2.2.3/1)
  • 并不是说调用exit就等于从main返回。它说从main返回相当于调用exit 用从main返回的值。请注意,“返回”一词意味着在相当于调用exit 的操作发生时返回已经发生。和往常一样,return 的影响之一是自动对象的生命周期结束。
  • @R.. 谢谢你的解释,真的很容易错过。
【解决方案2】:

C 标准的第 5.1.2.2.1 节说不:

程序启动时调用的函数名为main。这 实现没有声明这个函数的原型。应该是 返回类型为 int 且不带参数定义:

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

或带有两个参数(此处称为 argc 和 argv,尽管任何 可以使用名称,因为它们对于它们所在的函数是本地的 声明):

int main(int argc, char *argv[]) { /* ... */ } 

或等效的;)或以其他一些实现定义的方式

【讨论】:

  • implementation-defined是什么意思no
  • 恕我直言,“实现定义”属于第二种形式的参数
  • 嗯,这是可能的,但不是很清楚(好吧,至少对于像我这样的非英国人来说)。无论如何,标准明确谈论了main 的不同返回类型,说行为不是未定义的。
  • 一个实现可以为 main 定义额外的签名,但它必须记录这些额外的签名。如果文档未列出,则不支持。
【解决方案3】:

不可以

如果主函数的返回类型是与int兼容的类型, 从初始调用返回到主函数相当于 使用主函数返回的值调用退出函数 作为它的参数;10) 到达终止主函数的 } 返回值 0。如果返回类型与 int 不兼容, 返回宿主环境的终止状态为 未指定。

而且您不能将结构传递给 main,因此最好将此结构写入二进制文件。你想做什么?

编辑(用于@effeffe):

#include <stdio.h>

struct st{float f;};

int main(void)
{
    struct st x;
    x.f = 3.14;
    return x;
}

返回

demo.c: In function ‘main’:
demo.c:9:5: error: incompatible types when returning type ‘struct st’ but ‘int’ was expected

【讨论】:

  • 那句话在哪里说我们可以做到?不是说在这种情况下,我们不知道返回的状态吗? (这当然不是一件好事)
  • 如果返回类型与int不兼容,则返回宿主环境的终止状态未指定。
  • 是的,如果我们不关心这一点,为什么我们不能这样做?
  • 我不明白,这和问题有什么关系?该代码试图返回一个与函数声明的返回类型不兼容的类型的值,这总是错误的。您引用的标准说如果返回类型与int...不兼容,而不是如果返回类型的值与int不兼容...我>。它谈论的是函数声明的返回类型,而不是return 语句中值的实际类型。
  • ohhhh,是的,现在我明白了,(引用的文字是在谈论int main中的声明,而不是关于返回值),你是对的!!
【解决方案4】:

main 在 C/C++ 中只能返回 int。这与程序完成时返回状态码的能力有关。 0 表示成功,而 1255 表示特定错误。程序会以文本文件或印刷形式出现,其中包含这些错误的含义,因此您可以确定程序无法运行的原因。这是假设有人进行了错误检查并制作了文档。

【讨论】:

    【解决方案5】:

    由于 main 最初是从操作系统的程序加载器调用的,因此它不知道您要返回什么或应该用它做什么。

    因此,约定是:返回一个整数。无论是什么语言,或什么程序,它都为程序提供了一个通用接口,以便与启动它的 shell 进行通信。这也意味着编写脚本的非技术用户可以使用这个整数在他们的脚本中做出决定。

    您可以执行您所要求的最简单的方法是将结构保存到文件中。这样,任何知道您的结构数据的程序都可以访问该文件。

    【讨论】:

    • Main 不是从 OS 程序加载器调用的。实际上,它甚至不是启动程序后执行的第一个代码。在此处阅读更多信息stackoverflow.com/questions/4783404/…
    • 我不是在写一篇关于操作系统结构的论文。当有人问他们是否可以从 main 返回结构时,我认为他们的技术含量不高。哦,顺便说一句,是的。还有什么可以让 main 执行?打印后台处理程序?
    【解决方案6】:

    开玩笑的回答:

    很多人说不,但我认为是的! (有点)

    您可以返回一个 32 位指针,然后将其转换为一个 int,该指针指向堆上的一个结构,假设 int 的大小为 32 位,并且您有一个 32 位系统,因此指针是大小也是 32 位。

    然后,相当危险的是,希望操作系统不要将该内存分配给另一个程序使用,并希望该程序不会覆盖它。如果您使用 Windows 或 Linux 之类的操作系统,那么我的理解是,即使您不释放内存,操作系统也会为您释放内存。 (当然你应该总是释放你的内存,否则你就是一个肮脏的程序员!)

    据我所知,另一个程序可以声明指向 main() 返回的位置的指针,然后逐字节读取(现已消失的)结构中的内容。

    我认为这应该可行吗?是时候测试它了! (这可能会出现可怕的错误,并且可能会发生许多未定义的事情。)

    不要太认真地对待这个答案。如果您提出建议,您可能会毁掉您的就业机会。

    【讨论】:

      【解决方案7】:

      正如其他人所指出的,如果main 的返回值不是与int 兼容的类型,则其值为“未指定”。这意味着编译器可以在不违反 C 标准的情况下对返回值做任何它喜欢的事情,并且可移植 C 程序不可能返回结构类型。另一方面,C 标准中没有任何内容要求编译器供应商不记录如果代码试图让 main 返回结构类型会发生什么,也不要求编译器记录的行为必须永远有用。如果操作系统有primaryReturnCodesecondaryReturnCode 变量,并且编译器供应商希望指定返回包含两个int 值的结构将导致第一个值存储在primaryReturnCode 中,第二个值存储在secondaryReturnCode 中,这样的规范是完全合法的。

      在 C++ 中,程序需要有一个返回 intmain 函数。也可以使用名称为 main 的其他函数返回其他内容。我不知道一个名为 main 但与启动 main 函数具有不同参数和返回类型的函数是否可以出现在与启动函数相同的上下文中,但如果没有其他函数称为 main 应该是允许在类范围内。

      【讨论】:

        猜你喜欢
        • 2019-08-29
        • 2021-10-15
        • 2018-03-13
        • 1970-01-01
        • 2014-07-14
        • 2021-10-18
        • 2014-08-26
        • 2012-11-12
        • 2011-10-31
        相关资源
        最近更新 更多