Linux編程基礎

來源:互聯網
上載者:User
實驗二 Linux編程基礎

一、實驗目的
熟悉Linux下使用C語言編程的方法,通過在編程中使用進程式控制制系統調用功能,直觀理解Linux下進程並發執行情況。

二、實驗題目
使用vi編輯C語言來源程式;分析例子程式並通過man命令熟悉相關係統調用,編寫進程並發執行的程式;使用gcc、make等工具進行編譯;執行編譯產生的執行檔案並分析結果。

三、背景材料
因實驗用的Linux環境以字元介面為主,而Linux的字元介面並沒有廣泛使用的整合式開發環境,經典的C語言開發模式還是使用文本編輯軟體編寫來源程式,然後使用gcc和make工具進行編譯連結,產生可執行檔。在編輯來源程式環節,可以使用不同的文本編輯工具,例如在圖形化使用者介面下可以使用gedit或者kedit;字元介面下可以使用vi、emacs、nano等編輯器;甚至可以在其它環境下編輯,然後通過ftp上傳。
(一)編輯器vi的使用
vi或vim是Linux系統上經典的文本編輯工具,在字元介面下,廣泛用於系統管理、程式開發。本實驗要求熟悉vi基本操作,可以使用vi進行文本編輯。
1、調用vi
最常用的命令模式是:vi filename
2、vi的三種模式
Command(命令)模式,用於輸入命令;
Insert(插入)模式,用於插入文本;
Visual(可視)模式,用於可視化的的高亮並選定本文。
3、檔案的儲存和退出
Command模式是vi的預設模式,如果處於其它模式時,要通過ESC鍵切換過來,接著再輸入:號時,vi會在螢幕的最下方等待輸入命令;
:w 儲存;
:w filename 另存新檔filename;
:wq! 儲存退出;
:wq! filename 註:以filename為檔案名稱儲存後退出;
:q! 不儲存退出;
應該是儲存並退出 ,功能和:wq!相同
4、游標移動;
按ESC進入Command模式後,可以用下面的一些鍵位來移動游標;
j 向下移動一行;
k 向上移動一行;
h 向左移動一個字元;
l 向右移動一個字元;
ctrl+b 向上移動一屏;
ctrl+f 向下移動一屏;
向上箭頭 向上移動;
向下箭頭 向下移動;
向左箭頭 向左移動;
向右箭頭 向右移動;
對於 j、k、l和h鍵,還能在這些命令的前面加上數字,比如 3j,表示向下移動3行。
5、進入插入模式
i 在游標之前插入;
a 在游標之後插入;
I 在游標所在行的行首插入;
A 在游標所在行的行末插入;
o 在游標所在的行的上面插入一行;
O 在游標所在的行的下面插入一行;
s 刪除游標後的一個字元,然後進入插入模式;
S 刪除游標所在的行,然後進入插入模式;
6、常值內容的刪除
x 刪除一個字元;
#x 刪除幾個字元,#表示數字,比如3x;
dw 刪除一個單詞;
#dw 刪除幾個單詞,#用數字表示,比如3dw表示刪除三個單詞;
dd 刪除一行;
#dd 刪除多個行,#代表數字,比如3dd 表示刪除游標行及游標的下兩行;
d$ 刪除游標到行尾的內容;
J 清除游標所處的行與上一行之間的空格,把游標行和上一行接在一起;
7、可視模式
在最新的Linux發行版本中,vi提供了可視模式。按ESC鍵,然後按v就進入可視模式; 退出可視模式,還是用ESC鍵。可視模式提供了友好的選取文本範圍,以高亮顯示。
8、複製和粘帖的操作
複製:對於可視模式下選中的文本,可以按y進行複製;按yy可以複製當前游標所在行。此外,刪除也帶有剪下的意思,當我們刪除文字時,相應內容會自動複製;
粘貼:可以把游標移動到某處,然後按p或shift+p鍵進行粘貼,其中,p 在游標之後粘帖;shift+p 在游標之前粘帖。
9、行號
可以在命令模式輸入 :set number 來開啟行號顯示,輸入 :set number 來關閉行號顯示。
10、尋找功能
在命令模式下,輸入/或?就可以進行尋找;
/SEARCH 註:正向尋找,按n鍵把游標移動到下一個合格地方;
?SEARCH 註:反向尋找,按shift+n 鍵,把游標移動到下一個合格
11、替換功能
按ESC鍵進入命令模式;
:s /SEARCH/REPLACE/g 註:把當前游標所處的行中的SEARCH單詞,替換成REPLACE,並把所有SEARCH高亮顯示;
:%s /SEARCH/REPLACE 註:把文檔中所有SEARCH替換成REPLACE;
:#,# s /SEARCH/REPLACE/g 註:#號表示數字,表示從多少行到多少行,把SEARCH替換成REPLACE;
註:命令中g表示全域尋找,在指定的替換範圍之外,也會把SEARCH高亮顯示。

(二)gcc和make的使用
Linux下編輯好的C語言程式,需要使用gcc編譯工具(Linux系統上一般也可以通過cc別名調用)進行編譯串連,產生可執行檔。對於複雜的應用,可能把多個來源程式分別編譯,最後串連形成執行檔案;為了有效管理這類項目,make代碼維護工具可以用來定義一系列規則來管理編譯串連過程。
【注】Linux下的可執行檔沒有特別的尾碼名約定,而是通過設定“可執行”屬性來區分;另外,Linux預設的執行檔案搜尋路徑也不包括目前的目錄,所以編譯產生的執行檔案需要顯示指明檔案路徑來執行。
1、gcc的使用
(1) 簡單使用方法
假設一個C語言來源程式名為demo.c,根據該檔案產生執行檔案的最簡單命令為:
gcc hello.c
該命令將產生預設名字為a.out的執行檔案;如果希望產生執行檔案的名字不同,可以在命令中通過參數指定:
gcc -o hello hello.c
該命令將產生名字為demo的執行檔案。
(2) 分解使用
實際上,gcc所做的工作包括先行編譯、編譯、串連等多個環節,上述簡單用法隱含了對這幾個環節的調用,如果需要分開調用,可以通過不同的命令列參數指定:
gcc -E hello.c -o hello.i-E參數指定進行先行編譯,預先處理的宏定義插入到hello.i中;
gcc -c hello.i -o hello.o-c參數指定編譯為目標代碼 hello.o,也可以通過源檔案直接產生(gcc -c hello.c);
gcc hello.o -o hello將產生可執行檔,如果由多個來源程式檔案產生,一般需要在產生時指定多個目標代碼模組,例如:gcc hello.o e1.o s2.o -o hello
(3) 常用參數
gcc命令列的常用參數如下:
-c 通知GCC取消連結步驟,即編譯源碼並在最後產生目標檔案;
-Dmacro 定義指定的宏,使它能夠通過源碼中的#ifdef進行檢驗;
-E 不經過編譯預先處理程式的輸出而輸送至標準輸出;
-g3 獲得有關偵錯工具的詳細資料,它不能與-o選項聯合使用;
-Idirectory 在包含檔案搜尋路徑的起點處添加指定目錄;
-llibrary 提示連結程式在建立最終可執行檔時包含指定的庫;
-O、-O2、-O3 將最佳化狀態開啟,該選項不能與-g選項聯合使用;
-S 要求編譯器產生來自原始碼的組譯工具輸出;
-v 啟動所有警報;
-Wall 在發生警報時取消編譯操作,即將警報看作是錯誤;
-Werror 在發生警報時取消編譯操作,即把警示當作是錯誤;
-w 禁止所有的警示。
2、make的使用
(1) make工具簡介
make是一種代碼維護工具,在大中型項目中,根據程式各個模組的更新情況,自動的維護和產生目標。能很好的做到“不多、不重、不漏”:
•不多:只更新那些需要更新的檔案,而不動那些並不過時的東西;
•不重:是指當make對某個檔案進行更新時,即使有很多檔案過時,也將只更新一次;
•不漏:是指他不會漏下任何應該更新的檔案。
make在使用時有一系列的規則,將根據這些規則來解釋其配置指令碼,以達到設計目的。配置指令碼的預設名是makefile或Makefile,也可在命令列指定其它檔案名稱。使用形式為:
make [option] [macrodef] [target]
option指出make的工作行為,具體參數可參考man手冊頁。
(2) makefile檔案編寫
make工具使用的關鍵是編寫高效、簡潔、正確的makefile,這需要學習和實踐。雖然make工具的使用有較高的門檻,但是一旦掌握,其帶來的靈活和便捷遠遠超過一般IDE所能提供的管理功能。
實際makefile檔案編寫涉及的知識很多,有專著專門最次講解。此處只是介紹概貌,藉助一個簡單的例子來說明:假設一個項目hello,依賴於hello.o、e1.o、e2.o,而hello.o依賴於hello.c、hello.h,e1.o依賴於e1.c、hello.h,e2.o依賴於e2.c;這樣形成一棵相依樹狀結構,父節點依賴於子節點。使用make進行維護時,會對這棵樹進行一次遍曆,如果發現子節點形成的時間晚於父節點形成的時間便開始調用makefile中指定的命令進行維護。針對此例子的makefile樣本如下:
hello: hello.o e1.o e2.o
gcc -o hello hello.o e1.o e2.o
main.o: hello.c hello.h
gcc -c hello.c
e1.o: e1.c hello.h
gcc -c e1.c hello.h
e2.o: e2.c
gcc -c e2.c
makefile放置在與項目來源程式檔案相同目錄中,在該目錄中執行make hello或者make命令(命令列未target時會預設使用makefile的第一個target),將會根據makefile中定義的依賴關係依次執行編譯、串連各個命令,產生hello執行檔案。
實際項目的makefile因為會使用大量的宏、條件變數以及預設規則,對初學者而言較難理解。對於一般的開源項目,在編寫makefile時,target的命名都會遵循一些預定俗稱的規則,常見的用法包括:
make all編譯項目中所有實際目標
make install進行安裝
make clean清除所有中間檔案
(3) 預設規則和簡單用法
make的預設規則是系統或者自訂的一些規則,在定義時不指出全名,而是根據副檔名定義一類依賴關係和相關命令。例如,與c語言相關的預設規則包括:
.c:
$(CC) $(FLAGS) -o $@ $
#include
#include

int main(void)
{
int x, i;

printf("Input a initial value for i: ");
scanf("%d", &i);
while((x=fork())==-1);
if(x==0)/* child run */
{
printf("When child runs, i=%d/n", i);
printf("Input a value in child: ");
scanf("%d", &i);
printf("i=%d/n", i);
}
else/* parent run */
{
wait();
printf("After child runs, in parent, i=%d/n", i);
}
}
(2) 預測程式的執行結果
閱讀程式,根據自己的理解,預期程式執行後的結果。
(3) 實際執行結果分析
編譯產生執行檔案,執行後記錄結果,說明與預期的結果是否一致。分析為什麼是這樣的結果。

2、父子進程執行過程分析
(1) 按照給定架構編程
按照如下程式架構,完成來源程式編寫:
// ①
pid=fork();
// ②
if(pid==0)
{
sleep(3);
printf("Child: pid=%d, ppid=%d/n", getpid(), getppid());
}
else
{
printf("Parent: Child=%d, pid=%d, ppid=%d/n", pid, getpid(), getppid());
wait();
printf("After Child ends./n");
}
printf("In which process?/n"); // ③
(2) 預測程式的執行結果
閱讀程式,根據自己的理解,預期程式執行後的結果。
(3) 實際執行結果分析
編譯產生執行檔案,執行後記錄結果,說明與預期的結果是否一致。分析為什麼是這樣的結果。
(4) 修改程式並分析執行結果
把程式架構中最後一句輸出語句(位置③處)分別移至位置①和②處,預期輸出結果是什嗎?實際執行結果如何?分析原因。
(5) 修改程式驗證父子進程關係
修改程式,使父進程先執行完成,驗證子進程是否會一起終止?如果不是,前後子進程的父進程號是否變化?記錄並分析結果。

五、實驗報告書寫要求
應在實驗報告中說明如下事項:
1、所使用的文字編輯器;
2、編譯產生執行檔案的命令;
3、相關程式的名稱及儲存位置,以便指導教師抽查;
4、實驗內容1的結果:包括預期結果和實際執行結果,以及結果分析;
5、實驗內容2的結果:包括預期結果和實際執行結果,對結果的分析;按照要求進行修改後的預期結果、實際結果及分析。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.