久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

專欄中心

EEPW首頁 > 專欄 > Linux C/C++開發(fā)~入門

Linux C/C++開發(fā)~入門

發(fā)布人:電子禪石 時(shí)間:2019-10-29 來源:工程師 發(fā)布文章

Linux C/C++開發(fā)            

首先就是要熟練在vim里面寫代碼,其實(shí)就是沒有提示和自動(dòng)補(bǔ)全了,這個(gè)問題并不大。

我服務(wù)器gcc版本是4.8.5,所以就按照這個(gè)來了 https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/

其實(shí)我的開發(fā)者環(huán)境是最新的9.1.0,非常不建議哦。生產(chǎn)環(huán)境和開發(fā)環(huán)境盡量相同,不同的話一定要進(jìn)行大量的測(cè)試

然后就是編譯,先cd到工程文件夾,然后使用編譯命令編譯

一、編譯

編譯:當(dāng)前源代碼編譯成二進(jìn)制目標(biāo)文件(.obj文件)

鏈接(link):將生成的.obj文件與庫文件.lib等文件鏈接,生成可執(zhí)行文件

一個(gè)現(xiàn)代編譯器的主要工作流程如下:

源程序(source code)→預(yù)處理器(preprocessor)→編譯器(compiler)→匯編程序(assembler)→目標(biāo)程序(object code)→連接器(鏈接器,Linker)→可執(zhí)行程序(executables)

執(zhí)行過程 雖然我們稱gcc是C語言的編譯器,但使用gcc由C語言源代碼文件生成可執(zhí)行文件的過程不僅僅是編譯的過程,而是要經(jīng)歷四個(gè)相互關(guān)聯(lián)的步驟∶

1.預(yù)處理(也稱預(yù)編譯,Preprocessing):命令gcc首先調(diào)用cpp進(jìn)行預(yù)處理,在預(yù)處理過程中,對(duì)源代碼文件中的文件包含(include)、預(yù)編譯語句(如宏定義define等)進(jìn)行分析。

2.編譯(Compilation):接著調(diào)用cc1進(jìn)行編譯,這個(gè)階段根據(jù)輸入文件生成以.o為后綴的目標(biāo)文件。

3.匯編(Assembly):匯編過程是針對(duì)匯編語言的步驟,調(diào)用as進(jìn)行工作,一般來講,.S為后綴的匯編語言源代碼文件、.s為后綴的匯編語言文件經(jīng)過預(yù)編譯和匯編之后都生成以.o為后綴的目標(biāo)文件。 

4.鏈接(Linking):當(dāng)所有的目標(biāo)文件都生成之后,gcc就調(diào)用ld來完成最后的關(guān)鍵性工作,這個(gè)階段就是連接。在連接階段,所有的目標(biāo)文件被安排在可執(zhí)行程序中的恰當(dāng)?shù)奈恢茫瑫r(shí),該程序所調(diào)用到 的庫函數(shù)也從各自所在的檔案庫中連到合適的地方。 

實(shí)例:

1.編寫hello.c文件2.預(yù)編譯過程:

gcc -E ./hello.c -o hello.i //.i 為后綴的文件,是已經(jīng)預(yù)處理過的C源代碼文件,可以省略這一步。

cat hellp.c | wc -l //查看hello.c文件內(nèi)容的行數(shù)。

cat hellp.i | wc -l //查看hello.i文件內(nèi)容的行數(shù)。

3.匯編過程:

gcc -S hello.i -o hello.s //.s為后綴的文件,是匯編語言源代碼文件;可以省略這一步。

4.編譯過程

gcc -c ./hello.c //在當(dāng)前文件夾下生成hello.o .o為后綴的文件,是編譯后的目標(biāo)文件;

gcc -c hello.c -o hello.o //在當(dāng)前文件夾下生成hello.o

5.鏈接過程:

gcc hello.o -o hello

6.直接在終端輸入文件路徑或者把hello文件拖動(dòng)到終端即可執(zhí)行

用g++編譯c++源程序

用g++編譯c++源程序和c語言類似,可將gcc改為g++逐個(gè)嘗試。以下只提供一些簡單介紹:

-E Preprocess only; do not compile, assemble or link

-S Compile only; do not assemble or link

-c Compile and assemble, but do not link

-o Place the output into

-g Use of extra debugging information

-w 關(guān)閉編譯時(shí)的警告

-o 參數(shù)謹(jǐn)慎使用,也許開了編譯優(yōu)化會(huì)出現(xiàn)問題,但是開了編譯優(yōu)化代碼真的會(huì)變快,做好測(cè)試就行

二、gdb調(diào)試

assert斷言函數(shù) 如果參數(shù)expression等于零,一個(gè)錯(cuò)誤消息將會(huì)寫入到設(shè)備的標(biāo)準(zhǔn)錯(cuò)誤集并且會(huì)調(diào)用abort函數(shù),就會(huì)結(jié)束程序的執(zhí)行。這個(gè)雖然可以找到錯(cuò)誤,但是我們有更厲害的東西

gdb的其實(shí)是一個(gè)可執(zhí)行文件,所以我們需要先編譯出這個(gè)文件

復(fù)制代碼
#include <stdio.h>int main()
{    int a = 0;
    printf("%d\n", a++);
    printf("%d\n", a--);
    printf("%d\n", ++a);
    printf("%d\n", --a);
}
復(fù)制代碼
gcc -g A.c -o A

命令中出現(xiàn)了-g參數(shù),這個(gè)不僅可以創(chuàng)建符號(hào)表,符號(hào)表包含了程序中使用的變量名稱的列表,而且可以關(guān)閉所有的優(yōu)化機(jī)制,以便程序執(zhí)行過程中嚴(yán)格按照原來的C代碼進(jìn)行。

一定要記得加入這個(gè)參數(shù)

輸入gdb就可以有了,當(dāng)然你可能不想看到那一坨,可以加-q參數(shù)得到一個(gè)清爽的界面

gdb后可以file 跟上文件名,也可以進(jìn)入之后再指定

[root@BobHuang ~]# gdb -q A

Reading symbols from /root/A...done.

(gdb) file A

想回過頭看看以前的代碼,就用list,一次可以顯示十行,繼續(xù)list可以顯示接下來的十行

(gdb) list

1 #include<stdio.h>

2 int main()

3 {

4     int a=0;

5     printf("%d\n",a++);

6     printf("%d\n",a--);

7     printf("%d\n",++a);

8     printf("%d\n",--a);

9 }

10

list默認(rèn)參數(shù)可以用show listsize來查看,如果感覺10行太多或者太少,還可以用set listsize <count>來更改。

但是我有時(shí)候只是想部分,就可以給list加上參數(shù) 

list 還可以加上其他參數(shù),比如:
list 5,10   顯示第5行到第10行的代碼;

list func   顯示func函數(shù)周圍的代碼,顯示范圍和list參數(shù)有關(guān);

list test.c:5,10  顯示源文件test.c第5行到第10行的代碼,一般用于調(diào)試含多個(gè)源文件的程序。

gdb 還支持字符串查找,search str,從當(dāng)前行開始,向前查找含str的字符串;

reverse-search str,從當(dāng)前行開始,向后查找含str的字符串。

在gdb里也可以使用shell+命令,比如

shell clear

就會(huì)完成清屏

然后就可以設(shè)置斷點(diǎn)了,和在圖形界面類似,可以設(shè)置在某一行斷點(diǎn)。甚至可以直接寫一個(gè)判斷表達(dá)式

(gdb) break 5

Breakpoint 1 at 0x40052c: file A.c, line 5.

(gdb) break 6 if a==1

Breakpoint 2 at 0x400546: file A.c, line 6.

(gdb) break 7 if a==1

Breakpoint 3 at 0x400560: file A.c, line 7.

然后可以通過info breakpoints來查看斷點(diǎn)

(gdb) info breakpoints

Num     Type           Disp Enb Address            What

1       breakpoint     keep y   0x000000000040052c in main at A.c:5

2       breakpoint     keep y   0x0000000000400546 in main at A.c:6

stop only if a==1

3       breakpoint     keep y   0x0000000000400560 in main at A.c:7

stop only if a==1

 

Num表示斷點(diǎn)的編號(hào);Type表示斷點(diǎn)的斷點(diǎn)的類型,第二個(gè)斷點(diǎn)類型還加上了條件;Disp表示中斷點(diǎn)在執(zhí)行一次之后是否失去作用,dis為是,keep為不是;Enb表示當(dāng)前中斷點(diǎn)是否有效,y為是,n為否;Address表示中斷點(diǎn)所處的內(nèi)存地址;What指出斷點(diǎn)所處的位置。 

(gdb) run

Starting program: /root/A 

 

Breakpoint 1, main () at A.c:5

5     printf("%d\n",a++);

Missing separate debuginfos, use: debuginfo-install glibc-2.17-260.el7_6.5.x86_64

(gdb) continue

Continuing.

0

 

Breakpoint 2, main () at A.c:6

6     printf("%d\n",a--);

(gdb) continue

Continuing.

1

1

0

[Inferior 1 (process 32035) exited with code 02]

但是他提示我軟件沒裝啊,我們裝一下

(gdb) shell debuginfo-install glibc-2.17-260.el7_6.5.x86_64

再次運(yùn)行,沒有變化,也就是沒有經(jīng)過breakpoint3,也就證明了,執(zhí)行斷點(diǎn)3時(shí)a!=1,所以這個(gè)判斷非常好用啊,能檢測(cè)出某些異常,不過bug復(fù)現(xiàn)是不太好實(shí)現(xiàn)

接下來就是刪除斷點(diǎn)了。如果不需要程序在該斷點(diǎn)暫停時(shí),有兩種方法,一種是使該斷點(diǎn)失效,一種是直接刪除該斷點(diǎn)。使斷點(diǎn)失效用的是Num,刪除斷點(diǎn)用的是行,這樣就巧妙完成了需求

(gdb) disable 2

(gdb) info breakpoints

Num     Type           Disp Enb Address            What

2       breakpoint     keep n   0x000000000040052c in main at A.c:5

(gdb) clear 5

Deleted breakpoint 1 

delete命令后面的參數(shù)也為Num;可以一次刪除多個(gè)斷點(diǎn),斷點(diǎn)編號(hào)之間用空格隔開;如果delete后沒有參數(shù),默認(rèn)刪除所有斷點(diǎn),會(huì)給出提示選擇是否操作。

上面雖然展示了一下,但是我們需要更多的演示,才展示他的強(qiáng)大

run,開始運(yùn)行程序;

continue,程序暫停時(shí)繼續(xù)運(yùn)行程序的命令;

print 變量名或表達(dá)式,打印該變量或者該表達(dá)式的值。whatis 變量名或者表達(dá)式,可以顯示該變量或表達(dá)式的數(shù)據(jù)類型。

print  變量=值,這種形式還可以給對(duì)應(yīng)的變量賦值;類似的還有set variable 變量=值。作用和用print賦值相同。

next,繼續(xù)執(zhí)行下一條語句;

還有一條命令step,與之類似,不同的是,當(dāng)下一條語句遇到函數(shù)調(diào)用的時(shí)候,next不會(huì)跟蹤進(jìn)入函數(shù),而是繼續(xù)執(zhí)行下面的語句,而step命令則會(huì)跟蹤進(jìn)入函數(shù)內(nèi)部。

復(fù)制代碼
(gdb) run
Starting program: /root/A 

Breakpoint 2, main () at A.c:55        printf("%d\n",a++);
(gdb)  next        //繼續(xù)執(zhí)行下一條語句,只執(zhí)行一條06        printf("%d\n",a--);
(gdb) continue    //讓程序繼續(xù)運(yùn)行,直到下個(gè)斷點(diǎn)或者結(jié)束Continuing.    
110[Inferior 1 (process 6553) exited with code 02]
復(fù)制代碼

直接賦值的結(jié)果

復(fù)制代碼
(gdb) run
Starting program: /root/A 

Breakpoint 2, main () at A.c:55        printf("%d\n",a++);
(gdb) print a=10$1 = 10(gdb) continue
Continuing.10111110[Inferior 1 (process 6693) exited with code 03]
復(fù)制代碼

還有nexti和stepi命令,這兩個(gè)是單步執(zhí)行一條機(jī)器指令,比如(i=0;i<n;i++)這條語句需要輸入多個(gè)nexti才能執(zhí)行完;兩個(gè)的區(qū)別和上面相同。

quit,退出gdb調(diào)試,如果調(diào)試中想要退出,可以直接輸入該命令,會(huì)出現(xiàn)提示選擇是否退出。kill命令,結(jié)束當(dāng)前程序的調(diào)試,(不會(huì)退出gdb)。

三、makefile編寫

makefile帶來直接好處就是——“自動(dòng)化編譯”。一旦寫好,只需要一個(gè)make命令,整個(gè)工程完全自動(dòng)編譯,所以十分方便。而Makefile文件就是告訴make命令怎么樣地去編譯和鏈接程序。但是想要比較靈活的運(yùn)用它,還是先要熟悉一些關(guān)于系統(tǒng)對(duì)程序編譯和鏈接的知識(shí)。


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。

關(guān)鍵詞:

相關(guān)推薦

2010全球電子峰會(huì):Lattice公司

2010全球電子峰會(huì):Panel Discussion(上)

Sumco計(jì)劃提升12寸硅片供應(yīng)能力,8寸硅片需求持續(xù)低迷

EDA/PCB 2025-05-09

等華為鴻蒙電腦操作系統(tǒng)ISO鏡像的沒戲了!所有Windows電腦都無法下載安裝

英特爾:推動(dòng)6G變革,驅(qū)動(dòng)未來通信新范式

英飛凌發(fā)布2025財(cái)年第二季運(yùn)營成果

AIX Reference for Sun Solaris Administrators.part3

AIX Reference for Sun Solaris Administrators.part2

2010全球電子峰會(huì):QuickLogic公司

視頻 2010-05-12

聚焦新的SHARC處理器系列

視頻 2010-05-12

英特爾和AMD的CPU被證明與Marvell的CXL產(chǎn)品組合兼容

AIX Reference for Sun Solaris Administrators.part1

肯睿Cloudera通過實(shí)時(shí)分析賦能企業(yè)網(wǎng)絡(luò)安全團(tuán)隊(duì)

ADS PowerPC標(biāo)準(zhǔn)試驗(yàn)板的調(diào)試工具,由LauterBach公司發(fā)布

射頻功率放大器中的記憶效應(yīng)

零售門店的“芯”機(jī)遇:英特爾為智慧零售提質(zhì)增效

開放原子“園區(qū)行”(深圳站)成功舉辦,開源技術(shù)對(duì)接平臺(tái)助推智慧交通生態(tài)繁榮

2010全球電子峰會(huì):Altera公司

視頻 2010-05-14

AM29LV160D datasheet

恩智浦發(fā)布第三代成像雷達(dá)處理器,可支持L2+至L4級(jí)自動(dòng)駕駛

更多 培訓(xùn)課堂
更多 焦點(diǎn)
更多 視頻

技術(shù)專區(qū)