C語言入門經典(第四版)13-支持功能.ppt_第1頁
C語言入門經典(第四版)13-支持功能.ppt_第2頁
C語言入門經典(第四版)13-支持功能.ppt_第3頁
C語言入門經典(第四版)13-支持功能.ppt_第4頁
C語言入門經典(第四版)13-支持功能.ppt_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第13章 支持功能,前面已完整介紹了C語言以及重要的庫函數。讀者應能使用C語言編寫各種程序了。如果不行,就需要多加練習。學習了一門語言的基本要素之后,所需要做的就是實踐,實踐,再實踐。 最后章將探討一些尚未解決的問題,深入討論預處理器的功能和一些很有用的庫函數 。,13.1 預處理,源代碼在編譯成機器指令之前,要進行預處理。預處理階段可以根據預處理指令(它的第一個字符是#)執(zhí)行一系列服務。預處理階段可以在編譯之前處理及修改C源代碼。完成預處理階段,并分析及執(zhí)行了所有預處理指令后,這些指令就不再出現在源代碼中。編譯器開始編譯階段,生成與程序對應的機器碼 。 在程序中包含頭文件 外部變量及函數 替

2、換程序源代碼 宏替換 看起來像函數的宏 多行上的預處理指令 字符串作為宏參數 結合兩個宏展開式的結果,13.1.1 在程序中包含頭文件,頭文件是外部的文件,使用#include預處理指令可以將它的內容包含在程序中。下面的語句: #include 這會將支持輸入輸出操作的標準庫頭文件放在程序中。將標準庫包含到程序中的一般語句如下: #include ,13.1.2 外部變量及函數,一個由幾個源文件組成的程序,常需要使用在其他文件內定義的全局變量。為此,可以使用關鍵字extern將它們聲明為外部變量。例如,使用如下語句在其他文件內定義了一個全局變量(是在任何函數之外): int number =

3、0; double in_to_mm = 2.54;,13.1.3 替換程序源代碼,程序在編譯之前,預處理器指令會替換源代碼中的符號。最簡單的符號替換前面已介紹過。例如,使用預處理器指令將字符串PI替換為特定值: #define PI 3.14159265; 標識符PI看起來像是變量,但它不是變量,與變量一點關系也沒有。PI是一個標志,有點像憑證,在預處理階段用來替換在#define指令中指定的一串數字。當預處理完成后,準備編譯程序時,PI字符串已經被它的定義取代,不再出現了,13.1.4 宏替換,宏基于前面的#define指令,但它的適用范圍比較大,允許進行多個參數化替換。不僅可以用固定的字

4、符串替換標志符,還允許指定一些參數,而這些參數可以被變元的值取代。 下面是一個例子: #define Print(My_var) printf( %d, My_var) 這個指令提供了兩層替換。一個是用其后的字符串替換Print(My_var),另一個是對My_var的替換。,13.1.5 看起來像函數的宏,這類替換語句的一般形式是: #define macro_name( list_of_identifiers ) substitution_string 在一般情況下,可以有許多參數,因此可定義比較復雜的替換。為了說明如何使用,下面定義一個宏,使用下面的語句找出兩個數中的較大值: #defi

5、ne max(x, y) x y ? x : y,13.1.6 多行上的預處理指令,預處理指令必須在一個邏輯行中,但可以使用續(xù)行符“”將它分成許多行??梢跃帉懭缦抡Z句: #define min(x, y) (x)(y) ? (x) : (y) 這里,語句定義在第二行的第一個非空白字符處繼續(xù),因此只要覺得這樣的安排比較好,可以將文本放在第二行。注意,必須是這行的最后一個字符,其后是回車符 。,13.1.7 字符串作為宏參數,使用宏時,字符串常量是一個潛在的混亂根源。最簡單的字符串替換是單層的定義,例如: #define MYSTR This string 假設編寫了下面的語句: printf(%

6、s, MYSTR); 在預處理期間,這行語句會轉換成: printf(%s, This string ); 結果正確無誤。但在#define指令中定義替換字符串時沒有加上雙引號,它就不會加上雙引號。,13.1.8 結合兩個宏展開式的結果,有時希望宏生成兩個結果,并將它們結合在一起,其中沒有空格。假設定義如下的宏: #define join(a, b) ab 這不能正常工作。這個展開式的定義會解讀成ab,而不是參數a后跟參數b。如果用空格將它們分開,結果也會有一個空格,這不是希望的結果。預處理階段提供了一個運算符來解決這個問題。,13.2 預處理器指定命令,上一個例子看起來好像相當有限,實在很難

7、想象在什么情形下需要把var和123連接起來。畢竟,總是可以使用一個參數,將變元編寫成varl23。但是預處理的一個作用是,允許前一個例子進行多個宏的替換,即一個宏中的變元派生于另一個宏中定義的替換。在上一個例子中,join()宏的兩個變元都可以由其他#define替換或宏生成。預處理也支持提供邏輯if功能的指令,它極大地擴展了預處理階段所能處理的范圍 。 條件編譯 測試指定值的指令 多項選擇 標準預處理宏,13.2.1 條件編譯,第一個要討論的邏輯指令測試前一個#define指令創(chuàng)建的標識符是否存在。它的形式如下: #if defined identifier 如果定義了指定的identif

8、ier,則#if和 #endif之間的語句就包含到程序代碼中。如果沒有定義該標識符,就跳過#if和#endif之間的語句。這和C編程中使用的邏輯過程相同,只是這里將程序語句包含或不包含在源文件中,13.2.2 測試指定值的指令,也可以使用#if指令的一種形式測試常量表達式的值。如果常量表達式的結果不是0,這條語句和下一個#endif之間的所有語句就都包含到程序代碼中。如果常量表達式的結果是0,就跳過這條語句和下一個#endif之間的所有語句。#if指令的一般形式如下: #if constant_expression 它經常用于測試前面的預處理器語句賦予標識符的指定值 。,13.2.3 多項選擇

9、,為了補足#if指令,可以使用#else指令。它的作用和else語句完全相同:當#if條件失敗時,就執(zhí)行一組指令或包含一些語句。例如: #if CPU = Pentium4 printf(nPerformance should be good. ); #else printf(nPerformance may not be so good. ); #endif 在這個例子中,將哪一個printf()語句包含到程序中,取決于CPU是否定義成Pentium4。,13.2.4 標準預處理宏,在編譯器的文檔說明中,通常定義了大量的標準預處理宏。這里只介紹其中兩個比較常用的宏。 宏_DATE_提供日期的

10、字符串表示法,在程序中調用它時,它的格式是Mmm dd yyyy。其中Mmm是月份,如Jan、Feb等,dd是日期,即131的數字,如果是一個數字,就在該數字前面加上空白。yyyy是4位數字的年份,例如2006 。,13.3 調試方法,第一次編寫完程序時,程序大都有一些錯誤。從程序中刪除這些錯誤大致和編寫程序所花的時間成正比。程序越大、越復雜,包含的錯誤就越多,使程序正常運行所需的時間也就越多。一些非常大的程序,如操作系統(tǒng),或復雜的應用程序,如字處理系統(tǒng),甚至C程序開發(fā)系統(tǒng),都因為過于復雜,不可能將錯誤完全消除。讀者也許對此有一些經驗。通常這類殘余的錯誤相當輕微,能與系統(tǒng)一起運行 。 集成的調

11、試器 調試階段的預處理 使用assert()宏,13.3.1 集成的調試器,許多編譯器都在程序開發(fā)環(huán)境中嵌入了大量的調試工具。這些工具的功能很強大,可以顯著減少使程序正常運行所需的時間。一般它們提供了各種幫助測試程序的工具 。,13.3.2 調試階段的預處理,使用條件預處理器指令,可以將代碼塊包含到程序中,以幫助測試。許多C語言開發(fā)系統(tǒng)的調試功能非常強大,但添加自己的追蹤代碼仍舊有用??梢钥刂扑@示的數據的格式,甚至根據程序中的條件或關系,輸出各種不同的數據以用于調試 。,13.3.3 使用assert()宏,assert()宏在標準庫的頭文件中定義。這個宏能在程序中插入測試用的任意表達式,如

12、果表達式是false(等于0),程序就中止,并輸出一條診斷信息。assert()宏的變元是一個結果為整數的表達式,例如: assert(a = b); 如果a等于b,表達式的結果就是true(非零)。如果a不等于b,表達式的結果就是false,程序就輸出一條相關的斷言信息,然后中止。程序的中止是調用 abort()實現的,所以是不正常結束。調用abort()時,程序會立即終止。流輸出緩沖區(qū)是否刷新,打開的流是否關閉,臨時文件是否刪除,都取決于C的實現方式,所以應參閱編譯器的文檔說明 。,13.4 其他庫函數,庫函數是C語言強大的基礎。前面已經介紹了許多標準庫函數,但討論所有的標準庫函數超出了本

13、書的范圍。但是本節(jié)打算介紹一些目前還未使用的常用函數 。 日期和時間函數庫 獲取日期,13.4.1 日期和時間函數庫,時間是一個很重要的參數,所以C的標準庫包含了一些處理時間與日期的函數。它們可以根據計算機的硬件計時器提供各種不同格式的輸出。 最簡單的函數原型如下: clock_t clock(void);,13.4.2 獲取日期,有一個自25年前開始算起的時間(秒)是很重要的,但使今天的日期顯示為字符串更方便。為此,可以使用函數ctime(),它的原型如下: char *ctime(const time_t *timer); 這個函數接受一個time_t變量的指針作為變元,它含有time()函數返回的日歷時間值。它返回一個指向26個字符的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論