[建议] GCC 新手入门【转】
本文是寫給 gcc 新手的入門文章,所以內(nèi)容比較簡單。如果你知道下面3條命令都可以編譯c++的話,就不用在本文浪費(fèi)時(shí)間了??
g++ -Wall hellocpp.cpp gcc -Wall hellocpp.cpp -lstdc++ gfortran -Wall hellocpp.cpp -lstdc++
?
注:本文最新版在wiki中?http://wiki.ubuntu.org.cn/Gcchowto?(建議大家直接訪問wiki中的版本)
如果你想找一個(gè)集成開發(fā)環(huán)境,可訪問?http://wiki.ubuntu.org.cn/C_Cpp_IDE
如果要搭建Gtk或Qt編譯環(huán)境,可訪問?http://wiki.ubuntu.org.cn/Gtk與Qt編譯環(huán)境安裝與配置
注意:開始之前請確保已經(jīng)安裝了 build-essential 軟件包
編譯簡單的 C 程序
C 語言經(jīng)典的入門例子是 Hello World,下面是一示例代碼:
#include <stdio.h> int main(void) {printf("Hello, world!\n");return 0; }
?
我們假定該代碼存為文件‘hello.c’。要用?gcc?編譯該文件,使用下面的命令:
$ gcc -Wall hello.c -o hello
該命令將文件‘hello.c’中的代碼編譯為機(jī)器碼并存儲(chǔ)在可執(zhí)行文件 ‘hello’中。機(jī)器碼的文件名是通過?-o?選項(xiàng)指定的。該選項(xiàng)通常作為命令行中的最后一個(gè)參數(shù)。如果被省略,輸出文件默認(rèn)為 ‘a(chǎn).out’。
注意到如果當(dāng)前目錄中與可執(zhí)行文件重名的文件已經(jīng)存在,它將被復(fù)蓋。
選項(xiàng)?-Wall?開啟編譯器幾乎所有常用的警告──強(qiáng)烈建議你始終使用該選項(xiàng)。編譯器有很多其他的警告選項(xiàng),但?-Wall?是最常用的。默認(rèn)情況下GCC 不會(huì)產(chǎn)生任何警告信息。當(dāng)編寫 C 或 C++ 程序時(shí)編譯器警告非常有助于檢測程序存在的問題。
本例中,編譯器使用了?-Wall?選項(xiàng)而沒產(chǎn)生任何警告,因?yàn)槭纠绦蚴峭耆戏ǖ摹?br />
要運(yùn)行該程序,輸入可執(zhí)行文件的路徑如下:
$ ./hello
Hello, world!
這將可執(zhí)行文件載入內(nèi)存,并使 CPU 開始執(zhí)行其包含的指令。 路徑?./?指代當(dāng)前目錄,因此 ./hello 載入并執(zhí)行當(dāng)前目錄下的可執(zhí)行文件 ‘hello’。
捕捉錯(cuò)誤
如上所述,當(dāng)用 C 或 C++ 編程時(shí),編譯器警告是非常重要的助手。為了說明這一點(diǎn),下面的例子包含一個(gè)微妙的錯(cuò)誤:為一個(gè)整數(shù)值錯(cuò)誤地指定了一浮點(diǎn)數(shù)控制符‘%f’。
#include <stdio.h>int main (void) {printf ("Two plus two is %f\n", 4);return 0; }
?
一眼看去該錯(cuò)誤并不明顯,但是它可被編譯器捕捉到,只要啟用了警告選項(xiàng)?-Wall。
編譯上面的程序‘bad.c’,將得到如下的消息:
$ gcc -Wall bad.c -o bad bad.c: In function 'main': bad.c:6: warning: double format, different type arg (arg 2)
這表明文件 ‘bad.c’第 6 行中的格式字符串用法不正確。GCC 的消息總是具有下面的格式?文件名:行號:消息。編譯器對錯(cuò)誤與警告區(qū)別對待,前者將阻止編譯,后者表明可能存在的問題但并不阻止程序編譯。
本例中,對整數(shù)值來說,正確的格式控制符應(yīng)該是?%d。
如果不啟用?-Wall,程序表面看起來編譯正常,但是會(huì)產(chǎn)生不正確的結(jié)果:
$ gcc bad.c -o bad $ ./bad Two plus two is 2.585495
?
顯而易見,開發(fā)程序時(shí)不檢查警告是非常危險(xiǎn)的。如果有函數(shù)使用不當(dāng),將可能導(dǎo)致程序崩潰或產(chǎn)生錯(cuò)誤的結(jié)果。開啟編譯器警告選項(xiàng)?-Wall?可捕捉 C 編程時(shí)的多數(shù)常見錯(cuò)誤。
編譯多個(gè)源文件
一個(gè)源程序可以分成幾個(gè)文件。這樣便于編輯與理解,尤其是程序非常大的時(shí)候。這也使各部分獨(dú)立編譯成為可能。
下面的例子中我們將程序 Hello World 分割成 3 個(gè)文件:‘main.c’,‘hello_fn.c’和頭文件‘hello.h’。這是主程序‘main.c’:
#include "hello.h" int main(void) {hello ("world");return 0; }
?
在先前的例子‘hello.c’中,我們調(diào)用的是庫函數(shù) printf,本例中我們用一個(gè)定義在文件‘hello_fn.c’中的函數(shù) hello 取代它。
主程序中包含有頭文件‘hello.h’,該頭文件包含函數(shù) hello 的聲明。我們不需要在‘main.c’文件中包含系統(tǒng)頭文件‘stdio.h’來聲明函數(shù) printf,因?yàn)椤甿ain.c’沒有直接調(diào)用 printf。
文件‘hello.h’中的聲明只用了一行就指定了函數(shù) hello 的原型。
void hello (const char * name);
?
函數(shù) hello 的定義在文件‘hello_fn.c’中:
#include <stdio.h> #include "hello.h"void hello (const char * name) {printf ("Hello, %s!\n", name); }
?
語句 #include "FILE.h" 與 #include <FILE.h> 有所不同:前者在搜索系統(tǒng)頭文件目錄之前將先在當(dāng)前目錄中搜索文件‘FILE.h’,後者只搜索系統(tǒng)頭文件而不查看當(dāng)前目錄。
要用gcc編譯以上源文件,使用下面的命令:
$ gcc -Wall main.c hello_fn.c -o newhello
?
本例中,我們使用選項(xiàng)?-o?為可執(zhí)行文件指定了一個(gè)不同的名字 newhello。注意到頭文件‘hello.h’并未在命令行中指定。源文件中的的 #include "hello.h" 指示符使得編譯器自動(dòng)將其包含到合適的位置。
要運(yùn)行本程序,輸入可執(zhí)行文件的路徑名:
$ ./newhello
Hello, world! ?
源程序各部分被編譯為單一的可執(zhí)行文件,它與我們先前的例子產(chǎn)生的結(jié)果相同。
鏈接外部庫
庫是預(yù)編譯的目標(biāo)文件(object files)的集合,它們可被鏈接進(jìn)程序。靜態(tài)庫以后綴為‘.a’的特殊的存檔文件(archive file)存儲(chǔ)。
標(biāo)準(zhǔn)系統(tǒng)庫可在目錄 /usr/lib 與 /lib 中找到。比如,在類 Unix 系統(tǒng)中 C 語言的數(shù)學(xué)庫一般存儲(chǔ)為文件 /usr/lib/libm.a。該庫中函數(shù)的原型聲明在頭文件 /usr/include/math.h 中。C 標(biāo)準(zhǔn)庫本身存儲(chǔ)為 /usr/lib/libc.a,它包含 ANSI/ISO C 標(biāo)準(zhǔn)指定的函數(shù),比如‘printf’。對每一個(gè) C 程序來說,libc.a 都默認(rèn)被鏈接。
下面的是一個(gè)調(diào)用數(shù)學(xué)庫 libm.a 中?sin?函數(shù)的的例子:
#include <math.h> #include <stdio.h>int main (void) {double x = sin (2.0);printf ("The value of sin(2.0) is %f\n", x);return 0; }
?
嘗試單獨(dú)從該文件生成一個(gè)可執(zhí)行文件將導(dǎo)致一個(gè)鏈接階段的錯(cuò)誤:
$ gcc -Wall calc.c -o calc /tmp/cckDHfI8.o: In function `main': calc.c:(.text+0x1b): undefined reference to `sin'
?
函數(shù)?sin,未在本程序中定義也不在默認(rèn)庫‘libc.a’中;除非被指定,編譯器也不會(huì)鏈接‘libm.a’。
為使編譯器能將?sin?鏈接進(jìn)主程序‘calc.c’,我們需要提供數(shù)學(xué)庫‘libm.a’。一個(gè)容易想到但比較麻煩的做法是在命令行中顯式地指定它:
$ gcc -Wall calc.c /usr/lib/libm.a -o calc
?
函數(shù)庫‘libm.a’包含所有數(shù)學(xué)函數(shù)的目標(biāo)文件,比如sin,cos,exp,log及sqrt。鏈接器將搜索所有文件來找到包含 sin 的目標(biāo)文件。
一旦包含 sin 的目標(biāo)文件被找到,主程序就能被鏈接,一個(gè)完整的可執(zhí)行文件就可生成了:
$ gcc -Wall calc.c -o calc /tmp/cckDHfI8.o: In function `main': calc.c:(.text+0x1b): undefined reference to `sin'
?
可執(zhí)行文件包含主城許的機(jī)器碼以及函數(shù)庫‘libm.a’中 sin 對應(yīng)的機(jī)器碼。
為避免在命令行中指定長長的路徑,編譯器為鏈接函數(shù)庫提供了快捷的選項(xiàng)‘-l’。例如,下面的命令
$ gcc -Wall calc.c -lm -o calc
?
與我們上面指定庫全路徑‘/usr/lib/libm.a’的命令等價(jià)。
一般來說,選項(xiàng)?-lNAME使鏈接器嘗試鏈接系統(tǒng)庫目錄中的函數(shù)庫文件?libNAME.a。一個(gè)大型的程序通常要使用很多 -l 選項(xiàng)來指定要鏈接的數(shù)學(xué)庫,圖形庫,網(wǎng)絡(luò)庫等。
編譯C++/Fortran
你可能知道:GCC 是 GNU 編譯器集合(GNU Compiler Collection)的首字母縮寫詞。它可以編譯 C,C++,Objective-C,Fortran,Java 和 Ada 語言。
前面我們只涉及到 C 語言,那么如何用 gcc 編譯其他語言呢?
編譯c++
(下面兩條命令是等價(jià)的,不過我相信你會(huì)選擇前者^_^)
g++ -Wall hello.cpp -o hellogcc -Wall hello.cpp -o hello -lstdc++ ?
編譯fortran
如果你的gcc版本>=4.0,以下命令任選其一即可
gfortran -Wall hello.f -o hellogcc -Wall hello.f -o hello -lgfortran -lgfortranbegin ?
如果gcc版本<4.0 ,那么以下命令任選其一
g77 -Wall hello.f -o hellogcc -Wall hello.f -o hello -lfrtbegin -lg2c ?
對于 java 和 ada編程,前者推薦用 sun-java6-jdk,而后者不太常用,本文作為入門文章,也就都不涉及了。
轉(zhuǎn)載于:https://www.cnblogs.com/armysheng/archive/2012/06/06/2538995.html
總結(jié)
以上是生活随笔為你收集整理的[建议] GCC 新手入门【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个QQ网名女古风
- 下一篇: 一个“复制/删除”方式的滚动