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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

我們現(xiàn)在有一個簡單的工程,有這么幾個文件

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; }

    現(xiàn)在,我們依次來看一下

    • 頭文件 和 C源文件 如何聯(lián)系在一起
    • 多文件如何變成1個可執(zhí)行目標(biāo)文件

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

    在32位Linux系統(tǒng)中。

    我們執(zhí)行g(shù)cc -E t1.c -o t1.i,對源程序進行預(yù)處理,將頭文件包含進來。

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

    # 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; }

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

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

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

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

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

    最后,需要說明

    對于函數(shù)的聲明(頭文件聲明、外部聲明、內(nèi)部聲明)與定義(內(nèi)部定義、外部定義)

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

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

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

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

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

    只討論全局變量

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

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

    注意

    函數(shù)有

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

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


    變量有

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

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

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。