main 函式的概念
- C 語言中 main 函式稱之為主函式
- 一個 C 程式是從 main 函式開始執行的
下面的 main 函式定義正確嗎?
A.
main()
{
}
B.
void main()
{
}
c.
int main()
{
}
D.
int main()
{
return 0;
}
A B C D 編譯無警告,無錯誤,執行正常
D 為最標準
main() 函式的本質
- main 函式是作業系統呼叫的函式
- 作業系統總是將 main 函式作為應用程式的開始
- 作業系統將 main 函式的返回值作為程式的退出狀態
思考:為什麼 C 編譯器支援那麼多不同的 main 函式元原型呢?
C 語言誕生初期就得到的廣泛的應用,,當時的程式比較簡單,主要應用於科學運算或嵌入式裝置中。在當時的環境下,只需要知道入口函式在哪裡便可以,在非作業系統中執行,返回值是無意義的。
隨著商業編譯器的競爭與發展,編譯器開始支援更多的 C 語言特性,並對編譯器的功能進行擴充套件。
程式設計實驗: main 函式的返回值
A.C
#include <stdio.h>
int main()
{
printf("I`m A!
");
return 0;
}
B.c
#include <stdio.h>
int main()
{
printf("I`m B!
");
return 99;
}
命令列:【GCC】
./a.out && ./b.out
輸出:
I`m A!
I`m B!
命令列:【GCC】
./b.out && ./a.out
輸出:
I`m B!
在作業系統中的作用
作業系統中存在批處理語言。在 linux 中為 shell 指令碼,其聯合各種應用程式協作完成任務,通過應用程式返回值監控程式的執行狀態。
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 編譯器的常見用法
./a.out a.c b.c c.c
argc ---> 4
argv[0] ---> a.out
argv[1] ---> a.c
argv[2] ---> b.c
argv[3] ---> c.c
例項分析: main 函式的引數
#include <stdio.h>
int main(int argc, char* argv[], char* env[])
{
int i = 0;
printf("=============Begin argv=============
");
for(i=0; i<argc; i++)
{
printf("%s
", argv[i]);
}
printf("=============End argv=============
");
printf("
");
printf("
");
printf("
");
printf("=============Begin env=============
");
for(i=0; env[i]!=NULL; i++)
{
printf("%s
", env[i]);
}
printf("=============End env=============
");
}
命令列: ./a.out a.c b.c c.c
輸出:
=============Begin argv=============
./a.out
a.c
b.c
c.c
=============End argv=============
=============Begin env=============
ORBIT_SOCKETDIR=/tmp/orbit-delphi
SSH_AGENT_PID=1695
TERM=xterm
SHELL=/bin/bash
XDG_SESSION_COOKIE=6c560f89cd4609726ff940b800000007-1544093738.93069-2082860285
WINDOWID=71303204
......
......
=============End env=============
例項,gcc 命令列不同引數,實現不同功能
小技巧
- 面試中的小問題,main 函式一定是程式執行的第一個函式嗎?
不一定。
在 gcc 中使用屬性關鍵字 attribute, 可以指定 main 之前與 main 之後分別執行一個函式。
但有的編譯器沒有支援相關功能關鍵字擴充套件,那麼 main 函式是第一個執行的函式,例BCC。
例項分析: gcc 中的屬性關鍵字
#include <stdio.h>
#ifndef __GNC__
#define __GNU__
#endif
__attribute__((constructor))
void before_main()
{
printf("%s
", __FUNCTION__);
}
__attribute__((destructor))
void after_main()
{
printf("%s
", __FUNCTION__);
}
int main()
{
printf("%s
", __FUNCTION__);
return 0;
}
輸出:
before_main
main
after_main
小結
- 一個 C 程式是從 main 函式開始執行的
- main 函式是作業系統呼叫的函式
- main 函式有引數和返回值
- 現代編譯器支援在 main 函式前呼叫其它函式
補充:不同編譯器有不同的功能擴充套件,為了程式的可以執性,如果不是及其特殊情況,不編寫依賴編譯器的程式碼
以上內容參考狄泰軟體學院系列課程,請大家保護原創!