C 語言之修煉與實踐

陳重嘉

  • 出版商: 琢學
  • 出版日期: 2008-01-31
  • 定價: $460
  • 售價: 9.0$414
  • 貴賓價: 8.5$391
  • 語言: 繁體中文
  • 頁數: 388
  • ISBN: 9868255511
  • ISBN-13: 9789868255517
  • 相關分類: C 程式語言
  • 立即出貨(限量) (庫存=7)

買這商品的人也買了...

商品描述

<本書簡介>

本書是根據作者的工作經驗與閱讀多本原文書籍後的心得所編著而成,創作的基調強調「循序漸進」與「做中學」,九十二幅的圖解說明、二十個列表與一百一十五個範例程式,都是為了提升讀者的學習興趣與效果的創作成果;用心地研讀本書,必能使初學者修煉成 C 語言的箇中好手。

第 1 章:Getting Started

以「在螢幕上列印 message」、「計算由 1 至 100 的和」與「求取平均數」等三個小程式來說明程式設計的基本觀念,引領讀者學會使用 compiler(gcc)、debugger(gdb)、vi 與 Makefile;Makefile 部分的說明包含 comment、macro、explicit rule、dependency tree、suffix rule 與 .PHONY target,章末的回顧與總結還特別地以生物的偽裝色來比喻 Makefile 的 dependency check,以加深讀者的學習印象。

第 2 章:Expressions

本章針對 operand's types 與 operator 做逐一的詳細解說,內容包含變數的命名規則與宣告語法、Literal 的宣告語法、Two's Complement 表示法與其優點、ASCII code 與 escape sequence 以及 IEEE 754 Floating Point 表示法、各個 operator 的意義與語法、operator 的 precedence 與 asscociativity。

範例程式包含如何利用 escape sequence 中的 backspace 來模擬一個 rotating bar (類似於 Sun Workstation 開機畫面中的 rotating bar)、如何於 text mode 的同一個位置顯示進度百分比;如何將任意一個數調整到某定數的倍數(例如 8 的倍數);如何利用 Two's Complement 的特性與 bitwise and 來計算某數有多少個 bit 之值為 1 等等。

看完本章的 IEEE 754 之解說,讀者即可明瞭為何有些 floating point value 的印出結果為 NaN 或 Infinite 等字樣,而不是一個 floating point value。

第 3 章:Decisions 與 Loops

本章針對 selection statement (if 與 switch)、iteration statement (while、do-while 與 for) 與 jump statement (break、continue、goto 與 return) 做逐一的詳細解說,並以實際的工作經驗點出要注意 null statement 可能造成的邏輯錯誤。

第 4 章:Functions

本章以某 H 公司的看護機器人之行銷計畫帶出函式的基本概念後,接著以 Body Mass Index 的程式設計來為讀者解說與函式有關的基本知識,例如 run time memory layout、activation flow 與 stack frame,再下來則是以肢體語言與意義之間的綑綁對應關係來介紹 C 語言的 binding 與 scope rules。

範例程式 read_books.c 與 get_reading_books.c 是以「某人閱讀兩本書籍的進度」為例,把函式的可被呼叫範疇、global variable 可被存取的範疇、變數的 storage duration 等說明的一清二楚。

範例程式 get_factorial_recursive 是以數學的階層為例,為讀者示範如何撰寫遞回程式,並點出要留意與確認 stopping rules 一定會被觸及,否則將會產生 stack area 被眾多的 stack frame 所用罄的致命錯誤 (stack overflow)。

第 5 章:Arrays 與 Pointers

本章以「單排平房」、「多排平房」以及「多排樓房」的隱喻帶出 one/two/three dimension array,其間則以計算某檔案的各個字母之出現頻率、九九乘法表、九十九乘九十九乘法表等範例程式來加深讀者的學習印象,並以 array 來實作 stack、infix expression to postfix expression、postfix expression calculator 等基本的資料結構,以展示 array 在問題解決上的實際應用。

Pointers 的部分則是以現實世界中的房子點出每個 data object 都有 address 且需耗費 memory storage,接著則是說明 generic pointer 的語法以及為何需要 generic pointer、什麼是 multiple indirection、pointer 的數學運算與其計量單位、pointer 與 array 的關係與對等轉換規則、pointer to multiple object 的語法、如何動態地配置記憶體資源、pointer to functions 等等。其間穿插的 ASCII to Integer 與 Inetger to ASCII 等程式可加深讀者對 pointer 的學習印象;arr_logical_view.c 則點明 array 的 dimension 只是為了解題需要而切割出來的邏輯觀念,實際上的 memory storage 仍是一個 linear memory storage;are_you_too_heavy.c 則是以 command line 的 argument 與 main 的 argv[] 來解說 array of pointer。

本章末是以 quick sort 與 binary 來整合說明 array 與 pointer 的實際應用,並順便介紹 quick sort 與 binarysearch 的核心思惟 ── divide and conquer ── 「較小的問題比較容易解決」與「分而擊之」。當每一個   sub-problem 與 parent problem 的本質相同時,我們可將 recursion 引入 divide and conquer 的解題模型之中,利用 recursion 去切割原來的問題,並引導 control flow 逐步地邁向 recursion 的 stopping rules ── 亦即「問題已經小到不需要再做切割即可迎刃而解」。

第 6 章:Enumerations、Structures 與 Unions

enum、struct 與 union 都是為了滿足人類慣於列舉與歸類事物的天性所孕育而生的 construct,亦是建立解題模型時所不可或缺的語法。範例程式首先以 week day 與 US coin 來說明 enum 的語法與應用,接著是以幾何學上的點與線來說明 struct 的語法與應用,再來則是以一個人的姓名與出生年月日來說明 nested structures 的語法與用法;至於 structure data member 的 bit field declaration,本書是以 Unix File Permission (user/group/other) 為範例,為讀者示範 bit field 的語法與用法。

Data Structure 方面的範例程式,包含分別以 struct 與 union 所改寫的 stack,如何以 struct 來定義 list 的 node,如何將異質性的 node 串接起來,list 的 insert after 與 delete current 的抽象化運作等等。

第 7 章:Input 與 Output

本章將 Input 與 Output 分成兩類來做探討,分別為 Console IO 與 File IO。

Console IO 主要是以函式 printf 與函式 scanf 來做為解說的標的,據此說明各個 conversion specification 的意義,例如 flag、minimum field width、precision、length modifier 與 conversion character。穿插其間的範例程式,可引領讀者學會如何控制靠左靠右對齊、如何在 value 之前加上 leading zero、如何以 integer argument 控制minimum field width 與 precision、positional argument mapping 與 named argument mapping、如何使用 assignment suppresion 來跳過不感興趣的 argument、如何使用 scanset (a simple regular expression) 來對 input data 執行 character matching 等等。

File IO 部分是以「如何移動檔案讀寫頭」帶出檔案處理的基本概念,緊接著是將檔案運作的函式歸類為開啟、關閉、讀取、寫入、設定狀態、詢問狀態等六大類,並以主參數為 file stream object (FILE*) 與 file descriptor (int) 為依據來介紹這六大類的檔案函式。

本章的範例程式,包含以八個人的姓名、身高與體重為題所分別實作的 formatted io (text file) 與 binary io (binary file),以及 Unix command "find" 的雛形 ── print_file_info.c。

在 Unix 的環境下,我們可利用 find utility 來尋找某特定名稱的檔案,並對之執行某特定的運作。例如

  find . -name "core" -print

上述命令是以 present directory 為起始點,遞回地尋找該目錄與其下的所有子目錄是否含有一個名字叫做 core 的檔案,若有就將該目錄的 path 列印到螢幕上。

此外,當我們不小心取了一個名字很怪的檔案名稱,但卻無法使用 rename 改變其名,而且也無法使用 rm -f 來刪除它時,我們可先使用 ls -i 來查出它的 inode number,接著再鍵入下列指令即可刪除該檔

  find . -inum inode_number -exec \rm -f {} \;

本章末所實作的範例程式 ── print_file_info.c,就是上述 find utility 的基本雛形,它使用了 stat、opendir、readdir 與 closedir 這四個函式,以及 struct stat 與 struct dirent 這兩個 structure 的定義,程式的流程架構為 indirect recursive function call。讀者若能善加利用此程式,即可實作許多「不錯用」的功能,例如找到目標檔案後把它移到某個特定目錄中、依照某個編號順序依序地將目標檔案重新命名、在目標檔案的開頭添加 Copyright 的聲明等等。

第 8 章:Preprocessor 與 Library

本章以 preprocessor 的三個主要工作項目 ── 引入 header file 的內容、處理 conditional compilation 與將 macro 代換成 code snippet,來為本章揭開序幕,緊接著則是為讀著介紹 C 語言的五個 predefined macro 的意義與用法,它們分別是:__FILE__ 與 __LINE__、__DATE__ 與 __TIME__ 以及 __STDC__;接著是介紹兩個可用來命令 preprocessor 去執行特定運作的 special operator ── a single pound sign 與 double pound signs。

Library 部分是以「為何需要 library」與「如何建立一個 library」為開端,接著是介紹與解說於 1989 年所制訂的 Standard C Library,並將重點放在各個 header file 的函式分類上,據此為讀者提供一份指引地圖,好讓讀者知道有哪些標準函式可供使用。穿插其間的範例程式則展示了常用的標準函式之意義與用法。