1. 程式人生 > >深度剖析c語言main函式---main函式的返回值

深度剖析c語言main函式---main函式的返回值

  在接下來的幾篇博文中,我將對c語言的main函式進行深入的剖析,分別從函式返回值,函式引數,以及函式的執行順序對main函式作一總結。本文主要聊聊main函式的返回值。

main函式的返回值

  main函式的返回值用於說明程式的退出狀態。如果返回0,則代表程式正常退出。返回其它數字的含義則由系統決定。通常,返回非零代表程式異常退出。

void main()

  有一些書上的,都使用了void main( ) ,其實這是錯誤的。C/C++ 中從來沒有定義過void main( ) 。C++ 之父 Bjarne Stroustrup 在他的主頁上的 FAQ 中明確地寫著 “The definition void main( ) { /* … */ } is not and never has been C++, nor has it even been C.”
  這可能是因為 在 C 和 C++ 中,不接收任何引數也不返回任何資訊的函式原型為“void foo(void);”。可能正是因為這個,所以很多人都誤認為如果不需要程式返回值時可以把main函式定義成void main(void) 。然而這是錯誤的!main 函式的返回值應該定義為 int 型別,C 和 C++ 標準中都是這樣規定的。雖然在一些編譯器中,void main() 可以通過編譯,但並非所有編譯器都支援 void main() ,因為標準中從來沒有定義過 void main 。g++3.2 中如果 main 函式的返回值不是 int 型別,就根本通不過編譯。而 gcc3.2 則會發出警告。所以,為了程式擁有很好的可移植性,一定要用 int main ()。
  測試如下:
  

#include <stdio.h>

void main()
{
    printf("Hello world\n");
    return;
}

執行結果:g++ test.c
這裡寫圖片描述

main()

  那既然main函式只有一種返回值型別,那麼是不是可以不寫?規定:不明確標明返回值的,預設返回值為int,也就是說 main()等同於int main(),而不是等同於void main()。在C99中,標準要求編譯器至少給 main() 這種用法來個警告,而在c98中這種寫法是被允許的。但為了程式的規範性和可讀性,還是應該明確的指出返回值的型別。
  測試程式碼:
  

#include <stdio.h>

main()
{
    printf("Hello world\n");
    return 0;
}

執行結果:
這裡寫圖片描述

C和C++的標準

  在最新的 C99 標準中,只有以下兩種定義方式是正確的:

       int main( void ) 

       int main( int argc, char *argv[] ) 

  若不需要從命令列中獲取引數,就使用int main(void) ;否則的話,就用int main( int argc, char *argv[] )。當然引數的傳遞還可以有其他的方式,在下一個文章中,會單獨來講。 main 函式的返回值型別必須是 int ,這樣返回值才能傳遞給程式的呼叫者(如作業系統),等同於 exit(0),來判斷函式的執行結果。

C++98 中定義瞭如下兩種 main 函式的定義方式:

      int main( ) 

      int main( int argc, char *argv[] ) 

  int main( ) 等同於 C99 中的 int main( void ) ;int main( int argc, char*argv[] ) 的用法也和C99 中定義的一樣。同樣,main函式的返回值型別也必須是int。

return 語句

  如果 main 函式的最後沒有寫 return 語句的話,C99 和c++98都規定編譯器要自動在生成的目標檔案中加入return 0,表示程式正常退出。不過,建議你最好在main函式的最後加上return語句,雖然沒有這個必要,但這是一個好的習慣。
  在linux下我們可以使用shell命令:echo $? 檢視函式的返回值。
  
  

#include <stdio.h>

int main()
{
    printf("Hello world\n");
}

執行結果:
這裡寫圖片描述
  
  同時,需要說明的是return的返回值會進行 型別轉換,比如:若return 1.2 ;會將其強制轉換為1,即真正的返回值是1,同理,return ‘a’ ; 的話,真正的返回值就是97,;但是若return “abc”; 便會報警告,因為無法進行隱式型別轉換。

測試main函式返回值的意義

  前文說到,main函式如果返回0,則代表程式正常退出。通常,返回非零代表程式異常退出。在本文的最後,測試一下:
  
test.c

#include <stdio.h>

int main()
{
    printf("c 語言\n");
    return 11.1; 
}

在終端執行如下:

➜  testSigpipe git:(master) ✗ vim test.c
➜  testSigpipe git:(master) ✗ gcc test.c
➜  testSigpipe git:(master) ✗ ./a.out && echo "hello world"  #&&與運算,前面為真,才會執行後邊的
c 語言

  可以看出,作業系統認為main函式執行失敗,因為main函式的返回值是11

➜  testSigpipe git:(master) ✗ ./a.out 
➜  testSigpipe git:(master) ✗ echo $?
11

若將main函式中返回值該為0的話:

➜  testSigpipe git:(master) ✗ vim test.c
➜  testSigpipe git:(master) ✗ gcc test.c 
➜  testSigpipe git:(master) ✗ ./a.out && echo "hello world" #hello
c 語言
hello world

  可以看出,正如我們所期望的一樣,main函式返回0,代表函式正常退出,執行成功;返回非0,代表函數出先異常,執行失敗。

  在下文中會對main函式的引數的使用做一總結。