一.vim編譯器的使用
vi/vim的區別簡單點來說,它們都是多模式編輯器,不同的是vim是vi的升級版本,它不僅兼容vi的所有指令,而且 還有一些新的特性在裏面。例如語法加亮,可視化操作不僅可以在終端運行,也可以運行於x window、 mac os、 windows。
1.vim的基本概念(三種模式)
- (1)正常/普通/命令模式
控制屏幕光標的移動。字符。字或行的刪除,移動複製某區段及進入insert mode下,或者到last line mode。 - (2)插入模式(Insert mode)
只有在insert mode下,纔可以做文字輸入,按[esc]健可以回到命令行模式。 - (3)末行模式(last line mode)
文件保存或退出,也可以進行文件替換,找字符串,列出行號等操作。在命令模式下:shift + : 即可進入該模式。要查看所有的模式,打開vim,頂行命令下輸入 :help vim-modes
2.vim的基本操作
- (1)進入vim,在系統提示符號輸入vim及文件名稱後,就進入vim全屏幕編輯畫面:
$ vim test.c
不過有一點要特別注意,就是你進入vim之後,是處於[正常模式],你要切換到[插入模式]才能夠輸入文字
- (2)[正常模式]切換至[插入模式]
輸入a 輸入i 輸入o
- (3)[插入模式]切換至[正常模式]
目前處於[插入模式],就只能一直輸入文字,如果發現輸錯了字,想用光標鍵往回移動,將該字刪除,可 以先按一下「ESC」鍵轉到[正常模式]再刪除文字。當然,也可以直接刪除。
- (4)[正常模式]切換至[末行模式]
「shift + ;」, 其實就是輸入「:」
- (5)退出vim及保存文件,在[正常模式]下,按一下[:]冒號健進入[Last line mode],例如:
- w(保存當前文件)
- wq (輸入「wq」,存盤並退出vim)
- q! (輸入q!,不存盤強制退出vim)
3.vim正常模式命令集
- (1)插入模式
按「i」切換進入插入模式「insert mode」,按“i”進入插入模式後是從光標當前位置開始輸入文件;
按「a」進入插入模式後,是從目前光標所在位置的下一個位置開始輸入文字;
按「o」進入插入模式後,是插入新的一行,從行首開始輸入文字。
- (2)從插入模式切換爲命令模式
按[esc]鍵
- (3)移動光標
vim可以直接用鍵盤上的光標來上下左右移動,但正規的vim是用小寫英文字母「h」、「j」、「k」、 「l」,分別控制光標左、下、上、右移一格
按「G」:移動到文章的後
按「 $ 」:移動到光標所在行的“行尾”
按「^」:移動到光標所在行的“行首”
按「w」:光標跳到下個字的開頭
按「e」:光標跳到下個字的字尾
按「b」:光標回到上個字的開頭
按「#l」:光標移到該行的第#個位置,如:5l,56l
按[gg]:進入到文本開始
按[shift+g]:進入文本末端
按「ctrl」+「b」:屏幕往“後”移動一頁
按「ctrl」+「f」:屏幕往“前”移動一頁
按「ctrl」+「u」:屏幕往“後”移動半頁
按「ctrl」+「d」:屏幕往“前”移動半
- (4)刪除文字
「x」:每按一次,刪除光標所在位置的一個字符
「#x」:例如,「6x」表示刪除光標所在位置的“後面(包含自己在內)”6個字符
「X」:大寫的X,每按一次,刪除光標所在位置的“前面”一個字符
「#X」:例如,「20X」表示刪除光標所在位置的“前面”20個字符
「dd」:刪除光標所在行 「#dd」:從光標所在行開始刪除#
- (5)複製
「yw」:將光標所在之處到字尾的字符複製到緩衝區中。
「#yw」:複製#個字到緩衝區
「yy」:複製光標所在行到緩衝區。
「#yy」:例如,「6yy」表示拷貝從光標所在的該行“往下數”6行文字。
「p」:將緩衝區內的字符貼到光標所在位置。注意:所有與“y”有關的複製命令都必須與“p”配合才能完 成複製與粘貼功能。
- (6)替換
「r」:替換光標所在處的字符。
「R」:替換光標所到之處的字符,直到按下「ESC」鍵爲止。
- (7)撤銷上一次的操作
「u」:如果您誤執行一個命令,可以馬上按下「u」,回到上一個操作。按多次“u”可以執行多次回 復。 >「ctrl + r」: 撤銷的恢復
- (8)更改
「cw」:更改光標所在處的字到字尾處
「c#w」:例如,「c3w」表示更改3個字
- (9)跳到指定的行
「ctrl」+「g」列出光標所在行的行號。
「#G」:例如,「15G」,表示移動光標至文章的第15行行首。
4.vim末行模式命令集
- 列出行號
「set nu」: 輸入「set nu」後,會在文件中的每一行前面列出行號。
- 跳到文件中的某一行
「#」:「#」號表示一個數字,在冒號後輸入一個數字,再按回車鍵就會跳到該行了,如輸入數字15, 再回車,就會跳到文章的第15行。
- 查找字符
「/關鍵字」: 先按「/」鍵,再輸入您想尋找的字符,如果第一次找的關鍵字不是您想要的,可以一直按 「n」會往後尋找到您要的關鍵字爲止。
「?關鍵字」:先按「?」鍵,再輸入您想尋找的字符,如果第一次找的關鍵字不是您想要的,可以一直 按「n」會往前尋找到您要的關鍵字爲止。 問題:/ 和 ?查找有和區別?操作實驗一下
- 保存文件
「w」: 在冒號輸入字母「w」就可以將文件保存起來
- 離開vim
「q」:按「q」就是退出,如果無法離開vim,可以在「q」後跟一個「!」強制離開vim。
「wq」:一般建議離開時,搭配「w」一起使用,這樣在退出的時候還可以保存文件。
5.vim的簡單配置
(1)配置文件的位置
- 在目錄 /etc/ 下面,有個名爲vimrc的文件,這是系統中公共的vim配置文件,對所有用戶都有效。
- 而在每個用戶的主目錄下,都可以自己建立私有的配置文件,命名爲:“.vimrc”。例如,/root目錄下, 通常已經存在一個.vimrc文件,如果不存在,則創建之。
- 切換用戶成爲自己執行 su ,進入自己的主工作目錄,執行 cd ~
- 打開自己目錄下的.vimrc文件,執行 vim .vimrc
二.gcc/g++使用
1.gcc如何完成
-
(1)預處理(進行宏替換)
預處理功能主要包括宏定義,文件包含,條件編譯,去註釋等。
預處理指令是以#號開頭的代碼行。
實例: gcc –E hello.c –o hello.i
選項“-E”,該選項的作用是讓 gcc 在預處理結束後停止編譯過程。
選項“-o”是指目標文件,“.i”文件爲已經過預處理的C原始程序。 -
(2)編譯(生成彙編)
在這個階段中,gcc 首先要檢查代碼的規範性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤後,gcc 把代碼翻譯成彙編語言。
用戶可以使用“-S”選項來進行查看,該選項只進行編譯而不進行彙編,生成彙編代碼。
實例: gcc –S hello.i –o hello.s -
(3)彙編(生成機器可識別代碼)
彙編階段是把編譯階段生成的“.s”文件轉成目標文件
讀者在此可使用選項“-c”就可看到彙編代碼已轉化爲“.o”的二進制目標代碼了
實例: gcc –c hello.s –o hello.o -
(4)連接(生成可執行文件或庫文件)
在成功編譯之後,就進入了鏈接階段。
實例: gcc hello.o –o hell
2.函數庫一般分爲靜態庫和動態庫兩種
- (1)靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也 就不再需要庫文件了。其後綴名一般爲“.a”
- (2)動態庫與之相反,在編譯鏈接時並沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時 鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般後綴名爲“.so”,如前面所述的 libc.so.6 就是動態 庫。gcc 在編譯時默認使用動態庫。完成了鏈接之後,gcc 就可以生成可執行文件,如下所示。 gcc hello.o –o hello
- (3)gcc默認生成的二進制程序,是動態鏈接的,這點可以通過 file 命令驗證
3.gcc選項
- -E 只激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件裏面
- -S 編譯到彙編語言不進行彙編和鏈接
- -c 編譯到目標代碼
- -o 文件輸出到 文件
- -static 此選項對生成的文件採用靜態鏈接
- -g 生成調試信息。GNU 調試器可利用該信息。
- -shared 此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫.
- -O0 -O1 -O2 -O3 編譯器的優化選項的4個級別,-O0表示沒有優化,-O1爲缺省值,-O3優化級別高
- -w 不生成任何警告信息。
- -Wall 生成所有警告信息。
三.gdb使用
** 1.背景**
- 程序的發佈方式有兩種,debug模式和release模式
- Linux gcc/g++出來的二進制程序,默認是release模式
- 要使用gdb調試,必須在源代碼生成二進制程序的時候, 加上 -g 選項 ,生成debug文件。
2.開始使用
- list/l 行號:顯示binFile源代碼,接着上次的位置往下列,每次列10行。
- list/l 函數名:列出某個函數的源代碼。
- r或run:運行程序。
- n 或 next:單條執行。
- s或step:進入函數調用
- break(b) 行號:在某一行設置斷點
- break 函數名:在某個函數開頭設置斷點
- info break :查看斷點信息。
- finish:執行到當前函數返回,然後挺下來等待命令
- print§:打印表達式的值,通過表達式可以修改變量的值或者調用函數
- p 變量:打印變量值。
- set var:修改變量的值
- continue(或c):從當前位置開始連續而非單步執行程序
- run(或r):從開始連續而非單步執行程序
- delete breakpoints:刪除所有斷點
- delete breakpoints n:刪除序號爲n的斷點
- disable breakpoints:禁用斷點
- enable breakpoints:啓用斷點
- info(或i) breakpoints:參看當前設置了哪些斷點
- display 變量名:跟蹤查看一個變量,每次停下來都顯示它的值
- undisplay:取消對先前設置的那些變量的跟蹤
- until X行號:跳至X行
- breaktrace(或bt):查看各級函數調用及參數
- info(i) locals:查看當前棧幀局部變量的值
- quit:退出gdb
四.make/Makefile
1.背景
- makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。
- make是一個命令工具,是一個解釋makefile中指令的命令工具,一般來說,大多數的IDE都有這個命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可見,makefile都成爲了一 種在工程方面的編譯方法。
- make是一條命令,makefile是一個文件,兩個搭配使用,完成項目自動化構建。
2.依賴關係
- 文件 hello ,它依賴 hell.o
- hello.o , 它依賴 hello.s
- hello.s , 它依賴 hello.i
- hello.i , 它依賴 hello.c
3.依賴方法
gcc hello.* -option hello.* ,就是與之對應的依賴關係
4.原理
make是如何工作的,在默認的方式下,也就是我們只輸入make命令。那麼,
- (1)make會在當前目錄下找名字叫“Makefile”或“makefile”的文件。
- (2)如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到“hello”這個文件, 並把這個文件作爲終的目標文件。
- (3)如果hello文件不存在,或是hello所依賴的後面的hello.o文件的文件修改時間要比hello這個文件新(可 以用 touch 測試),那麼,他就會執行後面所定義的命令來生成hello這個文件。
- (4)如果hello所依賴的hello.o文件不存在,那麼make會在當前文件中找目標爲hello.o文件的依賴性,如果 找到則再根據那一個規則生成hello.o文件。(這有點像一個堆棧的過程)
- (5)當然,你的C文件和H文件是存在的啦,於是make會生成 hello.o 文件,然後再用 hello.o 文件聲明 make的終極任務,也就是執行文件hello了。
- (6)這就是整個make的依賴性,make會一層又一層地去找文件的依賴關係,直到終編譯出第一個目標文 件。
- (7)在找尋的過程中,如果出現錯誤,比如後被依賴的文件找不到,那麼make就會直接退出,並報錯, 而對於所定義的命令的錯誤,或是編譯不成功,make根本不理。
- (8)make只管文件的依賴性,即,如果在我找了依賴關係之後,冒號後面的文件還是不在,那麼對不起, 我就不工作啦。
//Makefile文件的基本指令
1 test:test.c //依賴關係
2 gcc test.c -o test //依賴方法
3 .PHONY:clean //聲明僞目標的東西
4 clean:
5 rm -f test //clean的依賴方法
被.PHONY執行的目標是僞目標,該目標總是被執行的。跑多少次就執行多少次
總結:
(1)make是命令,Makefile是文件
(2)Makefile裏面放的是依賴關係和依賴方法
(3)僞目標:總是可以被執行的
(4)依賴方法必須是以tab鍵開頭的
(5)Makefile怎麼知道文件是否被修改的(通過修改時間判斷,.PHONY不關注生成的時間,總是被執行的)
//打印進度條的代碼
1 #include<unistd.h>
2 #include<string.h>
3 #include<stdio.h>
4 int main()
5 {
6 int i = 0;
7 char bar[102];
8 memset(bar,0,sizeof(bar));
9 const char* lable = "|/-\\";
10
11 while(i <= 100)
12 {
13 printf("[%-100s][%d%%][%c]\r",bar,i,lable[i%4]);
14 //[%-100s]從左往右打印,一共右100個大小得空間
15 fflush(stdout);//清理讀寫緩存區,每次都是一個新得開始
16 bar[i++] = '#';
17 sleep(1);
18 }
19 printf("\n");
20 return 0;
21 }