亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語言中的鏈接編寫教程

 更新時(shí)間:2015年08月10日 11:19:59   作者:zinss26914  
這篇文章主要介紹了C語言中的鏈接編寫教程,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下

鏈接
  鏈接就是將不同部分的代碼和數(shù)據(jù)收集和組合成為一個(gè)單一文件的過程,這個(gè)文件可被加載或拷貝到存儲(chǔ)器執(zhí)行.
  鏈接可以執(zhí)行與編譯時(shí)(源代碼被翻譯成機(jī)器代碼時(shí)),也可以執(zhí)行與加載時(shí)(在程序被加載器加載到存儲(chǔ)器并執(zhí)行時(shí)),甚至執(zhí)行與運(yùn)行時(shí),由應(yīng)用程序來執(zhí)行.在現(xiàn)代系統(tǒng)中,鏈接是由鏈接器自動(dòng)執(zhí)行的.
  鏈接器分為:靜態(tài)鏈接器和動(dòng)態(tài)鏈接器兩種.
靜態(tài)鏈接器
  靜態(tài)鏈接器以一組可重定位目標(biāo)文件和命令行參數(shù)作為輸入,生成一個(gè)完全鏈接的可以加載和運(yùn)行的可執(zhí)行目標(biāo)文件作為輸出.

  靜態(tài)鏈接器主要完成兩個(gè)任務(wù):
  1>符號(hào)解析:目標(biāo)文件定義和引用符號(hào).符號(hào)解析的目的在于將每個(gè)符號(hào)引用和一個(gè)符號(hào)定義聯(lián)系起來.
  2>重定位:編譯器和匯編器生成從地址零開始的代碼和數(shù)據(jù)節(jié).鏈接器通過把每個(gè)符號(hào)定義和一個(gè)存儲(chǔ)器位置聯(lián)系起來,然后修改所有對(duì)這些符號(hào)的引用,使得他們執(zhí)行這個(gè)存儲(chǔ)位置,從而重定位這些節(jié).

  目標(biāo)文件:
  目標(biāo)文件有三種形式:
  1>可重定位的目標(biāo)文件:
  包含二進(jìn)制代碼和數(shù)據(jù),其形式可以再編譯時(shí)與其他可定位目標(biāo)文件合并起來,創(chuàng)建一個(gè)可執(zhí)行目標(biāo)文件.
  2>可執(zhí)行目標(biāo)文件:
  包含二進(jìn)制代碼和數(shù)據(jù),其形式可以被直接拷貝到存儲(chǔ)器并執(zhí)行.
  3>共享目標(biāo)文件:
  一種特殊的可重定位目標(biāo)文件,可以再加載或運(yùn)行時(shí),被動(dòng)態(tài)地夾在到存儲(chǔ)器并執(zhí)行.
  編譯器和匯編器生成可重定位目標(biāo)文件(包括共享目標(biāo)文件),鏈接器生成可執(zhí)行目標(biāo)文件.

  可重定位目標(biāo)文件:
  EF頭L以一個(gè)16字節(jié)的序列開始,這個(gè)序列描述了字的大小和生成該文件的系統(tǒng)字節(jié)順序.ELF頭剩下的部分包含幫助鏈接器解析和解釋目標(biāo)文件的信息.其中包括ELF頭的大小,目標(biāo)文件的類型(比如,可重定位,可執(zhí)行,共享目標(biāo)文件),機(jī)器類型,節(jié)頭部表的文件偏移,以及節(jié)頭部表中的表目大小和數(shù)量.不同節(jié)的位置和大小是節(jié)頭部表描述的,其中目標(biāo)文件中的每個(gè)節(jié)都有一個(gè)固定大小的表目.ELF格式的可重定位目標(biāo)文件結(jié)構(gòu)如下圖:

2015810110408527.jpg (278×310)

.text:已編譯程序的機(jī)器代碼
.rodata:只讀數(shù)據(jù)
.data:已初始化的全局C變量
.bss:未初始化的全局C變量.在目標(biāo)文件中這個(gè)節(jié)不占實(shí)際空間,僅是一個(gè)占位符.
.sysmtab:一個(gè)符號(hào)表,存放在程序中被定義和引用的函數(shù)和全局變量的信息.
.rel.text:當(dāng)鏈接器把這個(gè)目標(biāo)文件和其他文件結(jié)合時(shí),.text節(jié)中的許多位置都需要修改.一般而言,任何調(diào)用外部函數(shù)或者引用全局變量的指令都要修改.另一個(gè)方面,調(diào)用本地函數(shù)的指令則不需要修改.
.rel.data:被模塊定義或引用的任何全局變量的信息.
.debug:一個(gè)調(diào)試符號(hào)表
.line:原始C源程序中的行號(hào)和.text節(jié)中機(jī)器指令之間的映射.
.strtab:一個(gè)字符串表,其中內(nèi)容包括.symtab和.debug節(jié)中的符號(hào)表,以及節(jié)頭部中的節(jié)名字.

 

  符號(hào)和符號(hào)表
  每個(gè)可重定位目標(biāo)模塊m都有一個(gè)符號(hào)表,它包含m所定義和引用的符號(hào)的信息.在鏈接器上下文中,有三種不同的符號(hào):
  1>由m定義并能被其他模塊引用的全局符號(hào).全局鏈接器符號(hào)對(duì)應(yīng)于非靜態(tài)的C函數(shù)以及被定義為不帶C的static屬性的全局變量.
  2>由其他模塊定義并被模塊m引用的全局符號(hào).這些符號(hào)成為外部符號(hào),對(duì)應(yīng)于定義在其他模塊中的C函數(shù)和變量.
  3>只被模塊m定義和引用的本地符號(hào).有的本地符號(hào)鏈接器符號(hào)對(duì)應(yīng)于帶static屬性的C函數(shù)和全局變量.這些符號(hào)在模塊m中的任何地方都可見,但是不能被其他模塊引用.目標(biāo)文件中對(duì)應(yīng)于模塊m的節(jié)和相應(yīng)的源文件的名字也能獲得本地符號(hào).

  符號(hào)表式有匯編器構(gòu)造的,使用編譯器輸出到匯編語言.s文件中的符號(hào).sysmab節(jié)中包含ELF符號(hào)表.這張符號(hào)表包含一個(gè)關(guān)于表目的數(shù)組.表目的格式如下:

typedef struct{
 int name; //string table offset
 int value; //section offset, or VM address
 int size; //object size in bytes
 char type:4, //data, func, section, or src file
    binding:4; //local or global
 char reserved; //unused
 char section; //section header index, ABS, UNDEF, or COMMON
}Elf_Symbol;

符號(hào)解析
  鏈接器解析符號(hào)引用的方法是將每個(gè)引用和它輸入的可重定位目標(biāo)文件按的符號(hào)表中的一個(gè)確定的符號(hào)定義聯(lián)系起來.
  對(duì)于那些和引用定義在相同模塊的本地符號(hào)的引用,符號(hào)解析式非常簡單明了的.編譯器只允許每個(gè)模塊中的每個(gè)本地符號(hào)只有一個(gè)定義.編譯器還確保靜態(tài)本地變量,它們會(huì)有本地鏈接器符號(hào),擁有唯一的名字.
  對(duì)于全局符號(hào)的引用解析,當(dāng)編譯器遇到一個(gè)不是在當(dāng)前模塊中定義的符號(hào)(變量或函數(shù)名)時(shí),它會(huì)假設(shè)該符號(hào)式在其他某個(gè)模塊中定義的,生成一個(gè)鏈接器符號(hào)表表目,并把它交給鏈接器處理.如果鏈接器在它的任何輸入模塊中都找不到這個(gè)被引用的符號(hào),它就輸出一條錯(cuò)誤信息并終止.
  在編譯時(shí),編譯器輸出的每個(gè)全局符號(hào)給匯編器,或者是強(qiáng),或者是弱,而匯編器把這個(gè)信息隱含地編碼在可重定位目標(biāo)文件的符號(hào)表中.函數(shù)和以初始化的全局變量是強(qiáng)符號(hào),未初始化的全局變量是弱符號(hào).
  根據(jù)符號(hào)的強(qiáng)弱,有如下規(guī)則:
  1>不允許有多個(gè)強(qiáng)符號(hào)
  2>如果有一個(gè)強(qiáng)符號(hào)和多個(gè)弱符號(hào),則選擇強(qiáng)符號(hào)
  3>如果有多個(gè)弱符號(hào),則任選一個(gè)弱符號(hào)

  與靜態(tài)庫鏈接
  所有編譯系統(tǒng)都提供一種機(jī)制,將所有相關(guān)的目標(biāo)模塊打包為一個(gè)單獨(dú)的文件,稱為靜態(tài)庫,它可以用做鏈接器的輸入.當(dāng)鏈接器構(gòu)造一個(gè)輸出的可執(zhí)行文件時(shí),它只拷貝靜態(tài)庫里被應(yīng)用程序引用的目標(biāo)模塊.
  在unix系統(tǒng)中,靜態(tài)庫以一種稱為存檔的特殊文件格式存放在磁盤中.存檔文件是一組連接起來的可重定位目標(biāo)文件的集合,有一個(gè)頭部描述每個(gè)成員目標(biāo)文件的大小和位置.

  鏈接器如何使用靜態(tài)庫來解析引用
  在符號(hào)解析階段,鏈接器從左到右按照它們?cè)诰幾g驅(qū)動(dòng)程序命令行上出現(xiàn)的相同順序來掃描可重定位目標(biāo)文件和存檔文件.在這次掃描中,鏈接器位置一個(gè)可重定位目標(biāo)文件集合E,這個(gè)集合中的文件會(huì)被合并起來形成可執(zhí)行文件,和一個(gè)未解析的符號(hào)集合U,以及一個(gè)在前面輸入文件中已定義的符號(hào)結(jié)合D.初始時(shí),E,U,D都是空的.
  1>對(duì)于命令行上的每個(gè)輸入文件f,鏈接器會(huì)判斷f是一個(gè)目標(biāo)文件還是一個(gè)存檔文件.如果是一個(gè)目標(biāo)文件,那么鏈接器把f添加到E,修改U和D來反映f中的符號(hào)定義和引用,并繼續(xù)下一個(gè)輸入文件.
  2>如果f是一個(gè)存檔文件,那么鏈接器就嘗試匹配U中未解析的符號(hào)由存檔文件成員定義的符號(hào).如果某個(gè)存檔文件成員m,定義了一個(gè)符號(hào)來解析U中的一個(gè)引用,那么就將m加到E中,并且鏈接器修改U和D來反映m中的符號(hào)定義和引用.對(duì)存檔文件中的所有成員目標(biāo)文件都反復(fù)進(jìn)行這個(gè)過程,知道U和D都不再發(fā)生變化.在此時(shí),任何不包含在E中的成員目標(biāo)文件都會(huì)被丟棄,而鏈接器將繼續(xù)到下一個(gè)輸入文件.
  3>如果當(dāng)鏈接器完成對(duì)輸入命令行的掃描后,U是非空的,那么鏈接器就會(huì)輸出一個(gè)錯(cuò)誤并終止.否則,它會(huì)合并重定位E中的目標(biāo)文件,從而構(gòu)建輸出的可執(zhí)行文件.

  這種方式,導(dǎo)致了在輸入命令時(shí)要考慮到,靜態(tài)庫和目標(biāo)文件的位置,庫文件放在目標(biāo)文件的后面,如果庫文件之間有引用關(guān)系,則被引用的庫放在后面.

重定位
  當(dāng)鏈接器完成了符號(hào)解析這一步時(shí),它就把代碼中的每個(gè)符號(hào)引用和確定的一個(gè)符號(hào)定義(也就是,它的一個(gè)輸入目標(biāo)模塊中的一個(gè)符號(hào)表表目)聯(lián)系起來.此時(shí),鏈接器就知道它的輸入目標(biāo)模塊中的代碼節(jié)和數(shù)據(jù)解的確切大小.然后就開始重定位步驟.重定位由兩步組成:
  1>重定位節(jié)和符號(hào)定義:
  在這一步中,鏈接器將所有相同類型的節(jié)合并為一個(gè)新的聚合節(jié).然后,鏈接器將運(yùn)行時(shí)存儲(chǔ)器地址賦值給新的聚合節(jié),賦給輸入模塊定義的每個(gè)節(jié),以及賦給輸入模塊定義的每個(gè)符號(hào).當(dāng)這一步完成時(shí),程序中的每個(gè)指令和全局變量都一個(gè)唯一的運(yùn)行時(shí)存儲(chǔ)器地址.
  2>重定位節(jié)中的符號(hào)引用:
  在這一步中,鏈接器修改代碼節(jié)和數(shù)據(jù)節(jié)中對(duì)每個(gè)符號(hào)的引用,使得它們指向正確的運(yùn)行時(shí)地址.為了執(zhí)行這一步,鏈接器依賴于稱為重定位表目的可重定位目標(biāo)模塊中的數(shù)據(jù)結(jié)構(gòu).

  重定位表目:
  當(dāng)匯編器生成一個(gè)目標(biāo)模塊時(shí),它并不知道數(shù)據(jù)和代碼最終將存放在存儲(chǔ)器中的什么位置.它也不知道這個(gè)模塊引用的任何外部定義的函數(shù)或者全局變量的位置.所以,無論何時(shí)匯編器遇到對(duì)最終位置未知的目標(biāo)引用,它就會(huì)生成一個(gè)重定位表目,告訴鏈接器在將目標(biāo)文件合并為可執(zhí)行文件時(shí),如何修改這個(gè)引用.代碼的重定位表目放在.rel.text中.已初始化數(shù)據(jù)的重定位表目放在rel.data中.
  ELF重定位表目的格式如下:
  typedef struct{
    int offset;  //offset of the reference to relocate
    int symbol:24,  //symbol the reference point to
        type:8;  //relocation type
  } Elf32_Rel;

  ELF定義了11中不同的重定位類型,其中最基本的兩種重定位類型是:R_386_PC32(重定位一個(gè)使用32PC相關(guān)的地址引用)和R_386_32(重定位一個(gè)使用32位絕對(duì)地址的引用).

動(dòng)態(tài)鏈接器
  共享庫是一個(gè)目標(biāo)模塊,在運(yùn)行時(shí),可以加載到任意的存儲(chǔ)器地址,并在存儲(chǔ)器中和一個(gè)程序鏈接起來.這個(gè)過程稱為動(dòng)態(tài)鏈接,是由動(dòng)態(tài)鏈接器完成的.
  共享庫的共享在兩個(gè)方面有所不同.首先,在任何給定的文件系統(tǒng)中,對(duì)于一個(gè)庫只有一個(gè).so文件.所有引用該庫德可執(zhí)行目標(biāo)文件共享這個(gè).so文件中的代碼和數(shù)據(jù),而不是像靜態(tài)庫德內(nèi)容那樣被拷貝和嵌入到引用它們的可執(zhí)行的文件中.其次,在存儲(chǔ)器中,一個(gè)共享庫的.text節(jié)只有一個(gè)副本可以被不同的正在運(yùn)行的進(jìn)程共享.

  多目標(biāo)文件的鏈接
stack.c

   

#include <stdio.h> 
   
  #define STACKSIZE 1000 
   
  typedef struct stack { 
    int data[STACKSIZE]; 
    int top; 
  } stack; 
   
  stack s; 
  int count = 0; 
   
  void pushStack(int d) 
  { 
    s.data[s.top ++] = d; 
    count ++; 
  } 
   
  int popStack() 
  { 
    return s.data[-- s.top]; 
  } 
   
  int isEmpty() 
  { 
    return s.top == 0; 
  } 


link.c

 

  #include <stdio.h> 
   
  int a, b; 
   
  int main() 
  { 
    a = b = 1; 
   
    pushStack(a); 
    pushStack(b); 
    pushStack(a); 
   
    while (! isEmpty()) { 
      printf("%d\n", popStack()); 
    } 
     
    return 0; 
  } 


編譯方式:

gcc -Wall stack.c link.c -o main

提示出錯(cuò)信息如下:

2015810110529983.png (828×104)

但是代碼是可以執(zhí)行的

定義和聲明

static和extern修飾函數(shù)
上述編譯出現(xiàn)錯(cuò)誤的原因是:編譯器在處理函數(shù)調(diào)用代碼時(shí)沒有找到函數(shù)原型,只好根據(jù)函數(shù)調(diào)用代碼做隱式聲明,把這三個(gè)函數(shù)聲明為:

  int pushStack(int); 
  int popStack(void); 
  int isEmpty(void); 


編譯器往往不知道去哪里找函數(shù)定義,像上面的例子,我讓編譯器編譯main.c,而這幾個(gè)函數(shù)定義卻在stack.c里,編譯器無法知道,因此可以用extern聲明。修改link.c如下:

 

  #include <stdio.h> 
   
  int a, b; 
   
  extern void pushStack(int d); 
  extern int popStack(void); 
  extern int isEmpty(void); 
   
  int main() 
  { 
    a = b = 1; 
   
    pushStack(a); 
    pushStack(b); 
    pushStack(a); 
   
    while (! isEmpty()) { 
      printf("%d\n", popStack()); 
    } 
     
    return 0; 
  } 


這樣編譯器就不會(huì)報(bào)警了。這里extern關(guān)鍵字表示這個(gè)標(biāo)識(shí)符具有External Linkage.pushStack這個(gè)標(biāo)識(shí)符具有External Linkage指的是:如果link.c和stack.c鏈接在一起,如果pushStack在link.c和stack.c中都聲明(在stack.c中的聲明同時(shí)也是定義),那么這些聲明指的是同一個(gè)函數(shù),鏈接后是同一個(gè)GLOBAL符號(hào),代表同一個(gè)地址。函數(shù)聲明中的extern可以省略不寫,不屑extern的函數(shù)聲明也表示這個(gè)函數(shù)具有External Linkage。

如果用static關(guān)鍵字修飾一個(gè)函數(shù)聲明,則表示該標(biāo)識(shí)符具有Internal Linkage,例如有以下兩個(gè)程序文件:

  /* foo.c */ 
   
  static void foo(void) {} 


  /*main.c*/ 
   
  void foo(void); 
   
  int main(void) { foo(); return 0;} 


編譯鏈接在一起會(huì)出錯(cuò),原因是:

雖然在foo.c中定義了函數(shù)foo,但是這個(gè)函數(shù)是static屬性,只具有internal Linkage。如果把foo.c編譯成目標(biāo)文件,函數(shù)名foo在其中是一個(gè)LOCAL的符號(hào),不參與鏈接過程,所以在鏈接時(shí),main.c中用到一個(gè)External Linkage的foo函數(shù),鏈接器卻找不到它的定義在哪,無法確定它的地址,也就無法做符號(hào)解析,只好報(bào)錯(cuò)。

凡是被多次聲明的變量或函數(shù),必須有且只有一個(gè)聲明是定義,如果有多個(gè)定義,或者一個(gè)定義都沒有,鏈接器就無法完成鏈接


static和extern修飾變量
如果我想在link.c中訪問stack.c中定義的int變量count,則可以用extern聲明

  

 #include <stdio.h> 
   
  int a, b; 
   
  extern void pushStack(int d); 
  extern int popStack(void); 
  extern int isEmpty(void); 
  extern int count; 
   
  int main() 
  { 
    a = b = 1; 
   
    pushStack(a); 
    pushStack(b); 
    pushStack(a); 
   
    printf("%d\n", count); 
   
    while (! isEmpty()) { 
      printf("%d\n", popStack()); 
    } 
     
    return 0; 
  } 


變量count具有external linkage,它的存儲(chǔ)空間是在stack.c中分配的,所以link.c中的變量聲明extern int count;不是變量定義,因?yàn)樗环峙浯鎯?chǔ)空間。

如果不想在stack.c外讓外界訪問到count,則可以用static關(guān)鍵字將count聲明為Internal Linkage
區(qū)別
變量生命和函數(shù)聲明有一點(diǎn)不同,函數(shù)聲明的extern可寫可不寫,而變量聲明如果不寫extern,意思就完全變了。如果上面的例子不寫extern就表示在main函數(shù)中定義一個(gè)全局變量count。

用static關(guān)鍵字聲明具有Internal Linkage的函數(shù)和關(guān)鍵字是處于保護(hù)內(nèi)部狀態(tài)的目的,也是一種封裝(Encapsulation)的思想。一個(gè)模塊中,有些函數(shù)是提供給外界使用的,也稱為導(dǎo)出(Export)給外界使用,這些函數(shù)用extern聲明為External Linkage的。


頭文件
為了防止每次函數(shù)extern聲明,例如又有一個(gè)foo.c也使用pushStack等函數(shù),又需要在foo.c中寫多個(gè)extern聲明,為了避免這種重復(fù)麻煩的操作,可以自己定義一個(gè)stack.h頭文件:

  

 #ifndef STACK_H 
  #define STACK_H 
   
  #define STACKSIZE 1000 
   
  typedef struct stack { 
    int data[STACKSIZE]; 
    int top; 
  } stack; 
   
  extern void pushStack(int d); 
  extern int popStack(void); 
  extern int isEmpty(void); 
   
  #endif 


這樣,在link.c里就只需要包含這個(gè)頭文件就可以了,而不需要寫三個(gè)函數(shù)聲明了:

   

 #include <stdio.h> 
  #include "stack.h" 
   
  int a, b; 
   
  extern int count; 
   
  int main() 
  { 
    a = b = 1; 
   
    pushStack(a); 
    pushStack(b); 
    pushStack(a); 
   
    printf("%d\n", count); 
   
    while (! isEmpty()) { 
      printf("%d\n", popStack()); 
    } 
     
    return 0; 
  } 


為什么#include <stdio.h>用角括號(hào),而#include "stack.h"用引號(hào)?原因:

  •     對(duì)于用角括號(hào)包含的頭文件,gcc首先查找-I選項(xiàng)指定的目錄,然后查找系統(tǒng)的頭文件目錄(通常是/usr/include)
  •     對(duì)于用“”包含的頭文件,gcc首先查找包含頭文件的.c文件所在的目錄,然后查找-I選項(xiàng)指定的目錄,然后查找系統(tǒng)的頭文件目錄


用#ifndef #define #endif是為了防止頭文件的重復(fù)包含,頭文件重復(fù)包含的問題如下:

  •     使預(yù)處理的速度變慢了,要處理很多本來不需要處理的頭文件
  •     如果a.h包含了b.h,然后b.h又包含了a.h的情況,預(yù)處理就陷入死循環(huán)了
  •     頭文件按有些代碼不允許重復(fù)出現(xiàn)


頭文件中的變量和函數(shù)聲明一定不能是定義。如果頭文件中出現(xiàn)變量或函數(shù)定義,這個(gè)頭文件又被多個(gè).c文件包含,那么這些.c文件就不能鏈接在一起

 

 

相關(guān)文章

  • 基于C語言實(shí)現(xiàn)簡易的掃雷游戲

    基于C語言實(shí)現(xiàn)簡易的掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了基于C語言實(shí)現(xiàn)簡易的掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Qt?QString的使用實(shí)現(xiàn)

    Qt?QString的使用實(shí)現(xiàn)

    本文主要介紹了Qt?QString的使用實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Qt控件之QPushButton使用及技巧

    Qt控件之QPushButton使用及技巧

    QPushButton類是Qt中用于創(chuàng)建按鈕的控件類,它繼承自QAbstractButton類,本文就來介紹一下Qt控件之QPushButton使用及技巧,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • Qt5實(shí)現(xiàn)qDebug日志信息寫入日志文件過程

    Qt5實(shí)現(xiàn)qDebug日志信息寫入日志文件過程

    這篇文章主要為大家介紹了Qt5實(shí)現(xiàn)qDebug日志信息寫入日志文件的過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 使用CMake構(gòu)建一個(gè)簡單的C++項(xiàng)目的實(shí)現(xiàn)

    使用CMake構(gòu)建一個(gè)簡單的C++項(xiàng)目的實(shí)現(xiàn)

    CMake是一個(gè)跨平臺(tái)的自動(dòng)化構(gòu)建工具,可以用于構(gòu)建各種類型的項(xiàng)目,本文主要介紹了使用CMake構(gòu)建一個(gè)簡單的C++項(xiàng)目,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • C語言改造通訊錄操作詳解

    C語言改造通訊錄操作詳解

    這篇文章主要介紹了C語言文件操作改造通訊錄方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-01-01
  • C語言二叉樹層序遍歷

    C語言二叉樹層序遍歷

    這篇文章主要介紹了C語言二叉樹層序遍歷,文章基于C語言的相關(guān)資料展開詳細(xì)的文章內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-04-04
  • C數(shù)據(jù)結(jié)構(gòu)中串簡單實(shí)例

    C數(shù)據(jù)結(jié)構(gòu)中串簡單實(shí)例

    這篇文章主要介紹了C數(shù)據(jù)結(jié)構(gòu)中串簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Vscode搭建遠(yuǎn)程c開發(fā)環(huán)境的圖文教程

    Vscode搭建遠(yuǎn)程c開發(fā)環(huán)境的圖文教程

    很久沒有寫C語言了,今天抽空學(xué)習(xí)下C語言知識(shí),接下來通過本文給大家介紹Vscode搭建遠(yuǎn)程c開發(fā)環(huán)境的詳細(xì)步驟,本文通過圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-11-11
  • C++ 關(guān)于MFC多線程編程的注意事項(xiàng)

    C++ 關(guān)于MFC多線程編程的注意事項(xiàng)

    這篇文章主要介紹了C++ 關(guān)于MFC多線程編程的注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下
    2015-06-06

最新評(píng)論