Linux下C編程基礎(chǔ)之:實(shí)驗(yàn)內(nèi)容
(1)在“/root”目錄下建一個名為“vi”的目錄。
(2)進(jìn)入“vi”目錄。
(3)將文件“/etc/inittab”復(fù)制到“vi”目錄下。
(4)使用vi打開“vi”目錄下的inittab。
(5)設(shè)定行號,指出設(shè)定initdefault(類似于“id:5:initdefault”)的所在行號。
(6)將光標(biāo)移到該行。
(7)復(fù)制該行內(nèi)容。
(8)將光標(biāo)移到最后一行行首。
(9)粘貼復(fù)制行的內(nèi)容。
(10)撤消第9步的動作。
(11)將光標(biāo)移動到最后一行的行尾。
(12)粘貼復(fù)制行的內(nèi)容。
(13)光標(biāo)移到“si::sysinit:/etc/rc.d/rc.sysinit”。
(14)刪除該行。
(15)存盤但不退出。
(16)將光標(biāo)移到首行。
(17)插入模式下輸入“Hello,thisisviworld!”。
(18)返回命令行模式。
(19)向下查找字符串“0:wait”。
(20)再向上查找字符串“halt”。
(21)強(qiáng)制退出vi,不存盤。
分別指出每個命令處于何種模式下?
3.實(shí)驗(yàn)步驟(1)mkdir/root/vi
(2)cd/root/vi
(3)cp/etc/inittab./
(4)vi./inittab
(5):setnu(底行模式)
(6)17<enter>(命令行模式)
(7)yy
(8)G
(9)p
(10)u
(11)$
(12)p
(13)21G
(14)dd
(15):w(底行模式)
(16)1G
(17)i并輸入“Hello,thisisviworld!”(插入模式)
(18)Esc
(19)/0:wait(命令行模式)
(20)?halt
(21):q!(底行模式)
4.實(shí)驗(yàn)結(jié)果該實(shí)驗(yàn)的最終結(jié)果是對“/root/inittab”增加了一行復(fù)制的內(nèi)容:“id:5:initdefault”。
3.7.2用gdb調(diào)試程序的bug1.實(shí)驗(yàn)?zāi)康?p>通過調(diào)試一個有問題的程序,使讀者進(jìn)一步熟練使用vi操作,而且熟練掌握gcc編譯命令及gdb的調(diào)試命令,通過對有問題程序的跟蹤調(diào)試,進(jìn)一步提高發(fā)現(xiàn)問題和解決問題的能力。這是一個很小的程序,只有35行,希望讀者認(rèn)真調(diào)試。2.實(shí)驗(yàn)內(nèi)容(1)使用vi編輯器,將以下代碼輸入到名為greet.c的文件中。此代碼的原意為輸出倒序main函數(shù)中定義的字符串,但結(jié)果顯示沒有輸出。代碼如下所示:
#include<stdio.h>
intdisplay1(char*string);
intdisplay2(char*string);
intmain()
{
charstring[]="EmbeddedLinux";
display1(string);
display2(string);
}
intdisplay1(char*string)
{
printf("Theoriginalstringis%s\n",string);
}
intdisplay2(char*string1)
{
char*string2;
intsize,i;
size=strlen(string1);
string2=(char*)malloc(size+1);
for(i=0;i<size;i++)
{
string2[size-i]=string1[i];
}
string2[size+1]='';
printf("Thestringafterwardis%s\n",string2);
}
(2)使用gcc編譯這段代碼,注意要加上“-g”選項(xiàng)以方便之后的調(diào)試。
(3)運(yùn)行生成的可執(zhí)行文件,觀察運(yùn)行結(jié)果。
(4)使用gdb調(diào)試程序,通過設(shè)置斷點(diǎn)、單步跟蹤,一步步找出錯誤所在。
(5)糾正錯誤,更改源程序并得到正確的結(jié)果。
3.實(shí)驗(yàn)步驟(1)在工作目錄上新建文件greet.c,并用vi啟動:vigreet.c。
(2)在vi中輸入以上代碼。
(3)在vi中保存并退出,使用命令“:wq”。
(4)用gcc編譯:gcc-ggreet.c-ogreet。
(5)運(yùn)行g(shù)reet,使用命令“./greet”,輸出為:
TheoriginalstringisEmbeddedLinux
Thestringafterwardis
可見,該程序沒有能夠倒序輸出。
(6)啟動gdb調(diào)試:gdbgreet。
(7)查看源代碼,使用命令“l”。
(8)在30行(for循環(huán)處)設(shè)置斷點(diǎn),使用命令“b30”。
(9)在33行(printf函數(shù)處)設(shè)置斷點(diǎn),使用命令“b33”。
(10)查看斷點(diǎn)設(shè)置情況,使用命令“infob”。
(11)運(yùn)行代碼,使用命令“r”。
(12)單步運(yùn)行代碼,使用命令“n”。
(13)查看暫停點(diǎn)變量值,使用命令“pstring2[size-i]”。
(14)繼續(xù)單步運(yùn)行代碼數(shù)次,并檢查string2[size-1]的值是否正確。
(15)繼續(xù)程序的運(yùn)行,使用命令“c”。
(16)程序在printf前停止運(yùn)行,此時依次查看string2[0]、string2[1]…,發(fā)現(xiàn)string[0]沒有被正確賦值,而后面的賦值都是正確的,這時,定位程序第31行,發(fā)現(xiàn)程序運(yùn)行結(jié)果錯誤的原因在于“size-1”。由于i只能增到“size-1”,這樣string2[0]就永遠(yuǎn)不能被賦值而保持NULL,故不能輸出任何結(jié)果。
(17)退出gdb,使用命令“q”。
(18)重新編輯greet.c,把其中的“string2[size-i]=string1[i]”改為“string2[size–i-1]=string1[i];”即可。
(19)使用gcc重新編譯:gcc-ggreet.c-ogreet。
(20)查看運(yùn)行結(jié)果:./greet
TheoriginalstringisEmbeddedLinux
ThestringafterwardisxuniLdeddedbmE
這時,輸出結(jié)果正確。
4.實(shí)驗(yàn)結(jié)果
將原來有錯的程序經(jīng)過gdb調(diào)試,找出問題所在,并修改源代碼,輸出正確的倒序顯示字符串的結(jié)果。
3.7.3編寫包含多文件的makefile1.實(shí)驗(yàn)?zāi)康?p>通過對包含多文件的makefile的編寫,熟悉各種形式的makefile,并且進(jìn)一步加深對makefile中用戶自定義變量、自動變量及預(yù)定義變量的理解。2.實(shí)驗(yàn)過程(1)用vi在同一目錄下編輯兩個簡單的hello程序,如下所示:
#hello.c
#include"hello.h"
intmain()
{
printf("Helloeveryone!\n");
}
#hello.h
#include<stdio.h>
(2)仍在同一目錄下用vi編輯makefile,且不使用變量替換,用一個目標(biāo)體實(shí)現(xiàn)(即直接將hello.c和hello.h編譯成hello目標(biāo)體)。然后用make驗(yàn)證所編寫的makefile是否正確。
(3)將上述makefile使用變量替換實(shí)現(xiàn)。同樣用make驗(yàn)證所編寫的makefile是否正確。
(4)編輯另一個makefile,取名為makefile1,不使用變量替換,但用兩個目標(biāo)體實(shí)現(xiàn)(也就是首先將hello.c和hello.h編譯為hello.o,再將hello.o編譯為hello),再用make的“-f”選項(xiàng)驗(yàn)證這個makefile1的正確性。
(5)將上述makefile1使用變量替換實(shí)現(xiàn)。
3.實(shí)驗(yàn)步驟(1)用vi打開上述兩個代碼文件“hello.c”和“hello.h”。
(2)在shell命令行中用gcc嘗試編譯,使用命令:“gcchello.c–ohello”,并運(yùn)行hello可執(zhí)行文件查看結(jié)果。
(3)刪除此次編譯的可執(zhí)行文件:rmhello。
(4)用vi編輯makefile,如下所示:
hello:hello.chello.h
gcchello.c-ohello
(5)退出保存,在shell中鍵入:make,查看結(jié)果。
(6)再次用vi打開makefile,用變量進(jìn)行替換,如下所示:
OBJS:=hello.o
CC:=gcc
hello:$(OBJS)
$(CC)$^-o$@
(7)退出保存,在shell中鍵入make,查看結(jié)果。
(8)用vi編輯makefile1,如下所示:
hello:hello.o
gcchello.o-ohello
hello.o:hello.chello.h
gcc-chello.c-ohello.o
(9)退出保存,在shell中鍵入:make-fmakefile1,查看結(jié)果。
(10)再次用vi編輯makefile1,如下所示:
OBJS1:=hello.o
OBJS2:=hello.chello.h
CC:=gcc
hello:$(OBJS1)
$(CC)$^-o$@
$(OBJS1):$(OBJS2)
$(CC)-c$<-o$@
在這里請注意區(qū)別“$^”和“$<”。
(11)退出保存,在shell中鍵入make-fmakefile1,查看結(jié)果。
4.實(shí)驗(yàn)結(jié)果各種不同形式的makefile都能正確地完成其功能。
3.7.4使用autotools生成包含多文件的makefile1.實(shí)驗(yàn)?zāi)康?p>通過使用autotools生成包含多文件的makefile,進(jìn)一步掌握autotools的使用方法。同時,掌握Linux下安裝軟件的常用方法。2.實(shí)驗(yàn)過程(1)在原目錄下新建文件夾auto。
(2)將上例的兩個代碼文件“hello.c”和“hello.h”復(fù)制到該目錄下。
(3)使用autoscan生成configure.scan。
(4)編輯configure.scan,修改相關(guān)內(nèi)容,并將其重命名為configure.in。
(5)使用aclocal生成aclocal.m4。
(6)使用autoconf生成configure。
(7)使用autoheader生成config.h.in。
(8)編輯makefile.am。
(9)使用automake生成makefile.in。
(10)使用configure生成makefile。
(11)使用make生成hello可執(zhí)行文件,并在當(dāng)前目錄下運(yùn)行hello查看結(jié)果。
(12)使用makeinstall將hello安裝到系統(tǒng)目錄下,并運(yùn)行,查看結(jié)果。
(13)使用makedist生成hello壓縮包。
(14)解壓hello壓縮包。
(15)進(jìn)入解壓目錄。
(16)在該目錄下安裝hello軟件。
3.實(shí)驗(yàn)步驟(1)mkdir./auto。
(2)cphello.*./auto(假定原先在“hello.c”文件目錄下)。
(3)命令:autoscan。
(4)使用vi編輯configure.scan為:
#-*-Autoconf-*-
#Processthisfilewithautoconftoproduceaconfigurescript.
AC_PREREQ(2.59)
AC_INIT(hello,1.0)
AM_INIT_AUTOMAKE(hello,1.0)
AC_CONFIG_SRCDIR([hello.h])
AC_CONFIG_HEADER([config.h])
#Checksforprograms.
AC_PROG_CC
#Checksforlibraries.
#Checksforheaderfiles.
#Checksfortypedefs,structures,andcompilercharacteristics.
#Checksforlibraryfunctions.
AC_OUTPUT(makefile)
(5)保存退出,并重命名為configure.in。
(6)運(yùn)行:aclocal。
(7)運(yùn)行:autoconf,并用ls查看是否生成了configure可執(zhí)行文件。
(8)運(yùn)行:autoheader。
(9)用vi編輯makefile.am文件為:
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=hello
hello_SOURCES=hello.chello.h
(10)運(yùn)行:automake,然后運(yùn)行automake–a。
(11)運(yùn)行:./configure。
(12)運(yùn)行:make。
(13)運(yùn)行:./hello,查看結(jié)果是否正確。
(14)運(yùn)行:makeinstall。
(15)運(yùn)行:hello,查看結(jié)果是否正確。
(16)運(yùn)行:makedist。
(17)在當(dāng)前目錄下解壓hello-1.0.tar.gz:tar–zxvfhello-1.0.tar.gz。
(18)進(jìn)入解壓目錄:cd./hello-1.0。
(19)下面開始Linux下常見的安裝軟件步驟:./configure。
(20)運(yùn)行:make。
(21)運(yùn)行:./hello(在正常安裝時這一步可省略)。
(22)運(yùn)行:makeinstall。
(23)運(yùn)行:hello,查看結(jié)果是否正確。
4.實(shí)驗(yàn)結(jié)果能夠正確使用autotools生成makefile,并且能夠成功安裝短小的hello軟件。