c語言中int main 主函式的結尾為何有時有return 0有時沒有?

時間 2021-05-06 02:41:35

1樓:楓子

return 0首先是告知程式結束,很重要的一點是輸出到標準錯誤流,表示程式執行正確。除錯程式的時候可以編寫 return 1或者其他不是0的數字。表示程式執行出錯。。

2樓:文林

以上所有答案都不完整,甚至還有錯誤的答案,

其實這種問題,試試不就知道了嗎。

寫乙個test.c:

#include

int test1(void)

int test2(void)

int test3(void)

int main(void)

編譯一下,不要優化

gcc -S -O0 test.c

得到乙個test.s :

.file "test.c"

.text

.globl test1

.def test1; .scl 2; .type 32; .endef

.seh_proc test1

test1:

pushq %rbp

.seh_pushreg %rbp

movq %rsp, %rbp

.seh_setframe %rbp, 0

.seh_endprologue

movl $0, %eax

popq %rbp

ret.seh_endproc

.globl test2

.def test2; .scl 2; .type 32; .endef

.seh_proc test2

test2:

pushq %rbp

.seh_pushreg %rbp

movq %rsp, %rbp

.seh_setframe %rbp, 0

.seh_endprologue

movl $-1, %eax

popq %rbp

ret.seh_endproc

.globl test3

.def test3; .scl 2; .type 32; .endef

.seh_proc test3

test3:

pushq %rbp

.seh_pushreg %rbp

movq %rsp, %rbp

.seh_setframe %rbp, 0

.seh_endprologue

noppopq %rbp

ret.seh_endproc

.def __main; .scl 2; .type 32; .endef

.section .rdata,"dr"

.LC0:

.ascii "%d %d %d\0"

.text

.globl main

.def main; .scl 2; .type 32; .endef

.seh_proc main

main:

pushq %rbp

.seh_pushreg %rbp

movq %rsp, %rbp

.seh_setframe %rbp, 0

subq $48, %rsp

.seh_stackalloc 48

.seh_endprologue

call __main

call test1

movl %eax, -4(%rbp)

call test2

movl %eax, -8(%rbp)

call test3

movl %eax, -12(%rbp)

movl -12(%rbp), %ecx

movl -8(%rbp), %edx

movl -4(%rbp), %eax

movl %ecx, %r9d

movl %edx, %r8d

movl %eax, %edx

leaq .LC0(%rip), %rcx

call printf

movl $0, %eax

addq $48, %rsp

popq %rbp

ret.seh_endproc

.ident "GCC: (tdm64-1) 5.1.0"

.def printf; .scl 2; .type 32; .endef

其中rbp暫存器是幀指標,eax暫存器用於返回值。

其中 test1 ,test2,幀指標出棧前會把返回值放入eax中,例如 test1的情況

movl $0, %eax

eax暫存器是要求呼叫者儲存的暫存器,也就是說函式返回時,eax是不會出棧的。

注意到test3中沒有這條指令,也就是說test3函式沒有對eax暫存器的操作,那麼返回值取決於上一次對eax暫存器的操作

有意思的是main函式,雖然也沒有return語句,但在返回前有一條指令把eax設為0了,也就是編譯器自動設定返回0。

執行一下試試

gcc -o test -O0 test.c

執行結果為 0 -1 -1,大家可以自己試一下。

也就是說test3返回了-1,實際上就是上一次test返回時eax暫存器移入的值。

結論:

對於main函式,編譯器會自動返回0;

對於其他函式,返回值取決於上一次eax暫存器移入的值。

對了,以上結論只是在x86體系中,gcc編譯器,而且優化為O0的結果。另外@SuperSodaSea 提到標準中普通函式中這種做法是未定義行為。所以實際專案中普通函式的return 語句一定要寫。

3樓:SuperSodaSea

……如果main函式的返回值是乙個與int相容的值,那麼main函式的初始呼叫的返回相當於用main函式的返回值作為引數呼叫exit函式;到達終止main函式的}時會返回0。……

TL;DR:main函式不寫return預設返回0。

分割線既然 @劉彬 提到了,那麼就補充一下不是main的情況:

C11 6.9.1 Function definitions

如果到達終止函式的},且函式呼叫的值被呼叫者使用,則行為未定義。即使在x86中返回值的確存放在eax暫存器中,實際使用中也不應該依賴這種未定義行為。編譯器一般會扔給你乙個警告,比如:

[Warning] no return statement in function returning non-void [-Wreturn-type]

C 語言中 int main 和 void main 有何區別?

DR.JC int main代表你main函式定義為整形,函式最後要加上返回值。void main或者就main代表你是無型別函式,函式最後不能加上返回值。 Eason同學 害,我一開始也一直寫void 為了省事 後來發現到了一些嚴謹的編譯器會直接報錯 貌似c必須要有返回值?反正後來我也return...

C語言中函式的定義中 比如void print 括號裡面可以使空白嗎,像void main 就可以,前者這麼寫對嗎?

看到過一種說法是c中function 等價於function 即引數任意可變 無論型別還是數量 而 void 則是強制要求沒有引數,所以是完全不一樣的。對這種模糊的區別,最好的辦法就是別挑戰它,按確定無二意的寫法寫,別給自己找不痛快。 Victorique 詳細見此 http 簡而言之,C 可以省v...

在C語言中將function翻譯為函式合理嗎?

我認為其實翻譯成 函式 並不可取。主流叫函式是因為 函式 比 功能 聽著更技術一些。但實際上數學中使用 function 這個詞剛好跟樓上說的相反,這個詞是從 功能 借來的概念。函式這個詞實際上只存在數學中,雖然計算機發展一開始使用了數學的函式概念 但實際上在英文中 function 就是功能的意思...