【C】 33_main 函式與命令列引數

TianSong發表於2019-05-14

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 函式前呼叫其它函式

補充:不同編譯器有不同的功能擴充套件,為了程式的可以執性,如果不是及其特殊情況,不編寫依賴編譯器的程式碼

以上內容參考狄泰軟體學院系列課程,請大家保護原創!

相關文章