是否可以不使用 main() 函数来编写程序?

发布于 2024-11-29 07:30:10 字数 204 浏览 2 评论 0原文

我在面试中不断收到这样的问题:

在不使用 main() 函数的情况下编写一个程序。

我的一位朋友向我展示了一些使用宏的代码,但我无法理解它。

所以问题是:

是否真的可以在没有 main() 的情况下编写和编译程序?

I keep getting this question asked in interviews:

Write a program without using main() function.

One of my friends showed me some code using macros, but I could not understand it.

So the question is:

Is it really possible to write and compile a program without main()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

毅然前行 2024-12-06 07:30:10

不,您不能,除非您在独立环境(嵌入式环境、操作系统内核等)中编写程序,其中起点不必是main()。根据 C++ 标准,main()托管环境中任何程序的起点。

根据:

C++03标准3.6.1主函数

程序应包含一个名为 main 的全局函数,它是程序的指定开始。独立环境中的程序是否需要定义主函数是由实现定义的。 [注:在独立环境中,启动和
终止是实现定义的;启动包含具有静态存储持续时间的命名空间范围的对象的构造函数的执行;终止包含对具有静态存储持续时间的对象执行析构函数。


什么是独立环境和什么是托管环境
C++ 标准中定义了两种一致的实现; 托管独立

独立实现是为无需操作系统而执行的程序而设计的。
例如,操作系统内核或嵌入式系统将是一个独立的环境。

使用操作系统功能的程序通常是在托管实现中。

来自 C++03 标准第 1.4/7 节:

独立实现是一种无需操作系统即可执行的实现,并且具有一组实现定义的库,其中包括某些语言支持库。

此外,
部分:17.4.1.3.2 独立实现引用:

独立实现具有实现定义的标头集。该集合应至少包含以下标头,如表所示:

18.1 Types <cstddef>   
18.2 Implementation properties <limits>   
18.3 Start and termination <cstdlib> 
18.4 Dynamic memory management <new> 
18.5 Type identification <typeinfo> 
18.6 Exception handling <exception> 
18.7 Other runtime support <cstdarg>

No you cannot unless you are writing a program in a freestanding environment (embedded environment, OS kernel etc) where the starting point need not be main(). As per the C++ standard main() is the starting point of any program in a hosted environment.

As per the:

C++03 standard 3.6.1 Main function

A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function. [ Note: In a freestanding environment, start-up and
termination is implementation-defined; startup contains the execution of constructors for objects of namespace scope with static storage duration; termination contains the execution of destructors for objects with static storage duration.


What is a freestanding environment & what is a hosted environment?
There are two kinds of conforming implementations defined in the C++ standard; hosted and freestanding.

A freestanding implementation is one that is designed for programs that are executed without the benefit of an operating system.
For example an OS kernel or embedded system would be a freestanding environment.

A program using the facilities of an operating system would normally be in a hosted implementation.

From the C++03 Standard Section 1.4/7:

A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that includes certain language-support libraries.

Further,
Section: 17.4.1.3.2 Freestanding implementations quotes:

A freestanding implementation has an implementation-defined set of headers. This set shall include at least the following headers, as shown in Table:

18.1 Types <cstddef>   
18.2 Implementation properties <limits>   
18.3 Start and termination <cstdlib> 
18.4 Dynamic memory management <new> 
18.5 Type identification <typeinfo> 
18.6 Exception handling <exception> 
18.7 Other runtime support <cstdarg>
早茶月光 2024-12-06 07:30:10

在标准 C++ 中,需要一个 main 函数,因此这个问题对于标准 C++ 没有意义。

例如,在标准 C++ 之外,您可以编写 Windows 特定程序并使用 Microsoft 的自定义启动函数之一(wMain、winMain、wWinmain)。在 Windows 中,您还可以将程序编写为 DLL 并使用 rundll32 来运行它。

除此之外,您还可以创建自己的小型运行时库。曾经,这是一项常见的运动。

最后,您可以聪明地反驳说,根据标准的 ODR 规则 main 没有“使用”,因此任何程序都符合资格。呸!尽管除非面试官具有非凡的幽默感(如果有的话他们就不会问这个问题),否则他们不会认为这是一个好的答案。

Within standard C++ a main function is required, so the question does not make sense for standard C++.

Outside of standard C++ you can for example write a Windows specific program and use one of Microsoft's custom startup functions (wMain, winMain, wWinmain). In Windows you can also write the program as a DLL and use rundll32 to run it.

Apart from that you can make your own little runtime library. At one time that was a common sport.

Finally, you can get clever and retort that according to the standard's ODR rule main isn't "used", so any program qualifies. Bah! Although unless the interviewers have unusual good sense of humor (and they wouldn't have asked the question if they had) they'll not think that that's a good answer.

我爱人 2024-12-06 07:30:10

没有可见主函数的示例程序。

/* 
    7050925.c 
    $ gcc -o 7050925 7050925.c
*/

#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
        printf("How mainless!\n");
}

来自:http://learnhacking.in/c-program-without-main-function/

Sample program without a visible main function.

/* 
    7050925.c 
    $ gcc -o 7050925 7050925.c
*/

#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
        printf("How mainless!\n");
}

From: http://learnhacking.in/c-program-without-main-function/

莫多说 2024-12-06 07:30:10

main 表示入口点,即代码开始执行的点。尽管 main 不是第一个运行的函数。还有一些代码在 main 之前运行,并准备环境以使您的代码运行。然后,此代码调用 main 。您可以通过重新编译启动文件crt0.c的代码并更改main函数的名称来更改main函数的名称。或者您可以执行以下操作:

#include <stdio.h>

extern void _exit (register int code);

_start()
{
  int retval;
  retval = my_main ();
  _exit(retval);
}

int my_main(void)
{
  printf("Hello\n");
  return 0;
}

编译代码:

gcc -o no_main no_main.c -nostartfiles

-nostartfiles 将不包含默认启动文件。您使用 _start 指向主条目文件。

main只不过是用户代码的预定义入口点。因此,您可以将其命名为任何名称,但最终您确实需要一个入口点。在 C/C++ 和其他语言中,如果您创建另一种语言或破解这些语言编译器的源代码,则名称被选择为 main ,那么您可以将 main 的名称更改为 < code>pain 但它会带来痛苦,因为它会违反标准。

但操作入口函数名称对于内核代码、在内核中运行的第一个函数或为嵌入式系统编写的代码很有用。

main means an entry point, a point from which your code will start executing. although main is not the first function to run. There are some more code which runs before main and prepares the environment to make your code run. This code then calls main . You can change the name of the main function by recompiling the code of the startup file crt0.c and changing the name of the main function. Or you can do the following:

#include <stdio.h>

extern void _exit (register int code);

_start()
{
  int retval;
  retval = my_main ();
  _exit(retval);
}

int my_main(void)
{
  printf("Hello\n");
  return 0;
}

Compile the code with:

gcc -o no_main no_main.c -nostartfiles

The -nostartfiles will not include the default startup file. You point to the main entry file with the _start .

main is nothing but a predefined entrypoint for the user code. Therefore you can name it whatever, but at the end of the day you do need an entry point. In C/C++ and other languages the name is selected as main if you make another language or hack the sources of these language compilers then you can change the name of main to pain but it will bring pain, as it will violate the standards.

But manipulating the entry function name is useful for kernel code, the first function to run in the kernel, or code written for embedded systems.

咋地 2024-12-06 07:30:10

它们可能指的是为独立实现而编写的程序。 C++ 标准定义了两种实现。一种是托管实现。为这些实现编写的程序需要有一个 main 函数。但除此之外,如果独立实现不需要 main 函数,则不需要该函数。这对于操作系统内核或不在操作系统下运行的嵌入式系统程序很有用。

They may refer to a program written for a freestanding implementation. The C++ Standard defines two sorts of implementations. One is a hosted implementation. Programs written for those implementations are required to have a main function. But otherwise, no main function is required if the freestanding implementation doesn't require one. This is useful for operation system kernels or embedded system programs that don't run under an operation system.

意中人 2024-12-06 07:30:10

是的,

$ cat > hwa.S
write = 0x04
exit  = 0xfc
.text
_start:
        movl    $1, %ebx
        lea     str, %ecx
        movl    $len, %edx
        movl    $write, %eax
        int     $0x80
        xorl    %ebx, %ebx
        movl    $exit, %eax
        int     $0x80
.data
str:    .ascii "Hello, world!\n"
len = . -str
.globl  _start
$ as -o hwa.o hwa.S
$ ld hwa.o
$ ./a.out
Hello, world!

真正运行可执行文件的内核对内部符号一无所知,它只是传输到可执行映像头中以二进制形式指定的入口点。

您需要主程序的原因是因为通常您的“主程序”实际上只是另一个模块。入口点位于库提供的用 C 和汇编语言组合编写的启动代码中,并且该库代码恰好调用 main,因此您通常需要提供一个。但是直接运行链接器却不会。

要包含 C 模块1...

Mac:~/so$ cat > nomain.S
.text
.globl start
start:
        call   _notmain
Mac:~/so$ as -o nomain.o nomain.S
Mac:~/so$ cat > notmain.c
#include <unistd.h>

void notmain(void) {
  write(1, "hi\n", 3);
  _exit(0);
}
Mac:~/so$ cc -c notmain.c
Mac:~/so$ ld -w nomain.o notmain.o -lc
Mac:~/so$ ./a.out
hi


1. And I'm also switching to x86-64 here.

Yes

$ cat > hwa.S
write = 0x04
exit  = 0xfc
.text
_start:
        movl    $1, %ebx
        lea     str, %ecx
        movl    $len, %edx
        movl    $write, %eax
        int     $0x80
        xorl    %ebx, %ebx
        movl    $exit, %eax
        int     $0x80
.data
str:    .ascii "Hello, world!\n"
len = . -str
.globl  _start
$ as -o hwa.o hwa.S
$ ld hwa.o
$ ./a.out
Hello, world!

The kernel that really runs an executable knows nothing about internal symbols, it just transfers to an entry point specified in binary in the executable image header.

The reason you need a main is because normally your "main program" is really just another module. The entry point is in library-provided startup code written in some combination of C and assembly and that library code just happens to call main so you normally need to provide one. But run the linker directly and you don't.

To include a C module1...

Mac:~/so$ cat > nomain.S
.text
.globl start
start:
        call   _notmain
Mac:~/so$ as -o nomain.o nomain.S
Mac:~/so$ cat > notmain.c
#include <unistd.h>

void notmain(void) {
  write(1, "hi\n", 3);
  _exit(0);
}
Mac:~/so$ cc -c notmain.c
Mac:~/so$ ld -w nomain.o notmain.o -lc
Mac:~/so$ ./a.out
hi


1. And I'm also switching to x86-64 here.

稚然 2024-12-06 07:30:10

是的,可以在没有 main 的情况下进行编译,但是您无法通过链接阶段。

 g++ -c noMain.cpp -o noMain.o

Yes it possible to compile with out main but you cannot pass the linking phase though.

 g++ -c noMain.cpp -o noMain.o
一抹微笑 2024-12-06 07:30:10

“不使用 main”也可能意味着 main 内不允许任何逻辑,但 main 本身存在。我可以想象这个问题已经被清除了,但由于这里没有清除,这是另一个可能的答案:

struct MainSub
{
   MainSub()
   {
      // do some stuff
   }
};

MainSub mainSub;

int main(int argc, char *argv[]) { return 0; }

这里会发生的是 MainSub 构造函数中的内容将在不可用的 之前执行>main 被执行,你可以把程序的逻辑放在那里。这当然需要 C++,而不是 C(从问题中也不清楚)。

"Without using main" might also mean that no logic is allowed within main, but the main itself exists. I can imagine the question had this cleared out, but since it's not cleared here, this is another possible answer:

struct MainSub
{
   MainSub()
   {
      // do some stuff
   }
};

MainSub mainSub;

int main(int argc, char *argv[]) { return 0; }

What will happen here is that the stuff in MainSub's constructor will execute before the unusable main is executed, and you can place the program's logic there. This of course requires C++, and not C (also not clear from the question).

贪了杯 2024-12-06 07:30:10

只要您使用 g++,您就可以使用链接器选项 -e 更改入口点,因此以下代码和编译命令可以让您创建一个没有 main() 的程序> 功能:

#import <iostream>

class NoMain
{
public:
    NoMain()
    {
        std::cout << "Hello World!" << std::endl;
        exit(0);
    }
} mainClass;

我给的文件名为noname.cpp,编译选项为:

g++ nomain.cpp -Wl,-e,_mainClass -v

说实话,我并没有完全理解为什么代码可以正常运行。我怀疑全局变量 mainClass 的地址与 NoMain 类的构造函数相同。然而,我也有几个理由可以看出我的猜测可能不正确。

As long as you are using g++ you could change your entry point with linker option -e, so the following code and compile command may let you create a program without a main() function:

#import <iostream>

class NoMain
{
public:
    NoMain()
    {
        std::cout << "Hello World!" << std::endl;
        exit(0);
    }
} mainClass;

I gave file name as noname.cpp, and the compile option is:

g++ nomain.cpp -Wl,-e,_mainClass -v

To tell the truth, I didn't fully understand why the code can works fine. I suspect that the address of global variable mainClass is the same to constructor of NoMain class. However, I also have several reasons that I could tell my guess may not correct.

﹉夏雨初晴づ 2024-12-06 07:30:10

当C或C++代码运行时,它在已知的起始地址执行,这里的代码初始化运行时环境,初始化堆栈指针,执行数据初始化,调用静态构造函数,然后跳转到main( )。

执行此操作的代码在构建时由链接器链接到您的代码。在 GCC 中,它通常位于 crt0.s 中,使用商业编译器时,您不太可能获得此代码。

最后,它必须从某个地方开始,而 main() 只是该位置的符号名称。它由语言标准指定,以便开发人员知道如何称呼它,否则代码将无法从一个工具链移植到另一个工具链。

如果您正在为没有操作系统或至少没有进程加载器意义上的操作系统的“裸机”系统编写代码(嵌入式系统通常包括在 main() 之后启动的 RTOS 内核) ,那么理论上您可以随意调用 C 代码入口点,因为您通常可以完全控制运行时启动代码。但这样做是愚蠢的,而且有些反常。

一些 RTOS 环境(例如 VxWorks)和大多数应用程序框架通常在其自己的库代码中包含 main() )或其等效项),以便它在用户应用程序代码之前运行。例如,VxWorks 应用程序从 usrAppInit() 启动,Win32 应用程序从 WinMain() 启动。

When C or C++ code runs, it executes at a known start address, the code here initialises the run-time environment, initialises the stack pointer, performs data initialisation, calls static constructors, then jumps to main().

The code that does this is linked with your code at build time by the linker. In GCC it is usually in crt0.s, with a commercial compiler it is unlikely that this code will be available to you.

In the end, it has to start somewhere and main() is just a symbolic name for that location. It is specified by the language standard so that developers know what to call it, otherwise code would not be portable from one tool chain to another.

If you are writing code for a 'bare-metal' system with no OS or at least no OS in the sense of a process loader (embedded systems often include an RTOS kernel that is started after main()) , then you can in theory call the C code entry point whatever you wish since you usually have complete control over run-time start-up code. But do do so would be foolish and somewhat perverse.

Some RTOS environments such as VxWorks, and most application frameworks in general include main() )or its equivalent) within their own library code so that it runs before the user application code. For example VxWorks applications start from usrAppInit(), and Win32 applications start from WinMain().

っ〆星空下的拥抱 2024-12-06 07:30:10

我意识到这是一个老问题,但我刚刚发现并不得不分享。它可能不适用于所有链接器,但至少可以通过以下方式欺骗ld(我正在运行版本2.24.51.20140918)认为有一个main-函数这样做:

int main[] {};

或者甚至

int main;

您可以应用上述技巧之一来让程序执行一些代码,例如通过使用构造函数:

struct Main
{
    Main()
    {
        cout << "Hello World!\n";
        exit(0);
    }
} main_;

exit(0) 是为了防止数组被“叫”。很有趣:-)

I realize this is an old question, but I just found this out and had to share. It will probably not work with all linkers, but it's at least possible to trick ld (I'm running version 2.24.51.20140918) into thinking there is a main-function by doing this:

int main[] {};

or even just

int main;

You can then apply one of the aforementioned tricks to let the program execute some code, e.g. through the use of a constructor:

struct Main
{
    Main()
    {
        cout << "Hello World!\n";
        exit(0);
    }
} main_;

The exit(0) is to prevent the array from being "called". Good fun :-)

王权女流氓 2024-12-06 07:30:10

我认为宏引用是重命名主函数,以下不是我的代码,并演示了这一点。虽然编译器仍然看到一个 main 函数,但从技术上看,从源代码的角度来看,没有 main 函数。我在这里得到它 http://www.exforsys.com/forum/c-and-c/96849-without-main-function-how-post412181.html#post412181

#include<stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
  printf(" hello ");
}

I think the macro reference was to renaming the main function, the following is not my code, and demonstrates this. The compiler still sees a main function though, but technically there's no main from a source point of view. I got it here http://www.exforsys.com/forum/c-and-c/96849-without-main-function-how-post412181.html#post412181

#include<stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
  printf(" hello ");
}
痞味浪人 2024-12-06 07:30:10

无论特定的语言标准如何,大多数链接加载器都提供了一些方法来声明函数名称(入口点),该函数名称必须在二进制文件加载到内存中时执行。

对于老式 C 语言,默认值类似于“start”或“_start”,在所谓的 crt(c 运行时?)中定义,它执行 c 标准函数所需的多项日常工作,例如准备内存堆、初始化静态变量区域,将命令行解析为 argc/argv 等。

如果您足够小心,不要使用需要这些家庭用品的标准函数(例如 malloc()、free()、printf()、任何类定义都有自定义构造函数,...)
如果您使用操作系统提供的函数而不是标准 c 运行时提供的函数,则相当有限制,但并非不可能。

例如,您可以在描述符 1 上使用 write() 函数创建一个简单的 helloworld。

Disregarding specific language standards, most linking loader provides some means to declare a function name (entry point) which must be executed when the binary is loaded is loaded into memory.

For old school c language, default was something like 'start' or '_start', defined in so-called crt (c runtime?), which does several householding jobs needed for c standard functions, such as preparing memory heap, initialising static variable areas, parsing command line into argc/argv, etc.

Possibly you could override the entry point function if you take enough care not to use the standard functions which requires those household things (e.g. malloc(), free(), printf(), any class definitions have custom constructor, ...)
Quite restrictive but not impossible if you use functions provided by o/s, not by standard c runtime.

For example, you can make a simple helloworld using write() function on descriptor 1.

來不及說愛妳 2024-12-06 07:30:10

编写一个类并在该类的构造函数中打印您的名字并声明该类的全局对象。因此类的构造函数在 main 之前执行。所以你可以将主栏留空,但仍然打印你的名字。

class MyClass
{
   myClass()
   {
       cout << "printing my name..." <<endl;
   }
};

MyClass gObj; // this will trigger the constructor.

int main()
{
   // nothing here...
}

Write a class and print your name in the constructor of that class and declare a GLOBAL OBJECT of that class. So the class' constructor gets executed before main. So you can leave the main empty and still print your name.

class MyClass
{
   myClass()
   {
       cout << "printing my name..." <<endl;
   }
};

MyClass gObj; // this will trigger the constructor.

int main()
{
   // nothing here...
}
蹲墙角沉默 2024-12-06 07:30:10

是的,您可以通过将 C 语言的入口点从 main() 更改为 _start 来做到这一点
代码如下:

#include<stdio.h>
#include<stdlib.h>
int sid()
{
printf("Hallo World\n");
exit(0);
}

然后使用 gcc 编译器运行代码。假设您已经保存了名为 test.c 的文件。

gcc -nostartfiles test.c
./a.out

Yes you can do it by changing the entry point of the C language from main() to _start
Here is the code :

#include<stdio.h>
#include<stdlib.h>
int sid()
{
printf("Hallo World\n");
exit(0);
}

Then run the code using gcc complier.Let's assume that you have saved the file with the name of test.c then.

gcc -nostartfiles test.c
./a.out
苏璃陌 2024-12-06 07:30:10

参加聚会迟到了——这篇旧文章有很多有问题的答案。用作参考的更好的可能是 main() 应该返回什么C 和 C++? 例如,您真诚的回答,并引用了语言标准的相关内容。

简要摘要:

  • C 和 C++ 都对托管程序独立程序有所区别。托管程序是在操作系统之上运行的程序。独立程序要么是操作系统本身,要么是为 RTOS 编写的程序,或者是根本没有操作系统的所谓“裸机”嵌入式系统。

    编译器+所有支持的标准库被标准正式称为实现。因此,托管实现是操作系统环境的编译器+标准库,而独立实现是嵌入式系统编译器。标准允许独立实现来实现标准库的最小子集。

  • 对于独立程序,C 和 C++ 都允许首先执行函数的实现定义形式。实现定义意味着编译器可能会为首次执行的函数选择不同的名称和格式,并将记录该名称和格式。

    这并不意味着程序员可以决定该函数的名称或格式 - 任何尝试这样做的人都在编写不合格/格式错误的程序。因此,此类程序应被视为语言之外的扩展 - 它不同于 C 或 C++。

  • C++ 比 C 更挑剔,因为它强制想要使用名称 main 作为实现定义形式的独立实现也使用格式 int main()。这对于裸机程序来说非常不方便,因为它有时会在“CRT”调用 main 时产生一些无用的开销。 C 更加宽松,没有这样的要求,因此独立系统中最常见的实现定义形式是 void main (void)

  • 托管系统也(可以说)允许实现定义的形式。例如,熟悉 Windows 编程的人可能会认识 WinMain。 C 允许这种实现定义的形式,但是 C++ 是否允许或者这种形式是否只是不符合/格式不正确,这是有争议的。

    再次强调,只有编译器支持实现定义的表单并记录它们,才允许实现定义的表单。程序员无法继续发明自己的形式。

Arriving late to the party - there are lot of questionable answers to this old post. A better one to use as reference might be What should main() return in C and C++? for example the answer by yours sincerely there, with relevant quotes from the language standards.

Brief summary:

  • Both C and C++ make a difference between hosted programs and freestanding programs. Hosted programs are those running on top of an OS. Freestanding programs are either the OS itself or a program written for a RTOS, or a so-called "bare-metal" embedded system with no OS at all.

    A compiler + all the standard libs supported is formally called an implementation by the standards. And so a hosted implementation is a compiler + standard libs for an OS environment, whereas a freestanding implementation is an embedded systems compiler. Freestanding implementations are allowed by the standard to implement a minimal subset of the standard library.

  • For freestanding programs, both C and C++ allow implementation-defined forms of the function first executed. Implementation-defined meaning that the compiler might chose a different name and format for the function first executed and will document that name and format.

    It does not mean that the programmer gets to decide the name or format of that function - anyone attempting such is writing a non-conforming/ill-formed program. And so such programs are to regarded as extensions beyond the language - it is something else than C or C++.

  • C++ is a bit pickier than C since it forces freestanding implementations that want to use the name main for the implementation-defined form to also use the format int main(). This is quite inconvenient for bare metal programs since it sometimes creates a bit of useless overhead where the "CRT" calls main. C is more relaxed and has no such requirement, and so the most common implementation-defined form in freestanding systems is void main (void).

  • Implementation-defined forms are also (arguably) allowed for hosted systems. Those familiar with Windows programming may recognize WinMain, for example. C allows such implementation-defined forms, but it is debatable if C++ does or if such forms are just non-conforming/ill-formed.

    Once again, implementation-defined forms are only allowed if the compiler supports them and document them. The programmer cannot go ahead and invent their own forms.

孤芳又自赏 2024-12-06 07:30:10

这取决于他们的意思。

他们的意思是:

编写一个没有 main() 函数的程序。

那么一般来说不会。
但作弊的方法还是有的。

  • 您可以使用预处理器将 main() 隐藏起来。
  • 大多数编译器允许您指定代码的入口点。
    默认情况下它是 main(int,char*[])

或者它们的意思是:

编写一个不使用 main 运行代码的程序(运行您的代码)。

这是一个相对简单的技巧。全局命名空间中的所有对象在进入 main() 之前运行其构造函数,并在 main() 退出后销毁。因此,您需要做的就是定义一个带有运行所需代码的构造函数的类,然后在全局命名空间中创建一个对象。

注意:编译器可以优化这些对象以实现延迟加载(但通常不会),但为了安全起见,只需将全局对象放在与主函数相同的文件中(可以为空)。

It depends what they mean.

Did they mean:

Write a program with no main() function.

Then generally speaking no.
But there are ways to cheat.

  • You can use the pre-processor to hide main() in plain sight.
  • Most compiler allow you to specify the entry point into your code.
    By default it is main(int,char*[])

Or did they mean:

Write a program that runs code without using main (to run your code).

This is a relatively simple trick. All objects in the global namespace run their constructors before main() is entered and destruction after main() exits. Thus all you need to do is define a class with a constructor that runs the code you want, then create an object in the global namespace.

Note: The compiler is allowed to optimize these objects for delayed load (but usually does not) but to be safe just put the global in the same file as the main function (that can be empty).

绝情姑娘 2024-12-06 07:30:10

1) 使用定义主输出的宏

#include<stdio.h>
#define fun main
int fun(void)
{
printf("stackoverfow");
return 0;
}

stackoverflow

2) 使用令牌粘贴运算符
上面的解决方案中有“main”一词。如果我们甚至不允许编写 main,我们可以使用令牌粘贴运算符(有关详细信息,请参阅此)

#include<stdio.h>
#define fun m##a##i##n
int fun()
{
printf("stackoverflow");
return 0;
}

1) Using a macro that defines main

#include<stdio.h>
#define fun main
int fun(void)
{
printf("stackoverfow");
return 0;
}

Output:

stackoverflow

2) Using Token-Pasting Operator
The above solution has word ‘main’ in it. If we are not allowed to even write main, we ca use token-pasting operator (see this for details)

#include<stdio.h>
#define fun m##a##i##n
int fun()
{
printf("stackoverflow");
return 0;
}
小猫一只 2024-12-06 07:30:10

通过使用 C++ 构造函数,您可以编写一个没有 main 函数的 C++ 程序。举例来说,我们可以打印一个 hello world,而无需在 main 函数中编写任何内容,如下所示:

class printMe{
   private:
   //
   public:
   printMe(){
       cout<<"Hello Wold! "<<endl;
  }
       protected:
       //
 }obj;

 int main(){}

By using C++ constructors you write a C++ program without the main function with nothing it it. Let's say for example we can print a hello world without writing anything in the main function as follows:

class printMe{
   private:
   //
   public:
   printMe(){
       cout<<"Hello Wold! "<<endl;
  }
       protected:
       //
 }obj;

 int main(){}
筱武穆 2024-12-06 07:30:10

函数 main 只是程序开始执行的地址的默认标签。所以从技术上讲是可以的,但是您必须设置将在您的环境中开始执行的函数的名称。

Function main is only default label for address where program will start execution. So technically yes it`s possible, but you have to set name of function that will start execution in your environment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文