窺探C語言程序的編譯、鏈接與.h文件


概述

C語言程序從源文件經過編譯、鏈接生成可執行文件。那么編譯與鏈接分別做了什么? 開發中為什么使用.h編寫函數的聲明?接下來使用案例說清楚為什么這樣編寫代碼。

C語言程序的編譯和鏈接

C語言程序從源文件到生成可執行程序需要經過編譯器的預處理,匯編、編譯、鏈接。這里簡化為編譯、鏈接兩個階段

編譯:對源文件語法做檢查
鏈接:會查找函數的具體實現並把項目中所有相關的.o目標文件、C語言函數庫合並在一起生成可執行文件

我來編寫一個main.c

對main.c進行編譯,可以用clang或者gcc編譯器都可以

$gcc -c main.c
$clang -c main.c

一旦執行編譯你會發現,編譯通過了,編譯器只是提示一個警告

警告只是告訴main.c調用sum函數沒有函數聲明,那我們添加sum函數聲明再次編譯

perfect!編譯完美通過,生成目標文件main.o

接着問題就來了,mian.c根本就沒有sum函數定義,怎么就可以編譯通過呢? 編譯只是檢查語法,main.c中調用sum函數並且有函數聲明就沒有語法問題,編譯自然可以通過。

接下來你想生成可執行程序還差一步鏈接的操作

$gcc main.o -o main
$clang main.o -o main

報錯是因為找不到main.c中的調用sum函數的定義,鏈接失敗。 由此證明鏈接會查找該文件調用所有函數的定義

這次就完美了,可以編譯器、鏈接一起來

$gcc main.c -o main
$clang main.c -o main

編譯鏈接通過,輸出執行結果21

C語言多文件開發

上面main.c調用了函數sum,在企業開發中是分文件開發,現在模擬一個場景。
A負責編寫main.c, B負責編寫Math.c(數學運算的一些函數)提供給A調用。

$ gcc -c main.c Math.c
$ gcc main.o Math.o -o app

執行程序app運行成功!

雖然A與B這樣配合可以完成項目開發,但是會發現A調用B中的函數,需要去B的Math.c中找函數定義,並將在main.c中手動添加該函數的聲明。這樣做法是不合理的,Math.c是由B寫的,B對它最熟悉的,對於調用者不需要這么麻煩,因此.h文件的作用就誕生了!

B除了編寫Math.c,還要維護一個.h文件,將Math.c可以供外界調用的函數聲明寫在.h中。這樣A在調用只需要在main.c中包含Math.h文件即可。即使以后B的Math.c中新增加了函數,A不需要修改代碼,查看Math.h有這個函數聲明直接調用就可以了。

.h文件作用是被其它文件包含,是不參與編譯的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM