天天看點

【C】33. main函數與指令行參數

main 函數的概念

  • C語言中 mian 函數稱為主函數
  • 一個C程式是從 main 函數開始的

下面的寫法都正确,但是最後一種是标準形式

main()
{}

void main()
{}


int main()
{}


int main()
{
    return 0;
}
           

思考:

為什麼C編譯器支援那麼多 main 函數原型?

這麼多種形式也有曆史原因,編譯器廠商為了商用競争,更多支援不同形式。同時部分廠商在标準的C标準上右擴充了自己的規範,關鍵字

main 函數的本質

  • main 函數是作業系統調用的函數
  • 作業系統總是将 main 函數作為應用程式的開始
  • 作業系統将 main 函數的傳回值作為程式退出狀态

main 函數的傳回值實驗

在BCC編譯環境下實驗

補充:

//BCC編譯指令
bcc32 file.c

//執行可執行程式(在視窗輸入)
file.exe

//顯示函數傳回值
echo %ERRORLEVEL%
           
#include <stdio.h>

int main()
{
    printf("I'm A!\n");
    return 0;
}
// 生成 A.exe

#include <stdio.h>

int main()
{
    printf("I'm B!\n");
    return 99;
}
// 生成 B.exe
           
//指令行執行:
B.exe && A.exe
           

結果:

【C】33. main函數與指令行參數

分析:

B.exe 傳回99,作業系統認為程式沒有正常結束,就短路了。

// 執行指令
A.exe && B.exe
           

結果:

【C】33. main函數與指令行參數

分析:

A.exe 傳回0,作業系統認為程式正常結束,就運作下一個程式 B.exe

main 函數的參數

程式執行時可以向main函數傳遞參數

int main()
int main(int argc)
int main(int argc, char* argv[]
int main(int argc, char* argv[], char*env)
           
  • argc :指令行參數個數
  • argv:指令行參數數組
  • env: 環境變量數組

gcc編譯器的常見用法

【C】33. main函數與指令行參數

面試中小問題

  • main函數一定是程式執行的第一個函數嘛?

不一定,不同編譯器不同的,有些編譯器擴張可以在main 函數之前使用,比如gcc屬性關鍵字。

#include <stdio.h>

#ifndef __GNUC__
#define __attribute__(x) 
#endif

__attribute__((constructor))
void before_main()
{
    printf("%s\n",__FUNCTION__);
}

__attribute__((destructor)) 
void after_main()
{
    printf("%s\n",__FUNCTION__);
}

int main()
{
    printf("%s\n",__FUNCTION__);
    
    return 0;
}
           
before_main
main
after_main
           

在 main 函數之前執行了函數,這是因為GCC編譯器擴充了C标準。

小結

  • 一個C程式是從 main 函數開始執行的
  • main 是作業系統調用的函數
  • main 函數有參數和傳回值
  • 現代編譯器支援在 main 函數前調用其他函數