img
                                    從新手到高手C++全方位學習

                                    下載網址: 從新手到高手C++_程式碼.rar http://fp.io/3355b224 從新手到高手C++_書籍PDF.rar http://fp.io/a8ba9fd4 從新手到高手C++_視頻教學.part1.rar http://fp.io/13f997fa 從新手到高手C++_視頻教學.part2.rar http://fp.io/b2c1a7bf 中文名: 從新手到高手C++全方位學習隨書DVD文件 作者: 範磊 出版社: 科學出版社 書號: 703024706X 發行時間: 2009年09月 地區: 大陸 語言: 簡體中文 簡介: 內容簡介 《從新手到高手C++全方位學習》總結了十幾本C++圖書及教材的優點,擯棄了它們語言拖沓、層次結構混亂等缺陷,從零開始、由淺入深、層層遞進、細緻而又詳盡地講解C++這門大型編程語言。 《從新手到高手C++全方位學習》知識系統全面,擁有字典般的容量,可隨用隨查,涵蓋指針、面向對象、操作符重載、流、命名空問、模板、異常處理、宏等主流C++開發技術。為了使讀者能夠活學活用,《從新手到高手C++全方位學習》針對重要的概念精心設計了438個實用範例,囊括大量經驗和技巧,即使已從事C++工作多年的朋友,也能從中汲取新的養料。 《從新手到高手C++全方位學習》適合於從未學習過任何編程語言的新手,以及學習C++多年,仍舊不能融會貫通的讀者,對於正在使用C++進行開發的程序員也有很好的參考價值。 光盤提供的視頻教程,包含了第1章到第17章的內容,網上有18、19章的教程,這個光盤沒有包括。 視頻教程目錄的截圖: 源代碼目錄的截圖 從新手到高手C++目錄: 第1章 初識C++ 1.1 C++簡介 1.2 C++與C的區別 1.3 學習C++之前需要先學C嗎 1.4 C++與其他語言的區別 1.5 C++的版本以及安裝問題 第2章 做一個最簡短的C++程序 2.1 簡單的屏幕輸出小程序 2.2 輸出語句的使用 2.3 std::介紹 2.4 iostream與iostream.h的區別 2.5 重名問題 2.6 註釋 第3章 初步了解函數 3.1 一個簡單的函數 3.2 函數的傳參 3.3 函數的返回值. 參數與變量 3.4 函數的聲明與定義 3.5 局部變量 3.6 全局變量 第4章 C++數據類型 4.1 變量的定義 4.2 將變量及數據存儲在內存中 4.3 布爾型變量 4.4 字符型變量 4.5 wchar_t雙字節型變量 4.6 整型概述 4.7 整型變量的定義 4.8 浮點型變量 4.9 常量 4.10 枚舉型常量 第5章 if語句與邏輯運算符 5.1 語句的定義 5.2 塊的定義 5.3 表達式的定義 5.4 運算符的定義 5.4.1 賦值運算符的定義 5.4.2 數學運算符的定義 5.4.3 賦值運算符與數學運算符的聯合 5.5 自加與自減 5.5.1 前置 5.5.2 後置 5.6 表達式的優先級 5.7 關係運算符 5.8 if語句 5.8.1 else語句 5.8.2 else if語句 5.8.3 if語句的嵌套 5.9 邏輯運算符及其使用 5.9.1 邏輯“與” 5.9.2 邏輯“或” 5.9.3 邏輯“非” 5.9.4 邏輯運算符的優先級 5.9.5 運算式的真假關係 5.10 三目運算符 5.10.1 三目運算符的優先問題 5.10.2 三目運算符的使用問題 5.10.3 三目運算符的型別問題 5.10.4 三目運算符在字符型變量中的使用 5.11 複雜嵌套的if語句 第6章 面向對象 6.1 面向對象程序語言的主要特徵 6.2 類. 對象和成員 6.3 類. 對象和成員的使用方法及區別 6.3.1 聲明一個類 6.3.2 命名習慣 6.3.3 定義一個對象 6.3.4 類與對象的區別 6.3.5 對象與成員的關係 6.3.6 不要給類賦值 6.3.7 對像只能調用類中存在的成員 6.4 公有 6.5 私有 6.6 成員函數的聲明和定義 6.7 為什麼將成員函數的聲明和定義分開 6.7.1 普通內聯函數 6.7.2 成員內聯函數 6.8 將類聲明和定義部分保存在頭文件中 6.9 const成員函數 6.10 構造函數 6.11 默認構造函數 6.12 析構函數 6.13 析構對像數組 第7章 循環語句 7.1 循環語句的前身——goto語句 7.2 慎用goto語句 7.3 while語句 7.3.1 帶運算符的while語句 7.3.2 以字符為條件的while語句 7.3.3 限定while循環的次數 7.3.4 continue語句 7.3.5 break語句 7.3.6 永不休止的while循環 7.4 do… while循環 7.5 for循環 7.5.1 靈活的for循環 7.5.2 條件為空的for循環 7.5.3 執行為空的for循環 7.5.4 嵌套的for循環 7.6 switch語句 7.6.1 switch語句常見錯誤 7.6.2 switch的菜單功能 7.7 總結 第8章 指針 8.1 什麼是地址 8.2 用指針來保存地址 8.2.1 空指針 8.2.2 指針與變量類型 8.2.3 用指針來訪問值 8.2.4 指針地址. 指針保存的地址和該地址的值 8.2.5 指針對數值的操作 8.2.6 更換指針保存的地址 8.3 為什麼使用指針 8.3.1 棧和堆 8.3.2 用指針創建堆中空間 8.3.3 用指針刪除堆中空間 8.4 動態內存 8.4.1 內存洩漏 8.4.2 在堆中創建對象 8.4.3 在堆中刪除對象 8.4.4 訪問堆中的數據成員 8.4.5 在構造函數中開闢內存空間 8.4.6 對像在棧與堆中的不同 8.5 this指針 8.6 指針的常見錯誤 8.7 指針運算 8.7.1 指針的加減運算 8.7.2 指針的賦值運算 8.7.3 指針的相減運算 8.7.4 指針的比較運算 8.8 指針 8.8.1 常量指針 8.8.2 指向常量的指針 8.8.3 指向常量的常指針 8.9 總結 第9章 引用 9.1 什麼是引用 9.1.1 引用的地址 9.1.2 引用就是別名常量 9.1.3 引用對象 9.1.4 空引用 9.2 函數的參數傳遞 9.2.1 通過值來傳遞函數參數 9.2.2 通過指針來傳遞函數參數 9.2.3 通過引用來傳遞函數參數 9.2.4 讓函數返回多個值 9.3 傳遞對象 9.3.1 用值來傳遞對象 9.3.2 使用指針來傳遞對象 9.3.3 使用const指針來傳遞對象 9.3.4 使用引用來傳遞對象 9.3.5 到底是使用引用還是指針 9.3.6 引用和指針可以一塊用 9.4 引用應注意的問題 9.4.1 引用容易犯的錯誤 9.4.2 引用一個按值返回的堆中對象 9.4.3 引用一個按別名返回的堆中對象 9.4.4 在哪裡創建,就在哪裡釋放 9.5 總結 第10章 深入函數 10.1 函數重載 10.1.1 普通函數的重載 10.1.2 成員函數的重載 10.2 函數的默認參數 10.3 重載構造函數 10.3.1 成員變量的初始化 10.3.2 成員變量的初始化與構造函數 10.3.3 複製構造函數 10.3.4 構造函數和new運算符 10.3.5 再談默認構造函數 10.4 析構函數和delete運算符 10.4.1 默認析構函數 10.4.2 調用構造函數進行類型轉換 10.5 淺層複製構造函數 10.6 深層複製構造函數 第11章 運算符重載 11.1 運算符重載 11.2 在成員函數中實現自加 11.3 重載前置自加運算符 11.4 創建臨時對象 11.5 創建無名臨時對象 11.6 取消創建臨時對象 11.7 重載後置自加運算符 11.8 重載加法運算函數operator+ 11.9 重載賦值運算函數operator= 11.10 轉換類型運算符 11.10.1 溫習調用構造函數實現的類型轉換 11.10.2 通過構造函數將變量轉換為一個對象的成員變量 11.10.3 通過operator關鍵字進行轉換 11.11 什麼可以被重載,什麼不可以 第12章 繼承 12.1 什麼是繼承和派生 12.1.1 複雜的繼承和派生 12.1.2 繼承和派生如何在C++中實現 12.1.3 繼承的種類及語法 12.1.4 單一繼承 12.2 公有型. 保護型和私有型 12.3 訪問權限 12.4 多重繼承 12.5 繼承的構造與析構 12.6 向基類構造函數傳遞參數 12.7 繼承和重載的兩義性問題 12.7.1 多重繼承容易產生兩義性 12.7.2 兩義性在重載時的一些問題 12.7.3 兩義性的歸屬問題 12.7.4 減少兩義性產生的混淆問題 12.7.5 虛基類不會產生兩義性 12.8 總結 第13章 虛函數 13.1 指向對象的指針 13.2 虛函數 13.3 拳擊遊戲 13.4 繼承是否可以實現多態性 13.5 在編譯時的靜態聯編 13.6 在運行時的靜態聯編 13.7 在編譯時的動態聯編 13.8 在運行時的動態聯編 13.9 調用虛函數 13.9.1 在虛函數中調用成員函數 13.9.2 三種調用虛函數的方式比較 13.10 被繼承的虛函數仍然是虛函數 13.11 系統是如何調用虛函數的 13.12 在虛函數中使用成員名限定 13.13 虛析構函數 第14章 數組 14.1 數組的基本用法 14.1.1 什麼是數組 14.1.2 數組元素 14.1.3 數組下標越界 14.1.4 倒序輸出 14.1.5 將數組的下標定義為常量 14.1.6 手動操作數組元素 14.1.7 數組的初始化 14.2 數組的用途 14.2.1 求平均考試成績 14.2.2 兔子繁殖問題 14.2.3 數字排序問題 14.3 數組在內存中的分佈 14.4 輸出數組名 14.5 數組名與函數 14.6 傳遞與接收 14.7 數組與函數 14.7.1 函數傳參實例一——求數組所有元素的和 14.7.2 函數傳參實例二——用遞增法查找數據 14.7.3 函數傳參實例三——用二分法查找數據 14.7.4 函數傳參實例四——判斷數組是否按照順序排列 14.7.5 函數傳參實例五——判斷數組排列方式後執行不同的函數 14.8 數組在對像中的傳參 14.9 數組對象 14.10 在數組對像中初始化成員變量 14.11 指針數組 14.12 枚舉常量與數組.. 14.13 多維數組 14.14 多維數組的初始化 14.15 字符數組 14.16 重載數組下標操作符 第15章 鍊錶 15.1 聲明鍊錶結構 15.2 簡單的圖書鍊錶 15.2.1 圖書鍊錶 15.2.2 類的鍊錶 15.3 動態鍊錶 15.3.1 動態鍊錶的建立 15.3.2 解決輸入字符造成死循環的問題 15.3.3 動態鍊錶的顯示 15.3.4 動態鍊錶的刪除 15.3.5 動態鍊錶的插入 15.3.6 鍊錶統計 15.3.7 使用鍊錶 15.4 完整的動態鍊錶清單 15.5 鍊錶使用案例——走迷宮 15.5.1 創建Windows應用程序項目 15.5.2 創建窗口 15.5.3 加載圖片 15.5.4 句柄是什麼 15.5.5 顯示圖片 15.5.6 動畫 15.5.7 鍵盤控制人物移動 15.5.8 迷宮牆壁 15.5.9 走迷宮 15.5.10 用鍊錶記錄行走路線 第16章 多態性 16.1 為什麼要使用多重繼承 16.2 在派生類中增加函數 16.3 使用多重繼承 16.4 多重繼承中初始化構造函數的參數 16.5 多個子基類共享一個父基類 16.6 虛基類 16.7 慎用多重繼承 16.8 空的虛函數 16.9 抽像類和純虛函數 16.10 純虛函數 16.11 複雜的抽象結構 第17章 類的特殊成員 17.1 靜態成員變量 17.2 私有靜態成員變量 17.3 靜態成員函數 17.4 靜態成員的使用 17.5 函數指針 17.6 函數指針數組 17.7 函數指針也可以作為函數的參數 17.8 使用typedef簡化函數指針的聲明及定義 17.9 類的函數指針 17.10 成員函數指針數組 第18章 字符串 18.1 char型字符串 18.2 string型字符串 18.2.1 string型字符串的賦值 18.2.2 string型字符串的合併 18.2.3 string型字符串的部分合併 18.2.4 string型字符串的替換 18.2.5 string型字符串的複制 18.2.6 string型字符串的插入 18.2.7 string型字符串的刪除 18.2.8 string型字符串的查找 18.2.9 string型字符串的比較 18.2.10 判斷string型字符串是否為空 18.3 字符串的使用 18.3.1 swap() 交換兩個字符串的內容 18.3.2 將string型字符串轉為char型字符串 18.3.3 char型字符串與函數 18.3.4 函數如何返回字符串 18.4 結構體 18.4.1 結構體的賦值 18.4.2 結構體與函數 18.4.3 結構體與string 18.5 string數組與函數 18.6 流的使用 18.6.1 重載輸出運算符<< 18.6.2 友元的方式重載輸出運算符 18.6.3 重載自加運算符的執行次序 18.6.4 重載輸入運算符>> 18.7 編寫一個String類 18.7.1 創建String類 18.7.2 創建可自動調節大小的String類字符串對象 18.7.3 限制數組越界 18.7.4 用複制構造函數實現字符串的賦值功能 18.7.5 用重載賦值運算符函數實現真正的字符串賦值功能 18.7.6 用重載輸出運算符operator<<()函數實現字符串的輸出 18.7.7 用重載輸入運算符operator>>()函數實現字符串的輸入 18.7.8 用重載比較運算符實現字符串的比較 18.7.9 為String類添加字符串的相加功能 18.7.10 為String類添加字符串的+=功能 18.7.11 完成後的String類 第19章 代碼重用 19.1 包含 19.2 將String類作為包含類 19.3 為book類重載執行相加運算的成員函數 19.4 包含對系統造成的消耗 19.5 按別名傳遞book對象 19.6 包含指向另一個類的指針 19.6.1 數據類Date 19.6.2 鍊錶類Node 19.6.3 標籤類linkelist 19.6.4 頭節點類HeadNode 19.6.5 尾節點TailNode類 19.6.6 中間節點InterNode類 19.6.7 InterNode類的構造函數 19.6.8 InterNode類的插入函數 19.6.9 全部程序 19.7 將頭節點. 中間節點和尾節點合併為一個節點 19.7.1 數據類Date 19.7.2 由Date類派生的圖書類Book 19.7.3 由Date類派生的藥品類medica 19.7.4 創建一個節點類Node 19.7.5 用來操作節點類Node的list類 19.7.6 list類的getfirst()方法 19.7.7 list類的operator[]方法 19.7.8 list類的repeat()方法 19.7.9 list類的insert()方法 19.7.10 list類的find()方法 19.7.11 重寫的藥品管理全部程序 19.8 利用類的包含來實現代碼重用 19.9 私有繼承 19.10 什麼時候使用私有繼承,什麼時候使用包含 19.11 保護繼承 第20章 友元類與嵌套類 20.1 友元類 20.2 嵌套類 第21章 流 21.1 流的操作 21.1.1 緩衝 21.1.2 流和緩衝區 21.1.3 標準輸入輸出對象 21.1.4 重定向 21.1.5 對象代表流 21.2 用cout輸出 21.2.1 重載運算符operator<< 21.2.2 清理緩衝區 21.2.3 有關輸出的相關函數 21.2.4 設置輸出的字段寬度 21.2.5 設置填充字段 21.2.6 設置浮點數的顯示精度 21.2.7 輸出末尾的0 21.2.8 設置標誌 21.2.9 setf()函數原型 21.2.10 所有15個標誌以及3個指示標誌 21.2.11 unset()函數 21.2.12 標準控制符 21.2.13 iomanip頭文件與標準控制符 21.3 用cin輸入 21.3.1 字符串的輸入 21.3.2 字符串的輸入問題 21.3.3 get()函數 21.3.4 帶字符引用參數的get()函數 21.3.5 帶2個參數的get()函數 21.3.6 帶3個參數的get()函數 21.3.7 getline()函數 21.3.8 read()函數 21.3.9 gcount()函數 21.3.10 peek()函數 21.3.11 putback()函數 21.4 文件的輸入和輸出 21.4.1 輸出數據到文件 21.4.2 讀取文件中的數據 21.4.3 讀取空格及空格後面的字符 21.5 多種打開文件的方式 21.6 檢查文件是否打開 21.7 二進製文件和文本文件 21.7.1 以文本形式輸出到文件 21.7.2 以二進制形式輸出到文件 21.8 打開多個文件 21.9 命令行處理文件 21.10 使用命令行處理文件例程 21.11 指定讀取文件中的數據 21.12 輸出數據到文件指定位置處 21.13 seekp()和seekg()函數的結合使用 21.14 臨時文件 21.15 sstream字符串輸入輸出流類 第22章 命名空間 22.1 什麼是命名空間 22.2 創建命名空間 22.2.1 擴充命名空間的內容 22.2.2 盡量在命名空間之外定義函數 22.2.3 命名空間中的成員都是公有的 22.3 使用命名空間 22.4 使用關鍵字using 22.5 為你的命名空間取個別名 22.6 未命名的命名空間 22.6.1 未命名命名空間與全局變量的區別 22.6.2 未命名命名空間與static的區別 22.6.3 未命名命名空間. static與extern的區別 22.7 標準命名空間std 第23章 模板 23.1 什麼是模板 23.2 重載模板 23.3 具體化函數模板 23.3.1 函數模板不能重載 23.3.2 具體化函數模板解決重載問題 23.3.3 具體化函數模板與實例化模板函數 23.4 普通函數. 函數模板與具體化函數模板的優先級 23.4.1 普通函數和函數模板的執行次序 23.4.2 函數模板與具體化函數模板的執行次序 23.4.3 具體化函數模板與普通函數的優先級 23.5 函數模板的匹配 23.6 類模板的定義 23.7 複雜類模板 23.8 數組模板 23.9 對像數組模板 23.10 具有多個參數的模板 23.11 為模板參數提供默認值 23.12 約束模板 23.13 模板成員 23.14 將模板用作參數 23.15 模板和??友元 23.15.1 非模板友元類和友元函數 23.15.2 通用模板友元類和友元函數 23.15.3 特定類型模板友元函數 23.16 多餘的臨時對象 23.17 靜態成員和模板 23.18 標準模板庫 23.18.1 容器 23.18.2 順序容器 23.18.3 關聯容器 23.18.4 算法類 23.18.5 總結 第24章 異常和錯誤處理 24.1 異常 24.2 設置多條catch語句 24.3 異常的派生 24.4 創建異常類的成員函數 24.5 異常類的虛函數 24.6 異常類與模板的關係 第25章 補充內容 25.1 預處理過程 25.1.1 預處理指令 25.1.2 #include指令 25.1.3 #define指令 25.1.4 用#define指令替換常量 25.1.5 用#define定義一個特定字符串並對其進行測試 25.1.6 #ifdef. #define和#endif的用途 25.1.7 帶參數的#define 25.1.8 宏與內聯函數 25.1.9 #運算符 25.1.10 ##運算符 25.1.11 #undef指令 25.1.12 #if指令 25.1.13 #endif指令 25.1.14 #if defined指令 25.1.15 #ifdef和#ifndef指令 25.1.16 #elif指令 25.1.17 #error指令 25.1.18 #line指令 25.1.19 #pragma 指令 25.2 預定義的宏 25.3 assert()宏 25.4 嘗試編寫一個簡單的assert()宏 25.5 不能為0的變量 25.6 用宏函數來輸出表達式的值 25.7 調試的級別 25.8 C++類型轉換及運行時類型信息(RTII) 25.8.1 動態類型轉換符 25.8.2 靜態類型轉換 25.8.3 重新解釋類型轉換 25.8.4 常類型轉換 25.8.5 運行時類型信息 25.9 關鍵字volatile 25.10 關鍵字const 25.11 關鍵字mutable 25.12 聯合數據類型union 25.13 聯合數據類型的內存佔用 25.14 匿名聯合體 25.15 再談指針 25.15.1 指針與數組 25.15.2 指針操作多維數組 25.15.3 指向多維數組的指針作為函數參數 25.15.4 字符串的指針 25.15.5 接受字符串指針的函數 25.15.6 指向字符串的指針變量與字符數組的區別 25.15.7 指向函數的指針 25.15.8 指向函數的指針的用途 25.15.9 指針數組 25.15.10 指向指針的指針 25.16 位運算 25.16.1 按位與“&”運算符 25.16.2 按位或“|”運算符 25.16.3 異或“^”運算符 25.16.4 取反“~”運算符 25.16.5 左移“<<”運算符 25.16.6 右移“>>”運算符 25.16.7 複合位運算符 25.16.8 不同長度數字的位運算 25.16.9 位運算的實例 25.17 位字段 25.18 區域差異 25.18.1 locale類 25.18.2 默認區域表示或全局區域表示 25.18.3 時間與地理設置 25.18.4 locale與time.h中時間函數的搭配使用 25.18.5 區域表示locale與流的搭配使用 25.18.6 區域表示locale與模板的搭配使用 附錄A ASCII碼對照表 附錄B C++的關鍵字 附錄C C++常用頭文件列表

                                    img
                                    HDMI 產品通過ATC相容性認證設計要點

                                    HDMI Licensing LLC目前授權兩家HDMI授權測試中心(ATC),其中一家位於日本大阪,由Matsushita Electric Industries經營,另一家則位於美國加州Sunnyvale,由晶像公司(Silicon Image, Inc.)主持。HDMI Licensing LLC可能在日後授權其他ATC。 之前曾經提過,HDMI技術採用廠商在四類產品(來源裝置、終端裝置、複送器與纜線)當中,所開發的第一臺HDMI產品,必須送往HDMI ATC接受認證。只要某類別中的第一臺產品通過ATC相容性認證,技術採用廠商即可對未來產品進行內部的相容性自我測試,也可以繼續將產品提交ATC認證。 技術採用廠商在提交產品進行測試時,必須一併送出產品、操作指南與操作產品所需的其他所有設備。例如,許多STB產品要求廣播品質的來源訊號才能正常運作。HDMI ATC並未配備有線電視或衛星電視訊號源設備,因此STB製造商必須提供能讓產品之HDMI輸出端正常運作的訊號來源。 提交的來源或複送器DUT必須能夠中止HDCP加密以進行測試,此外還必須隨測試產品附上兩份表格。HDMI申請表包括所有的申請人聯絡資訊和產品資訊。製造商可以在HDMI申請表中,列出相同系列的多項產品。必須要與提交測試的產品使用相同的HDMI軟硬體(終端裝置則還需要相同的EDID),才能列為系列產品,。第二份表格為性能聲明表(CDF)。CDF詳細描述產品的HDMI性能以及所有應測試相容性的功能。這是ATC技師決定DUT測試項目的指南。

                                    img
                                    偏微分方程(臺灣出版)

                                    ISBN-13: 9789574835096 ISBN-10: 957483509X 書名: 高等工程數學 第4版 作者: 莊紹容、楊精松 定價: NT 850 出版商: 東華書局 版次: 4 年份: 2008 一、本書全一冊,含微分方程式、拉普拉斯變換、線性代數、向量分析、傅立葉級數、傅立葉變換、複變函數、偏微分方程式(此章與本書各節習題答案置於本書光碟中),適合作為大學工學院或四年制技術學院工程數學每週三小時,共計一學年講授之用。 二、本書對於電機系或電子系在電路學及自動控制方面所需用到的數學部分,如矩陣的特徵值、矩陣微分方程式、eAt的計算,均有詳細討論。有關工學院其他系所用到工程數學部分,本書亦有所討論。有關工學院其他系所用到工程數學部分,本書亦有所討論。 三、作者對於工程數學教學皆有豐富的教學經驗,特將教學心得作有系統的整理,內容力求簡,條理分明,循序漸近;並以代表性的例題、習題相互配合,俾使學習者能加深觀念、觸類旁通,以收事半功倍之效。 四、本書另備有全部習題詳解,提供教師參考。 這僅是其中的第十三章

                                    img
                                    GNU Make 使用手冊(繁體版)

                                    1 make概述1.1 怎樣閱讀本手冊1.2 問題和BUG2 Makefile檔案介紹2.1 規則的格式2.2一個簡單的Makefile檔案 2.3mke處理Makefile檔案的過程2.4使用變數簡化Makefile檔案2.5讓make推斷命令2.6另一種風格的Makefile檔案 2.7在目錄中刪除檔案的規則3編寫Makefile文件3.1Makefile檔案的內容3.2Makefile檔案的命名 3.3引入(include)其它的Makefile檔案3.4變數MAKEFILES3.5Makefile檔案重新生成的過程3.6重載其它Makefile檔案 3.7make讀取Makefile檔案的過程4 編寫規則4.1規則的語法4.2在檔案名中使用萬用字元4.2.1萬用字元例子4.2.2使用萬用字元的常見錯誤 4.2.3函數wildcard4.3在目錄中搜尋先決條件4.3.1VPATH:所有先決條件的搜尋路俓(stem)4.3.2vpath指令4.3.3目錄搜尋過程 4.3.4編寫搜尋目錄的shell命令4.3.5目錄搜尋和隱含規則4.3.6連接庫(Link Libraries)的搜尋目錄4.4假想(phony)目標 4.5沒有命令或先決條件的規則4.6使用空目錄檔案記錄事件4.7內建的特殊目標名4.8具有多個目標的規則4.9具有多條規則的目標4.10靜態樣式規則 4.10.1靜態樣式規則的語法4.10.2靜態樣式規則和隱含規則4.11雙冒號規則(::)4.12自動生成先決條件5 在規則中使用命令5.1命令回顯 5.2執行命令5.3並行執行5.4命令錯誤5.5中斷或關閉make5.6遞迴make5.6.1變數MAKE的工作模式5.6.2與子make通訊的變數 5.6.3與子make通訊的選項5.6.4`--print-directory'選項5.7定義固定次序命令5.8使用空命令6使用變數6.1變數引用基礎 6.2變數的兩個特色6.3變數進階引用技術6.3.1替換引用6.3.2巢狀變數引用6.4變數取值6.5設定變數6.6為變數值附加文字(text) 6.7撤銷(override)指令6.8定義多行變數6.9環境變數6.10特定目標變數的值6.11特定樣式變數的值7 Makefile檔案的條件語句 7.1條件語句的例子7.2條件語句的語法7.3測試標誌的條件語句8 文字(text)轉換函數8.1函數呼叫語法8.2字元串替換和分析函數8.3檔案名函數 8.4函數foreach8.5函數if8.6函數call8.7函數origin8.8函數shell8.9控制Make的函數9執行make 9.1指定Makefile檔案的參數9.2指定最終目標的參數9.3代替執行命令9.4避免重新編譯檔案9.5變數重載9.6測試編譯程式9.7選項概要10 使用隱含規則10.1使用隱含規則10.2隱含規則目錄10.3隱含規則使用的變數10.4隱含規則鏈10.5定義與重新定義樣式規則10.5.1樣式規則簡介 10.5.2樣式規則的例子10.5.3自動變數10.5.4樣式匹配10.5.5萬用規則10.5.6刪除隱含規則10.6定義最新類型的預設規則 10.7舊式的後置規則(suffix rule)10.8隱含規則搜尋算法11 使用make更新資料庫檔案11.1資料庫成員目標11.2資料庫成員目標的隱含規則 11.2.1更新資料庫成員的符號索引表11.3使用檔案的危險11.4資料庫檔案的後置規則(suffix rule)12 GNU make的特點13 不相容性和失去的特點14 Makefile檔案慣例14.1makefile檔案的通用慣例14.2makefile檔案的工具14.3指定命令的變數 14.4安裝路俓(stem)變數14.5用戶標準目標14.6安裝命令分類15快速參考16make產生的錯誤17複雜的Makefile檔案例子附錄名詞翻譯對照表

                                    img
                                    中文串口監聽軟件

                                    SUDT AccessPort 1.37 說明 ===================== 在使用之前請仔細閱讀本說明 1.軟體說明 --------------------- SUDT AccessPort 是一款用於PC機串口(RS232)調試、監控的軟體。 特點﹕ 1).監控串口﹕具有埠監控功能,可以監控、攔截、保存所收發的資料(NT/2K/XP)。 2).串口調試﹕支援常用的串口操作功能,支援大資料量的收發、保存,支援自動發送。 3).動態變參﹕在不改變當前所打開埠的情況下,能動態改變埠參數(如﹕串列傳輸速率、校驗位、流控制等)。 4).雙模編輯﹕資料發送區內嵌十六進位編輯器(類似UltraEdit),支援十六進位<=>文本雙模式切換編輯,支援unicode。 5).國際版本﹕國際版,支援多國語言。 6).無需安裝﹕介面友好,方便易用。 簡要描述﹕ 1).用於串口調試,支援常用的110-256000串列傳輸速率,支援自定義串列傳輸速率。 2).能以字元或十六進位接收或發送任何資料,能發送、接收任意大小的檔。 3).在不改變當前所打開埠的情況下,能動態改變埠參數(如﹕串列傳輸速率、校驗位、流控制等)。 4).資料發送區可即時編輯、發送文本資料。 5).能將所接收的原始資料以及顯示資料分別保存。 6).資料發送區允許設置發送週期,自動發送資料。 7).可調試的埠範圍是COM1-COM255,支援擴展埠(USB<->RS232)。 8).可設置字體、文字顏色、背景顏色。 9).允許將發送區的資料在接收區回顯,類比終端操作。 10).允許發送區資料以回車鍵作為發送操作信號。 11).Terminal模式支援自動回應功能,支援Hex、Text、浮點數等類型。 12).Terminal模式支援預定義資料發送,支援Hex、Text、浮點數等類型。 13).Monitor模式支援彩色文本顯示,便於更好的區分、觀察資料. 14).允許Monitor模式下攔截到的資料以十六進位或字元方式顯示。 15).允許接收區在接收到的資料後添加回車字元(CRLF),便於觀察資料。 16).可將Terminal模式下接收到的資料按照十六進位文本方式導出到檔或剪貼板。 17).允許保存程式環境變數。 18).定義熱鍵,方便操作。 19).國際版,支援多國語言。 20).資料發送區內嵌十六進位編輯器,支援unicode。 21).支援串口監控功能,可以監控串口設置以及收發的資料。 22).線上自動更新提示功能,當有可用新版本時提示用戶下載。 23).本程式線程安全,可以同時啟動多個副本調試多個串口。 A.程式擁有埠監控功能,可以監控內核事件並攔截所有通過指定埠收發的資料,該功能 目前只在2000/XP/2003平臺上有效。 1.在使用監控功能前必須保證所要監控的埠處於關閉狀態。 2.運行本程式,選擇所要監控的埠並啟動監控功能,然後啟動要被監控的埠﹔ B.程式第一次啟動時自動設置語言,也可以手動在View->Language功能表項選擇相應的語言, 目前支持英文、簡體中文、繁體中文。 2.運行環境 --------------------- Windows 9x/2000/XP/2003/Vista/Win7, 32Bit/64Bit 3.安裝與卸載 --------------------- 運行解壓軟體,將壓縮包解壓到指定目錄完成安裝。卸載時只需將程式目錄刪除。 4.軟體使用 --------------------- SUDT AccessPort 安裝完成後即可使用。 5.使用許可 --------------------- 本軟體為免費軟體,許可"個人用戶"自由使用,複製和分發此套裝軟體,但要保證此套裝軟體的完整性。您不能將本軟體用於商業目的,如需要商業使用,需得到軟體作者的授權許可。 6.拒絕擔保 --------------------- SUDT.COM 保證該軟體不含任何木馬、病毒等,能夠對您的系統造成破壞的惡意代碼。但拒絕任何責任擔保,對因使用或不能使用該軟體所導致的全部風險及後果均由用戶自己承擔。 7.版權申明 --------------------- Copyright(C) 2002-2012 SUDT Studio, All rights reserved. Author: Fred Chow E-Mail: support@sudt.com WWW: http://www.sudt.com 8.歷史版本 --------------------- AccessPort 1.37 (2012.04.23) 1.監控功能支援64位元系統。 2.修正監控功能在某些情況下引起程式崩潰的問題。 3.禁止Terminal模式下某些對使用者無用的錯誤訊息方塊的顯示。 AccessPort 1.36 (2011.11.11) 1.修正對於某些非標準埠,啟動監控時程式退出的問題。 2.修正與某些類型設備進行檔案傳輸時,程式掛起的問題。 3.修正作業系統與其它設備傳輸資料時0x00被過濾掉的問題。 AccessPort 1.35 (2011.11.08) 1.重寫監控驅動,支援多埠攔截。 2.檔案傳輸功能支援大檔。 AccessPort 1.34 (2010.09.30) 1.支持Vista/Win7。 AccessPort 1.33 (2006.08.31) 1.重寫埠狀態顯示代碼。 2.重寫Terminal資料接收代碼,相容SerialNull軟體,降低資源佔用率。 3.添加DTR、RTS信號手動控制按鈕。 4.為按鈕式下拉功能表提供多語言支援。 AccessPort 1.32 (2006.05.15) 1.修正Ctrl+F10、Shift+F10等熱鍵無法使用的問題。 2.修正XonLim、XoffLim參數設置失敗的問題。 3.修正XOn/XOff模式下檔傳輸、手動發送、自動發送等操作不能回應Xoff、Xon信號的問題。 4.修正win9x等系統下提示找不到PSAPI.DLL的問題 。 AccessPort 1.31 (2005.12.28) 1.優化Monitor模式核心代碼。 2.Monitor驅動程式Apsm.sys升級為2.8版本,正式支援windows 2003系統。 3.修正Monitor模式下,無法監控串口號大於COM9的問題。 4.修正Monitor模式下,保存日誌時點擊進度提示框上“取消”按鈕後,程式異常退出的問題。 5.修正Monitor模式下,監控驅動與其他串口驅動的不相容的問題。 6.修正Terminal模式下,預定義資料列表以及自動回應列表顯示/資料裝載不正確等問題。 AccessPort 1.30 (2005.10.13) 1.主功能表添加"編輯"項。 2.右健彈出功能表支援語言本地化操作,並與常用熱健相關聯。 3.為Monitor模式添加工具欄,便於操作。 4.為Monitor日誌增加記錄頭,包括:被監控埠號/電腦名/系統版本,等資訊。 5.為Monitor模式增加資料包截獲時間。 6.更改了Terminal附屬工具欄的某些圖示。 7.Monitor驅動程式Apsm.sys升級為2.3版本。 8.Monitor日誌保存完畢後自動關閉進度對話方塊。 9.修正win2000系統下,Monitor驅動啟動偶爾失敗的問題。 10.修正Monitor模式下,監控處於停止狀態時保存檔失敗的問題。 11.修正Terminal模式下,自動發送間隔小於100ms時無法停止發送的問題。 AccessPort 1.29 (2005.08.03) 1.為手動發送按鈕增加熱鍵Ctrl+Enter。 2.修正win98下,Termianl模式無法發送字串的問題。 3.win98系統下不再顯示Monitor模式相關操作。 AccessPort 1.28 (2005.07.19) 1.優化代碼,改善對USB-RS232設備的支援。 2.改進Termianl/Monitor模式的切換,操作更直觀。 AccessPort 1.27 (2005.07.11) 1.增加視窗記憶功能,自動保存視窗大小、位置。 2.增加流控制設置自動裝載功能。 AccessPort 1.26 (2005.07.08) 1.Terminal模式增加自動回應功能,支援Hex,Text,Float等類型。 2.修正部分bug。 AccessPort 1.25 (2005.07.06) 1.Monitor模式增加存檔提示。 2.Monitor驅動程式Apsm.sys升級為2.0版本。 3.增加預定義模式功能,支援Hex,Text,Float等類型的資料。 AccessPort 1.24 (2005.06.21) 1.Monitor模式支援彩色標記。 2.Monitor模式下停止監控後,不再自動切換至Terminal模式。 3.修正部分bug. AccessPort 1.23 (2005.06.18) 1.支援右鍵功能表,提供剪切、複製等功能。 2.將Monitor模式下自動滾屏的熱鍵由Ctrl+A改為Alt+A。 3.修正1.21、1.22版本所積累的問題。 AccessPort 1.22 (2005.05.31) 1.修正建立通信後背景螢幕閃爍的問題。 2.修正即時發送模式下游標位置顯示不正確的問題。 3.修正即時發送選項狀態保存失敗的問題。 4.重新設置Rx,Tx面板位置,更符合使用習慣。 5.為Tx發送區增加回顯、回車發送功能,貼近終端操作習慣。 6.為Terminal的字元顯示方式增加文字顏色、背景顏色設置功能。 AccessPort 1.21 (2005.05.26) 1.增加事件、超時控制設置。 2.增加埠狀態顯示。 3.增加Hex格式字串的發送、導出功能,導出功能支援檔保存以及剪貼板複製。 4.Rx接收區增加自動換行功能。 5.工具欄增加Terminal、Monitor模式切換按鈕。 6.增加字體設置功能。 7.Monitor功能表下增加埠刷新按鈕,及時獲取系統埠資訊。 8.Monitor模式下增加Hex、String顯示切換功能,便於觀察資料資訊。 9.Monitor模式下增加自動滾屏功能。 10.Monitor模式下增加停止監控的等待提示對話方塊。 11.發送區可編輯資料長度增加到64K,並在介面上作提示。 12.重新設計資料攔截功能代碼,防止資料量積累到一定程度時系統崩潰的錯誤。 13.增加對cts,dsr hold信號的檢測判斷,若接收端未準備好時不允許發送資料。 14.修正發送區Hex編輯模式下,使用大寫輸入時AA變成EA,BB變成FB等的錯誤。 AccessPort 1.20 (2005.04.26) 1.增加流控制設置。 2.修正幾個bug。 AccessPort 1.19 (2005.04.02) 1.增加對自定義串列傳輸速率的設置,串列傳輸速率範圍擴大到256000。 2.可調試埠範圍從COM32擴大到COM255。 AccessPort 1.18 (2004.12.25) 1.修正幾個bug。 AccessPort 1.17 (2004.12.10) 1.為資料發送區增加即時編輯、發送資料的功能。 2.修正資料攔截功能中的格式化輸出功能,使得攔截到的資料能夠按照0xXX的方式對齊顯示。 3.優化資料接收代碼,使得資料接收更加及時、高效。 AccessPort 1.16 (2004.11.04) 1.修正在網路不通情況下,自動檢測新版本資訊時出現無效版本號的錯誤。 2.為檔發送提供重新裝載資料功能(每次發送時都重新將檔內容讀入資料緩衝區,保證資料同步)。 3.增加檔另存功能。 AccessPort 1.15 (2004.10.10) 1.更新資料接收區的十六進位顯示代碼。 2.為資料攔截功能提供清空記錄的功能。 3.修正資料發送區字串自動發送模式下,資料被誤操作清空的問題。 4.修正保存檔後資料攔截功能啟動失敗的錯誤。 AccessPort 1.14 (2004.09.22) 1.重新構造程式框架。 2.修正幾個已知bug。 3.為串口資料發送區提供顯示/隱藏功能。 AccessPort 1.13 (2004.07.18) 1.修正幾個bug。 AccessPort 1.12 Beta 6 (2004.06.16) 1.修正在win98下存檔失敗的錯誤。 2.修正打開大於COM9時失敗的錯誤。 3.修正字元發送區按回車鍵時無法換行的錯誤。 4.修正週期性迴圈發送時資料都為0的錯誤。 AccessPort 1.12 Beta 5 (2004.03.20) 1.修正幾個bug,包括程式退出時清理暫存檔案失敗的問題。 AccessPort 1.12 Beta 4 (2004.02.15) 1.修正資料發送區在HEX模式下只能輸入10個位元組的問題,緩衝區擴大至8192。 2.應用程式第一次啟動時不再採用默認的英語設置,改為自動識別方式。 3.完全開放資料監控功能,取消資料監控時只顯示前8個位元組的限制,並增加存檔功能。 AccessPort 1.12 Beta 3 (2003.10.21) 1.增加串口監控功能,可以監控串口設置以及所收發的資料。 AccessPort 1.12 Beta 2 (2003.10.04) 1.為資料發送區添加十六進位編輯器,類似于UltraEdit的編輯功能,支援unicode。 AccessPort 1.12 Beta 1 (2003.09.25) 1.更新為國際版,支援多國語言。 2.添加線上自動更新提示功能,當有可用更新版本時提示用戶下載。 3.將AccPort.dat更新為AccessPort.ini,使程式環境變數的保存、調用更加穩定、可靠。 4.修正自動發送資料時清空按鈕可以清除發送區資料,並造成程式無法結束的問題。 AccessPort 1.11 (2003.01.10) 1.修正接收資料保存不完整的問題。 2.修正程式啟動時調用歷史設置時失敗的問題。 3.添加熱鍵方便調試操作。 4.添加28800bps串列傳輸速率。 5.將可調試的埠數由4個擴大到32個。 AccessPort 1.10 (2002.11.10) 1.重新設計介面元素,佈局更合理。 2.添加自動發送功能。 3.添加程式啟動資訊的記錄功能。 4.修正頻繁開關埠後,發送檔時線程鎖死的問題。 5.修正不能刪除暫存檔案的問題。 AccessPort 1.00 (2002.10.23) 1.提供基本的資料收發功能。 2.提供接收資料存檔功能。 3.實現線程安全,允許多副本調試。

                                    img
                                    北軟還原精露 V.7 最新版 破解版

                                    【軟件介紹】: 享譽全球的創新技術、新時代硬碟還原極品﹐讓您成為電腦維護高手! 新一代還原精靈7.1由北軟研發團隊所開發之純軟體硬碟保護工具。安裝容易、無須插硬體卡﹐無論是作業系統當機﹐還是病毒入侵﹐都可以將您的電腦硬碟安全的保護起來。 獨步全球領先技術 (1)新時代硬碟還原精靈 第三代還原精靈V7.1為創新的硬碟還原軟體﹐安裝於企業或家庭電腦上﹐可立即保護整個硬碟的系統與資料。 (2)全球首創不同磁碟分割區﹐可設定不同保護模式 對每個磁碟分割區(C:D:E:..)可獨立設定不同保護模式﹐讓你可針對受損的分割區進行還原﹐而不會影響其他正常分割區的資料。 (3)每個磁碟分割區可設定多個還原保護點 在不同的時間點上﹐可對每個磁碟分割區設定多個保護點﹐若分割區發生異常時﹐可選擇一個最適當的保護點來還原﹐讓系統返回到正常狀態。 為何需要用還原精靈 因為: 防毒軟體無法讓您完全免除中毒的損害! 因為: 不是電腦專家的你﹐碰到家裡電腦系統當機、損毀、中毒時﹐就得花錢、花時間送修電腦﹐無法自己DIY輕鬆搞定! 因為: MIS電腦專家﹐得花時間搶救中毒的電腦、損毀的檔案或重灌系統﹐無法立即修復﹐造成企業工作停頓﹐讓老闆急得跳腳! 所以:創新的第三代還原精靈7.1 幫您輕鬆解決上述難題﹐讓您只花一秒鐘﹐就可以輕鬆、快速修復電腦﹐不用備份也不用重灌﹐就是這麼簡單又神奇! 安裝操作方便 (1)簡單易懂的安裝操作介面 純軟體版本﹐不論安裝或操作使用﹐均可在Windows環境下﹐一般大眾輕鬆上手。 (2)直接安裝﹐即時保護 您不需重新切割磁碟分割區﹐或是重新安裝作業系統﹐只要直接安裝本產品﹐就可立即啟用還原精靈﹐即時保護磁碟。 (3)獨創「硬碟空間動態管理」技術﹐安裝佔空間最小 安裝還原精靈V7.1﹐只需利用硬碟坑間的0.05%﹐就可保護整顆硬碟﹐讓您能充分使用99.95%的硬碟空間﹐不像其他廠牌需耗用10~20%的硬碟空間。 功能強大最實用 (1)全方位的磁碟保護功能﹐1秒鐘立即還原 純軟體版本,不論安裝或操作使用,均可在Windows環境下,一般大眾輕鬆上手。 (2)全球首創不同磁碟分割區(C:D:E:..)可設定各自的保護模式 您可針對不同性質的磁碟分割區﹐設定不同策略的保護模式: (a) 自動還原: 每次開機分割區立即自動還原 (b) 定期還原: 每隔幾日分割區開機時自動還原 (c) 不還原: 不自動還原﹐需由使用者手動執行還原 您可針對受損的分割區進行還原﹐不會影響其他正常分割區資料。 您可針對特定的分割區進行轉存﹐不會影響其他正常分割區資料。 (3)每個磁碟分割區可設定多個保護點 您可對每個磁碟分割區﹐在不同時間點上設定多個還原點﹐當分割區系統異常、資料損毀時﹐便可選擇一個您想要的保護點﹐立即讓磁碟還原到當時的系統狀態﹐珍貴資料完整無缺。還原點的個數由磁碟大小而定。 (4) 獨家續存技術﹐資料轉存安全零失誤 還原精靈V7.1能讓您將新異動資料轉存到永久保護區﹐您可轉存所有的異動資料﹐或某個保護點前的異動資料﹐且轉存過程中不怕斷電、異常中斷﹐只要重新開機﹐系統自動繼續完成轉存﹐資料安全零失誤。 (5) 安全防護的CMOS 還原精靈V7.1不只能保護磁碟,系統會備份CMOS的最新版本,並設有密碼管控,防止他人竄改,即使CMOS資料損毀亦可立即還原。 (6) 功能強大的多重開機精靈(Boot Genius) 還原精靈V7.1另提供您多重開機精靈,協助您規劃使用硬碟空間,可切割多個不同用途的磁碟分割區,作為開機磁碟或資料磁碟使用,最多可支援達90個磁碟(包含32個可開機的系統磁碟)。 (7) 便利、全面、靈活 便利: 插入安裝光碟,作業系統自動執行安裝程式,就可以直接安裝,沒有繁瑣的設 定和讓人難懂的專業術語,即使您對電腦不十分了解,也不用擔心,您完全可以在最短的時間內掌握還原精靈 V7.1 安裝與使用。 全面: 還原精靈V7.1可以防止任何對硬碟的破壞。 靈活: 還原精靈V 7.1 的功能因為各用戶對產品的要求可能不同,我們的程式也為用戶提供了多種保護方式的選擇,已滿足不同用戶的需要。 (8) 純軟體設計 使您安裝更為輕鬆,不存在與硬體相容性的問題,並且成本較低。 (9) 首創圖形化介面的安裝與使用 不論是安裝,還是使用都在Windows作業系統下,優美的圖形化介面,徹底告別原先硬體還原產品生硬刻板的介面,會給您耳目一新的感覺。 (10)權限管理嚴密 您可能擔心別人使用您的電腦進行破壞,為此還原精靈 7.1 提供設定管理者密碼功能,並且對密碼進行加密,只有您才能對還原精靈 7.1 進行操作,而其他人員則無法進行操作。 (11)移除後不會破壞硬碟資料 還原精靈V7.1 具有移除功能,且移除後不會破壞硬碟資料,可以恢復到上次資料轉存或是安裝的硬碟狀態,您不用擔心移除後硬碟資料被破壞。 (12)具有Virus防護功能 管他什麼病毒,只需執行還原,所有病毒皆不見,您就不用擔心病毒會發作了。 (13)硬碟空間使用狀況監控 可以讓您隨時瞭解硬碟的使用狀況,使您更加合理的分配您的硬碟空間。 (14)支援多種作業系統 支援Windows 95 、Windows 98、Windows Me、Windows NT、Windows2000、Windows XP、Windows 2003 Server。 (15)支援檔案格式豐富 支援FAT16、FAT32、NTFS檔案格式。 (17)支援各式硬碟 支援當前市面上,所有各類型,品牌的硬碟。 Windows系列通用 安裝後重啟電腦在離線啟用輸入序號即可使用 即時還原也可定時還原 免於重灌麻煩

                                    img
                                    Effective c ++and More effective c++

                                    這本書是多年來我對專業程式員所做的C++ 教學課程下的一個自然產物。我發現,大部份學生在一個星期的密集訓練之後,即可適應這個語言的基本架構,但要他們「將這些基礎架構以有效的方式組合運用」,我實在不感樂觀。於是我開始嘗試組織出一些簡短、明確、容易記憶的準則,做為C++ 高實效性程式開發過程之用。那都是經驗豐富的C++ 程式員幾乎總是會奉行或幾乎肯定要避免的一些事情。我最初的興趣在於整理出一些可被某種「lint-like 程式」施行的規則,最後我甚至領導一個計劃,研究某種可將C++ 原始碼中違反使用者指定條件之處檢驗出來的工具(你可以在Effective C++ 網站上找到此研究的一份概要報告)。不幸的是在我尚未完成其完整原型之前,這個研究計劃便結束了。幸運的是,目前市面上已有這類C++ 檢驗工具(商品),而且不只一個。 雖然我最初的興趣是在研究可被(某種工具)自動實施的程式設計準則,但我很快瞭解到那個研究方向的侷限性。優秀的C++ 程式員所奉行的準則,多數都難以「公式化」;要不就是雖然它們有許多重要的例外情況,卻被程式員盲目地奉行不渝。這使我念頭一轉:某些東西雖然不比電腦程式精準,但仍能比一本泛泛的C++ 教科書更集中火力,更打到重點。這個念頭的結果就是你手上這本書:一本內含50 個有效建議(如何改善你的C++ 程式技術和你的設計思維)的書。 在這本書中,你會發現一些忠告,告訴你應該做些什麼,為什麼如此;告訴你不應該做些什麼,又為什麼如此。基本而言當然whys 比whats 更重要,但檢閱一列列準則,也確實比強記一本或兩本教科書更輕鬆更方便得多。和大部份的C++ 書籍不同,我的組織方式並非以語言特性做為依據。也就是說我並不在某處集中討論constructors(建構式),在另一處集中討論virtual functions (虛擬函式),又在第三個地方集中討論inheritance(繼承機制)。不,不是這樣,本書的每一個討論主題都剪裁合度地以一個個準則陳列出來。至於我對某特定語言性質的探討,散佈面積可能涵蓋整本書。 這種作法的優點就是比較容易反映出「特意挑選C++ 做為開發工具」的那些軟體系統的複雜度。在那些系統之中,光只瞭解個別語言特性是不夠的。例如,有經驗的C++ 程式員知道,瞭解inline 函式和瞭解virtual destructors,並不一定表示你瞭解inline virtual destructors。身經百戰的開發人員都認知到,理解C++ 各個特性之間的互動關係,才是有效使用這個語言的最重要關鍵。本書組織反映出這一基本事實。 這種作法的缺點是,你恐怕必須前後交叉參考而非只看一個地方,才能發現我所說的某個C++ 架構的全貌。為了將不方便性降至最低,我在書中各處放了許多交叉索引,書後並有一份涵蓋全部範圍的索引。(譯註:為了協助讀者更容易掌握 Effective C++ 和More Effective C++ 二書,我以Effective C++ CD 為本,為兩書的中文版額外加上兩書之間的交叉索引。此乃原書所無。如果文中出現像條款 M5 這樣的參考指示,M 便是代表More Effective C++) 籌劃第二版期間,我改寫此書的雄心一再被恐懼所取代。成千上萬的程式員熱情擁抱Effective C++ 第一版,我不希望破壞吸引他們的任何東西。但是自從我寫了第一版之後,六年過去了,C++ 有了變化,C++ 程式庫有了變化(見條款49),我對C++ 的瞭解也有了變化,乃至於C++ 的用途也有了變化。許許多多的變化。對我而言,重要的是我必須修訂Effective C++ 以反映那些變化。我嘗試一頁一頁地修改內容,但是書籍和軟體十分類似,局部加強是不夠的,唯一的機會就是系統化地重寫。本書就是重寫後的結果:Effective C++ 2.0 版。熟悉第一版的讀者,可能有興趣知道,書中的每一個條款都經過重新檢驗。然而我相信第一版的結構至今仍是流暢的,所以整本書的結構並沒有改變。50 個條款中,我保留了48 個,其中某些標題稍有變化(附隨的討論內容亦復如此)。退休下來(被取代的)兩個條款是32 和49,不過原條款32 的許多資訊被我移到如今煥然一新的條款1 中。我將條款41 和42 的次序做了對調,因為這樣比較能夠適當呈現它們修訂後的內容。最後,我把上一版繼承體系圖所採用的箭頭方向顛倒過來,以符合目前幾乎已經一致的習慣:從derived classes 指往base classes。我的More Effective C++ 一書也採用相同習慣(本書最後列有該書摘要)。 本書提供的準則,離鉅細糜遺的程度還很遠,但是完成一個好的準則— 一個幾乎可於任何時間應用於任何程式的準則,動手遠比動嘴困難得多。如果你知道其他準則,可以協助撰寫有效的C++ 程式,我非常樂意聽到你告訴我它們的故事。 此外,說不定你會覺得本書的某些條款不適合成為一般性忠告;或許你認為另有比較好的方法來完成書中所說的任務;或許你認為某些條款在技術討論方面不夠清楚,不夠完全,抑或有誤導之嫌。我衷心盼望你也能夠讓我知道你的這些想法。 Donald Knuth(譯註:經典書籍The Art of Computer Programming, Volume I,II,III 的作者)長久以來為挑出其書錯誤的熱心讀者準備有一份小小的報酬。這個故事傳為美談。追求完美的精神令人佩服。看過那麼多倉促上市錯誤壘壘的C++ 書籍後,我更是特別強烈地希望踵隨Knuth 的風範。因此,如果有人挑出本書的任何錯誤並告訴我— 不論是技術、文法、錯別字、或任何其他東西— 我將在本書新刷的時候,把第一位挑出錯誤的讀者大名加到致謝名單中。請將你的建議、你的見解、你的批評、以及(喔…真糟…)你的臭蟲報告,寄至:Scott Meyers c/o Publisher, Corporate and Professional PublishingAddison Wesley Longman, Inc. 1 Jacob WayReading, MA 01867U. S. A.或者傳送電子郵件到ec++@awl.com。 我維護有本書第一刷以來的修訂記錄,其中包括錯誤更正、文字修潤、以及技術更新。你可以從Effective C++ 網站取得這份記錄。如果你希望擁有這份資料,但無法上網,請寄申請函到上述地址,我會郵寄一份給你。Scott Douglas Meyers Stafford, OregonJuly 1997

                                    img
                                    effectivec++ 中文版

                                    前言這本書是多年來我對專業程式員所做的C++ 教學課程下的一個自然產物。我發現,大部份學生在一個星期的密集訓練之後,即可適應這個語言的基本架構,但要他們「將這些基礎架構以有效的方式組合運用」,我實在不感樂觀。於是我開始嘗試組織出一些簡短、明確、容易記憶的準則,做為C++ 高實效性程式開發過程之用。那都是經驗豐富的C++ 程式員幾乎總是會奉行或幾乎肯定要避免的一些事情。我最初的興趣在於整理出一些可被某種「lint-like 程式」施行的規則,最後我甚至領導一個計劃,研究某種可將C++ 原始碼中違反使用者指定條件之處檢驗出來的工具(你可以在Effective C++ 網站上找到此研究的一份概要報告)。不幸的是在我尚未完成其完整原型之前,這個研究計劃便結束了。幸運的是,目前市面上已有這類C++ 檢驗工具(商品),而且不只一個。 雖然我最初的興趣是在研究可被(某種工具)自動實施的程式設計準則,但我很快瞭解到那個研究方向的侷限性。優秀的C++ 程式員所奉行的準則,多數都難以「公式化」;要不就是雖然它們有許多重要的例外情況,卻被程式員盲目地奉行不渝。這使我念頭一轉:某些東西雖然不比電腦程式精準,但仍能比一本泛泛的C++ 教科書更集中火力,更打到重點。這個念頭的結果就是你手上這本書:一本內含50 個有效建議(如何改善你的C++ 程式技術和你的設計思維)的書。 在這本書中,你會發現一些忠告,告訴你應該做些什麼,為什麼如此;告訴你不應該做些什麼,又為什麼如此。基本而言當然whys 比whats 更重要,但檢閱一列列準則,也確實比強記一本或兩本教科書更輕鬆更方便得多。和大部份的C++ 書籍不同,我的組織方式並非以語言特性做為依據。也就是說我並不在某處集中討論constructors(建構式),在另一處集中討論virtual functions (虛擬函式),又在第三個地方集中討論inheritance(繼承機制)。不,不是這樣,本書的每一個討論主題都剪裁合度地以一個個準則陳列出來。至於我對某特定語言性質的探討,散佈面積可能涵蓋整本書。 這種作法的優點就是比較容易反映出「特意挑選C++ 做為開發工具」的那些軟體系統的複雜度。在那些系統之中,光只瞭解個別語言特性是不夠的。例如,有經驗的C++ 程式員知道,瞭解inline 函式和瞭解virtual destructors,並不一定表示你瞭解inline virtual destructors。身經百戰的開發人員都認知到,理解C++ 各個特性之間的互動關係,才是有效使用這個語言的最重要關鍵。本書組織反映出這一基本事實。 這種作法的缺點是,你恐怕必須前後交叉參考而非只看一個地方,才能發現我所說的某個C++ 架構的全貌。為了將不方便性降至最低,我在書中各處放了許多交叉索引,書後並有一份涵蓋全部範圍的索引。(譯註:為了協助讀者更容易掌握 Effective C++ 和More Effective C++ 二書,我以Effective C++ CD 為本,為兩書的中文版額外加上兩書之間的交叉索引。此乃原書所無。如果文中出現像條款 M5 這樣的參考指示,M 便是代表More Effective C++) 籌劃第二版期間,我改寫此書的雄心一再被恐懼所取代。成千上萬的程式員熱情擁抱Effective C++ 第一版,我不希望破壞吸引他們的任何東西。但是自從我寫了第一版之後,六年過去了,C++ 有了變化,C++ 程式庫有了變化(見條款49),我對C++ 的瞭解也有了變化,乃至於C++ 的用途也有了變化。許許多多的變化。對我而言,重要的是我必須修訂Effective C++ 以反映那些變化。我嘗試一頁一頁地修改內容,但是書籍和軟體十分類似,局部加強是不夠的,唯一的機會就是系統化地重寫。本書就是重寫後的結果:Effective C++ 2.0 版。熟悉第一版的讀者,可能有興趣知道,書中的每一個條款都經過重新檢驗。然而我相信第一版的結構至今仍是流暢的,所以整本書的結構並沒有改變。50 個條款中,我保留了48 個,其中某些標題稍有變化(附隨的討論內容亦復如此)。退休下來(被取代的)兩個條款是32 和49,不過原條款32 的許多資訊被我移到如今煥然一新的條款1 中。我將條款41 和42 的次序做了對調,因為這樣比較能夠適當呈現它們修訂後的內容。最後,我把上一版繼承體系圖所採用的箭頭方向顛倒過來,以符合目前幾乎已經一致的習慣:從derived classes 指往base classes。我的More Effective C++ 一書也採用相同習慣(本書最後列有該書摘要)。 本書提供的準則,離鉅細糜遺的程度還很遠,但是完成一個好的準則— 一個幾乎可於任何時間應用於任何程式的準則,動手遠比動嘴困難得多。如果你知道其他準則,可以協助撰寫有效的C++ 程式,我非常樂意聽到你告訴我它們的故事。 此外,說不定你會覺得本書的某些條款不適合成為一般性忠告;或許你認為另有比較好的方法來完成書中所說的任務;或許你認為某些條款在技術討論方面不夠清楚,不夠完全,抑或有誤導之嫌。我衷心盼望你也能夠讓我知道你的這些想法。 Donald Knuth(譯註:經典書籍The Art of Computer Programming, Volume I,II,III 的作者)長久以來為挑出其書錯誤的熱心讀者準備有一份小小的報酬。這個故事傳為美談。追求完美的精神令人佩服。看過那麼多倉促上市錯誤壘壘的C++ 書籍後,我更是特別強烈地希望踵隨Knuth 的風範。因此,如果有人挑出本書的任何錯誤並告訴我— 不論是技術、文法、錯別字、或任何其他東西— 我將在本書新刷的時候,把第一位挑出錯誤的讀者大名加到致謝名單中。請將你的建議、你的見解、你的批評、以及(喔…真糟…)你的臭蟲報告,寄至:Scott Meyers c/o Publisher, Corporate and Professional PublishingAddison Wesley Longman, Inc. 1 Jacob WayReading, MA 01867U. S. A.或者傳送電子郵件到ec++@awl.com。 我維護有本書第一刷以來的修訂記錄,其中包括錯誤更正、文字修潤、以及技術更新。你可以從Effective C++ 網站取得這份記錄。如果你希望擁有這份資料,但無法上網,請寄申請函到上述地址,我會郵寄一份給你。Scott Douglas Meyers Stafford, OregonJuly 1997

                                    img
                                    EFFECTIVE c++ 第二版

                                    這本書是多年來我對專業程式員所做的C++ 教學課程下的一個自然產物。我發現,大部份學生在一個星期的密集訓練之後,即可適應這個語言的基本架構,但要他們「將這些基礎架構以有效的方式組合運用」,我實在不感樂觀。於是我開始嘗試組織出一些簡短、明確、容易記憶的準則,做為C++ 高實效性程式開發過程之用。那都是經驗豐富的C++ 程式員幾乎總是會奉行或幾乎肯定要避免的一些事情。 我最初的興趣在於整理出一些可被某種「lint-like 程式」施行的規則,最後我甚至領導一個計劃,研究某種可將C++ 原始碼中違反使用者指定條件之處檢驗出來的工具(你可以在Effective C++ 網站上找到此研究的一份概要報告)。不幸的是在我尚未完成其完整原型之前,這個研究計劃便結束了。幸運的是,目前市面上已有這類C++ 檢驗工具(商品),而且不只一個。 雖然我最初的興趣是在研究可被(某種工具)自動實施的程式設計準則,但我很快瞭解到那個研究方向的侷限性。優秀的C++ 程式員所奉行的準則,多數都難以「公式化」;要不就是雖然它們有許多重要的例外情況,卻被程式員盲目地奉行不渝。這使我念頭一轉:某些東西雖然不比電腦程式精準,但仍能比一本泛泛的C++ 教科書更集中火力,更打到重點。這個念頭的結果就是你手上這本書:一本內含50 個有效建議(如何改善你的C++ 程式技術和你的設計思維)的書。 在這本書中,你會發現一些忠告,告訴你應該做些什麼,為什麼如此;告訴你不應該做些什麼,又為什麼如此。基本而言當然whys 比whats 更重要,但檢閱一列列準則,也確實比強記一本或兩本教科書更輕鬆更方便得多。 和大部份的C++ 書籍不同,我的組織方式並非以語言特性做為依據。也就是說我並不在某處集中討論constructors(建構式),在另一處集中討論virtual functions (虛擬函式),又在第三個地方集中討論inheritance(繼承機制)。不,不是這樣,本書的每一個討論主題都剪裁合度地以一個個準則陳列出來。至於我對某特定語言性質的探討,散佈面積可能涵蓋整本書。 這種作法的優點就是比較容易反映出「特意挑選C++ 做為開發工具」的那些軟體系統的複雜度。在那些系統之中,光只瞭解個別語言特性是不夠的。例如,有經驗的C++ 程式員知道,瞭解inline 函式和瞭解virtual destructors,並不一定表示你瞭解inline virtual destructors。身經百戰的開發人員都認知到,理解C++ 各個特性之間的互動關係,才是有效使用這個語言的最重要關鍵。本書組織反映出這一基本事實。 這種作法的缺點是,你恐怕必須前後交叉參考而非只看一個地方,才能發現我所說的某個C++ 架構的全貌。為了將不方便性降至最低,我在書中各處放了許多交叉索引,書後並有一份涵蓋全部範圍的索引。(譯註:為了協助讀者更容易掌握 Effective C++ 和More Effective C++ 二書,我以Effective C++ CD 為本,為兩書的中文版額外加上兩書之間的交叉索引。此乃原書所無。如果文中出現像條款 M5 這樣的參考指示,M 便是代表More Effective C++) 籌劃第二版期間,我改寫此書的雄心一再被恐懼所取代。成千上萬的程式員熱情擁抱Effective C++ 第一版,我不希望破壞吸引他們的任何東西。但是自從我寫了第一版之後,六年過去了,C++ 有了變化,C++ 程式庫有了變化(見條款49),我對C++ 的瞭解也有了變化,乃至於C++ 的用途也有了變化。許許多多的變化。對我而言,重要的是我必須修訂Effective C++ 以反映那些變化。我嘗試一頁一頁地修改內容,但是書籍和軟體十分類似,局部加強是不夠的,唯一的機會就是系統化地重寫。本書就是重寫後的結果:Effective C++ 2.0 版。 熟悉第一版的讀者,可能有興趣知道,書中的每一個條款都經過重新檢驗。然而我相信第一版的結構至今仍是流暢的,所以整本書的結構並沒有改變。50 個條款中,我保留了48 個,其中某些標題稍有變化(附隨的討論內容亦復如此)。退休下來(被取代的)兩個條款是32 和49,不過原條款32 的許多資訊被我移到如今煥然一新的條款1 中。我將條款41 和42 的次序做了對調,因為這樣比較能夠適當呈現它們修訂後的內容。最後,我把上一版繼承體系圖所採用的箭頭方向顛倒過來,以符合目前幾乎已經一致的習慣:從derived classes 指往base classes。我的More Effective C++ 一書也採用相同習慣(本書最後列有該書摘要)。 本書提供的準則,離鉅細糜遺的程度還很遠,但是完成一個好的準則— 一個幾乎可於任何時間應用於任何程式的準則,動手遠比動嘴困難得多。如果你知道其他準則,可以協助撰寫有效的C++ 程式,我非常樂意聽到你告訴我它們的故事。 此外,說不定你會覺得本書的某些條款不適合成為一般性忠告;或許你認為另有比較好的方法來完成書中所說的任務;或許你認為某些條款在技術討論方面不夠清楚,不夠完全,抑或有誤導之嫌。我衷心盼望你也能夠讓我知道你的這些想法。 Donald Knuth(譯註:經典書籍The Art of Computer Programming, Volume I,II,III 的作者)長久以來為挑出其書錯誤的熱心讀者準備有一份小小的報酬。這個故事傳為美談。追求完美的精神令人佩服。看過那麼多倉促上市錯誤壘壘的C++ 書籍後,我更是特別強烈地希望踵隨Knuth 的風範。因此,如果有人挑出本書的任何錯誤並告訴我— 不論是技術、文法、錯別字、或任何其他東西— 我將在本書新刷的時候,把第一位挑出錯誤的讀者大名加到致謝名單中。 請將你的建議、你的見解、你的批評、以及(喔…真糟…)你的臭蟲報告,寄至: Scott Meyers c/o Publisher, Corporate and Professional Publishing Addison Wesley Longman, Inc. 1 Jacob Way Reading, MA 01867 U. S. A. 或者傳送電子郵件到ec++@awl.com。 我維護有本書第一刷以來的修訂記錄,其中包括錯誤更正、文字修潤、以及技術更新。你可以從Effective C++ 網站取得這份記錄。如果你希望擁有這份資料,但無法上網,請寄申請函到上述地址,我會郵寄一份給你。 Scott Douglas Meyers Stafford, Oregon July 1997

                                    img
                                    JDK 1.5的泛型實現(Generics in JDK 1.5)

                                    JDK 1.5的泛型實現(Generics in JDK 1.5) 1 侯捷觀點 JDK 1.5的泛型實現 — Generics in JDK 1.5 — 北京《程序員》 2004/09 臺北《Run!PC》2004/09 作者簡介:侯捷,資訊教育、專欄執筆、大學教師。常著文章自娛,頗示己志。 侯捷網站:http://www.jjhou.com(繁體) 北京鏡站:http://jjhou.csdn.net(簡體) 永久郵箱:jjhou@jjhou.com . 讀者基礎:有 Java語言基礎,使用過 Java Collections。 . 本文適用工具: JDK1.5 . 本文程式源碼可至侯捷網站下載 http://www.jjhou.com/javatwo-2004-reflection-and-generics-in-jdk15-sample.ZIP . 本文是 JavaTwo-2004技術研討會同名講題之部分內容書面整理。 . 關鍵術語: persistence(永續性、持久性) serialization(序列化、次第讀寫) generics(泛型) polymorphism(多型) 全文提要 泛型技術與 Sun JDK的淵源可追溯自 JDK1.3。但無論 JDK 1.3或 JDK1.4,都只是 以編譯器外掛附件的方式來支援泛型語法,並且 Java標準程式庫未曾針對泛型全 侯捷觀點 Generics in JDK 1.5 面改寫。而今 JDK1.5正式納入泛型。本文討論 JDK1.5的泛型實現,包括如何使 用及自訂 generic classes and algorithms,其中若干語法異於 JDK 1.3和 1.4。 我 我我我我曾經在 JavaTwo 2002大會上針對泛型技術給出一個講題,並將內容整理為《Java 泛型技術之發展》一文(http://www.jjhou.com/javatwo-2002.htm)。該文所談的 Java 泛型語法以及 Java泛型技術之內部實作技術,在今天(被 JDK 1.5正式納入)依 然適用。但由於有了若干小變化,並且由於 Java標準程式庫的全面改寫,使我認 為有必要再整理這篇文章,讓讀者輕鬆地在 JDK 1.5中繼續悠遊「泛型」技術。 閱讀本文之前,如果自覺基礎不夠,可以補充閱讀適才提到的《Java泛型技術之 發展》,那是一篇非常完整的文章,可助您完整認識泛型技術的來龍去脈。 Sun JDK的泛型發展歷史要從 1.3版說起。該版本配合 GJ,正式進入泛型殿堂。 所謂 GJ是 "Generic Java" 的縮寫,是一個支援泛型的 Java編譯器補充件,可謂 Java 泛型技術的先趨。隨後,泛型議題正式成為 JSR #14,其技術基礎便是源自 GJ。 JDK1.4搭配 JSR14提供的外掛附件,使泛型技術在 Java世界從妾身未明的身份扶 正而為眾所屬目的焦點。今天,JDK1.5終於內建泛型特性,不僅編譯器不再需要 任何外力(外掛附件)的幫助,整個 Java標準程式庫也被翻新(retrofit),許多 角落針對泛型做了改寫。 讓我們把帶有「參數化型別」(parameterized types)的 classes稱為 generic classes, 把帶有「參數化型別」的 methods稱為 generic algorithms,那麼,對眾多 Java程 式員而言,泛型帶來的影響不外乎以下四點,稍後逐一說明。 ..如何使用 generic classes ..如何使用 generic algorithms ..如何自訂 generic classes ..如何自訂 generic algorithms 在此先提醒您,運用泛型時,加上 –Xlint:unchecked編譯選項,可讓編譯器幫 助我們檢查潛在的型別轉換問題。 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5)3 使用 Generic Classes Generic classes的最大宗運用是 collections(群集),也就是實作各種資料結構(例 如 list, map, set, hashtable)的那些 classes。也有人稱它們為容器( containers)。這 些容器被設計用來存放 Object-derived元素。而由於 Java擁有單根繼承體系,任 何 Java classes都繼承自 java.lang.Object,因此任何 Java objects都可以被放進 上述各種容器。換句話說 Java容器是一種異質容器,從「泛型」的字面意義來說, 其實這(原本的設計)才是「泛型」。 然而有時候,而且是大半時候,我們不希望容器元素如此異質化。我們多半希望 使用同質容器。即使用於多型( polymorphism),我們也希望至少相當程度地規 範容器,令其元素型別為「帶有某種約束」的 base class。例如面對一個準備用來 放置各種形狀(圓圈、橢圓、矩形、四方形、三角形 …)的容器,如果我們能夠 告知這個容器其每個元素都必須是 Shape-derived objects,將相當有助於程式的可 讀性,並減少錯誤,容易除錯,甚至可避免一大堆轉型( cast)動作。 Java同質容器的語法如下,其中角括號( <>)的用法和 C++完全相同,角括號之 內的指定型別,就是同質容器的元素型別,如圖 1。 ArrayList strList = new ArrayList(); strList.add("zero"); strList.add("one"); strList.add("two"); strList.add("five"); System.out.println(strList); // [zero, one, two, five] 圖 1 /同質容器的用法。角括號( <>)內就是元素型別。 下面是另一個實例,程式員要求容器內的每一個元素都必須是「一種形狀」,這 是一種「多型」應用,如圖 2。這些泛型語法自 JDK 1.3+GJ以來不曾改變過。 侯捷觀點 Generics in JDK 1.5 Shape Object Stroke Rect Circle 圖 2a /典型的 "Shape"多型繼承體系。 //假設 Stroke, Rect, Circle皆繼承自 Shape LinkedList sList = new LinkedList(); sList.add(new Stroke(…)); sList.add(new Rect(…)); sList.add(new Circle(…)); 圖 2b /令容器內含各種 Shape元素,並加入一個 Stroke,一個 Rect和一個 Circle。 Li LiLiLiLink nknknknked ededededLis LisLisLisList tttt sL sLsLsList tistisistt; ;;;; >>> sLis 18 2b 18 2c 5 18 2c 22 11 33 44 Ci CiCiCiCirc rcrcrcrcle lelelele Re ReReReRect ctctctct 66 55 77 St StStStStro rorororoke kekekeke 圖 2c /圖 2b程式碼所製造的結果。 Boxing和 Un-boxing帶來的影響 前面曾經說過,任何 Java objects都可以被放進各種容器內。但是 Java基本數值型 別(primitive types,例如 int, double, long, char)並不是一種 class,而數值也談 不上是個 object。如果要把這一類數值放進容器內,必須將容器元素宣告為基本型 別所對應的外覆類別(wrapper classes),例如圖 3。這實在是非常不方便。JDK1.5 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5)5 新增自動 boxing(封箱)和 un-boxing(拆箱)特性,也就是在必要時刻自動將數 值轉為外覆物件,或將外覆物件轉為數值。有了這項特性,我們可以將圖 3改寫 為圖 4,那就方便多了。 LinkedList iList = new LinkedList(); iList.add(new Integer(0)); iList.add(new Integer(1)); iList.add(new Integer(5)); iList.add(new Integer(2)); 圖 3 /容器元素必須是 object,不可是數值,所以必須使用外覆型別( wrapper)。 LinkedList iList = new LinkedList(); iList.add(0); //boxing iList.add(1); iList.add(5); iList.add(2); int i = iList.get(2); //un-boxing 圖 4 / JDK1.5新增的 boxing/un-boxing特性,使得以方便地將數值放進容器。 使用 Generic Algorithms 在 Java程式庫中,針對容器而設計的 algorithms並不多(不像 C++ 標準程式庫所 提供的那麼多),它們都被置於 java.util.Collections內以 static methods的形 式呈現,例如 sort() , max(), min(), copy(), fill()。圖 5是兩個運用實例,其 語法和 C++完全相同:使用 generic algorithms時並不需要以角括號( <>)為「參 數化型別」做任何具體指定。這種泛型語法自 JDK1.3+GJ以來不曾改變過。 String str = Collections.max(strList); //strList見前例(圖 1) Collections.sort(strList); 圖 5 /運用 max()和 sort() 自訂 Generic Classes 先前的 LinkedList 運用實例中,我曾假設 Stroke, Rect, Circle皆繼承自 Shape。如果我們希望這些 classes有足夠的彈性,讓用戶得以在運用這些 classes 時才指定其內部數據(長、寬、半徑等等)的型別,那就得用上泛型語法,如圖 6, 侯捷觀點 Generics in JDK 1.5 而先前的運用實例也得對應地修改為圖 7。 public abstract class Shape { public abstract void draw(); } public class Rect extends Shape implements Serializable { T m_left, m_top, m_width, m_height; public Rect(T left, T top, T width, T height ) { ... } ... } public class Circle extends Shape implements Serializable { T m_x, m_y, m_r; public Circle(T x, T y, T r) { ... } ... } public class Stroke extends Shape implements Serializable { W m_width; ArrayList m_ia; public Stroke(W width, ArrayList ia) { ... } ... } 圖 6 /自訂 generic classes。本圖實現圖 2a的繼承體系,並以「參數化型別」(圖 中灰色的 T,W等等)代表各 classes內的數據型別。 LinkedList sList = new LinkedList(); sList.add(new Stroke(…)); sList.add(new Rect(…)); sList.add(new Circle(…)); 圖 7 /容器的每個元素型別都是 generic classes,所以製造元素時必須使用泛型語 法(角括號)。請與圖 2b比較。 圖 6和圖 7的泛型語法自 JDK1.3+GJ以來不曾改變過。它迥異於 C++,後者要求 程式必須在 class名稱前加上語彙單元 template<>,藉此告訴編譯器哪些符號是 型別參數( type parameters),如圖 8。 template class Rect : public Shape 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5)7 { private: T m_left, m_top, m_width, m_height; public: Rect(T left, T top, T width, T height ) { ... } ... } 圖 8 / C++ class必須以 template這種語彙單元型式,告訴編譯器 T是個參數化型別。請與圖 6之同名 Java class比較。 現在讓我們看看 Java程式庫源碼,從中學習更多的泛型語法。圖 9a是 java.util.ArrayList的 JDK1.5源碼,圖 9b是其 JDK 1.4源碼,可資比較。 #001 public class ArrayList extends AbstractList #002 implements List, RandomAccess, #003 Cloneable, java.io.Serializable #004 { #005 private transient E[] elementData; #006 private int size; #007 public ArrayList(int initialCapacity) { #008 super(); #009 // check if (initialCapacity < 0)... #010 this.elementData = (E[])new Object[initialCapacity]; #011 } #012 #013 public ArrayList() { #014 this(10); #015 } #016 ... #017 } 圖 9a / JDK1.5的 java.util.ArrayList源碼 #001 public class ArrayList extends AbstractList #002 implements List, RandomAccess, #003 Cloneable, java.io.Serializable #004 { #005 private transient Object elementData[]; #006 private int size; #007 public ArrayList(int initialCapacity) { #008 super(); #009 // check if (initialCapacity < 0) ... #010 this.elementData = new Object[initialCapacity]; #011 } #012 侯捷觀點 Generics in JDK 1.5 #013 public ArrayList() { #014 this(10); #015 } #016 ... #017 } 圖 9b / JDK1.4的 java.util.ArrayList源碼 從圖 9a可以看出,參數型別(圖中的 E)不但可以繼續被沿用做為 base class或 base interfaces的參數型別,也可以出現在 class定義區內「具體型別可以出現」的任何 地方。不過,例外還是有的,例如這一行: #010 this.elementData = (E[])new Object[initialCapacity]; 不能寫成: #010 this.elementData = new E[initialCapacity]; 那會出現 generic array creation error. 自訂 Generic Algorithms 定義於任何 classes內的任何一個 static method,你都可以說它是個 algorithm。如 果這個 method帶有參數化型別,我們就稱它是 generic algorithm。例如: //在某個 class之內 public static T gMethod (List list) { ... } 這種語法和 generic classes有相當程度的不同:泛型符號 必須加在 class名稱 之後,卻必須加在 method名稱(及回傳型別)之前。 JDK 1.5比以前版本增加了更多彈性,允許所謂 bounded type parameter,意指「受 到更多約束」的型別參數。下例表示 gMethod()所收到的引數不但必須是個 List, 而且其元素型別必須實作 Comparable: public static> T gMethod (List list) { ... } 這種「受到更多約束」的型別參數寫法,雖然不存在於 JDK1.4+JSR14,但其實原 本存在於 JDK1.3+GJ中,只不過用的是另一個關鍵字: 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5)9 public static> T gMethod (List list) JDK 1.5還允許將「不被 method實際用到」的型別參數以符號 '?' 表示,例如: public static List gMethod (List list) { return list; //本例簡單地原封不動傳回 } 此例 gMethod()接受一個 List(無論其元素型別是什麼),傳回一個 List(無論 其元素型別是什麼)。由於不存在(或說不在乎)型別參數(因為 method內根本 不去用它),也就不必如平常一般在回傳型別之前寫出來告知編譯器了。 上面這個例子無法真正表現出符號 '?' 的用途。真正的好例子請看 JDK1.5的 java.util.Collections源碼,見圖 10a。圖 10b則是其 JDK1.4源碼,可資比較。 請注意,例中的 '?' 不能被替換為任何其他符號。圖 10a程式碼所描述的意義, 請見圖 11的細部解釋。 #001 public class Collections #002 ... #003 public static #004> #005 T max(Collection coll) { #006 Iterator i = coll.iterator(); #007 T candidate = i.next(); #008 #009 while(i.hasNext()) { #010 T next = i.next(); #011 if (next.compareTo(candidate) > 0) #012 candidate = next; #013 } #014 return candidate; #015 } #016 ... #017 } // of Collections 圖 10a / JDK1.5的 java.util.Collections源碼。 #001 public class Collections #002 ... #003 public static #004 //這裡我刻意放空一行,以利與 JDK1.5源碼比較 侯捷觀點 Generics in JDK 1.5 #005 Object max(Collection coll) { #006 Iterator i = coll.iterator(); #007 Comparable candidate = (Comparable)(i.next()); #008 #009 while(i.hasNext()) { #010 Comparable next = (Comparable)(i.next()); #011 if (next.compareTo(candidate) > 0) #012 candidate = next; #013 } #014 return candidate; #015 } #016 ... #017 } // of Collections 圖 10b / JDK1.4的 java.util.Collections源碼。 3 4 5> T max(Collection coll) { 1 26 1. max()接收一個 Collection object。 2.該 Collection object所含元素必須是 T-derived object。 3. T必須繼承 Object(這倒不必明說,因為 Java必定如此)。 4. T必須實作 Comparable。 5. Comparable所比較的型別必須是 T的 super type。 6. max()傳回 T object。 圖 11 /本圖詳細說明圖 10a的怪異內容(#4, #5兩行) 面對圖 11如此「怪異而罕見」的語法,給個實際用例就清楚多了: LinkedList sList = new LinkedList(); ... Shape s = Collections.max(sList); 我們讓 Collections.max()接受一個先前曾經說過的 LinkedList(見圖 2a,b),那是個 Collections object(符合圖 11條件 1),其中每個元素都是 Shape-derived objects(符合圖 11條件 2),因此本例中的 T就是 Shape。Shape的 確繼承自 Object(符合圖 11條件 3),並且必須實作 Comparable(才能符合圖 11 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5)11 條件 4),而被比較物的型別必須是 Shape的 super class(才能符合圖 11條件 5)。 max()比較所得之最大值以 Shape表示(符合圖 11條件 6)——這是合理的,因 為不知道比較出來的結果會是 Rect或 Circle或 Stroke,但無論如何它們都可以 向上轉型為 Shape。 為了完成上述的條件 4和條件 5,先前的 Shape必須修改,使得以被比較。也就是 說 Shape必須實作 Comparable介面,如圖 12,其中針對 compareTo()用上了典 型的 Template Method設計範式(design pattern),再令每一個 Shape-derived classes 都實作 L()如圖 13,這就大功告成了。 public abstract class Shape implements Comparable { ... public abstract double L(); //計算周長 public int compareTo(Shape o) { //假設「以周長為比較依據」合理! return (this.L() < o.L() ? -1 : (this.L() == o.L() ? 0 : 1)); } } 圖 12 /修改圖 7的 Shapeclass public double L() { ... 計算周長 //這裡有點學問,見最後「擦拭法帶來的遺憾」討論。 return xxx; //傳回周長 } 圖 13 /每個 Shape-derived classes都必須實作出如此型式的 L()。 參數化型別(Parameterized type)存在多久? 究竟 generic classes所帶的參數化型別,在編譯後是否還保留?或者說,假設我們 將一個元素型別為 Integer的 LinkedList容器寫入檔案,而後讀出並恢復「先前 被 serialized(序列化)至檔案」的容器,如圖 14。此時我們的第一個考慮作法或 許如下(和最初的宣告完全相同): LinkedList iList2 = (LinkedList)in.readObject(); 但 JDK1.5編譯器發出警告,告訴我們 "unchecked cast"(JDK1.4則直接抱怨它是 錯誤的)。改成這樣情況亦同: LinkedList iList2 = (LinkedList)in.readObject(); 侯捷觀點 Generics in JDK 1.5 看來編譯器面對即將被 deSerialized(反序列化)讀得的型別資訊,似乎無法判別 是否可以成功轉型為 LinkedList。另一種寫法是: LinkedList iList2 = (LinkedList)in.readObject(); 這一次 JDK1.5編譯器發出的警告訊息是: "unchecked conversion"。改為這樣更非 警告可以善了: LinkedList iList2 = in.readObject(); 對此 JDK1.5編譯器會直接報錯: "incompatible types"。如果改成這樣: LinkedList iList2 = (LinkedList)in.readObject(); 這才是既無錯誤又無警告的完美寫法。 LinkedList iList = new LinkedList (); ... ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("out")); out.writeObject(iList); //寫入 out.close(); ObjectInputStream in = new ObjectInputStream( new FileInputStream("out")); //…這裡準備進行讀取動作 readObject() 圖 14 /將元素型別為 Integer的容器寫入檔案,而後準備讀出。 由以上測試結果可以預期,似乎存在這一事實:當 object被寫入檔案,即失去其 泛型型別參數(如果有的話)。因此讀回的只是「非泛型」的 class資訊。如果上 述最後那個「完美」寫法改成這樣: ArrayList iList2 = (ArrayList)in.readObject(); 仍可順利編譯,在編譯器的眼裡看來也很完美,但執行期會出現異常,告知「讀 入的 class資訊」和「程式預備接收的 class資訊」不相符合。異常訊息如下: Exception in thread "main" java.lang.ClassCastException: 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5) 13 java.util.LinkedList 我們可以觀察 serialization的輸出檔獲得證據。從圖 15可以看出來,檔案內記錄 的 class名稱是 java.util.LinkedList,並一併記錄了元素型別 java.lang.Integer(及其 base class java.lang.Number)。但元素型別其實是針對每一個元素都會記 錄的(當然啦,如果遇上相同型別的元素,這些資訊並不會又被傻傻地完整記錄 一遍,那太浪費時間和空間,而是只記錄一個 handle,詳見《Java的物件永續之 道》,網址列於文後)。這些記錄對於 deSerialization過程中恢復容器原型和內容 有其必要,但無法讓編譯器推論當初使用的是 LinkedList容器或是 LinkedList容器。 000000: AC ED 00 05 73 720014 6A6176 61 2E 75 74 69秒..sr..ja jajajajava vavavava. ...uti iutiututii .ut 000010: 6C 2E 4C 69 6E 6B 65 64 4C 69 73 74 0C 29 53 5D l. l.l.l.l.Li LiLiLiLink nknknknked ededededLi LiLiLiList stststst.)S] 000020: 4A 60 88 22 03 00 00 78 70 77 04 00 00 00 04 73 J`."...xpw.....s 000030: 72 00 11 6A 61 76 61 2E 6C 61 6E 67 2E 49 6E 74 r..ja jajajajava vavavava. ...la lalalang ngngng. ...Int tIntInIntt `" .lang.In 000040: 65 67 65 72 12 E2 A0 A4 F7 81 87 38 02 00 01 49 eg egegegeger erererer.?父?8...I 000050: 00 05 76 61 6C 75 65 78 72 00 10 6A 61 76 61 2E ..valuexr..ja jajajajava vavavava. .... 000060: 6C 61 6E 67 2E 4E 75 6D 62 65 72 86 AC 95 1D 0B la lalalalang ngngngng.N .N.N.N.Num umumumumbe bebebeber rrrr ... 圖 15 /將元素型別為 Integer的容器寫入檔案,而後準備讀出。 Java擦拭法 vs. C++膨脹法 為什麼 Java容器的參數化型別無法永續存在於檔案(或其他資料流)內?本文一 開始已經說過,這些容器被設計用來存放 Object-derived元素,而 Java擁有單根 繼承體系,所有 Java classes都繼承自 java.lang.Object,因此任何 Java objects 都可以被放進各種容器,換句話說 Java容器本來就是一種「泛型」的異質容器。 今天加上參數化型別反而是把它「窄化」了。「泛型」之於 Java,只是一個角括 號面具(當然這個面具帶給了程式開發過程某些好處);摘下面具,原貌即足夠 應付一切。因此 Java使用所謂「擦拭法」來對待角括號內的參數化型別,如圖 16a。 下面是「擦拭法」的四大要點(另有其他枝節,本文不談): . 一個參數化型別經過擦拭後應該去除參數(於是 List被擦拭成為 List) . 一個未被參數化的型別經過擦拭後應該獲得型別本身(於是 Byte被擦拭成為 Byte) . 一個型別參數經過擦拭後的結果為 Object(於是 T被擦拭後變成 Object) 侯捷觀點 Generics in JDK 1.5 . 如果某個 method call的回傳型別是個型別參數,編譯器會為它安插適當的轉型 動作。 這種觀念和 C++的泛型容器完全不同。 C++容器是以同一套程式碼,由編譯器根 據其被使用時所被指定的「不同的參數化型別」建立出不同版本。換句話說一份 template(範本、模板)被膨脹為多份程式碼,如圖 16b。 java.util.LinkedList.java public class LinkedList { ... }; Java 擦拭法 public class LinkedList { ... }; import java.util.* LinkedList ...; LinkedList ...; LinkedList ...; .class .class import java.util.* LinkedList ...; LinkedList ...; LinkedList ...; 圖 16a / Java以擦拭法成就泛型 template class list { ... }; #include list li; list ls; list ld; list C++ class list; // string版本 list li; list ls; list ld; class list; // int版本 class list; // double版本 .exe 膨脹法 圖 16b / C++以膨脹法成就泛型 擦拭法帶來的遺憾 先前談到的 "Shape"多型實例(圖 2a),其中的 class Rect: public class Rect extends Shape implements Serializable { T m_left, m_top, m_width, m_height; public Rect(T left, T top, T width, T height ) { ... } ... } 經過擦拭後變成了: public class Rect extends Shape 侯捷觀點 JDK 1.5的泛型實現(Generics in JDK 1.5) 15 implements Serializable { Object m_left, m_top, m_width, m_height; public Rect(Object left, Object top, Object width, Object height ) { ... } ... } 這麼一來,任何數值運算,例如先前提過的「周長計算」 L()將無法編譯,如圖 17: //class Rect內 public double L() { return (double)((m_width + m_height) * 2); } 圖 17 / L()發生錯誤 錯誤訊息是: "operator + cannot be applied to T,T"。是的,兩個 Object object如何 相加呢? Java並沒有提供像 C++ 那樣的運算子重載( operator overloading)功能! 可以說,圖 2a的 Shape繼承體系只是介面正確,一旦面臨某些情況,卻無實用性。 我的結論是,將參數化型別用於 Java non-collection classes身上,恐怕會面臨許多 束縛。(註:讀者來函提供了此問題的一個解答,見本文末尾添加之補充) 更多資訊 以下是與本文主題相關的更多討論。這些資訊可以彌補本文篇幅限制而造成的不 足,並帶給您更多視野。 . 《Java泛型技術之發展》 ,by侯捷。 http://www.jjhou.com/javatwo-2002-genericsin- jdk14.pdf . 《 Java的物件永續之道》 ,by侯捷。 http://www.jjhou.com/javatwo-2003serialization- doc.pdf 侯捷觀點 Generics in JDK 1.5 ■補充 讀者 AutoWay針對無法計算周長這個問題,來信如下: From: AutoWay Sent: Monday, January 17, 2005 7:57 PM Subject: 《JDK 1.5的泛型實現》讀者回應 侯捷兄:隨函寄上Rect.java程式之修訂,俾可以進行「周長計算」。修訂內容如 下:在設定type parameter時,同時宣告其type bound,例如本例修改為。系統進行編譯時,就知道T是Number或其subclass;因此內部程式就 可運用Number提供的methods進行運算了。 我想,這就是type parameters之所以提供type bounds機制的主要原因。如果type bounds光用來限制type arguments之傳遞,實在沒啥意思!感謝本文揭示的例子, 讓我對type bounds有進一步的省思與認識;若有謬誤,亦請來信指教。 侯捷回覆:非常感謝 AutoWay兄的指正,解除了我的盲點。整理於下。圖 6之程 式碼應改為: public class Rect extends Shape implements Serializable { ... } public class Circle extends Shape implements Serializable { ... } public class Stroke extends Shape implements Serializable { ... } 圖 17程式碼應改為: //class Rect內 public double L() { return (m_width.doubleValue() + m_height.doubleValue()) * 2; } 另兩個 classes(Circle和 Stroke)同理修改。 侯捷觀點

                                    img
                                    項目管理

                                     項目管理是項目的管理者,在有限的資源約束下,運用系統的觀點、方法和理論,對項目涉及的全部工作進行有效地管理。即從項目的投資決策開始到項目結束的全過程進行計劃、組織、指揮、協調、控制和評價,以實現項目的目標。   按照傳統的做法,當企業設定了一個項目後,參與這個項目的至少會有好幾個部門,包括財務部門、市場部門、行政部門等等,而不同部門在運作項目過程中不可避免地會產生摩擦,須進行協調,而這些無疑會增加項目的成本,影響項目實施的效率。   而項目管理的做法則不同。不同職能部門的成員因為某一個項目而組成團隊,項目經理則是項目團隊的領導者,他們所肩負的責任就是領導他的團隊準時、優質地完成全部工作,在不超出預算的情況下實現項目目標。項目的管理者不僅僅是項目執行者,他參與項目的需求確定、項目選擇、計劃直至收尾的全過程,併在時間、成本、質量、風險、合同、採購、人力資源等各個方面對項目進行全方位的管理,因此項目管理可以幫助企業處理需要跨領域解決的複雜問題,並實現更高的運營效率。   項目管理的應用從80年代僅限於建築、國防、航天等行業迅速發展到今天的電腦、電子通訊、金融業甚至政府機關等眾多領域。   人們通常認為,項目管理是第二次世界大戰的產物(如:曼哈頓計劃)。在1950年至1980年期間,應用項目管理的主要是國防建設部門和建築公司。傳統的觀點認為,項目管理者的工作就是單純地完成既定的任務。   從本世紀八十年代開始,項目管理的應用擴展到其他工業領域(行業),如製藥行業、電信部門、軟體開發業等。項目管理者也不再被認為僅僅是項目的執行者,要求他們能勝任其它各個領域的更為廣泛的工作,同時具有一定的經營技巧。美國項目管理學會(PMI)已提出了關於一個有效的專業項目管理者必須具備的幾個方面的基本能力: 項目範圍管理 項目時間管理 項目費用管理 項目質量管理 項目人力資源管理 項目溝通管理 項目風險管理 項目採購管理 項目綜合管理   從根本上講,項目管理並不神秘,人類數千年來進行的組織工作和團隊活動,都可以視為項目管理行為。   人類的活動可以分為兩大類:一類是重覆性、連續不斷、周而複始的活動,稱為“運作”,如:用自動化流水線批量生產某些產品的活動;另一類是獨特的、一次性的活動,稱為“項目”,如:任何一項開發活動、改造活動、建造活動等。在這個社會上,項目隨處可見,小到一次聚會、一次郊游,大到一場文藝演出、一次教育活動、一項建築工程、一次開發活動等。因此,項目管理同社會的發展息息相關。   但項目管理被髮展、提煉成一種具有普遍科學規律的理論模式,卻只是近年來的事。

                                    韩国女主播视频