天天看點

Linux下的C程式設計實戰之開辟平台搭建

1.弁言  Linux應用細碎在幹事器範疇的應用和普遍曾經有較長的汗青,這源于它的開源特點以及其逾越Windows的平靜性和不亂性。而近年來,Linux應用細碎在嵌入式細碎範疇的延長也可謂是蒸蒸日上,良多版本的嵌入式Linux細碎被開辟出來,如ucLinux、RTLinux、ARM-Linux等等。在嵌入式應用細碎方面,Linux的職位地方是不容疑心的,它開源、它包括TCP/IP協定棧、它易內建GUI。

  鑒于Linux應用細碎在幹事器和嵌入式細碎範疇愈來愈普遍的應用,社會上越來越必要基于Linux應用細碎停止程式設計的開辟職員。

  浏覽良多論壇,常常碰到多麼的發問:“今朝是不是很盛行unix/linux下的c程式設計?以是想進修一下!然則不曉得該從何學起,若何動手!有什麼好的發起嗎?列位高手!哪些書籍對照适宜初學者?在深切淺出的程序中應該看哪些差别條理的書?比如好的網站、論壇請大師見示!不慎謝謝!”

  鑒于讀者的需求,在本文中,筆者将對Linux平台下C程式設計的幾個方面停止執行個體講授,并力争回答讀者們眷注的成績,以與讀者冤家們停止交換,合營進步。在本文的連載程序中,有任何成績或發起,您可以給筆者發送email:[email protected],您也可以進入筆者的部落格參預評論鬥嘴:http://blog.donews.com/21cnbao。

  筆者發起在PC記憶體充沛大的外形下,不要直接安置Linux應用細碎,最好把它安置在運轉VMWare虛拟機軟體的Windows平台上,如下圖:

  在Linux平台下,可用恣意一個文本編輯東西編輯源代碼,但筆者發起運用emacs軟體,它具有文法高亮、版本節制等附帶服從,如下圖:

  2.GCC編譯器

  GCC是Linux平台下最重要的開辟東西,它是GNU的C和C 編譯器,其根柢用法為:

gcc [options] [filenames]

  options為編譯選項,GCC總共供應的編譯選項逾越100個,但隻要大都幾個會被頻繁運用,我們僅對幾個常用選項停止引見。

  假定我們編譯一輸入“Hello World”的程式:

/* Filename:helloworld.c */

main()

{

printf("Hello Worldn");

}

  最大抵的編譯法子是不指定任何編譯選項:

gcc helloworld.c

  它會為目标程式生成默許的檔案名a.out,我們可用-o編譯選項來為将發生的可執行檔案指定一個檔案名來替代a.out。比方,将上述名為helloworld.c的C程式編譯為名叫helloworld的可執行檔案,必要輸入如下下令:

gcc –o helloworld helloworld.c

  -c選項通知GCC僅把源代碼編譯為目标代碼而跳過彙編和銜接的步驟;

  -S 編譯選項通知GCC 在為 C代碼發生了彙編言語檔案後截止編譯。GCC 發生的彙編言語檔案的預設擴充名是.s,上述程式運轉如下下令:

gcc –S helloworld.c

  将生成helloworld.c的彙編代碼,運用的是AT&T彙編。用emacs翻開彙編代碼如下圖:

  -E選項訓示編譯器僅對輸入檔案停止預處置責罰。當這個選項被運用時,預處置責罰器的輸入被送到規範輸入(預設為螢幕)而不是儲存在檔案裡。

  -O選項通知GCC對源代碼停止根柢優化進而使得程式執行地更快;而-O2選項通知GCC發生盡可以小和盡可以快的代碼。運用-O2選項編譯的速率比運用-O時慢,但發生的代碼執行速率會更快。

  -g選項通知GCC發生能被GNU調試器運用的調試資訊以便調試你的程式,可喜的是,在GCC裡,我們能聯用-g和-O (發生優化代碼)。

  -pg選項通知GCC在你的程式裡參預額外的代碼,執行時,發生gprof用的解析資訊以透露表現你的程式的耗時外形。

  3.GDB調試器

  GCC用于編譯程式,而Linux的另一個GNU東西gdb則用于調試程式。gdb是一個用來調試C和C 程式的強力調試器,我們能經過它停止一系列調試任務,包孕設定斷點、觀觀查變量、單步等。

其最常用的下令如下:

  file:裝入想要調試的可執行檔案。

  kill:截至正在調試的程式。

  list:清單透露表現源代碼。

  next:執行一行源代碼但不進入函數外部。

  step:執行一行源代碼并且進入函數外部。

  run:執行以後被調試的程式

  quit:截至gdb

  watch:監視一個變量的值

  break:在代碼裡設定斷點,程式執行到這裡時挂起

  make:不插足gdb而重新發生可執行檔案

  shell:不分隔斷距離絕渙散gdb而執行shell

  上面我們來示範怎樣用GDB來調試一個求0 1 2 3 … 99的程式:

/* Filename:sum.c */

int i, sum;

sum = 0;

for (i = 0; i < 100; i )

sum = i;

printf("the sum of 1 2 ... is %d", sum);

  執行如下下令編譯sum.c(加-g選項發生debug資訊):

gcc –g –o sum sum.c

  在下令行上鍵入gdb sum并按Enter鍵就可以入部下手調試sum了,再運轉run下令執行sum,螢幕上将看到如下内容:

  list下令:

  list下令用于列出源代碼,對上述程式兩次運轉list,将出現如下畫面(源代碼被标行号):

  依據列出的源程式,如果我們将斷點設定在第5行,隻需在gdb 下令行提示符下鍵入如下下令設定斷點:(gdb) break 5,執行外形如下圖:

  這個時分我們再run,程式會截止在第5行,如下圖:

  設定斷點的另一種文法是 break <function>,它在進入指定函數(function)時停住。

  相反的,clear用于清除齊備的已定義的斷點,clear <function>清除設定在函數上的斷點, clear <linenum>則清除設定在指定行上的斷點。

  watch下令:

   

  watch下令用于觀觀查變量或表達式的值,我們觀觀查sum變量隻必要運轉watch sum:

   watch <expr>為表達式(變量)expr設定一個觀觀測點,一量表達式值有變化時,程式會截止執行。

  要觀觀查以後設定的watch,可以運用info watchpoints下令。

  next、step下令:

   next、step用于單步執行,在執行的程序中,被watch變量的變化外形将及時出現(劃分透露表現Old value和New value),如下圖:

   next、step下令的差別在于step碰到函數挪用,會跳轉到到該函數定義的入部下手行去執行,而next則不進入到函數外部,它把函數挪用語句看成一條往常語句執行。

  4.Make

  make是齊備想在Linux細碎上程式設計的使用者必須把握的東西,關于任何稍具局限的程式,我們都市運用到make,确實可以說不運用make的程式不具有任何實用價值。

  在此,我們有必要表明編譯和銜接的差別。編譯器運用源碼檔案來發生某種法子的目标檔案(object files),在編譯程序中,外部的辨別表記标幟參考并沒有被表明或交換(即外部全局變量和函數并沒有被找到)。是以,在編譯階段所報的錯誤一樣往常都是文法錯誤。而銜接器則用于銜接目标檔案和程式包,生成一個可執行程式。在銜接階段,一個目标檔案中對其餘檔案中的辨別表記标幟的參考被表明,如果有辨別表記标幟不克不及找到,會呈報銜接錯誤。

  編譯和銜接的一樣往常步驟是:第一階段把源檔案一個一個的編譯成目标檔案,第二階段把齊備的目标檔案加上必要的程式包銜接成一個可執行檔案。多麼的程序很痛苦,我們必要運用大量的gcc下令。

  而make則使我們從大量源檔案的編譯和銜接任務中束縛出來,綜合為一步完成。GNU Make的重要任務是讀進一個文本檔案,稱為makefile。這個檔案記錄了哪些檔案(目的檔案,目的檔案不一定是最後的可執行程式,它可以是任何一種檔案)由哪些檔案(請托檔案)發生,用什麼下令來發生。Make請托此makefile中的資訊搜檢磁盤上的檔案,如果目的檔案的建立或修正工夫比它的一個請托檔案舊的話,make就執行響應的下令,以便更新目的檔案。

  假定我們寫下如下的三個檔案,add.h用于聲明add函數,add.c供應兩個整數相加的函數體,而main.c中挪用add函數:

/* filename:add.h */

extern int add(int i, int j);

/* filename:add.c */

int add(int i, int j)

return i j;

/* filename:main.c */

#include "add.h"

int a, b;

a = 2;

b = 3;

printf("the sum of a b is %d", add(a b));

  如作甚上述三個檔案發生makefile呢?如下:

test : main.o add.o

gcc main.o add.o -o test

main.o : main.c add.h

gcc -c main.c -o main.o

add.o : add.c add.h

gcc -c add.c -o add.o

  上述makefile應用add.c和add.h檔案執行gcc -c add.c -o add.o下令發生add.o目标代碼,應用main.c和add.h檔案執行gcc -c main.c -o main.o下令發生main.o目标代碼,最後應用main.o和add.o檔案(兩個子產品的目标代碼)執行gcc main.o add.o -o test下令發生可執行檔案test。

  我們可在makefile中參預變量,其餘。情形變量在make程序中也被表明成make的變量。這些變量是大小寫敏感的,一樣往常運用大寫字母。Make變量可以做良多事項,比方:

  i) 存儲一個檔案名清單;

  ii) 存儲可執行檔案名;

  iii) 存儲編譯器選項。

  要定義一個變量,隻必要在一行的入部下手寫下這個變量的名字,後面跟一個=号,再跟變量的值。援用變量的法子是寫一個 $辨別表記标幟,後面跟(變量名)。我們把後面的 makefile 應用變量重寫一遍(并假定運用-Wall -O –g編譯選項):

OBJS = main.o add.o

CC = gcc

CFLAGS = -Wall -O -g

test :  $(OBJS)

 $(CC)  $(OBJS) -o test

 $(CC)  $(CFLAGS) -c main.c -o main.o

 $(CC)  $(CFLAGS) -c add.c -o add.o

  makefile 中還可定義清除(clean)目标,可用來清除編譯程序中發生的地方檔案,比方在上述makefile檔案中添加下列代碼:

clean:

rm -f *.o

  運轉make clean時,将執行rm -f *.o下令,删除齊備編譯程序中發生的地方檔案。

  不論怎樣說,本人脫手編寫makefile仍然是很龐大和啰嗦的,并且很友善出錯。是以,GNU也為我們供應了Automake和Autoconf來匡助快速自動發生makefile,讀者可以參閱相關材料。

  5.小結

  本章重要論述了Linux程式的編寫、編譯、調試法子及make,實際上便是指導讀者進修怎樣在Linux下程式設計,為後續章節做好預備。

版權聲明:

原創作品,答應轉載,轉載時請務必以超連結法子标明文章 原始來由 、作者資訊和本聲明。不然将清查法則責任。

繼續閱讀