對于C語言的癡迷,讓小編我從此走上了編程這條不歸路,在這段職業生涯中,小編也稱得上是C語言的深入了解者,一篇深入了解C語言中常見的編譯錯誤,武林技術頻道的小編在這里獻給各位,我們一起在編程中揮灑青春吧。
1. /usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld 返回 1
Reason: no main function in source file
2. to get compile options -I and -lpkg-config lib
e.g: pkg-config --cflags --libs dbus-1 glib-2.0 dbus-glib-1
gcc -o send-sms send-sms.c `pkg-config --cflags --libs dbus-1 glib-2.0 dbus-glib-1`
3. 如何讓pkg-config找到自己寫的庫
在庫中有一個文件libxxx.pc.in,其中會定義它所提供的頭文件在哪里,有哪些,其庫鏈接方式是怎么樣,庫在哪里,當然這都是庫安裝到系統以后的信息,換句話說,可能對于編譯環境是無意義的。
?
?
?
這個文件定義了安裝后此庫的所有信息,而pkg-config就會讀取此信息。
4. forward declaration and incomplete type
出現這種錯誤的時候通常是由于具體使用了某種類型,但此類型(到使用的時候)還僅有聲明,未有定義。比如說,某個頭文件有如下聲明:
?
?
如果包含了此頭文件的文件,可以使用Point去聲明:
??? 1).如聲明函數時的形式參數,void print_point(Point p),注意是聲明函數時,而不是定義函數
??? 2). 聲明指針:Point *p;
但是不能使用Point去定義變量,
??? 1). 如定義變量,Point p;
??? 2). 定義函數時的形參,void print_point(Point p) { ... }
??? 3) .或者為其指針申請內在空間時,Point *point = (Point *) calloc(1, sizeof(Point));
會報出incomplete type的編譯錯誤。因為這個時候需要Notification所占的內存大小和具體的定義形式,但是頭文件中并沒有給出具體的定義,所以編譯器不知道此類型所需要的內存,所以會編譯出錯。
C++中也是如此,為了效率會Forward declaration,也即在使用某個類前,不具體指定其類,而是聲明一個沒有定義的類:
class Point;
Point a;
使用Foward declaration時,也只能用其去聲明,而不能具體使用此類型。
所以,如果要具體使用某個類型時,其所包含的頭文件中必須要有類型的具體定義:
?
?
其實原因也很簡單,當令需要某個類型來聲明變量時,不需分配內存,不需要對其進行操作,自然就不用了解其具體的類型定義。但當你使用時,要分配內存時,就必須要了解類型是怎么定義的,否則這些操作無法完成,這自然就需要知道類型的具體定義。
其實,在頭文件中僅聲明類型的目的是為了信息隱藏,也就是不讓調用者知道這個類型具體的定義是什么樣子的,那么就需要像Java/C++中那樣去定義這個類型,
??? 1) 把類型聲明為指針類型:
??? typedef struct Point *Point;
??? 否則調用者還是有可能去定義。
??? 2) 也即在頭文件的對應源文件中封裝操作此類型的所有方法,這樣外界就沒有必要去了解類型是如何定義的了。它想操作時,僅需要調用封裝的方法即可。
典型的實例:
頭文件point.h:
?
?
實現源文件:point.c
?
?
深入了解C語言中常見的編譯錯誤,到這里就講解完了,不知你是否已經了解,如果還有不清楚的地方,隨時都可以找小編我聊聊,更多精彩內容,請關注武林技術頻道,我們每天都有更新新內容。
新聞熱點
疑難解答
圖片精選