版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1. C語(yǔ)言l 預(yù)處理2.1預(yù)處理操作符 .預(yù)處理操作符只用在宏定義的單詞系列中,其中#是一元操作符,#是二元操作符, 例如: #a ; a#b # 以預(yù)處理操作符#號(hào)開(kāi)頭的宏參數(shù),有它自己對(duì)應(yīng)的轉(zhuǎn)換為字符串字面量的非擴(kuò)展實(shí) 參數(shù).(字符變量或字符串變量成員中包含的每個(gè)雙引號(hào)和反斜線都使用反斜線轉(zhuǎn)義). 這個(gè)規(guī)則僅在類似函數(shù)的宏內(nèi)部中使用. # 如果一個(gè)替換單詞系列包含#操作符,則刪除#以及它前后的空格符,把相鄰的單詞連 接起來(lái),建立一個(gè)新單詞.這種情況僅在擴(kuò)展宏時(shí)才發(fā)生,可用在任何宏定義.例如: #define M1 3 #define M2 M1#2 M2 = M12 注:1.#只能用在宏
2、函數(shù)的定義中,#可用在任何情況 2.#的操作數(shù)如是宏,則預(yù)編譯時(shí),該宏不展開(kāi) 3.#首先把它兩邊的空格去掉,把#兩邊的字符連接起來(lái),#的操作數(shù)如是宏,則預(yù)編譯 時(shí),該兩個(gè)宏不展開(kāi)2.2預(yù)處理數(shù) 預(yù)處理數(shù)由一個(gè)數(shù)字構(gòu)成,前面可以加一個(gè)可選的點(diǎn)號(hào),后面可以跟著字母,下劃線,數(shù)字,點(diǎn)號(hào)以及一個(gè)e+,e-,E+或E-,例: #define R 2e#32.3宏定義和擴(kuò)展 格式: #define MacroName token-sequence #define MacroFunc(identifier-list) token-sequence 擴(kuò)展:1.實(shí)參在調(diào)用中可以被擴(kuò)展,然后,它們替換宏定義在替換
3、單詞系列中對(duì)應(yīng)的參數(shù).如 果宏實(shí)參在替換串里是#或#的操作數(shù),那么在調(diào)用中不擴(kuò)展它們,否則都實(shí)行擴(kuò)展. 例如: #define M1 3 FLM(a,b)定義 調(diào)用 結(jié)果 是否擴(kuò)展 a+b FLM(2,3) 2+3 a+b FLM(M1,2) 3+2 是,是 #a FLM(M1,2) “M1” 否 a#b FLM(M1,2) M12 否,否 a+#a FLM(M1,2) 3+”M1” 是,否2.4條件編譯 #ifdef #ifndef #elif #else #endif #ifdef后的條件表達(dá)式之一: defined(MacroName)2.5行控制 #line constant “fil
4、ename” 含義:使編譯程序相信,為了出錯(cuò)診斷和排錯(cuò)的目的,下一個(gè)源碼行的行號(hào)等于constant(它 必須是十進(jìn)制)2.6斷言 格式: 定義 #assert predicate(token-sequence) 刪除 #unassert predicate(token-sequence) 一個(gè)斷言可以在#if語(yǔ)句中用下述語(yǔ)法測(cè)試: #if # predicate(token-sequence) 假如定義了斷言,則返回真. 系統(tǒng)為6386提供下列缺省謂詞: #assert machine(i386) #assert system(unix) #assert cpu(i386) 2.7版本控制
5、格式: #ident “version”2.8出錯(cuò)信息生成 格式: #error token-sequence 含義:使編譯系統(tǒng)產(chǎn)生一條包含token-sequence的診斷信息,然后停止l 變量的定義 .C語(yǔ)言編寫的程序是以函數(shù)為基礎(chǔ)的,其中main也是一個(gè)函數(shù)(主函數(shù)),所以任何一個(gè) 變量,它只可能要么在函數(shù)內(nèi)定義,要么在函數(shù)外定義.定義一個(gè)變量時(shí)應(yīng)先確定該變量的 作用域,其次在確定該變量在內(nèi)存中的生存期(對(duì)于變量的生存期與變量在內(nèi)存中所分配 的空間有很大的聯(lián)系) .定義一個(gè)變量的三要素:1.何地定義(確定作用域);2.數(shù)據(jù)類型;3.數(shù)據(jù)的存儲(chǔ)類別(確定 變量的生存周期) 1.從變量的作用
6、域來(lái)看變量 .局部變量:在一個(gè)函數(shù)內(nèi)部定義的變量,它只在本函數(shù)內(nèi)才能使用,在函數(shù)外是不能使 用這些變量. .補(bǔ)充:主函數(shù)main中定義的變量也只在主函數(shù)中有效,而主函數(shù)也不能使用在其 它函數(shù)中定義的局部變量 不同函數(shù)中可以用相同名字的變量,它們之間互不干擾. 函數(shù)的形參也是局部變量 在函數(shù)內(nèi)部,可以在復(fù)合語(yǔ)句中定義變量,這些變量也只在本復(fù)合 語(yǔ)句中有效.如下: main( ) int a,b; : int c; c=a+b; 其中c變量只在子括號(hào)中有效 .全局變量:在一個(gè)函數(shù)外部定義的變量,它的有效范圍:從定義變量的位置開(kāi)始到本源 文件結(jié)束.2.從變量的生存期來(lái)看 .存儲(chǔ)方式有:1.自動(dòng)的(a
7、uto);2.靜態(tài)的(static);3.寄存器的(register);4.外部的(extern) .寄存器變量:即把局部變量存放在寄存器中 補(bǔ)充:只有局部變量和形式參數(shù)能定義為寄存器變量 寄存器變量的生命周期在本次函數(shù)調(diào)用結(jié)束后即結(jié)束 一個(gè)計(jì)算機(jī)系統(tǒng)中能定義的寄存器變量是有限的 自動(dòng)變量:函數(shù)中的局部變量如不做說(shuō)明,都是動(dòng)態(tài)分配存儲(chǔ)空間的,其空間是由編譯系統(tǒng) 自動(dòng)釋放的 補(bǔ)充:只有局部變量和形式參數(shù)能定義為自動(dòng)變量 自動(dòng)變量的生命周期在本次函數(shù)調(diào)用結(jié)束后即結(jié)束 外部變量:是在函數(shù)的外部定義的,編譯時(shí)分配在靜態(tài)存儲(chǔ)區(qū) 補(bǔ)充:只有全局變量能定義為外部變量 外部變量的生命周期從該變量的定義開(kāi)始到進(jìn)
8、程結(jié)束 靜態(tài)變量:可用在自動(dòng)變量,外部變量之前,改變自動(dòng)變量,外部變量的生存期 局部靜態(tài)變量:能使局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,即占用的存儲(chǔ)單 元不釋放,在下一次調(diào)用該函數(shù)時(shí),該變量已有值,就是上一次函數(shù)調(diào)用結(jié)束 時(shí)的值. 補(bǔ)充:只有局部變量能定義為局部靜態(tài)變量 初始化的局部靜態(tài)變量的生命周期從該變量的定義開(kāi)始到進(jìn)程結(jié)束 未初始化的局部靜態(tài)變量的生命周期從該變量的第一次調(diào)用開(kāi)始到進(jìn)程結(jié)束 靜態(tài)局部變量在靜態(tài)存儲(chǔ)區(qū)內(nèi)分配空間,自動(dòng)變量則在動(dòng)態(tài)存儲(chǔ)區(qū)分配空間 靜態(tài)局部變量在定義時(shí),如沒(méi)賦初值,系統(tǒng)給其賦缺省值0或空字符,而對(duì)自動(dòng)變 量則不賦初值 只有靜態(tài)局部變量能對(duì)數(shù)組進(jìn)行初始化
9、全局靜態(tài)變量:保留外部變量可以在全局使用的特性,但該變量?jī)H局限于在定義該變量的 文件中使用,在別的文件中不能使用. .函數(shù)也可定義靜態(tài)函數(shù),作用同全局靜態(tài)變量 .各種變量在內(nèi)存中的表示:l 指針1.指針的類型定義含義Int *p指向整型變量的指針I(yè)nt *pn指向整型變量的指針數(shù)組,每一個(gè)元素的是指針變量Int (*p)n指向含n個(gè)元素的一維數(shù)組的指針變量(少用此類型)Int *p( )返回值為指針變量的函數(shù)Int (*p)( )指向函數(shù)的指針I(yè)nt *p指向指針變量的指針Void *p無(wú)類型指針2. 指針的基本特性 指針變量是用來(lái)存放內(nèi)存中某一地址空間的地址的變量.指針變量指向的空間只能是
10、用malloc分配的空間或程序中定義的變量擁有的地址空間也僅只能使用以上兩種空間, 其中用malloc分配的空間必須釋放.因?yàn)橹羔樧兞看娣诺氖堑刂?所以任何數(shù)據(jù)類型的變 量的地址基本上都可以賦給指針變量,僅需在賦值時(shí)進(jìn)行強(qiáng)制類型為指針變量定義時(shí)的 類型.指針變量指向的空間是很自由的,所以能使指針指向任何空間,同時(shí)對(duì)指針指向空間 范圍的控制,指向空間的控制也就必須由用戶來(lái)控制.3. 指針的基本運(yùn)算 指針變量加減一個(gè)整數(shù)是將指針變量的地址和它指向的變量所占的內(nèi)存字節(jié)數(shù)相加減 當(dāng)定義一個(gè)指針變量時(shí),應(yīng)給它賦初值為NULL(NULL在stdio.h中定義),否則指針變 量可能指向一個(gè)事先未指定的空間
11、對(duì)于指向同一個(gè)數(shù)組的兩個(gè)指針變量可以進(jìn)行相減,差是兩個(gè)指針之間元素個(gè)數(shù);但相 加沒(méi)有意義 對(duì)于指向同一個(gè)數(shù)組的兩個(gè)指針變量可以進(jìn)行比較,指向前面元素的指針變量小于指 向后面元素的指針變量 malloc分配的空間是void類型的,所以在給指針變量賦值時(shí)必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換4. 指針變量與const的關(guān)系 指向常量的指針 語(yǔ)法: const char *p 功能:p指向的變量的值不能改變(用*p去訪問(wèn)該變量時(shí)),但p的值可以改變.即可以 賦不同的地址給p,但對(duì)于每一個(gè)已賦給p的地址空間,用給*p賦值的方法來(lái)改 變地址空間指向的值是不行的,但用原變量賦值是可以的. example: const ch
12、ar *p; char ch; p=&ch; p=a; /*錯(cuò)*/ ch=a; /*正確*/常指針 語(yǔ)法: char * const p=&ch; 功能:指針變量p的值是固定的且必須在定義時(shí)就進(jìn)行賦值,但p指向的空間的值卻 是可以改變的l 函數(shù)調(diào)用時(shí)系統(tǒng)內(nèi)部的處理步驟1. 把實(shí)參壓入堆棧中,在把函數(shù)的返回地址壓入堆棧中2. 在堆棧中為形參分配空間,同時(shí)把實(shí)參的值拷貝給形參3. 為函數(shù)的局部變量分配空間,執(zhí)行函數(shù)體程序4. 函數(shù)返回,釋放堆??臻g2.C語(yǔ)言程序的編譯過(guò)程1. 編譯預(yù)處理,對(duì)源程序中的偽指令進(jìn)行處理;C語(yǔ)言中的偽指令主要包括四個(gè)方面: 宏定義指令,如#define
13、條件編譯指令,如#ifdef , #ifndef , #else , #elif , #endif 頭文件包括指令,如#include 特殊符號(hào),如_FILE_,_LINE_,_DATE_,_TIME_,_STDC_在編譯時(shí)即進(jìn)行 替換5. 編譯階段,把經(jīng)過(guò)編譯預(yù)處理編譯成匯編程序6. 優(yōu)化階段7. 匯編過(guò)程,把匯編程序編譯成目標(biāo)程序;目標(biāo)程序主要由兩個(gè)段組成: 代碼段 主要是程序的指令.該段是可讀可執(zhí)行的,但確不可寫 數(shù)據(jù)段 主要是程序的個(gè)種全局或靜態(tài)的數(shù)據(jù),一般都是可讀,可執(zhí)行,可寫的 UNIX環(huán)境下有三類目標(biāo)文件:可重定位文件(匯編得到地是此類文件); 共享的目標(biāo)文件; 可執(zhí)行文件8.
14、鏈接程序,通過(guò)匯編得到的目標(biāo)文件經(jīng)過(guò)鏈接形成可執(zhí)行文件;鏈接的方式有兩種: 靜態(tài)鏈接:函數(shù)的代碼將從其所在的靜態(tài)庫(kù)中拷貝到最終的可執(zhí)行文件中,程序運(yùn)行 時(shí)該函數(shù)將被拷貝到內(nèi)存中 動(dòng)態(tài)鏈接:函數(shù)被放到動(dòng)態(tài)鏈接庫(kù)中;鏈接時(shí),可執(zhí)行程序中僅含有該動(dòng)態(tài)庫(kù)和該函數(shù) 的簡(jiǎn)單信息.運(yùn)行時(shí),把該動(dòng)態(tài)庫(kù)的內(nèi)容全部映射到內(nèi)存中.但該庫(kù)能被別的 進(jìn)程共享3.CC編譯器的使用cc Options file -Bc這里c可以是dynamic或static. Bdynamic 指示鏈接程序?qū)?yīng)于其后的-lx選項(xiàng),應(yīng)搜索 名為libx.so的動(dòng)態(tài)庫(kù),找不到才搜索libx.a庫(kù).-Bstatic只搜索libx.a庫(kù)
15、;缺省狀況下先搜索 libx.so動(dòng)態(tài)庫(kù),其次才搜索libx.a庫(kù)-C 在編譯時(shí)不要?jiǎng)h除原文件中的注釋-c 指示cc不進(jìn)行鏈接,不要?jiǎng)h除所生成的任何文件-Dname=tokens 定義一個(gè)宏name,并將其值指定為tokens.其效果同在源文件中使 用:#define name tokens一樣.當(dāng)不指定tokens時(shí),name的值將是1-dc 這里c可以是y或n.-dy指定進(jìn)行動(dòng)態(tài)鏈接(缺省方式).指定-dn則進(jìn)行靜態(tài)鏈接.-G 指定鏈接程序生成一個(gè)可共享的目標(biāo)文件-g 告訴編譯程序在目標(biāo)代碼中加入供調(diào)試程序sdb用的附加信息-H 顯示當(dāng)前編譯過(guò)程中所包括的每一個(gè)文件的路徑名,每行一個(gè)-Id
16、ir 指定頭文件搜索路徑.各-I選項(xiàng)指定的路徑將在標(biāo)準(zhǔn)路徑之前被搜索-K PIC 指示cc產(chǎn)生獨(dú)立于位置的代碼(PIC)-Ldir 把指定的dir加到鏈接程序搜索庫(kù)文件的路徑表中-I name 搜索庫(kù)文件libname.so或libname.a-O 進(jìn)行編譯優(yōu)化-o pathname 指定鏈接程序最終生成的目標(biāo)文件為pathname.而非缺省a.out-P 對(duì)指定的.c文件進(jìn)行編譯預(yù)處理,將得到的結(jié)果放到.i文件中-V 讓每個(gè)被調(diào)用的工具均在標(biāo)準(zhǔn)錯(cuò)誤輸出上顯示其版本信息-v 指示編譯程序進(jìn)行更為嚴(yán)格的語(yǔ)義檢查注:1.在cc沒(méi)跟任何參數(shù)時(shí),系統(tǒng)將使用/etc/default/cc文件中的缺省參數(shù)
17、FLAGS 和LIBS的 設(shè)置.但可設(shè)置環(huán)境變量CCFLAGS和CCLIBS,TMPDIR來(lái)代替FLAGS和LIBS的值 2.鏈接時(shí),在同一路徑下既有動(dòng)態(tài)庫(kù)(.so)又有靜態(tài)庫(kù)(.a)則優(yōu)先鏈接動(dòng)態(tài)庫(kù)4.ar檔案生成器的使用.ar -V key Arg PosName afile Name-V 指示ar在標(biāo)準(zhǔn)錯(cuò)誤輸出上顯示其版本信息-key key為如下字母中的一個(gè): d 從檔案文件afile中刪除指定的文件Name r 用指定的文件Name替換檔案afile中已有的文件Name.在r后可跟一個(gè)選項(xiàng)u,此 時(shí)ar將只替換修改日期比檔案文件要晚的那些文件.如果指定a,b或I這三個(gè)選 項(xiàng),則應(yīng)指定
18、PosName參數(shù).a選項(xiàng)指示ar將新文件放到檔案中PosName之后,b 或I則指定放在其前面 q 將指定文件Name簡(jiǎn)單放到文件尾部 t 列表顯示檔案文件中的內(nèi)容.在指定Name時(shí),只列出指定的那些文件 p 顯示檔案中的指定文件Name m 將指定的文件Name移到檔案文件尾.如果在此關(guān)鍵字之后指定了a,b或I選項(xiàng), 則必須指定PosName x 從檔案文件中提取出指定的那些文件Name.不指定時(shí),提出所有文件.5.動(dòng)態(tài)靜態(tài)庫(kù)地編寫l 動(dòng)態(tài)靜態(tài)庫(kù)的生成1.靜態(tài)庫(kù)生成: cc c function1.c function2.c function3.c ar -r libfoo.a funct
19、ion1.o function2.o function3.o2.動(dòng)態(tài)庫(kù)生成: cc K PIC G o $HOME/lib/libtest.so myfunc.cl 鏈接程序搜索目錄1. 對(duì)非標(biāo)準(zhǔn)庫(kù)的鏈接搜索目錄的設(shè)置,有如下兩種方法: 在cc命令中加入-L選項(xiàng)以指定非標(biāo)準(zhǔn)的庫(kù)文件所在的目錄 利用環(huán)境變量定義非標(biāo)準(zhǔn)庫(kù)的鏈接搜索目錄,定義方式如下: $ LD_LIBRARY_PATH=dir1:dir2:dir3;dir4:dir5 $ export LD_LIBRARY_PATH 注:1.dir必須為絕對(duì)路徑 2. 在環(huán)境變量中分號(hào)之前的的各個(gè)目錄將被鏈接程序在-L指定的路徑之前被搜索;而分號(hào)
20、之 后的各路徑則在-L指定的路徑之后被搜索.其中用分號(hào)將兩部路徑分開(kāi)并不是必需的3. 在同一鏈接中使鏈接程序?qū)δ承?kù)進(jìn)行靜態(tài)鏈接而對(duì)另外一些庫(kù)使用動(dòng)態(tài)鏈接的方法: 將靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)放到不同的目錄中 利用-Bstatic和-Bdynamic取消或轉(zhuǎn)向動(dòng)態(tài)鏈接,例: cc L$(HOME)/lib file1.c file2.c Bstatic lfoo file3.c Bdynamic lsharedob 注:使用-Bstatic后必須使用-Bdynamic,否則缺省庫(kù)libc被靜態(tài)鏈接4.動(dòng)態(tài)鏈接程序運(yùn)行時(shí),對(duì)非標(biāo)準(zhǔn)動(dòng)態(tài)庫(kù)的搜索的方法: 通過(guò)設(shè)置LD_RUN_PATH或LD_LIBRARY_P
21、ATH環(huán)境變量來(lái)指定運(yùn)行時(shí)非標(biāo)準(zhǔn)動(dòng)態(tài) 庫(kù)的搜索路徑,方式如下: $ LD_RUN_PATH=$HOME/lib1:$HOME/lib2:$HOME/lib3 $ export LD_RUN_PATH $ LD_LIBRARY_PATH=dir1:dir2:dir3;dir4:dir5 $ export LD_LIBRARY_PATH 注:在搜索完LD_RUN_PATH指定的各個(gè)目錄后,如設(shè)置了LD_LIBRARY_PATH, 則再搜索LD_LIBRARY_PATH指定的各個(gè)目錄.搜索完后,動(dòng)態(tài)鏈接程序?qū)⒏?據(jù)缺省設(shè)置搜索系統(tǒng)標(biāo)準(zhǔn)位置 LD_RUN_PATH與LD_LIBRARY_PATH的區(qū)別
22、: . LD_RUN_PATH:在編譯時(shí),動(dòng)態(tài)被放在某一目錄$HOME/lib1下;運(yùn)行時(shí),把動(dòng)態(tài)庫(kù)移到 了目錄$HOME/lib2下,同時(shí)修改LD_RUN_PATH變量.此時(shí)程序是無(wú) 法找到該庫(kù). . LD_LIBRARY_PATH: 在編譯時(shí),動(dòng)態(tài)被放在某一目錄$HOME/lib1;運(yùn)行時(shí),把動(dòng)態(tài)庫(kù) 移到了目錄$HOME/lib2下,同時(shí)修改LD_LIBRARY_PATH,此時(shí)程序 能找到所需的庫(kù)l .動(dòng)態(tài)庫(kù)的建立原則1. 準(zhǔn)備知識(shí)1. 進(jìn)程上下文在內(nèi)存中的映射2. C語(yǔ)言程序在內(nèi)存中的映射3. UNIX目標(biāo)文件的結(jié)構(gòu)2. 建立共享庫(kù)原則(臨時(shí)待修改)1. 盡量減小共享數(shù)據(jù)段的大小 盡量使
23、用自動(dòng)(堆棧)變量.如果自動(dòng)變量行得通,就不要使用全局變量或靜態(tài)變量 盡量使用函數(shù)接口而少用全局變量進(jìn)行參數(shù)的傳遞. 將那些大量使用全局變量的函數(shù)排除在動(dòng)態(tài)鏈接庫(kù)之外.對(duì)于此類函數(shù),將其放到靜態(tài)鏈接庫(kù)中比較合適 動(dòng)態(tài)鏈接庫(kù)是自包的.也就是說(shuō)在生成某個(gè)動(dòng)態(tài)鏈接庫(kù)時(shí),對(duì)其他庫(kù)的函數(shù)調(diào)用不要使用 動(dòng)態(tài)鏈接而應(yīng)使用靜態(tài)鏈接.2. 盡量減少內(nèi)存頁(yè)面的交換動(dòng)作 改進(jìn)對(duì)符號(hào)引用的定位性 其一,在共享庫(kù)中排除哪些很少使用的,庫(kù)本身不依賴于它們 的那些函數(shù)定義 其二,要盡可能的把相關(guān)的函數(shù)組合在一起,放到同一頁(yè)面以 改進(jìn)引用的定位性 調(diào)整頁(yè)面安排 主要是指對(duì)共享庫(kù)的目標(biāo)文件進(jìn)行整理,使那些頻繁使用的函數(shù)的代碼
24、不要越過(guò)頁(yè)邊界而被分到兩個(gè)不同的頁(yè)上去.相關(guān)工具有nm命令l 核實(shí)運(yùn)行時(shí)的兼容性 .在采用動(dòng)態(tài)鏈接庫(kù)進(jìn)行鏈接的程序中,動(dòng)態(tài)庫(kù)與可執(zhí)行程序是可以分開(kāi)編譯的,也就是當(dāng)修改了動(dòng)態(tài)庫(kù)程序時(shí),僅需要編譯動(dòng)態(tài)庫(kù)程序,并不需要編譯可執(zhí)行程序.問(wèn)題與由此而產(chǎn)生,當(dāng)刪除某函數(shù)而又沒(méi)有編譯原可執(zhí)行程序時(shí),則可執(zhí)行程序只有執(zhí)行到調(diào)用此函數(shù)的位置才會(huì)發(fā)現(xiàn)錯(cuò)誤,用ldd命令或設(shè)置環(huán)境變量LD_BIND_NOW將可解決此問(wèn)題. $ ldd -r|-d prog(可執(zhí)行程序) -d 打印關(guān)于prog執(zhí)行時(shí),將遇到的每一個(gè)未解決的數(shù) 據(jù)引用的診斷. -r 打印關(guān)于prog執(zhí)行時(shí),將遇到的每一個(gè)未解決的數(shù) 據(jù)或函數(shù)引用的診斷
25、設(shè)置: $LD_BIND_NOW=1 export LD_BIND_NOW 注:設(shè)置LD_BIND_NOW后,在main( )開(kāi)始執(zhí)行以前,要求動(dòng)態(tài)鏈接程序立即解決所有 的函數(shù),數(shù)據(jù)的引用 6.makefile文件的編寫規(guī)則.makefile主要描述目的文件,依賴文件之間的關(guān)系與及相應(yīng)的操作l 注釋:符號(hào)#和在它之后的同一行的所有字符將被忽略l 續(xù)行:如一行太長(zhǎng),則可用來(lái)續(xù)行;make文件能把間的上下兩行合并為一行l(wèi) make變量(宏)1.用戶自定義變量宏名(字母和數(shù)字)=字符串(字母和數(shù)字)注:1.宏名前不能有冒號(hào)(:)或制表符,字符串中可包含空格,字符串前后的空格將被去掉 2.宏的引用方式
26、:$(宏名)例: abc= -ll ly LIBES=2.make缺省定義的宏類別宏名缺省值檔案庫(kù)ARarARFLAGSrvC編譯命令CCccCFLAGSCPPFLAGSCOMPILE.c$(CC) $(CFLAGS) $(CPPFLAGS) cLINK.cc$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)Rm 命令RMrm f3.make動(dòng)態(tài)宏名稱含義$當(dāng)前目標(biāo)文件名稱(用于命令行)$當(dāng)前目標(biāo)文件名稱(用于依賴關(guān)系行中)$?比當(dāng)前目的文件更新的那些依賴文件.對(duì)于引用了此變量的命令行將不在進(jìn)行依賴檢查(等同于在規(guī)則中命令行的開(kāi)頭加上”?”字符)$*去掉后綴的當(dāng)前文件
27、名名稱,只能用在隱含規(guī)則中$<當(dāng)前目的文件的依賴文件名,只能用在隱含規(guī)則中$%若當(dāng)前文件是一個(gè)靜態(tài)庫(kù)文件成員名,則$%表示的是該成員的名稱,而此時(shí)$表示的是相應(yīng)的庫(kù)文件名稱4.make變量同Shell環(huán)境變量交互作用.環(huán)境變量可以在makefile中使用,方法為:$(環(huán)境變量名).環(huán)境變量也可以在makefile中重新定義,其值按如下順序判定 缺省狀況:讀入內(nèi)部宏定義表 讀入環(huán)境變量,在makefile定義相同變量 讀入makefile,makefile中的賦值取代環(huán)境變量的值 讀入命令行 make e:讀入內(nèi)部宏定義表 讀入makefile,makefile中進(jìn)行賦值 讀入環(huán)境變量,取
28、代makefile中的賦值 讀入命令行5.變量的條件賦值6.變量值的替換格式: $(Macro:String1=String2)含義:make把指定的變量Macro的值中所有的String1串均替換成String2.當(dāng)String2沒(méi)有定 義時(shí),Macro值中的所有String1均被刪除掉.例:OBJECTS=myprog.o myfunc.o $(OBJECTS:.o=.c) OBJECTS=myprog.c myfunc.cl 規(guī)則的一般描述形式形式一:目的文件名列表:依賴文件名列表;Shell命令形式二: 目的文件名列表:依賴文件名列表 t命令 t命令 注: 1.t 表示Tab鍵,命令可
29、為除cc外的UNIX操作命令 2.目的文件名列表與依賴文件名列表必須在同一行 3.可以在Tab與命令行之間插入如下四個(gè)特殊字符,而使make對(duì)相應(yīng)命令進(jìn)行特殊處理: - 指示make不必理睬所執(zhí)行的命令是否成功返回(退出碼不為0)而繼續(xù)進(jìn)行處理. 一般情況下,當(dāng)退出碼不為0,make將終止 指示make在生成Shell進(jìn)程執(zhí)行相應(yīng)命令時(shí)不要顯示此命令行 ? 指示make不進(jìn)行命令依賴性檢查 ! 強(qiáng)制進(jìn)行命令的依賴檢查 4.當(dāng)一個(gè)目標(biāo)文件出現(xiàn)在多個(gè)依賴關(guān)系行中時(shí),使用單冒號(hào)與雙冒號(hào)具有明顯差別: 使用單冒號(hào),則從該目標(biāo)文件所在的第一個(gè)依賴關(guān)系行到最后一個(gè)依賴關(guān)系行進(jìn)行 搜索,若某個(gè)依賴關(guān)系行中的
30、依賴文件比目標(biāo)文件新,則make按該目標(biāo)文件所在的 的第一個(gè)依賴關(guān)系行的命令組進(jìn)行編譯 注:1.依賴關(guān)系的兩層含義:確定目標(biāo)文件何時(shí)編譯,如依賴文件比目標(biāo)文件新,則 進(jìn)行編譯 確定目標(biāo)文件根據(jù)什么文件來(lái)生成 2.在單冒號(hào)依賴關(guān)系中,第一個(gè)依賴關(guān)系行確定目標(biāo)文件何時(shí)編譯, 確定目標(biāo)文 件根據(jù)什么文件來(lái)生成; 第二個(gè)依賴關(guān)系行僅確定目標(biāo)文件何時(shí)編譯, 目標(biāo) 文件根據(jù)什么文件來(lái)生成則由第一個(gè)依賴關(guān)系行來(lái)確定 使用雙冒號(hào),則從該目標(biāo)文件所在的第一個(gè)依賴關(guān)系行到最后一個(gè)依賴關(guān)系行進(jìn) 行搜索,若某個(gè)依賴關(guān)系行中的依賴文件比目標(biāo)文件新,則編譯該依賴關(guān)系行;然后 在繼續(xù)往下一個(gè)依賴關(guān)系行進(jìn)行搜索.若搜索到某個(gè)
31、依賴關(guān)系行中的依賴文件比目 標(biāo)文件新,則編譯該依賴關(guān)系行;繼續(xù).l 依賴關(guān)系的確定(略)l make的后綴規(guī)則.利用文件后綴來(lái)描述文件之間的依賴關(guān)系1.可識(shí)別的常用后綴SUFFIXES=.o.c.c.y.y.l.l.s.s.sh.sh.h.h.o目標(biāo)文件.c源文件.cSCCS C文件.yYacc C源文件.ySCCS yacc C源文件.lLex C源文件.lSCCS Lex C源文件.s匯編文件.sSCCS匯編文件.shShell文件.shSCCS Shell文件.h前導(dǎo)文件SUFFIXES是make的一個(gè)缺省變量,其中記錄了系統(tǒng)能識(shí)別的缺省后綴名,在make中加入自定義的后綴的方法如下:
32、.SUFFIXES:.x (x為自定義后綴)2.make的標(biāo)準(zhǔn)后綴規(guī)則.SUFFIXES: .o.c.c.y.y.l.l.s.s.sh.sh.h.h等AR=arARFLAGS= -rvAS=asCC=ccCFLAGS=CPPFLAGS=COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) cLINK.cc=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)RM= Rm fGET=getLD=ldLDFLAGS=.c: $(CC) $(CFLAGS) $( LDFLAGS) o $ $<.sh: $(GET) $(GFLAGS) $< cp $*.sh $*;chmod 0777 $ rm f $*.sh.c: $(
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024版石灰石供應(yīng)合同模板
- 二零二五年度應(yīng)急管理及救援裝備租賃合同3篇
- 2025年度人工智能專利池共享與許可合同3篇
- 2025年度城市公共交通設(shè)施建設(shè)合同規(guī)范3篇
- 二零二四年商業(yè)地產(chǎn)項(xiàng)目新型業(yè)態(tài)招商代理服務(wù)合同樣本3篇
- 年度芳香除臭化學(xué)品:空氣清新劑產(chǎn)業(yè)分析報(bào)告
- 2025年新型材料現(xiàn)貨購(gòu)銷合同標(biāo)準(zhǔn)范本3篇
- 2024-2025學(xué)年高中歷史第二單元古希臘和古羅馬的政治制度單元總結(jié)學(xué)案含解析岳麓版必修1
- 2025年度校園配送服務(wù)食品安全快速檢測(cè)質(zhì)量管理體系建設(shè)合同3篇
- 2025年度人工智能算法工程師保密協(xié)議及知識(shí)產(chǎn)權(quán)保護(hù)合同3篇
- 2025年病案編碼員資格證試題庫(kù)(含答案)
- 企業(yè)財(cái)務(wù)三年戰(zhàn)略規(guī)劃
- 提高膿毒性休克患者1h集束化措施落實(shí)率
- 山東省濟(jì)南市天橋區(qū)2024-2025學(xué)年八年級(jí)數(shù)學(xué)上學(xué)期期中考試試題
- 主播mcn合同模板
- 新疆2024年中考數(shù)學(xué)試卷(含答案)
- 2024測(cè)繪個(gè)人年終工作總結(jié)
- DB11 637-2015 房屋結(jié)構(gòu)綜合安全性鑒定標(biāo)準(zhǔn)
- 制造業(yè)生產(chǎn)流程作業(yè)指導(dǎo)書(shū)
- DB34∕T 4444-2023 企業(yè)信息化系統(tǒng)上云評(píng)估服務(wù)規(guī)范
- 福建中閩能源股份有限公司招聘筆試題庫(kù)2024
評(píng)論
0/150
提交評(píng)論