www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > 21ic電子網(wǎng)
[導(dǎo)讀]你知道,為什么在C中使用了pow函數(shù)不需要鏈接libm庫嗎?什么情況需要指定鏈接庫?在解釋之前,先回顧一下。//來源:公眾號【編程珠璣】//https://www.yanbinghu.com#include#includeint?main(void){????int?b?=?2;...

你知道,為什么在C 中使用了pow函數(shù)不需要鏈接libm庫嗎?

什么情況需要指定鏈接庫?

在解釋之前,先回顧一下。

//來源:公眾號【編程珠璣】
//https://www.yanbinghu.com
#include
#include
int?main(void)
{
????int?b?=?2;
????double?a?=?pow(b,b);
????printf("%f\n",a);
????return?0;
}
代碼本身比較簡單,pow(x,y)用于計算x的y次冪。

這里由于pow函數(shù)并不在lib庫中,默認情況下,編譯的時候只鏈接了libc庫,因此如果不指定鏈接庫,則會報錯:

$?gcc?-o?test?test.c
/tmp/ccKDgtzz.o:?In?function?`main':
test.c:(.text 0x22):?undefined?reference?to?`pow'
collect2:?error:?ld?returned?1?exit?status
從報錯信息來看,我們知道是找不到pow函數(shù)的定義。

通過man手冊也可以查看到,編譯是需要包含頭文件math.h和鏈接數(shù)學(xué)庫的:

$?man?pow
???????#include?

???????double?pow(double?x,?double?y);
???????float?powf(float?x,?float?y);
???????long?double?powl(long?double?x,?long?double?y);

???????Link?with?-lm.
即像下面這樣是可以的:

$?gcc?-o?test?test.c?-lm
$?./test
4.000000
gcc在編譯的時候默認鏈接的是libc庫,其他庫需要手動指定。

但是,看下面的代碼:

//來源:公眾號【編程珠璣】
//作者:守望先生
#include
#include
int?main()
{
????int?b?=?2;
????double?a?=?pow(b,b);
????std::cout::endl;
????return?0;
}
編譯運行:

$?g ?-o?test?test.cpp
$?./test
4

我們并沒有手動指定鏈接庫,但是卻可以編譯過!

那么,問題來了!

為何在C 中使用pow函數(shù)不需要手動指定鏈接數(shù)學(xué)庫libm,而C里面卻需要呢?

為了解答這個問題,我們必須知道C 的程序中,到底有沒有鏈接libm庫。如何查看呢?還記得在《linux常用命令-開發(fā)調(diào)試篇》中提到的ldd嗎?它可以查看當(dāng)前程序鏈接了哪些動態(tài)庫:

$?ldd?test
????linux-vdso.so.1?=>??(0x00007ffd41bda000)
????libstdc .so.6?=>?/usr/lib/x86_64-linux-gnu/libstdc .so.6?(0x00007f6230cca000)
????libm.so.6?=>?/lib/x86_64-linux-gnu/libm.so.6?(0x00007f62309c1000)
????libc.so.6?=>?/lib/x86_64-linux-gnu/libc.so.6?(0x00007f62305f7000)
????/lib64/ld-linux-x86-64.so.2?(0x00007f623104c000)
????libgcc_s.so.1?=>?/lib/x86_64-linux-gnu/libgcc_s.so.1?(0x00007f62303e1000)
看到?jīng)]有,除了鏈接了最基本的libstdc 庫,還鏈接了libc和libm庫!也就是說,雖然沒有手動指定鏈接,但是實際上還是鏈接了。但是這是什么時候鏈接上的呢?

我們再看libstdc 的鏈接庫發(fā)現(xiàn):

$?ldd?/usr/lib32/libstdc .so.6
????linux-gate.so.1?=>??(0xf7f92000)
????libm.so.6?=>?/lib/i386-linux-gnu/libm.so.6?(0xf7da6000)
????libc.so.6?=>?/lib/i386-linux-gnu/libc.so.6?(0xf7bf0000)
????/lib/ld-linux.so.2?(0xf7f94000)
????libgcc_s.so.1?=>?/lib/i386-linux-gnu/libgcc_s.so.1?(0xf7bd3000)
看見沒有!原來是libstdc 已經(jīng)鏈接了libm庫,這也就解釋了為什么C 代碼中不需要手動指定鏈接數(shù)學(xué)庫libm。

總結(jié):

通過前面的內(nèi)容我們總結(jié)如下:

  • C代碼編譯時,通常會默認鏈接libc庫

  • C 代碼編譯時,通常會默認鏈接libstdc 庫

  • 由于libstdc 中有依賴一些數(shù)學(xué)函數(shù)或者libc庫中的函數(shù),因此默認鏈接了libc庫和libm庫。



作者:守望先生來源:編程珠璣版權(quán)歸原作者所有,如有侵權(quán),請聯(lián)系刪除。

21ic電子網(wǎng)

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀
關(guān)閉