gcc 與g++ 的使用_第1頁
gcc 與g++ 的使用_第2頁
gcc 與g++ 的使用_第3頁
gcc 與g++ 的使用_第4頁
gcc 與g++ 的使用_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、G+ 中文使用教程簡介     gcc and g+分別是GNU的c & c+編譯器gcc/g+在執(zhí)行編譯工作的時候,總共需要4步 1.預(yù)處理,生成.i的文件預(yù)處理器cpp 2.將預(yù)處理后的文件不轉(zhuǎn)換成匯編語言,生成文件.s編譯器egcs 3.有匯編變?yōu)槟繕舜a(機器代碼)生成.o的文件匯編器as 4.連接目標代碼,生成可執(zhí)行程序鏈接器ld 操作指南參數(shù)詳解 -x language filename 設(shè)定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根 據(jù)約定C語言的后綴名稱是.c的,而C+的后綴名是.C或者.cpp,如果 你很個性,決

2、定你的C代碼文件的后綴名是.pig 哈哈,那你就要用這 簡介     gcc and g+分別是GNU的c & c+編譯器gcc/g+在執(zhí)行編譯工作的時候,總共需要4步 1.預(yù)處理,生成.i的文件預(yù)處理器cpp 2.將預(yù)處理后的文件不轉(zhuǎn)換成匯編語言,生成文件.s編譯器egcs 3.有匯編變?yōu)槟繕舜a(機器代碼)生成.o的文件匯編器as 4.連接目標代碼,生成可執(zhí)行程序鏈接器ld 操作指南參數(shù)詳解 -x language filename 設(shè)定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根 據(jù)約定C語言的后綴名稱是.c的,而C+的后綴名

3、是.C或者.cpp,如果 你很個性,決定你的C代碼文件的后綴名是.pig 哈哈,那你就要用這 個參數(shù),這個參數(shù)對他后面的文件名都起作用,除非到了下一個參數(shù) 的使用。 可以使用的參數(shù)嗎有下面的這些 c', objective-c', c-header', c+', cpp-output', assembler', and assembler-with-cpp'. 看到英文,應(yīng)該可以理解的。 例子用法: gcc -x c hello.pig -x none filename 關(guān)掉上一個選項,也就是讓gcc根據(jù)文件名后綴,自動識別文件類型 例子

4、用法: gcc -x c hello.pig -x none hello2.c -c 只激活預(yù)處理,編譯,和匯編,也就是他只把程序做成obj文件 例子用法: gcc -c hello.c 他將生成.o的obj文件 -S 只激活預(yù)處理和編譯,就是指把文件編譯成為匯編代碼。 例子用法 gcc -S hello.c 他將生成.s的匯編代碼,你可以用文本編輯器察看 -E 只激活預(yù)處理,這個不生成文件,你需要把它重定向到一個輸出文件里 面. 例子用法: gcc -E hello.c > pianoapan.txt gcc -E hello.c | more 慢慢看吧,一個hello word 也要

5、與處理成800行的代碼 -o 制定目標名稱,缺省的時候,gcc 編譯出來的文件是a.out,很難聽,如果 你和我有同感,改掉它,哈哈 例子用法 gcc -o hello.exe hello.c (哦,windows用習(xí)慣了) gcc -o hello.asm -S hello.c -pipe 使用管道代替編譯中臨時文件,在使用非gnu匯編工具的時候,可能有些問 題 gcc -pipe -o hello.exe hello.c -ansi 關(guān)閉gnu c中與ansi c不兼容的特性,激活ansi c的專有特性(包括禁止一 些asm inline typeof關(guān)鍵字,以及UNIX,vax等預(yù)處理宏

6、, -fno-asm 此選項實現(xiàn)ansi選項的功能的一部分,它禁止將asm,inline和typeof用作 關(guān)鍵字。 -fno-strict-prototype 只對g+起作用,使用這個選項,g+將對不帶參數(shù)的函數(shù),都認為是沒有顯式 的對參數(shù)的個數(shù)和類型說明,而不是沒有參數(shù). 而gcc無論是否使用這個參數(shù),都將對沒有帶參數(shù)的函數(shù),認為城沒有顯式說 明的類型 -fthis-is-varialble 就是向傳統(tǒng)c+看齊,可以使用this當(dāng)一般變量使用. -fcond-mismatch 允許條件表達式的第二和第三參數(shù)類型不匹配,表達式的值將為void類型 -funsigned-char -fno-s

7、igned-char -fsigned-char -fno-unsigned-char 這四個參數(shù)是對char類型進行設(shè)置,決定將char類型設(shè)置成unsigned char(前 兩個參數(shù))或者 signed char(后兩個參數(shù)) -include file 包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時候,就可以 用它設(shè)定,功能就相當(dāng)于在代碼中使用#include<filename> 例子用法: gcc hello.c -include /root/pianopan.h -imacros file 將file文件的宏,擴展到gcc/g+的輸入文件,宏定義本身并不出

8、現(xiàn)在輸入文件 中 -Dmacro 相當(dāng)于C語言中的#define macro -Dmacro=defn 相當(dāng)于C語言中的#define macro=defn -Umacro 相當(dāng)于C語言中的#undef macro -undef 取消對任何非標準宏的定義 -Idir 在你是用#include"file"的時候,gcc/g+會先在當(dāng)前目錄查找你所制定的頭 文件,如果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他 回先在你所制定的目錄查找,然后再按常規(guī)的順序去找. 對于#include<file>,gcc/g+會到-I制定的目錄查找,查找不到,然后將

9、到系 統(tǒng)的缺省的頭文件目錄查找 -I- 就是取消前一個參數(shù)的功能,所以一般在-Idir之后使用 -idirafter dir 在-I的目錄里面查找失敗,講到這個目錄里面查找. -iprefix prefix -iwithprefix dir 一般一起使用,當(dāng)-I的目錄查找失敗,會到prefix+dir下查找 -nostdinc 使編譯器不再系統(tǒng)缺省的頭文件目錄里面找頭文件,一般和-I聯(lián)合使用,明確 限定頭文件的位置 -nostdin C+ 規(guī)定不在g+指定的標準路經(jīng)中搜索,但仍在其他路徑中搜索,.此選項在創(chuàng)建 libg+庫使用 -C 在預(yù)處理的時候,不刪除注釋信息,一般和-E使用,有時候分析程

10、序,用這個很 方便的 -M 生成文件關(guān)聯(lián)的信息。包含目標文件所依賴的所有源代碼 你可以用gcc -M hello.c來測試一下,很簡單。 -MM 和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關(guān)系。 -MD 和-M相同,但是輸出將導(dǎo)入到.d的文件里面 -MMD 和-MM相同,但是輸出將導(dǎo)入到.d的文件里面 -Wa,option 此選項傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選 項,然后傳遞給會匯編程序 -Wl.option 此選項傳遞option給連接程序;如果option中間有逗號,就將option分成多個選 項,然

11、后傳遞給會連接程序. -llibrary 制定編譯的時候使用的庫 例子用法 gcc -lcurses hello.c 使用ncurses庫編譯程序 -Ldir 制定編譯的時候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然 編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。 -O0 -O1 -O2 -O3 編譯器的優(yōu)化選項的4個級別,-O0表示沒有優(yōu)化,-O1為缺省值,-O3優(yōu)化級別最 高 -g 只是編譯器,在編譯的時候,產(chǎn)生調(diào)試信息。 -gstabs 此選項以stabs格式聲稱調(diào)試信息,但是不包括gdb調(diào)試信息. -gstabs+ 此選項以stabs格式聲稱調(diào)試信息,并且包含僅供g

12、db使用的額外調(diào)試信息. -ggdb 此選項將盡可能的生成gdb的可以使用的調(diào)試信息. -static 此選項將禁止使用動態(tài)庫,所以,編譯出來的東西,一般都很大,也不需要什么 動態(tài)連接庫,就可以運行. -share 此選項將盡量使用動態(tài)庫,所以生成文件比較小,但是需要系統(tǒng)由動態(tài)庫. -traditional 試圖讓編譯器支持傳統(tǒng)的C語言特性 GNU 的調(diào)試器稱為 gdb,該程序是一個交互式工具,工作在字符模式。在 X Window 系統(tǒng)中,有一個 gdb 的 前端圖形工具,稱為 xxgdb。gdb 是功能強大的調(diào)試程序,可完成如下的調(diào)試任務(wù): * 設(shè)置斷點; * 監(jiān)視程序變量的值; * 程序的

13、單步執(zhí)行; * 修改變量的值。 在可以使用 gdb 調(diào)試程序之前,必須使用 -g 選項編譯源文件??稍?makefile 中如下定義 CFLAGS 變量: CFLAGS = -g 運行 gdb 調(diào)試程序時通常使用如下的命令: gdb progname 在 gdb 提示符處鍵入help,將列出命令的分類,主要的分類有: * aliases:命令別名 * breakpoints:斷點定義; * data:數(shù)據(jù)查看; * files:指定并查看文件; * internals:維護命令; * running:程序執(zhí)行; * stack:調(diào)用棧查看; * statu:狀態(tài)查看; * tracepoint

14、s:跟蹤程序執(zhí)行。 鍵入 help 后跟命令的分類名,可獲得該類命令的詳細清單。 #DENO# gdb 的常用命令 表 1-4 常用的 gdb 命令 命令 解釋 break NUM 在指定的行上設(shè)置斷點。 bt 顯示所有的調(diào)用棧幀。該命令可用來顯示函數(shù)的調(diào)用順序。 clear 刪除設(shè)置在特定源文件、特定行上的斷點。其用法為:clear FILENAME:NUM。 continue 繼續(xù)執(zhí)行正在調(diào)試的程序。該命令用在程序由于處理信號或斷點而 導(dǎo)致停止運行時。 display EXPR 每次程序停止后顯示表達式的值。表達式由程序定義的變量組成。 file FILE 裝載指定的可執(zhí)行文件進行調(diào)試。

15、help NAME 顯示指定命令的幫助信息。 info break 顯示當(dāng)前斷點清單,包括到達斷點處的次數(shù)等。 info files 顯示被調(diào)試文件的詳細信息。 info func 顯示所有的函數(shù)名稱。 info local 顯示當(dāng)函數(shù)中的局部變量信息。 info prog 顯示被調(diào)試程序的執(zhí)行狀態(tài)。 info var 顯示所有的全局和靜態(tài)變量名稱。 kill 終止正被調(diào)試的程序。 list 顯示源代碼段。 make 在不退出 gdb 的情況下運行 make 工具。 next 在不單步執(zhí)行進入其他函數(shù)的情況下,向前執(zhí)行一行源代碼。 print EXPR 顯示表達式 EXPR 的值。 1.8.5

16、 gdb 使用范例 - 清單 一個有錯誤的 C 源程序 bugging.c - #include #include static char buff 256; static char* string; int main () printf ("Please input a string: "); gets (string); printf ("nYour string is: %sn", string); - 上面這個程序非常簡單,其目的是接受用戶的輸入,然后將用戶的輸入打印出來。該程序使用了一個未經(jīng)過初 始化的字符串地址 string,因此,編譯并運行

17、之后,將出現(xiàn) Segment Fault 錯誤: $ gcc -o test -g test.c $ ./test Please input a string: asfd Segmentation fault (core dumped) 為了查找該程序中出現(xiàn)的問題,我們利用 gdb,并按如下的步驟進行: 1運行 gdb bugging 命令,裝入 bugging 可執(zhí)行文件; 2執(zhí)行裝入的 bugging 命令; 3使用 where 命令查看程序出錯的地方; 4利用 list 命令查看調(diào)用 gets 函數(shù)附近的代碼; 5唯一能夠?qū)е?gets 函數(shù)出錯的因素就是變量 string。用 prin

18、t 命令查看 string 的值; 6在 gdb 中,我們可以直接修改變量的值,只要將 string 取一個合法的指針值就可以了,為此,我們在第 11 行處設(shè)置斷點; 7程序重新運行到第 11 行處停止,這時,我們可以用 set variable 命令修改 string 的取值; 8然后繼續(xù)運行,將看到正確的程序運行結(jié)果。 如何使用gcc編譯器?作者:Zhang Wei 翻譯 2004-10-05 20:24:41 來自:linuxfocus目錄: · GCC rules · 開始. · 預(yù)編譯 · 編譯 · 匯編 · 連接 

19、3; 另外兩個重要選項 · 調(diào)試 · 小結(jié) · 站點鏈接   摘要: 要想讀懂本文,你需要對C語言有基本的了解,本文將介紹如何使用gcc編譯器。首先,我們介紹如何在命令行方式下使用編譯器編譯簡單的C源代碼。然后,我們簡要介紹一下編譯器究竟作了那些工作,以及如何控制編譯過程。我們也簡要介紹了調(diào)試器的使用方法。   GCC rules 你能想象使用封閉源代碼的私有編譯器編譯自由軟件嗎?你怎么知道編譯器在你的可執(zhí)行文件中加入了什么?可能會加入各種后門和木馬。Ken Thompson是一個著名的黑客,他編寫了一個編譯器,當(dāng)編譯器編譯自己時,就在'

20、;login'程序中留下后門和永久的木馬。請到 這里 閱讀他對這個杰作的描述。幸運的是,我們有了gcc。當(dāng)你進行 configure; make; make install 時, gcc在幕后做了很多繁重的工作。如何才能讓gcc為我們工作呢?我們將開始編寫一個紙牌游戲,不過我們只是為了演示編譯器的功能,所以盡可能地精簡了代碼。我們將從頭開始一步一步地做,以便理解編譯過程,了解為了制作可執(zhí)行文件需要做些什么,按什么順序做。我們將看看如何編譯C程序,以及如何使用編譯選項讓gcc按照我們的要求工作。步驟(以及所用工具)如下: 預(yù)編譯 (gcc -E), 編譯 (gcc), 匯編 (as),和

21、 連接 (ld)。   開始. 首先,我們應(yīng)該知道如何調(diào)用編譯器。實際上,這很簡單。我們將從那個著名的第一個C程序開始。(各位老前輩,請原諒我)。 #include <stdio.h>int main() printf("Hello World!n");把這個文件保存為 game.c。 你可以在命令行下編譯它: gcc game.c在默認情況下,C編譯器將生成一個名為 a.out 的可執(zhí)行文件。你可以鍵入如下命令運行它: a.outHello World每一次編譯程序時,新的 a.out 將覆蓋原來的程序。你無法知道是哪個程序創(chuàng)建了 a.out。我們可

22、以通過使用 -o 編譯選項,告訴 gcc我們想把可執(zhí)行文件叫什么名字。我們將把這個程序叫做 game,我們可以使用任何名字,因為C沒有Java那樣的命名限制。 gcc -o game game.cgameHello World到現(xiàn)在為止,我們離一個有用的程序還差得很遠。如果你覺得沮喪,你可以想一想我們已經(jīng)編譯并運行了一個程序。因為我們將一點一點為這個程序添加功能,所以我們必須保證讓它能夠運行。似乎每個剛開始學(xué)編程的程序員都想一下子編一個1000行的程序,然后一次修改所有的錯誤。沒有人,我是說沒有人,能做到這個。你應(yīng)該先編一個可以運行的小程序,修改它,然后再次讓它運行。這可以限制你一次修改的錯誤

23、數(shù)量。另外,你知道剛才做了哪些修改使程序無法運行,因此你知道應(yīng)該把注意力放在哪里。這可以防止這樣的情況出現(xiàn):你認為你編寫的東西應(yīng)該能夠工作,它也能通過編譯,但它就是不能運行。請切記,能夠通過編譯的程序并不意味著它是正確的。 下一步為我們的游戲編寫一個頭文件。頭文件把數(shù)據(jù)類型和函數(shù)聲明集中到了一處。這可以保證數(shù)據(jù)結(jié)構(gòu)定義的一致性,以便程序的每一部分都能以同樣的方式看待一切事情。 #ifndef DECK_H#define DECK_H#define DECKSIZE 52typedef struct deck_t int cardDECKSIZE; /* number of cards used

24、 */ int dealt;deck_t;#endif /* DECK_H */把這個文件保存為 deck.h。只能編譯 .c 文件,所以我們必須修改 game.c。在game.c的第2行,寫上 #include "deck.h"。在第5行寫上 deck_t deck;。為了保證我們沒有搞錯,把它重新編譯一次。 gcc -o game game.c如果沒有錯誤,就沒有問題。如果編譯不能通過,那么就修改它直到能通過為止。   預(yù)編譯 編譯器是怎么知道 deck_t 類型是什么的呢?因為在預(yù)編譯期間,它實際上把"deck.h"文件復(fù)制到了"

25、;game.c"文件中。源代碼中的預(yù)編譯指示以"#"為前綴。你可以通過在gcc后加上 -E 選項來調(diào)用預(yù)編譯器。 gcc -E -o game_precompile.txt game.cwc -l game_precompile.txt 3199 game_precompile.txt幾乎有3200行的輸出!其中大多數(shù)來自 stdio.h 包含文件,但是如果你查看這個文件的話,我們的聲明也在那里。如果你不用 -o 選項指定輸出文件名的話,它就輸出到控制臺。預(yù)編譯過程通過完成三個主要任務(wù)給了代碼很大的靈活性。 1. 把"include"的文件拷貝

26、到要編譯的源文件中。 2. 用實際值替代"define"的文本。 3. 在調(diào)用宏的地方進行宏替換。 這就使你能夠在整個源文件中使用符號常量(即用DECKSIZE表示一付牌中的紙牌數(shù)量),而符號常量是在一個地方定義的,如果它的值發(fā)生了變化,所有使用符號常量的地方都能自動更新。在實踐中,你幾乎不需要單獨使用 -E 選項,而是讓它把輸出傳送給編譯器。   編譯 作為一個中間步驟,gcc把你的代碼翻譯成匯編語言。它一定要這樣做,它必須通過分析你的代碼搞清楚你究竟想要做什么。如果你犯了語法錯誤,它就會告訴你,這樣編譯就失敗了。人們有時會把這一步誤解為整個過程。但是,實際上還

27、有許多工作要gcc去做呢。   匯編 as 把匯編語言代碼轉(zhuǎn)換為目標代碼。事實上目標代碼并不能在CPU上運行,但它離完成已經(jīng)很近了。編譯器選項 -c 把 .c 文件轉(zhuǎn)換為以 .o 為擴展名的目標文件。 如果我們運行 gcc -c game.c我們就自動創(chuàng)建了一個名為game.o的文件。這里我們碰到了一個重要的問題。我們可以用任意一個 .c 文件創(chuàng)建一個目標文件。正如我們在下面所看到的,在連接步驟中我們可以把這些目標文件組合成可執(zhí)行文件。讓我們繼續(xù)介紹我們的例子。因為我們正在編寫一個紙牌游戲,我們已經(jīng)把一付牌定義為 deck_t,我們將編寫一個洗牌函數(shù)。這個函數(shù)接受一個指向deck類型

28、的指針,并把一付隨機的牌裝入deck類型。它使用'drawn' 數(shù)組跟蹤記錄那些牌已經(jīng)用過了。這個具有DECKSIZE個元素的數(shù)組可以防止我們重復(fù)使用一張牌。 #include <stdlib.h>#include <stdio.h>#include <time.h>#include "deck.h"static time_t seed = 0;void shuffle(deck_t *pdeck) /* Keeps track of what numbers have been used */ int drawnDECK

29、SIZE = 0; int i; /* One time initialization of rand */ if(0 = seed) seed = time(NULL); srand(seed); for(i = 0; i < DECKSIZE; i+) int value = -1; do value = rand() % DECKSIZE; while(drawnvalue != 0); /* mark value as used */ drawnvalue = 1; /* debug statement */ printf("%in", value); pde

30、ck->cardi = value; pdeck->dealt = 0; return;把這個文件保存為 shuffle.c。我們在這個代碼中加入了一條調(diào)試語句,以便運行時,能輸出所產(chǎn)生的牌號。這并沒有為我們的程序添加功能,但是現(xiàn)在到了關(guān)鍵時刻,我們看看究竟發(fā)生了什么。因為我們的游戲還在初級階段,我們沒有別的辦法確定我們的函數(shù)是否實現(xiàn)了我們要求的功能。使用那條printf語句,我們就能準確地知道現(xiàn)在究竟發(fā)生了什么,以便在開始下一階段之前我們知道牌已經(jīng)洗好了。在我們對它的工作感到滿意之后,我們可以把那一行語句從代碼中刪掉。這種調(diào)試程序的技術(shù)看起來很粗糙,但它使用最少的語句完成了調(diào)試任

31、務(wù)。以后我們再介紹更復(fù)雜的調(diào)試器。 請注意兩個問題。 1. 我們用傳址方式傳遞參數(shù),你可以從'&'(取地址)操作符看出來。這把變量的機器地址傳遞給了函數(shù),因此函數(shù)自己就能改變變量的值。也可以使用全局變量編寫程序,但是應(yīng)該盡量少使用全局變量。指針是C的一個重要組成部分,你應(yīng)該充分地理解它。 2. 我們在一個新的 .c 文件中使用函數(shù)調(diào)用。操作系統(tǒng)總是尋找名為'main'的函數(shù),并從那里開始執(zhí)行。 shuffle.c 中沒有'main'函數(shù),因此不能編譯為獨立的可執(zhí)行文件。我們必須把它與另一個具有'main'函數(shù)并調(diào)用'

32、;shuffle'的程序組合起來。 運行命令 gcc -c shuffle.c并確定它創(chuàng)建了一個名為 shuffle.o 的新文件。編輯game.c文件,在第7行,在 deck_t類型的變量 deck 聲明之后,加上下面這一行: shuffle(&deck);現(xiàn)在,如果我們還象以前一樣創(chuàng)建可執(zhí)行文件,我們就會得到一個錯誤 gcc -o game game.c/tmp/ccmiHnJX.o: In function main':/tmp/ccmiHnJX.o(.text+0xf): undefined reference to shuffle'collect2:

33、ld returned 1 exit status編譯成功了,因為我們的語法是正確的。但是連接步驟卻失敗了,因為我們沒有告訴編譯器'shuffle'函數(shù)在哪里。那么,到底什么是連接?我們怎樣告訴編譯器到哪里尋找這個函數(shù)呢?   連接 連接器ld,使用下面的命令,接受前面由 as 創(chuàng)建的目標文件并把它轉(zhuǎn)換為可執(zhí)行文件 gcc -o game game.o shuffle.o這將把兩個目標文件組合起來并創(chuàng)建可執(zhí)行文件 game。 連接器從shuffle.o目標文件中找到 shuffle 函數(shù),并把它包括進可執(zhí)行文件。目標文件的真正好處在于,如果我們想再次使用那個函數(shù),我們

34、所要做的就是包含"deck.h" 文件并把 shuffle.o 目標文件連接到新的可執(zhí)行文件中。 象這樣的代碼重用是經(jīng)常發(fā)生的。雖然我們并沒有編寫前面作為調(diào)試語句調(diào)用的 printf 函數(shù),連接器卻能從我們用 #include <stdlib.h> 語句包含的文件中找到它的聲明,并把存儲在C庫(/lib/libc.so.6)中的目標代碼連接進來。這種方式使我們可以使用已能正確工作的其他人的函數(shù),只關(guān)心我們所要解決的問題。這就是為什么頭文件中一般只含有數(shù)據(jù)和函數(shù)聲明,而沒有函數(shù)體。一般,你可以為連接器創(chuàng)建目標文件或函數(shù)庫,以便連接進可執(zhí)行文件。我們的代碼可能產(chǎn)生問

35、題,因為在頭文件中我們沒有放入任何函數(shù)聲明。為了確保一切順利,我們還能做什么呢?   另外兩個重要選項 -Wall 選項可以打開所有類型的語法警告,以便幫助我們確定代碼是正確的,并且盡可能實現(xiàn)可移植性。當(dāng)我們使用這個選項編譯我們的代碼時,我們將看到下述警告: game.c:9: warning: implicit declaration of function shuffle'這讓我們知道還有一些工作要做。我們需要在頭文件中加入一行代碼,以便告訴編譯器有關(guān) shuffle 函數(shù)的一切,讓它可以做必要的檢查。聽起來象是一種狡辯,但這樣做 可以把函數(shù)的定義與實現(xiàn)分離開來,使我們能

36、在任何地方使用我們的函數(shù),只要包含新的頭文件 并把它連接到我們的目標文件中就可以了。下面我們就把這一行加入deck.h中。 void shuffle(deck_t *pdeck);這就可以消除那個警告信息了。 另一個常用編譯器選項是優(yōu)化選項 -O# (即 -O2)。 這是告訴編譯器你需要什么級別的優(yōu)化。編譯器具有一整套技巧可以使你的代碼運行得更快一點。對于象我們這種小程序,你可能注意不到差別,但對于大型程序來說,它可以大幅度提高運行速度。你會經(jīng)常碰到它,所以你應(yīng)該知道它的意思。   調(diào)試 我們都知道,代碼通過了編譯并不意味著它按我們得要求工作了。你可以使用下面的命令驗證是否所有的號碼

37、都被使用了 game | sort - n | less并且檢查有沒有遺漏。如果有問題我們該怎么辦?我們?nèi)绾尾拍苌钊氲讓硬檎义e誤呢? 你可以使用調(diào)試器檢查你的代碼。大多數(shù)發(fā)行版都提供著名的調(diào)試器:gdb。如果那些眾多的命令行選項讓你感到無所適從,那么你可以使用KDE提供的一個很好的前端工具 KDbg。還有一些其它的前端工具,它們都很相似。要開始調(diào)試,你可以選擇 File->Executable 然后找到你的 game 程序。當(dāng)你按下F5鍵或選擇 Execution->從菜單運行時,你可以在另一個窗口中看到輸出。怎么回事?在那個窗口中我們什么也看不到。不要擔(dān)心,KDbg沒有出問題。問

38、題在于我們在可執(zhí)行文件中沒有加入任何調(diào)試信息,所以KDbg不能告訴我們內(nèi)部發(fā)生了什么。編譯器選項 -g 可以把必要的調(diào)試信息加入目標文件。你必須用這個選項編譯目標文件(擴展名為.o),所以命令行成了: gcc -g -c shuffle.c game.cgcc -g -o game game.o shuffle.o這就把鉤子放入了可執(zhí)行文件,使gdb和KDbg能指出運行情況。調(diào)試是一種很重要的技術(shù),很值得你花時間學(xué)習(xí)如何使用。調(diào)試器幫助程序員的方法是它能在源代碼中設(shè)置“斷點”。現(xiàn)在你可以用右鍵單擊調(diào)用 shuffle 函數(shù)的那行代碼,試著設(shè)置斷點。那一行邊上會出現(xiàn)一個紅色的小圓圈?,F(xiàn)在當(dāng)你按下

39、F5鍵時,程序就會在那一行停止執(zhí)行。按F8可以跳入shuffle函數(shù)。呵,我們現(xiàn)在可以看到 shuffle.c 中的代碼了!我們可以控制程序一步一步地執(zhí)行,并看到究竟發(fā)生了什么事。如果你把光標暫停在局部變量上,你將能看到變量的內(nèi)容。太好了。這比那條 printf 語句好多了,是不是?   小結(jié) 本文大體介紹了編譯和調(diào)試C程序的方法。我們討論了編譯器走過的步驟,以及為了讓編譯器做這些工作應(yīng)該給gcc傳遞哪些選項。我們簡述了有關(guān)連接共享函數(shù)庫的問題,最后介紹了調(diào)試器。真正了解你所從事的工作還需要付出許多努力,但我希望本文能讓你正確地起步。你可以在 gcc、 as 和 ld的 man 和

40、info page中找到更多的信息。 自己編寫代碼可以讓你學(xué)到更多的東西。作為練習(xí)你可以以本文的紙牌游戲為基礎(chǔ),編寫一個21點游戲。那時你可以學(xué)學(xué)如何使用調(diào)試器。使用GUI的KDbg開始可以更容易一些。如果你每次只加入一點點功能,那么很快就能完成。切記,一定要保持程序一直能運行! 要想編寫一個完整的游戲,你需要下面這些內(nèi)容: · 一個紙牌玩家的定義(即,你可以把deck_t定義為player_t)。 · 一個給指定玩家發(fā)一定數(shù)量牌的函數(shù)。記住在紙牌中要增加“已發(fā)牌”的數(shù)量,以便能知道還有那些牌可發(fā)。還要記住玩家手中還有多少牌。 · 一些與用戶的交互,問問玩家是否還

41、要另一張牌。 · 一個能打印玩家手中的牌的函數(shù)。 card 等于value % 13 (得數(shù)為0到12),suit 等于 value / 13 (得數(shù)為0到3)。 · 一個能確定玩家手中的value的函數(shù)。Ace的value為零并且可以等于1或11。King的value為12并且可以等于10。 g+的使用 C+中的一些文件后綴.a靜態(tài)庫 (archive).C.c.cc.cp.cpp.cxxC+源代碼(需要編譯預(yù)處理).hC或者C+源代碼頭文件.iiC+源代碼(不需編譯預(yù)處理).o對象文件.s匯編語言代碼.so動態(tài)庫<none>標準C+系統(tǒng)頭文件從單個源文件生成可執(zhí)行程序下面是一個保存在文件 helloworld.cpp 中一個簡單的 C+ 程序的代碼:1234567/* helloworld.cpp */#include <iostream>int main(int argc,char *argv) std:cout << "hello, worldn" return(0);程序使用標準輸入流對象cout,向標準輸出寫入一個簡單的字符串。該代碼可用以下命令編譯為可執(zhí)行文件:$ g+ helloworld.cpp編譯器 g+ 通過檢查命令行中指定的文件的后綴名可識別其為 C+ 源代碼文件。編譯器默認的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論