品悟C

品悟C

《品悟C》是清華大學出版社2012年出版的圖書,作者是薛非。本書是迄今為止國內僅有的一部全面且集中地討論C程式設計中常見錯誤的書籍。其主旨在於幫助讀者從錯誤中更準確地理解C語言,並在實踐中更好地運用C語言。

基本介紹

  • 書名:品悟C
  • 作者:薛非
  • ISBN:9787302296263
  • 頁數:502
  • 定價:69.00元
  • 出版社清華大學出版社
  • 出版時間:2012-10-1
  • 裝幀:平裝
  • 開本:16開
  • 副標題:拋棄C程式設計中的謬誤與惡習
內容簡介,作者簡介,目錄,序言,

內容簡介

《品悟C:拋棄C程式設計中的謬誤與惡習》 全書分為上下兩部:上部“形而下學”討論C代碼中常見的錯誤和編程惡習;下部“形上學”討論的是對C語言本身認識方面的常見誤區。這些問題特別具有普遍性,很多錯誤不僅僅存在於初學者之中,即使是職業程式設計師多半也會在本書中找到自己的錯誤。因此,對於任何想糾正自己對C語言的錯誤認識以及想不斷提高C語言水平的讀者來說,本書都提供了一種獨到且重要的視角,是一本不容錯過的、具有重要參考價值的技術資料。
本書並非那種長篇大論環環相扣的書籍,它的各個主題獨立成篇,使人閱讀起來輕鬆愉快。讀這本書並不需要正襟危坐在書房裡,它可以隨時隨地地拿過來翻閱。
《品悟C:拋棄C程式設計中的謬誤與惡習》可作為各高校C語言或相關課程的教學參考書,也適合那些具有一定經驗的C語言程式設計師閱讀使用。

作者簡介

薛非,貌不出眾,所以照片還是免了吧。編輯非要也不給,有碼無碼都不行。沒有什麼豐功偉績,所以也不敢自吹自擂。不過我堅信,書籍本身是作者最好的名片,作者的形象決定於讀者的閱讀感受。
所以,這裡的空白還是留給讀者的想像吧。

目錄

上部 形而下學--代碼錯誤及陋習

第1章 低級錯誤
問題1 C啊,多少C++假汝之名而行--C、C++不分
問題2 環節缺失--關於C程式開發過程
問題3 錯誤的“標點”--混用中英文字元
問題4 錯誤的“單詞”
問題5 “合併單詞”產生的問題
問題6 形形色色的“分號”誤用
問題7 “一仆二主”--兩個main()函式
問題8 忘記“&”
問題9 who's who
問題10 同形異質--為符號常量賦值
問題11 詞不達意
問題12 使用switch語句的常見錯誤
第2章 初級錯誤
問題1 隨手寫出的大數
問題2 關於數據類型的潛規則
問題3 使用垃圾值
問題4 對數組的誤用與誤解
問題5 好心辦壞事--修改代碼引發的錯誤
問題6 “右移運算等價於除法運算”
問題7 “中國人民很行”--C語言中的錯別字
問題8 學會數數--循環次數錯誤
問題9 忽視函式原型
問題10 張冠李戴--錯誤的格式轉換
問題11 只進不出--缺少輸出
問題12 鳩占鵲巢--數組越界
第3章 邏輯錯誤
問題1 喧賓奪主--換行問題
問題2 結構體鍊表的一個例題--輸出錯誤
問題3 一些幼稚的寫法
問題4 c=getchar()!=EOF--優先權錯誤
問題5 判斷三個整數相等--“==”運算符的誤用
問題6 懸掛else問題--怎樣寫出正確的if語句
問題7 浮點循環變數
問題8 不顧常識
問題9 自然語言的陷阱
問題10 c==' ' || '\n' || '\t'
問題11 亂做習題你傷不起啊
問題12 誤改循環變數
第4章 似是而非
問題1 void main()
問題2 生硬的嫁接,滑稽的實參
問題3 輸出之誤--輸出數組應注意的問題
問題4 多此一舉
問題5 笨拙的for語句
問題6 只用printf()函式輸出
問題7 容易招致編譯器誤解的代碼
問題8 使用“//”注釋注意事項
問題9 使用野指針
問題10 用驢子拖寶馬--濫用結構體
問題11 似是而非的k=sqrt(n)
問題12 scanf(“”%s“”,&str)
問題13 已知兩邊長求三角形面積--不完全函式參數
問題14 對“c”轉換說明符的誤解
問題15 多餘的計算
問題16 到處忙活與一勞永逸--函式類型聲明位置問題
問題17 半身不遂和粗中有細
問題18 忽視前提
問題19 char text[3][80]不是一篇文章,也並非3行文字
問題20 不安全的gets()函式
問題21 檔案名稱殘缺
問題22 exit(0)
問題23 捨近求遠
問題24 重複無效的代碼
問題25 拙劣的外部變數
第5章 畫蛇添足
問題1 KISS
問題2 為賦新詞強說愁
問題3 囉唆重複
問題4 表達式是什麼
問題5 不識指針
問題6 脫褲子放屁
問題7 怎樣利用scanf()函式自虐
問題8 自尋煩惱的scanf()函式調用方式
問題9 輸入指定範圍的整數--Basic風格寫法和C風格寫法
問題10 “豆漿買兩碗,喝一碗,倒一碗”--多餘的數組元素
問題11 篩法“四不像”
問題12 不徹底的思考
問題13 代碼寫得要“拽”(DRY)
問題14 作繭自縛的“%3d”
問題15 大腹便便--臃腫與重複
問題16 舍簡就繁
問題17 程式的劣化與最佳化
問題18 濫用變數綜合症
問題19 free空指針
第6章 疑難雜症
問題1 混亂是怎樣煉成的
問題2 無知亂吃藥--strcpy()函式的誤用
問題3 邊界測試--讓BUG現形
問題4 內褲外穿--錯位及不倫不類
問題5 flag標誌:代碼餿了(一)
問題6 flag標誌:代碼餿了(二)
問題7 flag標誌:代碼餿了(三)
問題8 雞窩裡飛出偽鳳凰
問題9 不顧常識
問題10 不易察覺的BUG
問題11 含糊之過、多做之過及亂做之過
問題12 怎樣調戲程式
問題13 糟蹋好題--魔方陣問題
第7章 風格問題
問題1 如何進行數組初始化
問題2 括弧不配對錯誤及如何免疫
問題3 不良代碼編輯風格引起的錯誤--怎樣寫控制語句
問題4 將main()函式進行到底
問題5 赤裸的scanf()
問題6 c + 32的問題
問題7 怎樣整理房間
問題8 貪小便宜--省略函式類型聲明等問題
問題9 常數Magic Number
問題10 搏二兔
下 部 形上學--概念錯誤及誤區

第8章 概念的缺失
問題1 C語言的歷史及C標準
問題2 只知變數不知對象
問題3 C語言中Byte的含義
問題4 “不知所云”的無定義行為(undefined behavior)
問題5 “可以清心也”應如何解讀--不確定行為(Unspecified behavior)
問題6 實現(Implemantation)
問題7 “編譯器自己做主”--實現定義的行為(implementation-defined behavior)
問題8 整數提升(Integer promotion)
問題9 副效應(side effects)
問題10 “左值就是可以出現在賦值運算符的左側”
第9章 基本詞法
問題1 字元集問題
問題2 “α,β,δ,ε,Ⅰ,Ⅱ,Ⅲ,Ⅳ等不是C語言的合法字元”
問題3 “各種字元集的基本集都包括了127個字元”
問題4 C源程式的組成--“單詞”視角
問題5 “a”、'a'與a辨析
問題6 “C語言關鍵字都是小寫的”
問題7 “C語言允許一行內寫多個語句”
問題8 “標識符由字母、下劃線和數字組成”
問題9 標識符的長度限制
問題10 “括弧、賦值、逗號都是運算符”
第10章 數據類型及類型轉換
問題1 “類型就是對數據存儲單元的安排”
問題2 1.%3之惑
問題3 “int為2個位元組或4個位元組”
問題4 int類型的範圍問題
問題5 混亂不堪的“整型”
問題6 “·345是整型常量”
問題7 “字元數據以ASCII碼存儲”
問題8 “char類型就是signed char類型”
問題9 通過程式測定char類型的性質
問題10 “C用1個位元組(8位)存儲一個字元”
問題11 “i='A'是字元型數據賦給整型變數”
問題12 “字元常量只能是一個字元”
問題13 “從常量的表示形式可以判斷其類型”
問題14 1、'1'與“”1“”
問題15 “變數值在存儲單元中都是以補碼形式存儲的”
問題16 “不應向無符號整型變數賦予一個負值”
問題17 3.0乘以4.2怎么就變成了12.59999
問題18 “實型變數”剖析
問題19 使用float招來的警告及“因噎廢食”的對策
問題20 123f--怎樣寫float類型的常量
問題21 “實型常量有兩種表示形式”
問題22 “浮點數類型包括float、double和long double”
問題23 “實數就是浮點數”
問題24 “編譯系統為每一個float型變數分配4個位元組”
問題25 “浮點型”、“雙精度浮點型”和“實型”
問題26 “Turbo C對long double 型分配16個位元組”
問題27 “必然以規範化的指數形式輸出”
問題28 “浮點型數據是用來表示具有小數點的實數的”
問題29 對類型轉換運算的誤解
問題30 “整型量與字元型數據以及邏輯型數據可以通用”
問題31 “C語言把所有的實數都作為雙精度數處理”
問題32 “所有float型數據都先轉換為double型”
問題33 “int型與float或double型數據進行運算,結果是double型”
問題34 關於char類型數據的運算規則
問題35 對表達式“10+'a'+i*f-d/3”的分析
問題36 “字元數據既可以字元形式輸出,也可以整數形式輸出”
問題37 3 · 1∶2.
問題38 “運算符兩側的數據類型不同,先自動進行型轉換”
第11章 運算和表達式(Expression)
問題1 關於“整型常量”
問題2 “變數名是以一個名字代表一個存儲地址”
問題3 “預設情況下所有變數都是auto 的”
問題4 “不能對一個類型賦值、存取或運算”
問題5 “變數必須先定義、後使用”
問題6 “常量是沒有名字的不變數”
問題7 “標識符用來標識一個對象”
問題8 啥叫“中間變數”
問題9 “先乘除後加減”--“優先權高先運算”
問題10 “賦值截斷”
問題11 對(a=b)>0 的誤讀
問題12 “'.'運算符優先權高於後綴'++'運算符”
問題13 “'結合性'是C語言的特點之一”
問題14 “'左結合性',即運算對象先與左面的運算符相結合”
問題15 “算術表達式”和“算術運算符”:兩個臆造的偽概念
問題16 關於“算術表達式”、“優先權”和“結合性”的胡扯
問題17 “C語言共有34種運算符”
問題18 “兩個實數相除的結果是雙精度實數”
問題19 整數除法的捨入方向問題
問題20 “++運算的作用是使變數的值加1”
問題21 為a+=a-=a*a預擬的悼詞
問題22 &&的運算規則
問題23 對“5>3&&8<4-!0”的分析
問題24 邏輯運算符和邏輯表達式
問題25 “二元運算符都可以與賦值符一起組合成複合賦值符”
問題26 “賦值運算符的作用是將一個數據賦給一個變數”
問題27 “執行表達式a=(b=5),就是執行b=5和a=b兩個賦值表達式”
問題28 類型系統?表達式?副效應?--C的“易筋經”
問題29 GB/T15272-94的一個錯誤
問題30 sizeof“函式”
問題31 逗號運算符是幾目運算符
問題32 怎樣濫用逗號運算符
問題33 “逗號運算符最常用於循環語句”
問題34 同名不同義的運算符:“++”與“++”
問題35 ++、--的運算對象問題
問題36 自增運算符(++)不能用於表達式
問題37 cast運算的優先權問題
第12章 聲明和語句
問題1 “全局變數”
問題2 聲明外部變數時省略類型名稱
問題3 聲明點(Declaration point)的問題
問題4 指向靜態整型變數的指針
問題5 存儲類別
問題6 “輸出語句”及“賦值語句”
問題7 “函式調用語句”
問題8 “C語言規定語句末尾必須有分號”
問題9 switch語句的一般形式
問題10 switch語句中的表達式類型問題
問題11 “while語句的範圍只到while後面第一個分號處”
問題12 “for語句和while語句無條件等價”
問題13 “語句的作用是向計算機系統發出操作指令,要求執行相應的操作”
第13章 函式
問題1 “實際參數可以是常量、變數或表達式”
問題2 “函式調用的形式”
問題3 “虛擬參數”和“虛實結合”
問題4 “值傳遞”和“址傳遞”
問題5 函式的指針是起始地址
問題6 用指針調用函式
問題7 “void意為函式無類型”
問題8 “函式必須'先定義後使用'”
問題9 “使用函式原型作聲明是C的一個重要特點”
問題10 “函式體包括聲明部分和執行部分”
問題11 “庫函式是編譯系統事先定義好的”
問題12 “定義無參函式的一般形式”
問題13 “不帶回值的函式的函式體中不得出現return語句”
問題14 過時的函式定義
問題15 “不能調用main函式”
問題16 “C程式在main()函式中結束”
問題17 五花八門的main()函式
問題18 “函式名代表函式的入口地址”
問題19 “函式聲明”、“函式原型”與“函式定義”辨析
第14章 指針
問題1 指針的種類問題
問題2 “指針就是一個變數”
問題3 “指針就是地址”
問題4 “一元'&'是取地址運算符”
問題5 錯誤觀念下的代碼
問題6 返回指向局部變數的指針
問題7 野指針問題
問題8 “指針是32位的無符號的整數”
問題9 “指針的大小都一樣”
問題10 “無類型指針”
問題11 指針加減法運算的“定義域”
問題12 const 悖論
問題13 不經意的錯誤:&a[10] 與a+10的差異
問題14 新編《守株待兔》--C語言版--兼聊為什麼不應該用%d
格式轉換輸出指針
第15章 數組和字元串
問題1 定義一維數組的一般形式
問題2 何謂“可變長數組”
問題3 “字元串是存放在字元型數組中的”
問題4 “數組中未被賦值的元素的值自動置'\0'”
問題5 “數組名不是左值”
問題6 數組名“只代表數組首元素的地址”
問題7 辨析“形參和實參可以分別用字元數組名或字元指針變數”
問題8 關於strncpy()函式的功能
問題9 “數組名作函式參數”問題
問題10 怎樣稱呼字元串
問題11 小氣的數組和危險的輸入--慎用scanf()函式和gets()函式
問題12 修改字元串文字量
問題13 對strcpy()功能斷章取義的描述
第16章 結構體、共用體、枚舉及位運算
問題1 成員運算問題
問題2 “->”稱為指向運算符
問題3 “只能對最低級的成員進行賦值或存取以及運算”
問題4 63、64還是68?--談談alignment
問題5 結構體的尺寸問題
問題6 空結構體的尺寸問題
問題7 “結構體變數的地址主要用作函式參數”
問題8 “共用體變數所占記憶體長度等於最長成員的長度”
問題9 “不能引用共用體變數”
問題10 “不能對共用體變數名賦值”
問題11 “枚舉變數的值限定在定義時規定的幾個枚舉元素範圍內”
問題12 “'位運算'是C語言區別於其他高級語言的一個重要特點”
問題13 “參加位運算的對象只能是整型或字元型的數據”
問題14 “'<<'用來將一個數的各二進制位全部左移若干位”
問題15 不同長度的數據進行位運算
問題16 用memcmp()函式比較兩個結構體
第17章 標準庫
問題1 “%c轉換說明符用於輸入單個字元”引發的潛在BUG
問題2 “對無符號整型數據用%u輸出”
問題3 “double類型應該用'%lf'輸出”
問題4 關於%g格式的錯誤認識
問題5 關於%o格式的錯誤認識
問題6 “gets()函式是fgets()函式用於stdin的特例”
問題7 “用puts函式輸出的字元串中可以包含轉義字元”
問題8 “檔案結束標誌EOF(即-1)”
問題9 “fseek(fp、100L、0)”
問題10 打開檔案時的兩種錯誤
問題11 “用”“a”“方式打開檔案應保證檔案事先存在”
問題12 “在程式中可以直接用FILE類型名定義變數”
問題13 “stdin是指向標準輸入流的指針變數”
問題14 關於feof()函式的錯誤
問題15 “度日如年”的故事及“feof()函式”的故事
問題16 關於fflush()函式的錯誤
問題17 盲目前行--忽視malloc()函式返回值
問題18 管殺不管埋--缺少free()函式
問題19 怎樣建立鍊表並同時造成記憶體泄漏
問題20 qsort()函式是快速排序
問題21 關於calloc()函式
問題22 關於free()函式
問題23 關於realloc()函式
問題24 為什麼不可以static char*p=malloc(10);
問題25 abs()是數學函式
第18章 預處理
問題1 “預處理功能是C語言特有的”
問題2 主動引進BUG
問題3 “#define是用一個指定的標識符來代表字元串”
問題4 “預處理器把程式中的注釋全部刪除”
問題5 “所有的PI都代表3.1416”
問題6 #define預處理命令的位置問題
問題7 能否用痰盂盛飯--談在頭檔案中定義外部變數
問題8 預處理次序錯誤
問題9 缺少#include
問題10 包含源檔案--是奇技淫巧還是飲鴆止渴
問題11 使用函式式宏的禁忌
問題12 不合格的宏
問題13 “宏實參從左到右進行置換”
問題14 條件編譯與if語句
第19章 關於C99
問題1 亡羊補牢還是越錯越遠--“C99允許在函式中的複合語句
中定義變數”
問題2 C99增加了哪些數據類型
問題3 “C99標準不支持一行內寫多個語句”
問題4 “C99把字元型數據作為整數類型的一種”
問題5 “C99要求main函式一律指定為int型”
問題6 “C99允許使用常變數”
問題7 “C99允許使用多位元組字元”
問題8 “C99允許使用基類型為void的指針類型”
問題9 “C99增加了C++中的功能”
問題10 “C99允許同類型的共用體變數互相賦值”
問題11 能否用Visual C++ 6.0學習C99
第20章 雜七雜八
問題1 “系統描述語言”與“系統程式語言”
問題2 關於計算機指令長度
問題3 同一律
問題4 為什麼不能用彙編解釋C
問題5 “檔案中的物理順序”
問題6 “C語言源程式的擴展名為.c”
問題7 缺乏測試意識
問題8 為Wirth正名
問題9 “bohra”是誰
問題10 “83 ANSI C”和“87 ANSI C”
問題11 關於ISO
問題12 關於勒讓德多項式
參考文獻

序言

編者序——敢於向權威挑戰
經常聽到我的作者朋友說類似這樣的話:“看我的代碼,多帥氣!”何謂帥氣、漂亮的代碼?
在我看來,先不談代碼醜俊,首先代碼必須沒有殘疾。在健康的代碼基礎上,才能談網路間流傳的各種稱號:漂亮代碼、優質代碼、帥氣代碼、性感代碼……
這就是本書要講的內容——摒棄一些錯誤的觀念,重新認識C語言的嚴謹與華麗。
計算機語言是人類操控計算機硬體的主要手段,是語言創造者智慧的濃縮。計算機語言在中國的普及,是伴隨著中國經濟騰飛的這幾十年。無數中國的程式設計師伴隨著很多經典教材順利入門並成長了起來,隨著網際網路的發展,更多的朋友在網上發表自己的看法,所以網際網路也成為了大家獲取編程技術的重要渠道。
但是,金無足赤,隨著C語言標準的不斷完善,C開發理念的不斷進步,市面上的一些教材和網上一些說法確實存在一些值得商榷的問題,或者謬誤,因為這些資料傳播甚廣,有些反而成為了“標準”,這種現象有時候可能會誤導初學者,讓初學者無法從一開始就建立相對準確的開發觀念。
本書就是這樣一本敢於向“權威”挑戰的書,通過作者多年的積累,以及眾多熱心網友的鼎力支持,對一些C語言中經常出現的問題進行討論。
在中國的教育體制下,不可否認,很多創造力被限制甚至扼殺,很多路被強制標註為正確途徑,很多人的學習興趣在一開始就被磨滅……。但是很高興能出現這么一本書,在閱讀過程中,可以體會一眾先鋒程式設計師對開發觀念的重視,對細節的精益求精,對邏輯的反覆推敲,甚至上升到——對真理的求索。
我通常拿到一本書,會先瀏覽一下,把我認為重要的文字用特殊形式標出來,比如“提示”、“注意”、“TIPS”之類的樣式以及文字加粗、代碼加黑之類的重點標註,但是本書我在做出努力之後,發現無法進行這樣的處理,因為似乎每句話都是重點,每段代碼都是精心挑選的,無論是正確代碼還是錯誤代碼。
最後一點不得不提一下,作者的文筆非常犀利,對一些問題的批判毫不留情,可能是作者本人以及相關參與編寫的網友受到過太多問題資料的影響,以至於走了不少彎路,所以面對問題資料,個別時候會流露出來一種憤青一般的憤怒。這可以理解,而且我在編輯加工過程中也儘量保持了文風,但是還是希望作者和所有讀者做一名淡定的程式設計師。
如果本書冒犯了某些朋友,請不要大動肝火,可以發郵件與作者討論,畢竟從一個角度看問題,存在片面的可能性。大家討論技術,以代碼會友。
權威之所以是權威,必然有其可取之處,對於權威,我們除了要有挑戰的勇氣,更多的是要理性的尊重,畢竟“權威”帶領太多人進入C語言門檻。沒有BUG的代碼是不存在,同樣沒有問題的資料也是不存在的,希望大家在學習過程中,多思考,多交流,早日樹立端正的開發思路。
在此感謝包括作者在內的熱心人,有監督才會有活力,有挑戰才會有發展!

相關詞條

熱門詞條

聯絡我們