在C语言中 main函数最后使用return 0结束和使用EXIT_exit successS结束...

c语言 int main的函数中如果不加return 0会怎样?如果最后return 1会怎样?_百度知道
c语言 int main的函数中如果不加return 0会怎样?如果最后return 1会怎样?
提问者采纳
没有返回值就报错,返回1也可以。返回0是正常返回,关键是你怎么使用返回值不加当然不行,main要求返回值的
如果我只要一个非常简单的main函数没其他事 最后return什么都可以吧?比如return 10 return一个变量?
提问者评价
太给力了,你的回答完美的解决了我的问题!
其他类似问题
为您推荐:
其他1条回答
如果不加return 0就代表没有传回值的意思如果是return 1的话就代表传回一个整数为1的值的意思。
return的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁C语言中没有main函数生成可执行程序的几种方法_Linux编程_Linux公社-Linux系统门户网站
你好,游客
C语言中没有main函数生成可执行程序的几种方法
来源:Linux社区&
作者:justlinux2010
1、define预处理指令这种方式很简单,只是简单地将main字符串用宏来代替,或者使用##拼接字符串。示例程序如下:#include &stdio.h&
#define begin main
int begin(void){printf("Hello, World!\n");return 0;}
#include &stdio.h&
#define begin m##a##i##n
int begin(void){printf("Hello, World!\n");return 0;}严格来说,这种方式只算是一种技巧......2、_start函数_start函数是C程序的入口函数,会调用main函数。在调用main函数之前,会先执行_start函数分配必要的资源,然后再调用main函数。但是在用gcc编译程序时可以使用-nostartfiles选项来重写_start函数。示例程序如下:#include &stdio.h&#include &stdlib.h&
_start(void) {printf("Hello, World!\n");exit(0);}编译上面的程序的命令为:gcc -nostartfiles _start.c -o a.out反汇编生成的可执行程序,如下所示:a.out: file format elf64-x86-64
Disassembly of section .plt:
0320 &puts@plt-0x10&:400320: ff 35 ea 01 20 00 pushq 0x2001ea(%rip) # 600510 &_GLOBAL_OFFSET_TABLE_+0x8&400326: ff 25 ec 01 20 00 jmpq *0x2001ec(%rip) # 600518 &_GLOBAL_OFFSET_TABLE_+0x10&40032c: 0f 1f 40 00 nopl 0x0(%rax)
0330 &puts@plt&:400330: ff 25 ea 01 20 00 jmpq *0x2001ea(%rip) # 600520 &_GLOBAL_OFFSET_TABLE_+0x18& 00 00 00 00 pushq $0x040033b: e9 e0 ff ff ff jmpq 400320 &puts@plt-0x10&
0340 &exit@plt&:400340: ff 25 e2 01 20 00 jmpq *0x2001e2(%rip) # 600528 &_GLOBAL_OFFSET_TABLE_+0x20& 01 00 00 00 pushq $0x140034b: e9 d0 ff ff ff jmpq 400320 &puts@plt-0x10&
Disassembly of section .text:
0350 &_start&: push %rbp 89 e5 mov %rsp,%rbp400354: bf 68 03 40 00 mov $0x400368,%edi400359: e8 d2 ff ff ff callq 400330 &puts@plt&40035e: bf 00 00 00 00 mov $0x0,%edi400363: e8 d8 ff ff ff callq 400340 exit@plt 上面的结果是完整的反汇编结果,我们可以看到_start函数中只有我们调用printf和exit函数相关的一些指令,并且.txt段中只有_start函数,没有看到main函数。如果将源代码中的_start替换为main,重新编译程序,反汇编的结果中会看到_start函数会调用到main。另外还有一点需要注意,因为这里重写了_start函数,所以gcc为默认的main函数准备的清理动作就没用上,所以如果退出的时候直接使用return,会导致程序崩溃。所以这里要使用exit()来退出程序。具体的原因可以参见这篇文章。3、gcc的-e选项示例程序如下:#include &stdio.h&#include &stdlib.h&
int nomain(int i, int j, int k) {printf("Hello, World!\n");exit(0);}将上面的程序保存为m.c,编译命令如下所示:gcc -nostartfiles -e nomain m.c -o a.out继续使用objdump反汇编生成的可执行程序,结果如下:a.out: file format elf64-x86-64
Disassembly of section .plt:
0320 &puts@plt-0x10&:400320: ff 35 f2 01 20 00 pushq 0x2001f2(%rip) # 600518 &_GLOBAL_OFFSET_TABLE_+0x8&400326: ff 25 f4 01 20 00 jmpq *0x2001f4(%rip) # 600520 &_GLOBAL_OFFSET_TABLE_+0x10&40032c: 0f 1f 40 00 nopl 0x0(%rax)
0330 &puts@plt&:400330: ff 25 f2 01 20 00 jmpq *0x2001f2(%rip) # 600528 &_GLOBAL_OFFSET_TABLE_+0x18& 00 00 00 00 pushq $0x040033b: e9 e0 ff ff ff jmpq 400320 &puts@plt-0x10&
0340 &exit@plt&:400340: ff 25 ea 01 20 00 jmpq *0x2001ea(%rip) # 600530 &_GLOBAL_OFFSET_TABLE_+0x20& 01 00 00 00 pushq $0x140034b: e9 d0 ff ff ff jmpq 400320 &puts@plt-0x10&
Disassembly of section .text:
0350 &nomain&: push %rbp 89 e5 mov %rsp,%rbp 83 ec 10 sub $0x10,%rsp 7d fc mov %edi,-0x4(%rbp)40035b: 89 75 f8 mov %esi,-0x8(%rbp)40035e: 89 55 f4 mov %edx,-0xc(%rbp)400361: bf 75 03 40 00 mov $0x400375,%edi400366: e8 c5 ff ff ff callq 400330 &puts@plt&40036b: bf 00 00 00 00 mov $0x0,%edi400370: e8 cb ff ff ff callq 400340 &exit@plt&从上面我们可以看到指定的nomain函数位于.text段的开始位置,同样在函数结束的时候没有gcc为main函数准备的清理动作,所以在这里也只能使用exit()来退出程序,而不能使用return。4、nostartfiles选项前面已经多次使用了该选项,不过都是配合其他选项使用的,这个选项也可以单独使用,其含义为"Do not use the standard system startup files when linking"。示例程序如下:#include &stdio.h&#include &stdlib.h&
void func() {printf("I am func....\n");}
int nomain1(int i, int j, int k) {func();printf("%s: Hello, World!\n", __func__);exit(0);}上面的程序保存为k.c,然后使用下面的命令编译:[root@_190 ~]# gcc -nostartfiles p.c/usr/bin/ld: warning: cannot find entry symbol _ defaulting to 0398在单独使用nostartfiles选项时会报警告,生成的可执行程序可以执行,但是会产生段错误,去掉对func()函数的调用就不会产生段错误了。将生成的可执行程序反汇编,和使用前面的方法生成可执行程序的反汇编结果比较,发现除了函数名不一样外,没有其他区别,不知道为什么会产生段错误。知道的麻烦告知一声,拜谢!
相关阅读:
C语言变长数组之剖析
C语言需要注意的问题
C语言位域的使用及其注意点
相关资讯 & & &
& (03月14日)
& (03/15/:43)
& (03月14日)
& (07/25/:51)
& (03/09/:10)
图片资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款在main函数执行结束后再执行的代码 - 单鱼游弋 - 博客园
posts - 151, comments - 55, trackbacks - 0, articles - 0
其实我不想废话的,但是我确实废话比较多,刚才电压突变,我的电脑自动关机了,后果,你懂的。
以前一直认为 main 函数执行完毕把返回值返回给操作系统,程序自己的事情就算结束了,以后的事情就全部交给操作系统去做了。昨晚看一本 C/C++ 面试题的书,才发现,原来 main 函数执行完毕后还可以在执行其他函数。好吧,也许你要鄙视我了,知道的高手可以飘过了,不知道的朋友一起来了解一下吧,代码献上:
//// 如果需要在 main 函数执行结束后在执行一段代码的话, // 可以使用 atexit 函数,注册一个或多个函数,它们被注册在栈中, // 在 main 函数结束后被调用,调用顺序与注册顺序相反。 // #include &stdlib.h&#include &stdio.h&&// // 声明将在 main 函数结束后执行的函数. // 这样的函数前置声明很特别吧!我以前也没想到过. //void fn1(void), fn2(void), fn3(void), fn4(void);int main(void){
// 注册需要在 main 函数结束后执行的函数.
// 请注意它们的注册顺序和执行顺序,看看它们的输出结果多有趣!
atexit(fn1);
atexit(fn2);
atexit(fn3);
atexit(fn4);
// 这条输出语句具有参照性,它可不是最后一句输出.
puts("This is executed first.");
// EXIT_SUCCESS 代表 0,它定义在 stdlib.h 中.
// 我只是顺便提一下,也许你知道,但我担心你不知道,呵呵.
return EXIT_SUCCESS;}void fn1(void){
printf("next.\n"); }void fn2(void){
printf("executed "); }void fn3(void){
printf("is "); }void fn4(void){
printf("This ");}
也许你很懒,不想打开 IDE 试一下,所以让我们来看一下运行效果吧!
This is executed first.This is executed next.
关于 atexit 函数我的稍微补充一下,原型如下:
int atexit(void (*func)(void));
atexit 函数是标准 C 新增的。它&注册&一个函数,使这个函数将在 exit 函数被调用时或者当 mian 函数返回时被调用。当程序异常终止时(例如调用 abort 或 raise),通过它注册的函数并不会被调用。编译器必须至少允许程序员注册32个函数。如果注册成功,atexit 返回0,否则返回非零值。没有办法取消一个函数的注册。在 exit 所执行的任何标准清理操作之前,被注册的函数按照与注册顺序相反的顺序被依次调用。每个被调用的函数不接受任何参数,并且返回类型是 void。被注册的函数不应该试图引用任何存储类别为 auto 或 register 的对象(例如通过指针),除非是它自己所定义的。多次注册同一个函数将导致这个函数被多次调用。有些传统 C 编译器用 onexit 这个名称实现了像是的功能。
上面这段话是我从《C语言参考手册》里面抄来的,哈哈!1、exit函数和return函数的主要区别是:
&&&&1)exit用于在程序运行的过程中随时结束程序,exit的参数是返回给OS的。main函数结束时也会隐式地调用exit函数。exit函数运行时首先会执行由atexit()函数登记的函数,然后会做一些自身的清理工作,同时刷新所有输出流、关闭所有打开的流并且关闭通过标准I/O函数tmpfile()创建的临时文件。exit是结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程;而return是返回函数值并退出函数。通常情况:exit(0)表示程序正常,
exit(1)和exit(-1)表示程序异常退出,exit(2)表示表示系统找不到指定的文件。在整个程序中,只要调用exit就结束(当前进程或者在main时候为整个程序)。
&&&&2)return是语言级别的,它表示了调用堆栈的返回;return( )是当前函数返回,当然如果是在主函数main,
自然也就结束当前进程了,如果不是,那就是退回上一层调用。在多个进程时。如果有时要检测上个进程是否正常退出。就要用到上个进程的返回值,依次类推。而exit是系统调用级别的,它表示了一个进程的结束。
&&&&3)exit函数是退出应用程序,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息。
&&&&4)和机器和操作系统有关的一般是:&0为正常退出,非0为非正常退出;
2、进程环境与进程控制
&&&&&exit(int n)其实就是直接退出程序,因为默认的标准程序入口为 int main(int argc, char** argv),返回值是int型的。一般在shell下面,运行一个程序,然后使用命令echo
$?就能得到该程序的返回值,也就是退出值,在main()里面,你可以用return n,也能够直接用exit(n)来做。unix默认的正确退出是返回0,错误返回非0。理论上exit可以返回小于256的任何整数。返回的不同数值主要是给调用者作不同处理的。
&&&&单独的进程是返回给操作系统的。如果是多进程,是返回给父进程的。父进程里面调用waitpid()等函数得到子进程退出的状态,以便作不同处理。根据相应的返回值来让调用者作出相应的处理。总的说来,exit()就是当前进程把控制权返回给调用该程序的程序,括号里的是返回值,告诉调用程序该程序的运行状态。
1)进程的开始:
&&&&&C程序是从main函数开始执行,原型如下:int
main(int argc, char *argv[]);通常main的返回值是int型,正确返回0。如果main的返回值为void,某些编译器会给出警告,此时main的返回值通常是0。
2)进程终止:
&&&&&C程序的终止分为两种:正常终止和异常终止。
&&&&&正常终止分为:return,exit,_exit,_Exit,pthreade_exit。异常中指分为:abort,SIGNAL,线程响应取消。
&&&&&主要说一下正常终止的前4种:即exit系列函数.
&&&&&#include
&stdlib.h&&&&
exit(int status);
_Exit(int status);
&&&&&#include
&unistd.h&&&&
_exit(int status);
&&&&&以上3个函数的区别是:exit()(或return
0)会调用终止处理程序和用户空间的标准I/O清理程序(如fclose),_exit和_Exit不调用而直接由内核接管进行清理。因此,在main函数中exit(0)等价于return 0。
3)atexit终止处理程序:
C规定,一个进程最多可登记32个终止处理函数,这些函数由exit按登记相反的顺序自动调用。如果同一函数登记多次,也会被调用多次。
&&&&&原型如下:
&&&&&#include
&stdlib.h&
atexit(void (*func)(void));
&&&&&其中参数是一个函数指针,指向终止处理函数,该函数无参无返回值。atexit函数本身成功调用后返回0。
&&&&&以下面的程序为例:
#include &stdlib.h&
static void myexit1()
printf(&first exit handler\n&);
static void myexit2()
printf(&second exit handler\n&);
int main()
atexit(my_exit2);
atexit(my_exit1);
atexit(my_exit1);
printf(&main is done\n&);
&&&&&运行结果:
&&&&&first
exit handler
&&&&&first
exit handler
&&&&&second
exit handler
&&&&&注意上面的结果,可以发现这些函数由exit按登记相反的顺序自动调用(先myexit1后myexit2)。如果同一函数登记多次, 也会被调用多次(如这里的myexit1)。程序退出的时候利用atexit函数调用了这些处理函数。但是如果用_exit()退出程序,则它不关闭任何文件,不清除任何缓冲器、也不调用任何终止函数!
阅读(...) 评论()

我要回帖

更多关于 shell return exit 的文章

 

随机推荐