C 基礎學習之3 編譯器

2021-07-26 00:16:53 字數 3527 閱讀 4813

編譯器(compiler)是指將一種語言 翻譯為另一種語言的工具,對於c++來講,是將我們寫的**語言 轉換為二進位制語言(exe或者elf),從而能夠在windows或者linux下執行。

很多新同學可能對編譯器並不敏感,直接用 ide(vs、eclipse)編譯一下就可以了,沒有感覺到編譯器的存在,這其實就是乙個問題,作者建議對於初學者盡量不要直接就用 ide,先用 linux命令,然後 逐漸過渡到 vim、emacs、sublime等,最後才考慮用 ide。

我們先來看一下 gcc 和 g++ :

sudo apt-get install g++

sudo apt-get install gcc

一般來講,gcc與g++打包在一起,對於 ubuntu 14.04 預設安裝的是 4.8.4 版本,當然也可以根據自己的需要進行公升級。

gcc和g++有什麼區別呢?

1. gcc是c程式編譯器,將.c的字尾檔案按照c語言格式編譯,將.cpp檔案按照c++語言格式編譯;

g++是c++編譯器,在編譯.c檔案時呼叫gcc,編譯.cpp檔案時按照c++編譯;

錯誤觀點:gcc只能編譯c**,g++只能編譯c++**。

2. 由於gcc無法鏈結c++庫(但可以鏈結純c),因此,對於c++鏈結這個工作就交給了g++;

3. gcc不會定義__cplusplus巨集,而g++會;

看一下linux下的命令列編譯的例子(sh檔案build):

#!/bin/bash

src=`ls *.cpp`

libs=`ls /usr/local/lib/libopencv*.so`

g++ -i./include $src -o main $libs

list所有的cpp檔案,載入lib庫(例子對應的是opencv),g++呼叫編譯(-o 生成目標檔案 main)。

> gcc compile

gcc -o hello hello.c -i/home/include -l/home/lib -lworld

core_libs="$core_libs -l/usr/lib64/mysql -wl,-bstatic -lmysqlclient \ -wl,-bdynamic -lz -lcrypt -lnsl -lm -l/usr/lib64 -lssl -lcrypto"

-static      # to find .a

-shared   # to find .o (default)

make與cmake

make是gnu 針對複雜的編譯過程開發的乙個排程器,通過makefile檔案 實現編譯選項的控制、使用者互動等操作。

cc = g++

src = `ls *.cpp`

target = main

$(cc) -i./include $src -o $(target)

clean:

rm main

這是乙個簡單的 makefile 例子,很容易看懂,在命令列輸入make,呼叫g++進行編譯,輸入clean,完成清理。

雖然寫 makefile 是程式設計師的必備技能,但是 有時候檔案太多、邏輯太複雜,並不能夠對solution進行有效管理,基於這種考慮,cmake誕生了。

cmake 能夠生成 makefile,所以我們把它看作是上層工具,目前cmake使用較廣的原因作者認為有兩點:

1. cmake 對大型工程的管理更為簡單,雖然也需要借助 cmakelists.txt 檔案,但維護工作量大大減少;

2. cmake 有比較好的視覺化工具,這堪稱利器,不解釋。

同樣來看乙個cmake的例子:

#

#project目錄下的cmakelists.txt

#///

cmake_minimum_required(version 2.8)

#工程名

project(cmaketest)

#工程檔案中使用相對路徑

set(cmake_suppress_regeneration 1)

set(cmake_use_relative_paths on)

#支援if(a) else()的寫法

set(cmake_allow_loose_loop_constructs on)

#定義工程的頂級路徑

set(projdir $)

#定義源檔案目錄

set(srcdir $/src)

#設定輸出路徑

set(executable_output_path $/build)

set(library_output_path $/build)

#設定安裝路徑

set(cmake_install_prefix $/build)

#定義標頭檔案安裝目錄

set(proj_include_dir $/headers)

#根據作業系統不同而設定不同的路徑

if(win32)

set(gdal_hdrs "e:/lib/gdal/include")

else()

set(gdal_hdrs "/home/sunsc/gdal/")

endif()

#設定標頭檔案的引用路徑

include_directories( $)

#設定引用庫路徑

set(libs $)

link_directories($)

#巨集,實現visio studio的目錄分組(過濾器)功能

macro(source_group_by_dir source_files)

if(msvc)

set(sgbd_cur_dir $)

foreach(sgbd_file $})

string(regex replace $//(.*/) //1 sgbd_fpath $)

string(regex replace "/(.*/)/.*" //1 sgbd_group_name $)

string(compare equal $ $ sgbd_nogroup)

string(replace "/" "//" sgbd_group_name $)

if(sgbd_nogroup)

set(sgbd_group_name "//")

endif(sgbd_nogroup)

source_group($ files $)

endforeach(sgbd_file)

endif(msvc)

endmacro(source_group_by_dir)

#新增子目錄

add_subdirectory(src)

除了 make 和 cmake 之外,很多人也會用到 qmake,這裡我們不再繼續展開討論,而對於 vs 對應的編譯器,大家可以與 g++ 進行比較,發現其相同與不同之處,這對於編譯器的理解很有好處。

C 學習(9) 配置編譯器 編譯器擴充套件

亞歷克斯於2018年9月19日 最後由alex於2018年9月26日修改 c 標準定義了程式在特定情況下應如何表現的規則。在大多數情況下,編譯器將遵循這些規則。但是,許多編譯器實現了對語言的更改,通常是為了增強與其他語言版本 例如c99 的相容性,或者出於歷史原因。這些特定於編譯器的行為稱為編譯器擴...

C語言基礎 GCC編譯器

預處理 pre processing 編譯 compiling 彙編 assembling 鏈結 linking 編譯器通過程式的副檔名來分辯編寫源程式所用的語言。由於不同的程式所需要執行編譯的步驟是不同的,因此gcc根據不同的字尾名對它們進行相應處理。後 綴 名 所對應的語言 編 譯 流 程 cc...

C 編譯器優化之RVO

寫這篇文章純屬意外收穫.先看一段 在這段 中定義了建構函式,拷貝建構函式,移動建構函式,賦值構造,移動賦值構造,以及析構函式.include using namespace std classaa const a a a a a a operator const a a else return th...