日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言多文件编译链接为1个可执行文件的简单原理

發布時間:2023/11/30 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言多文件编译链接为1个可执行文件的简单原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考1:C header files and compilation/linking
參考2:計算機系統基礎(一)袁春風 (符號鏈接部分)

我們現在有一個簡單的工程,有這么幾個文件

1.t1.h

extern int x;void tt();
  • t1.c
  • #include "t1.h"int x;void tt(){x = 100; }
  • main.c
  • #include <stdio.h> #include "t1.h"int main(){tt();printf("x = %d\n",x);return 0; }

    現在,我們依次來看一下

    • 頭文件 和 C源文件 如何聯系在一起
    • 多文件如何變成1個可執行目標文件

    預處理,組合頭文件與包含它的C源文件

    在32位Linux系統中。

    我們執行gcc -E t1.c -o t1.i,對源程序進行預處理,將頭文件包含進來。

    所謂預處理,就是將預編譯命令處理掉,比如,把頭文件的內容拷貝到C源文件中,因此,我們就能夠理解.h和.c文件中全部變量的關系了,我們看一下生成的文件內容

    # 1 "t1.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "t1.c" # 1 "t1.h" 1 extern int x;void tt(); # 2 "t1.c" 2int x;void tt(){x = 100; }

    可以看到,開始有一些記錄的信息,看起來應該是注釋,是一些說明性信息。

    然后我們看到,之前頭文件的內容在這個文件里面了。如果你把它近似地看為一個源文件,你就能大概理解全局變量聲明和定義,以及不要重復定義等。

    對于main.c文件的預處理,道理是一樣的

    然后,我們將t1.i和main.i分別生成其可重定位目標文件,最后鏈接起來,就生成了可執行目標文件。

    gcc -c t1.i -o t1.o # 生成可重定位目標文件 gcc -c main.i -o main.o # 生成可重定位目標文件 gcc -o main main.o t1.o # 鏈接,生成可執行目標文件 ./main # 運行可執行目標文件

    最后,需要說明

    對于函數的聲明(頭文件聲明、外部聲明、內部聲明)與定義(內部定義、外部定義)

    在c源文件中進行函數聲明,然后使用它,在鏈接的時候,這個聲明的函數(但未在該文件中定義)鏈接器會自動在其他的可重定位目標文件中尋找其定義,如果找到了就聯系起來,否則就報錯。這就意味著,所有的C源文件中的函數默認都是全局的,你可以在模塊1聲明函數a,然后調用它,在模塊2中定義函數a,之后將兩個模塊鏈接起來生成可執行文件。

    好吧,每次都聲明很麻煩,所以,我們在模塊2對應的頭文件聲明,然后模塊1引入頭文件,這樣,我們就能夠進行和之前一樣的操作了,你知道的,頭文件在預處理的時候會被包含進入源文件,這樣,其實達到了和我們手動聲明一樣的效果。

    如果你不想讓函數是全局的,那就加上static,這樣,只有該源文件可以使用它了!

    對于變量的定義與初始化
    • 局部變量:只能在其{ }內使用
    • static變量:只能在本模塊內使用
    • 全局變量:全部都可以用
      • 本模塊定義
      • 外部定義extern

    對于本模塊使用的,沒得說,就是只有這個源文件能夠使用這個變量!

    只討論全局變量

  • extern變量,不要初始化,只聲明即可!
  • 任何初始化的全局變量,全局范圍內只能初始化1次,可以定義n次,但是最終內存空間中的,就是初始化的內個變量的位置,只有一個!
  • 頭文件一般包含函數聲明,全局變量的定義似乎沒必要,或者說,不要在頭文件定義全局變量
  • 全局變量最好少出現,出現一次也就夠了,在不同編譯器下,要求不一樣。少用。 比如在Linux的gcc下,不同C源文件,可以出現多個int x弱符號,但是Windows的VS下就不允許。
  • 因此說,使用全局變量,最好

    • 初始化全局變量
    • 只定義一次
    • 其他的模塊如果要用,就聲明extern表示引用外部定義,而不是再聲明一個弱符號(不是不行,但是這樣的話,gcc能用,VS就不能用)
    • 不要在頭文件定義全局變量(頭文件被多次包含的話…得定義多少次,恐怖)

    注意

    函數有

  • 是否聲明
  • 是否定義
  • 是否使用
  • 對于任何模塊,必須先聲明,再使用,聲明之后可以不定義,因為可以外部定義,但是被聲明被使用的函數,必須有其定義。 要是聲明之后沒有使用也沒有定義,其實也行,但是最好不要這樣干,太奇怪了!

    對于同一模塊,先定義再使用也可以,但是不能先使用再定義,順序很重要。


    變量有

    • 是否定義
    • 是否初始化
    • 是否使用

    然后,還涉及到不同模塊之間…

    總結

    以上是生活随笔為你收集整理的C语言多文件编译链接为1个可执行文件的简单原理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。