C標準庫“聖經”:C標準庫
【作 者】(美)P.J.Plauger [同作者作品] [作譯者介紹]
【譯 者】 盧紅星;徐明亮;霍建同[同譯者作品]
【叢 書 名】 圖靈程式設計叢書
【出 版 社】 人民郵電出版社 【書 號】 9787115172860
【上架時間】 2009-6-2
【出版日期】 2009 年7月 【開 本】 16開
市場價 :¥79.00
會員價 : ¥59.25(75折)
網上預訂及樣章試讀http://www.china-pub.com/195624
【編輯精選】
C標準庫“聖經”.
提供完整原始碼,全面深入闡述庫函數的實現與運用..
C程式員必備參考書...
【內容簡介】
本書是由世界級C語言專家編寫的C標準庫經典著作。英文版已經重印十多次,影響了幾代程式員。.
本書結合C標準的 相關部分,精闢地講述了每一個庫函數的使用方法和實現細節,而這正是一個真正的C程式員所必須掌握的。更重要的是,書中給出了實現和測試這些函數的完整源 代碼,可以讓你更深入地學習C語言。不僅如此,本書還討論了一些即使是最有經驗的C程式員通常也不熟悉的知識,比如國際化和獨立於地區設定的程式的編寫、 與構建庫相關的概念和設計思想。...
前言
本書將告訴你如何使用符合C 語言的ANSI/ISO 標準的庫函數。因為已經有很多書出色地講解了C 語言本身,所以本書只專註於“庫”這個話題。本書還會告訴你C 標準庫是如何?的。本書提供了大約9 000 行測試過的可實際工作的代碼。我相信,看了C 標準庫的實現細節後你能更好地理解如何使用它。
庫函數的實現代碼儘可能地使用標準C,這樣做有3 個設計目的:首先,它使代碼具有可讀性和示範性;其次,它使代碼在各種電腦體繫結構間具有高度可移植性;最後,它能使編寫的代碼兼顧正確性、效能和規模各方面。
教你如何編寫C 程式並不是本書的目的。本書假定你能讀懂簡單的C 程式,對於那些稍有難度的代碼,我會向你解釋其中的痛點和技巧。
C 標準庫
C 標準庫是非常強大的,它在多種不同的環境下提供了相當多的功能:它允許使用者和實現者使用明確定義的名字空間;它對其所提供的數學函數的健壯性和精確性有非常嚴格的要求; 它率先對適應不同文化習慣的代碼提供支援,包括那些擁有很大字元集的文化習慣。
為了能有效利用標準庫所提供的強大功能,使用者應該瞭解其實現上的很多隱晦細節。庫的實現者必須向使用者提供這些細節,以使他們更好地使用標準庫。C 標準中並沒有把這些隱晦的實現細節都很好地描述清楚,因為制定標準的主要目的並不是給庫的實現者提供指導。與ANSI C 標準一起發布的Rationale 也沒有對這些細節作出很好的解釋。Rationale 要服務的物件範圍很廣,而關注這些細節的標準實現者只是眾多服務物件的一部分。
在C 的傳統實現中並不能找到上面提到的新特性。現在的實現已經可以支援國際化開發中的地區設定(locale)概念。每個地區設定都對應於專屬的某個國家、某種語言或者某個職業的特定習慣,一個C 程式可以通過修改和查詢地區設定來動態地適應多種文化。現在的實現也能支援很大的字元集,如字元數量眾多的漢字。C 程式能把它們作為多位元組字元(multibyte character)或者寬位元組字元(wide character)處理。它也能在這兩種形式之間轉換。在迅速加劇的市場競爭中,這就使得程式的編寫更加簡單和標準。
因為以前對這些新特性幾乎不存在相應的編程藝術,所以即使是最有經驗的C 程式員,在使用地區設定、多位元組字元和寬位元組字元的時候也需要一些指導。所以,這些主題在這裡給予了特殊的關注。
細節
本書向使用者和實現者解釋了庫的設計用意和可能用法。通過提供C 標準庫中所有庫函數的實際實現,本書用例子告訴你怎樣處理它的細節。在那些沒有明確是最好實現方法的地方,它還討論了可供選擇和折中的辦法。
一個涉及細節的例子是函數getchar 。標頭檔<stdio.h> 原則上可以用下面的宏來屏蔽函數的聲明:
#define getchar() fgetc(stdin) /* NOT WISE! */
然而,它卻不應該這樣做,一個合理(即使沒有用)的C 程式是
#include <stdio.h>#undef fgetc
int main(void) { int fgetc = getchar(); /* PRODUCES A MYSTERIOUS ERROR */
return (0);
}
當然,這個例子有點極端,但它卻闡述了即使是一個很好的程式員也可能犯的錯誤。使用者有權要求儘可能少地出現這類奇怪的錯誤,所以設計者就有義務避免出現這些奇怪的錯誤。
我最終確定的getchar 宏的形式是
#define getchar () (_Files[0]->_Next < _Files[0]->_Rend \ ? *_Files[0]->_Next++ : (getchar) ())
它和上面第一次給出的那個顯而易見(而且更具可讀性)的形式大不相同。第12 章會解釋其中的原因。
庫的設計
本書還有一個目的,那就是從一般角度教授程式員怎樣設計和實現庫。從本質上講,程式設計語言提供的庫是一個混合的“袋子”。庫的實現者要具備非常廣泛的技巧才能處理這個“袋子”中各種各樣的內容。僅僅是一個有能力的數值分析員,或者能熟練高效地操作字串,或者懂得很多作業系統介面方面的知識,都是不夠的。編寫庫不僅需要具備以上所有能力,還需要掌握更多的知識。
已經有很多好書告訴你怎樣編寫數學函數,也有很多書專門介紹某種特定用途的庫。這些都是告訴你怎樣使用現有的庫。有些書甚至證明某個庫的各種設計方案抉擇的正確性。很少有書致力於告訴讀者全面地構建一個庫要求具備的技能。
可複用性
很多書都介紹了設計和實現軟體的一般性原則。這些書中提到的方法有結構化分析、結構化設計、物件導向設計和結構化編程等。這些書中的大部分例子只考慮了為某個應用編寫的程式。然而,這些原則和方法也同樣適用於可複用的庫的實現。
但可複用性的目標進一步提高了要求。從結構化設計的角度來看,如果一個庫函數沒有很高的內聚性,它就不太可能有新的用途。同樣,如果它不具備低耦合性,它就會更難使用。簡單地說,庫函數一定要隱藏它的實現細節並且提供完整的功能。否則,從物件導向的角度看, 它們不能實現可複用的資料抽象。
所以本書的最終目的是討論構建庫所特有的設計和實現問題。C 標準庫的設計是固定的。然而,它從很多方面來看都是一個好的設計,值得討論。C 標準庫的實現也可以有很多選擇。任何一個選擇都要遵守一定的原則,例如正確性和可維護性等。其他的一些選擇還要遵循某個項目特定的優先順序,例如高效能、可移植性或者小規模等。這些選擇和原則也值得討論。
本書的結構
本書的結構基本對應C 標準庫本身。標準庫中15 個標頭檔聲明或定義了庫中所有的名字。本書中每一章講述一個標頭檔。大部分標頭檔都有比較緊湊的內容,書中對此也作了緊湊的討論。然而,也有一兩個很籠統,它們相應的章節自然也會涉及更多的內容。
在本書的每一章中,我都摘錄了ISO C 標準的相關部分。(除了格式細節,ISO 和ANSI 的C 標準是完全相同的。)這些摘錄補充說明了庫的每一部分通常是怎樣使用的。它們也使本書成為一個更完整的參考手冊(當然本書比單獨閱讀C 標準要容易理解)。本書也給出了實現那些部分和測試這些實現所需的代碼。
每一章最後都附有參考文獻和配套習題。假如本書作為大學的教材使用,這些習題可以當成作業。很多習題都只是簡單的代碼改寫,它們可以把某個知識點講得更清楚或者能夠說明在實現上可以做一些合理的修改。那些更具有挑戰性的題目都做了標記,可以將它們作為那些長期項目的基礎,而自學者則可以把這些習題當作深入思考的進入點。
代碼
本書中出現的代碼已經在Borland 、GNU 項目和VAX ULTRIX 的C 編譯器上進行了測試。它通過了廣泛使用的Plum Hall Validation Suite 的庫函數的測試,也通過了那些專門為C 實現設計的、發現C 實現的缺陷的公用域程式。雖然我盡最大努力使錯誤減到最少,但仍然不能保證代碼完全正確。
同時也請注意本書的代碼是受著作權保護的。它沒有放置在公用域中,也不是共用軟體。和那些自由軟體基金會(GNU 項目)發布的代碼不同,它不受“copyleft”協議的保護。我保留本書所有的權利。
合理使用
你可以把書中的代碼轉變為電子版的形式,供個人使用。你也可以從堪薩斯州勞倫斯市的C 使用者組那裡購買機器可識別的代碼。無論哪種情況,你對代碼的使用都要遵守著作權法關於“合理使用”的規定。合理使用不允許你以任何形式發布這些代碼的副本,不論是複本還是電子版,也不論是免費的還是收費的。
除了以上談到的,我允許合理使用範圍之外的一種重要用途。你可以編譯庫中的部分並且把產生的二進位目標模組和你自己的代碼串連產生可執行檔。無限發布這樣的可執行檔是允許的。對這樣的副本我不要求任何權利。但是,我強烈要求你聲明庫(在你的檔案中)的存在,不論你用了多少,也不論是修改過的還是沒有修改的。請在可執行檔的某個地方把下面的文字包含進去:“本作品的部分代碼源自The Standard C Library,copyright (c) 1992 by P. J. Plauger, Prentice-Hall 出版社出版,這些代碼已獲授權使用。”隨可執行檔一同發布的文檔中也要在適當的地方顯著地標註這些內容。如果你遺漏了其中的任何內容,將被視為侵權。
許可
你也可以被授權做更多的事。你可以以二進位目標模組的形式發布整個庫,甚至發行就緒本書中的源檔案的副本,不論是否修改過。簡單地說,你可以把整個庫合并到一個讓人們使用它來編寫可執行程式的產品中。但是,所有的這些都需要許可證。你可以購買許可證。如果你想購買許可證而且想不斷地獲得庫的支援,請和夏威夷州卡姆艾拉市的Plum Hall 公司聯絡。
雖然上面的幾段有很濃的商業色彩,但我的主要目的不是推銷一個商業產品。我非常信任C 標準,也已經很努力地參與了它的制定。我花了很大的精力制定C 標準庫規範。我想證明我們建立了一個良好的語言標準。編寫這個實現和這本書就是為了說明這個簡單但很重要的事實。
致謝
麻薩諸塞州韋克菲爾德市的Compass 公司在本書還沒完成的時候就很信任我。他們是我的庫代碼的第一批使用者,他們協助我測試、調試,並且在Intel 860 編譯器上使用的過程中對這些庫代碼進行了改進。特別是Ian Wells,願意忍受我的延遲和修改,體現了他良好的專業精神。Don Anderson 先生為了使這個庫的結構更合理,犧牲了很多休息時間給我發電子郵件。我衷心地感謝Compass 公司的每個同事的真誠和耐心。
Prentice-Hall 的出版人Paul Becker 對本書也很有信心。他的溫和與不懈的激勵是本書完成的一個保證。他請了一些匿名的審稿人協助我,使我的觀點更加明確,同時也減少了那些絕對化的語句。Paul 的職業精神使我明白了Prentice-Hall 能在技術出版領域輝煌這麼多年的原因。
寫作過程中我搬到了澳大利亞,這個項目面臨著重重困難。我的好朋友,澳大利亞White smiths 公司的商業夥伴 John O’Brien 經常協助我。他是一個“把荊棘變成玫瑰”的好手。他對 我的協助很大,不是友誼這個詞能概括的。
感謝Prentice Hall 的發行經理Andrew Binnie 為我提供了完成這本書所用的雷射印表機,他樂於在很多方面協助我。感謝新南威爾士大學電腦科學系給我提供時間和場所,儘管他們也需要這些來完成他們自己的計劃。
Tom Plum 一直告誡我們要深刻理解C 的基礎。我也多次從和他對本書中涉及的話題進行的討論中受益匪淺。Dave Prosser 也與我分享了他對C 的工作方式的深刻見解。作為ANSI 和ISO C 標準的編輯,Dave 提供了本書中大量電子版的文本資料。日本東京的進階資料控制公司(率先對C 提供日文中的漢字的支援)的兩個主要負責人Hiroshi Fukutomi 和Takashi Kawahara 在我瞭解日本程式員的技術需求的工作中,給了我很多協助。
這裡的大部分材料原來都在The C Users Journal 上發表過。Robert Ward 是一個很容易相處的出版人,我很感謝他能讓我重新使用這些材料。也同樣感謝Jim Brodie 允許我使用我們合著的Standard C 一書中的內容。
閱讀技術類書稿是一項很枯燥的任務。John O’Brien 和Tom Plum 審閱了本書的部分內容並且反饋了很有價值的資訊。發現第一次印刷版本中(只是一小部分)錯誤的人有:Nelson H. F. Beebe 、Peter Chubb 、Stephen D. Clamage 、Steven Pemberton 、Tom Plum 和Ian Lance Taylor 。
最後,我要感謝家長控制對我的支援。我的兒子Geoffrey 在本書的排版和頁面設計方面做了很多工作。我的妻子Tana 在這麼長的時間裡給我提供了巨大的精神支援和後勤保障。他們的參與使我的寫作過程充滿樂趣。
P. J. Plauger
邦迪,新南威爾士
目錄
第0 章 簡介 .........................................................1
0.1 背景知識........................................................1
0.2 C 標準的內容 ................................................3
0.3 庫的使用........................................................7
0.4 庫的實現........................................................9
0.5 庫的測試......................................................13
0.6 參考文獻......................................................15
0.7 習題..............................................................15
第1章 <assert.h> ........................................17
1.1 背景知識......................................................17
1.2 C 標準的內容 ..............................................18
1.3 <assert.h> 的使用 ..................................18
1.4 <assert.h> 的實現 ..................................20
1.5 <assert.h> 的測試 ..................................22
1.6 參考文獻......................................................23
1.7 習題..............................................................23
第2 章 <ctype.h> ..........................................25
2.1 背景知識......................................................25
2.2 C 標準的內容 ..............................................28
2.3 <ctype.h> 的使用 ....................................30
2.4 <ctype.h> 的實現 ....................................34
2.5 <ctype.h> 的測試 ....................................42
2.6 參考文獻......................................................45
2.7 習題..............................................................45
第3 章 <errno.h> ..........................................47
3.1 背景知識......................................................47
3.2 C 標準的內容 ..............................................50
3.3 <errno.h> 的使用 ....................................50
3.4 <errno.h> 的實現 ....................................51
3.5 <errno.h> 的測試 ....................................55
3.6 參考文獻......................................................55
3.7 習題..............................................................55
第4 章 <float.h>.........................................57
4.1 背景知識......................................................57
4.2 C 標準的內容 ..............................................59
4.3 <float.h> 的使用.....................................62
4.4 <float.h> 的實現.....................................64
4.5 <float.h> 的測試.....................................69
4.6 參考文獻......................................................71
4.7 習題..............................................................72
第5 章 <limits.h> ........................................73
5.1 背景知識......................................................73
5.2 C 標準的內容 ..............................................74
5.3 <limits.h> 的使用 ..................................75
5.4 <limits.h> 的實現 ..................................77
5.5 <limits.h> 的測試 ..................................79
5.6 參考文獻......................................................80
5.7 習題..............................................................80
第6 章 <locale.h> ........................................81
6.1 背景知識......................................................81
6.2 C 標準的內容 ..............................................84
6.3 <locale.h> 的使用 ..................................87
6.4 <locale.h> 的實現 ..................................94
6.5 <locale.h> 的測試 ................................123
6.6 參考文獻....................................................123
6.7 習題............................................................123
第7 章 <math.h> ...........................................127
7.1 背景知識....................................................127
7.2 C 標準的內容 ............................................130
7.3 <math.h> 的使用 ....................................135
7.4 <math.h> 的實現 ....................................137
7.5 <math.h> 的測試 ....................................171
7.6 參考文獻....................................................177
7.7 習題............................................................177
第8 章 <setjmp.h> ....................................181
8.1 背景知識....................................................181
8.2 C 標準的內容 ............................................184
8.3 <setjmp.h> 的使用 ................................185
8.4 <setjmp.h> 的實現 ................................187
8.5 <setjmp.h> 的測試 ...............................191
8.6 參考文獻 ...................................................192
8.7 習題 ...........................................................192
第9 章 <signal.h> ....................................193
9.1 背景知識....................................................193
9.2 C 標準的內容 ............................................195
9.3 <signal.h> 的使用 ................................197
9.4 <signal.h> 的實現 ................................199
9.5 <signal.h> 的測試 ................................203
9.6 參考文獻....................................................203
9.7 習題............................................................203
第10 章 <stdarg.h> .................................205
10.1 背景知識..................................................205
10.2 C 標準的內容 ..........................................207
10.3 <stdarg.h> 的使用 ..............................208
10.4 <stdarg.h> 的實現 ..............................211
10.5 <stdarg.h> 的測試 ..............................212
10.6 參考文獻..................................................212
10.7 習題..........................................................214
第11 章 <stddef.h> .................................215
11.1 背景知識 ..................................................215
11.2 C 標準的內容 ..........................................217
11.3 <stddef.h> 的使用 ..............................217
11.4 <stddef.h> 的實現 ..............................222
11.5 <stddef.h> 的測試 ..............................223
11.6 參考文獻 ..................................................223
11.7 習題 ..........................................................223
第12 章 <stdio.h> ......................................225
12.1 背景知識..................................................225
12.2 C 標準的內容 ..........................................233
12.3 <stdio.h> 的使用 ................................252
12.4 <stdio.h> 的實現 ................................274
12.5 <stdio.h> 的測試 ................................323
12.6 參考文獻..................................................325
12.7 習題..........................................................325
第13 章 <stdlib.h> ...................................331
13.1 背景知識..................................................331
13.2 C 標準的內容 ..........................................332
13.3 <stdlib.h> 的使用 ..............................342
13.4 <stdlib.h> 的實現 ..............................351
13.5 <stdlib.h> 的測試 ..............................379
13.6 參考文獻..................................................379
13.7 習題..........................................................382
第14 章 <string.h> ...................................385
14.1 背景知識..................................................385
14.2 C 標準的內容 ..........................................386
14.3 <string.h> 的使用 ..............................392
14.4 <string.h> 的實現 ..............................396
14.5 <string.h> 的測試 ..............................409
14.6 參考文獻..................................................409
14.7 習題..........................................................409
第15 章 <time.h> .......................................413
15.1 背景知識..................................................413
15.2 C 標準的內容 ..........................................414
15.3 <time.h> 的使用 ...................................418
15.4 <time.h> 的實現 ...................................422
15.5 <time.h> 的測試 ..................................440
15.6 參考文獻..................................................441
15.7 習題..........................................................441
附錄A 介面 ......................................................443
附錄B 名字 ......................................................451
附錄C 術語 ......................................................461