linux下gcc編譯sin函數出錯的問題

linux下gcc編譯sin函數出錯的問題 收藏

Q: I keep getting errors due to library functions being undefined, but I'm #including all the right header files.linux


--------------------------------------------------------------------------------ide

A: In the general case of calling code in an external library, using #include to pull in the right header file(s) is only half of the story; you also have to tell the linker to search the external library itself. The declarations in the header file only tell the compiler how to call the external functions; the header file doesn't supply the definitions of the external functions, or tell the compiler/linker where to find those definitions.函數

In some cases (especially if the functions are nonstandard) obtaining those definitions may require explicitly asking for the correct libraries to be searched when you link the program. (Some systems may be able to arrange that whenever you #include a header, its associated library, if nonstandard, is automatically requested at link time, but such a facility is not widespread.) See also questions 10.11 , 11.30 , 13.26 , 14.3 , and 19.40 .ui

Q: I'm trying to do some simple trig, and I am #including <math.h> , but the linker keeps complaining that functions like sin and cos are undefined..net


--------------------------------------------------------------------------------code

A: Make sure you're actually linking with the math library. For instance, due to a longstanding bug in Unix and Linux systems, you usually need to use an explicit -lm flag, at the end of the command line, when compiling/linking. See also questions 13.25 , 13.26 , and 14.2 .blog

當使用gcc編譯器編譯含數學函數的C程序時,會出現undefined reference to `sin'錯誤.這種錯誤通常是因爲缺乏庫形成的.使用-lm便可.Makefile能夠這樣寫:ci

pe14-18-11:pe14-18-11.o
         gcc pe14-18-11.o -lm -o pe14-18-11
pe14-18-11.o:pe14-18-11.c
         gcc -c pe14-18-11.c -o pe14-18-11.o
clean:
         rm -f *.o pe14-18-11get

具體緣由及解決辦法爲:編譯器

加入連結的函式庫

剛剛咱們都僅只是在屏幕上面印出一些字眼而已,若是說要計算數學公式呢?!例如咱們想要計算出三角函數裏面的 sin(90度角),要注意的是,大多數的程序語言都是使用徑度而不是通常咱們在計算的『角度』, 180 度角約等於 3.14 徑度!嗯!那咱們就來寫一下這個程序吧!
  [guest@test guest]# vi sin.c
#include <stdio.h>
int main(void)
{
        float value;
        value = sin ( 3.14 / 2 );
        printf("%f\n",value);
}
# 上面這個檔案的內容能夠在底下取得!
# http://linux.vbird.org/download/books/basic/source_code/sin.c
 
那要如何編譯這支程序呢?咱們先直接編譯看看:
  [guest@test guest]# gcc sin.c
/tmp/ccppUCx8.o(.text+0x1e): In function `main':
: undefined reference to `sin'
collect2: ld returned 1 exit status
 
特別注意上面的說明,唉啊!怎麼沒有編譯成功?它說的是『 undefined reference to sin 』,說的是『 沒有 sin 的相關定義參考值! 』,爲何會這樣呢?這是由於 C 語言裏面的 sin 函示是寫在 libm.so 這個函式庫中,而咱們並無在原始碼裏面加入相關的說明,因此固然就須要在編譯與連結的時候將這個函式庫給他連結進執行檔裏面啊!因此咱們能夠這樣作:
  [guest@test guest]# gcc sin.c -lm -L/lib -L/usr/lib
# 特別注意,那個 -lm 能夠拆開成兩部份來看,
# -l 是『加入某個函式庫(library)』的意思,而
# m 則是 libm.so 這個函式庫,其中, lib 與附檔名(.a 或 .so)不須要寫
# 因此 -lm 表示使用 libm.so (或 libm.a) 這個函式庫的意思~
# 至於那個 -L 後面接的路徑呢?這表示:
#『我要的函式庫 libm.so 請到 /lib 或 /usr/lib 裏面搜尋! 』
[guest@test guest]# ./a.out
1.000000
 
上面的說明很清楚了吧!!不過,要注意的是,因爲 Linux 預設是將函式庫放置在 /lib 與 /usr/lib 當中,因此您沒有寫 -L/lib 與 -L/usr/lib 也沒有關係的!不過,萬一哪天您使用的函式庫並不是放置在這兩個目錄下,那麼 -L/path 就很重要了!不然會找不到函式庫喔!
 
除了連結的函式庫以外,您或許已經發現一個奇怪的地方,那就是在咱們的 sin.c 當中第一行『 #include <stdio.h> 』,這行說的是要將一些定義數據由 stdio.h 這個檔案讀入,這包括 printf 的相關設定。這個檔案實際上是放置在 /usr/include/stdio.h 的!那麼萬一這個檔案並不是放置在這裏呢?那麼咱們就可使用底下的方式來定義出要讀取的 include 檔案放置的目錄:
  [guest@test guest]# gcc sin.c -lm -I/usr/include
 
-I/path 後面接的路徑( Path )就是設定要去搜尋相關的 include 檔案的目錄啦!不過,一樣的,默認值是放置在 /usr/include 底下,除非您的 include 檔案放置在其它路徑,不然也能夠略過這個項目!
 
透過上面的幾個小范例,您應該對於 gcc 以及原始碼有必定程度的認識了,再接下來,咱們來稍微整理一下 gcc 的簡易使用方法吧!

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/tylovemx/archive/2009/11/25/4872727.aspx

相關文章
相關標籤/搜索