欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

老生常談C語言靜態(tài)函數(shù)庫的制作和使用

 更新時間:2016年08月26日 10:02:06   投稿:jingxian  
下面小編就為大家?guī)硪黄仙U凜語言靜態(tài)函數(shù)庫的制作和使用。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

C語言的函數(shù)庫是多組經(jīng)過驗證的常用函數(shù)的集合,編寫C語言程序時使用庫函數(shù),既可以提高程序運行效率,又可以提高編程質(zhì)量,使用方法如#include 和#include。

根據(jù)使用庫函數(shù)時,函數(shù)庫加載時機的差異,將函數(shù)庫分為靜態(tài)函數(shù)庫和動態(tài)函數(shù)庫,具體差異是:C語言程序如果使用靜態(tài)函數(shù)庫的函數(shù),那么整個函數(shù)庫的代碼都會和C語言程序一起編譯成可執(zhí)行代碼,程序的體積會膨脹;如果使用動態(tài)函數(shù)庫的函數(shù),則C語言程序只會和函數(shù)庫文件名以及函數(shù)名一起編譯成可執(zhí)行代碼(不編譯函數(shù)代碼),運行時去查找函數(shù)庫文件和函數(shù)體,程序的體積基本不變。

簡單概括就是,靜態(tài)函數(shù)庫是“以空間換時間”,增加程序體積,減少運行時間,如果靜態(tài)函數(shù)庫發(fā)生改變,則整個程序必須重新編譯,因為函數(shù)庫被整合到了最終可執(zhí)行代碼中;動態(tài)函數(shù)庫則是“以時間換空間”,增加運行時間,減少程序體積,如果動態(tài)函數(shù)庫發(fā)生改變,程序無須重新編譯,因為函數(shù)庫沒有整合到最終可執(zhí)行代碼中。

Linux中靜態(tài)函數(shù)庫表示為”libxxx.a”,windows中后綴名為”.lib”;Linux中動態(tài)函數(shù)庫表示為”libxxx.so”,windows中后綴名為”.dll”。函數(shù)庫中存放內(nèi)容包括:(1)函數(shù)名稱,(2)函數(shù)目標代碼(二進制),(3)重定位信息(鏈接需要)等。

1 靜態(tài)函數(shù)庫的制作和使用

靜態(tài)函數(shù)庫的制作步驟可以用下圖來描述,具體包括

(1)編寫函數(shù)的.c文件(例如add.c、sub.c、mul.c和div.c)

(2)編寫Makefile,然后make,實現(xiàn)函數(shù)的編譯和歸檔入庫

函數(shù)的編譯:使用gcc –c 只編譯不鏈接函數(shù).c文件,分別生成函數(shù)的目標文件(例如add.o、sub.o、mul.o和div.o)。

函數(shù)的歸檔入庫:使用ar -rc libxxx.a $(objects) 將目標文件歸檔入庫。

(3)編寫頭文件(例如ku.h),聲明靜態(tài)函數(shù)庫中的所有函數(shù),目的是kumain.c函數(shù)#include頭文件后,可以調(diào)用相應的函數(shù),至此,完成函數(shù)庫的制作。

1.1 靜態(tài)函數(shù)庫的制作示例

示例的內(nèi)容是建立靜態(tài)函數(shù)庫libstatic.a,庫中包括addsub、muldiv函數(shù),然后在kumain.c函數(shù)中引用這4個函數(shù),實現(xiàn)兩個整數(shù)的加減乘除,整個文件的結(jié)構(gòu)是

(1) 編寫函數(shù)的.c文件

編寫4個函數(shù)文件add.c、sub.c、mul.c和div.c

// add.c 
float add(int a, int b)
{
 return (a+b);
} 
 // sub.c 
float sub(int a, int b)
{
return (a-b);
} 
 // mul.c 
float mul(int a, int b)
{
return (a*b);
} 
 // div.c 
float div(int a, int b)
{
return (a/b);
} 

(2)編寫頭文件

// ku.h 
float add(int a, int b);
float sub(int a, int b);
float mul(int a, int b);
float div(int a, int b);

(3)編寫Makefile

### Makefile for static func lib 
objects = add.o sub.o mul.o div.o
 
libstatic.a : $(objects)
   ar -rc libstatic.a $(objects)

add.o : add.c
  gcc -c add.c

sub.o : sub.c
  gcc -c sub.c

mul.o : mul.c
  gcc -c mul.c

div.o : div.c
  gcc -c div.c

clean : 
  rm libstatic.a $(objects)

(4)使用make編譯.c文件,生成.o文件,歸檔.o文件到函數(shù)庫libstatic.a中,完成靜態(tài)函數(shù)庫的制作。

1.2 靜態(tài)函數(shù)庫的使用

(1)編寫kumain.c,調(diào)用libstatic.a中的add、sub、mul和div函數(shù)

// kumain.c 
#include <stdio.h>
#include "ku.h" 

int main (void)
{
int a,b;
a = 10;
b = 3;

printf("a = %d.\nb = %d.\n",a,b);
printf("static a+b = %f.\n",add(a,b));
printf("static a-b = %f.\n",sub(a,b));
printf("static a*b = %f.\n",mul(a,b));
printf("static a/b = %f.\n",div(a,b));

return 0;

}

(2)使用gcc kumain.c –o kumain.o –L ./ku2 –lstatic 編譯kumain.c文件,運行./kumain.o查看運行結(jié)果,成功。

1.3 使用nm查看kumain.o中的符號信息

nm命令是列出.o文件,.a文件和.so文件中的符號信息,如符號的值,符號類型及符號名稱等。符號通常指定義出的函數(shù),全局變量等。

使用 nm libstatic.a查看符號信息,得到

使用nm kumain.o >label.text查看kumain.o中的符號信息,得到

080484f9 T add
0804a020 B __bss_start
0804a020 b completed.6591
0804a018 D __data_start
0804a018 W data_start
t deregister_tm_clones
0804853c T div
080483e0 t __do_global_dtors_aux
08049f0c t __do_global_dtors_aux_fini_array_entry
0804a01c D __dso_handle
08049f14 d _DYNAMIC
0804a020 D _edata
0804a024 B _end
080485c4 T _fini
080485d8 R _fp_hw
t frame_dummy
08049f08 t __frame_dummy_init_array_entry
080487b8 r __FRAME_END__
0804a000 d _GLOBAL_OFFSET_TABLE_
     w __gmon_start__
080482cc T _init
08049f0c t __init_array_end
08049f08 t __init_array_start
080485dc R _IO_stdin_used
     w _ITM_deregisterTMCloneTable
     w _ITM_registerTMCloneTable
08049f10 d __JCR_END__
08049f10 d __JCR_LIST__
     w _Jv_RegisterClasses
080485c0 T __libc_csu_fini
T __libc_csu_init
     U __libc_start_main@@GLIBC_2.0
0804842d T main
T mul
     U printf@@GLIBC_2.0
080483a0 t register_tm_clones
T _start
0804850f T sub
0804a020 D __TMC_END__
T __x86.get_pc_thunk.bx

1.4 nm命令簡介

nm [option(s)] [file(s)]

有用的options:

-A 在每個符號信息的前面打印所在對象文件名稱;
-C 輸出demangle過了的符號名稱;
-D 打印動態(tài)符號;
-l 使用對象文件中的調(diào)試信息打印出所在源文件及行號;
-n 按照地址/符號值來排序;
-u 打印出那些未定義的符號;

常見的符號類型

A 該符號的值在今后的鏈接中將不再改變;

B 該符號放在BSS段中,通常是那些未初始化的全局變量;

D 該符號放在普通的數(shù)據(jù)段中,通常是那些已經(jīng)初始化的全局變量;

T 該符號放在代碼段中,通常是那些全局非靜態(tài)函數(shù);

U 該符號未定義過,需要自其他對象文件中鏈接進來;

W 未明確指定的弱鏈接符號;同鏈接的其他對象文件中有它的定義就用上,否則就用一個系統(tǒng)特別指定的默認值。

相關(guān)文章

  • C++類與對象的詳細說明

    C++類與對象的詳細說明

    這篇文章主要為大家詳細介紹了C++的類與對象,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C++實現(xiàn)二叉樹遍歷序列的求解方法

    C++實現(xiàn)二叉樹遍歷序列的求解方法

    這篇文章主要介紹了C++實現(xiàn)二叉樹遍歷序列的求解方法,需要的朋友可以參考下
    2014-08-08
  • 一文解密C++中的多態(tài)機制

    一文解密C++中的多態(tài)機制

    眾所周知C++語言的三大特性:封裝、多態(tài)、繼承,其中多態(tài)就是去完成某個行為,但是會根據(jù)不同的對象產(chǎn)生不同的狀態(tài),下面小編就來帶大家深入了解一下C++的多態(tài)機制吧
    2023-07-07
  • C++實現(xiàn)日期類的方法詳解

    C++實現(xiàn)日期類的方法詳解

    這篇文章主要給大家介紹了C++實現(xiàn)日期類的方法,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • C++簡明分析inline函數(shù)的使用

    C++簡明分析inline函數(shù)的使用

    inline是C++關(guān)鍵字,在函數(shù)聲明或定義中,函數(shù)返回類型前加上關(guān)鍵字inline,即可以把函數(shù)指定為內(nèi)聯(lián)函數(shù)。這樣可以解決一些頻繁調(diào)用的函數(shù)大量消耗??臻g(棧內(nèi)存)的問題
    2022-07-07
  • C++中Overload,Override,Hide之間的區(qū)別

    C++中Overload,Override,Hide之間的區(qū)別

    重載overload,這個概念是大家熟知的。在同一可訪問區(qū)內(nèi)被聲名的幾個具有不同參數(shù)列的(參數(shù)的類型、個數(shù)、順序不同)同名函數(shù),程序會根據(jù)不同的參數(shù)列來確定具體調(diào)用哪個函數(shù),這種機制就是重載
    2013-09-09
  • C++實現(xiàn)Dijkstra(迪杰斯特拉)算法

    C++實現(xiàn)Dijkstra(迪杰斯特拉)算法

    這篇文章主要為大家詳細介紹了C++實現(xiàn)Dijkstra(迪杰斯特拉)算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++ pair的用法實例詳解

    C++ pair的用法實例詳解

    這篇文章主要介紹了C++ pair的用法實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • C語言枚舉(enum)和聯(lián)合(union)實例分享

    C語言枚舉(enum)和聯(lián)合(union)實例分享

    在本篇文章里小編給大家整理了關(guān)于C語言枚舉(enum)和聯(lián)合(union)實例內(nèi)容,需要的朋友們可以學習下。
    2020-03-03
  • C語言實現(xiàn)的階乘,排列和組合實例

    C語言實現(xiàn)的階乘,排列和組合實例

    這篇文章主要介紹了C語言實現(xiàn)的階乘,排列和組合的方法,涉及C語言數(shù)學運算的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07

最新評論