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