# 基本資料型別® 導讀人:Jim ---- <div style="display: flex; justify-content: center;align-items: center"> <img src="https://hackmd.io/_uploads/rkN8zs-QA.jpg" width="50%" style="margin-right: 50px;" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px"> <li>數值概論</li> <li>整數</li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px" /> </div> <div> ---- <div style="display: flex; justify-content: center;align-items: center"> <img src="https://hackmd.io/_uploads/rkN8zs-QA.jpg" width="50%" style="margin-right: 50px;" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;"><b>數值概論</b></li> <li>整數</li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px" /> </div> <div> ---- ## <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">數值概論</span></h3> <ul> <li>避免使用魔術數值(magic number)</li> <li>如果需要,可以使用硬編碼的 0 和 1 (hard-coding 的數字只允許 0 或 1)</li> <li>預防除以零(Division-by-zero)錯誤</li> <li>使型別轉換變得明顯</li> <li>避免混和型別的比較</li> <li>注意編譯器的警告</li> </ul> ---- #### 避免使用魔術數值(magic number) ```javascript= // 修改前 def calculate_final_price(price): # 0.08 是一個 magic number,代表 8% 的銷售稅率 tax = price * 0.08 final_price = price + tax return final_price # 這裡的 100 是商品的原價 final_price = calculate_final_price(100) print("The final price with tax is:", final_price) ``` ---- #### 避免使用魔術數值(magic number) ```javascript= // 修改後 TAX_RATE = 0.08 # 8% 的銷售稅率,清晰明確的命名 def calculate_final_price(price): tax = price * TAX_RATE final_price = price + tax return final_price final_price = calculate_final_price(100) print("The final price with tax is:", final_price) ``` ---- #### 如果需要,可以使用硬編碼的 0 和 1 ```= // 計算從 1 到 10 的總和 initTotal = 0 countStart = 1 countEnd = 10 def forward_addition(n): total = initTotal for i in range(countStart, n+1): total += i # 將 i 的值加到 total 上 print(f"Adding {i}, total now is {total}") return total sum_of_numbers = forward_addition(countEnd) print(f'The sum of numbers from {countStart} to {countEnd} is:', sum_of_numbers) ``` ---- #### 如果需要,可以使用硬編碼的 0 和 1 ```diff= // 計算從 1 到 10 的總和 - initTotal = 0 - countStart = 1 - countEnd = 10 def forward_addition(n): - total = initTotal + total = 0 - for i in range(countStart, n+1): + for i in range(1, n+1): total += i # 將 i 的值加到 total 上 print(f"Adding {i}, total now is {total}") return total - sum_of_numbers = forward_addition(countEnd) + sum_of_numbers = forward_addition(10) - print(f'The sum of numbers from {countStart} to {countEnd} is:', sum_of_numbers) + print(f'The sum of numbers from 0 to 10 is:', sum_of_numbers) ``` ---- #### 如果需要,可以使用硬編碼的 0 和 1 ```= // 計算從 1 到 10 的總和 def forward_addition(n): total = 0 for i in range(1, n+1): total += i # 將 i 的值加到 total 上 print(f"Adding {i}, total now is {total}") return total sum_of_numbers = forward_addition(10) print(f'The sum of numbers from 0 to 10 is:', sum_of_numbers) ``` ---- #### 預防除以零(Division-by-zero)錯誤 ![KRpI3](https://hackmd.io/_uploads/Bkr3iY47C.jpg) <p style="text-align: left">例:Pizza 分成兩份,等於 1 除以 2 等於 1/2</p> <p style="text-align: left">問:Pizza 如何分成 0 份? 1/0 = ?</p> ---- #### 使型別轉換變得明顯 ``` let num = "5"; let result = num + 1; console.log(result); // 輸出 "51" ``` ---- #### 使型別轉換變得明顯 ```= let num = "5"; let result = +num + 1; console.log(result); // 輸出 6 ``` ---- #### 使型別轉換變得明顯 ```diff= let num = "5"; - let result = +num + 1; + let result = Number(num) + 1; console.log(result); // 輸出 6 ``` ---- #### 避免混和型別的比較 ```javascript= const x = 1 const s = "1" if(x == s) { console.log("Two values are equal") ✅ } else { console.log("Two values are not equal") } // example2: console.log("0"==false) //true ``` ---- #### 避免混和型別的比較 ```javascript= const x = 1 const s = "1" if(x === s) { console.log("Two values are equal") } else { console.log("Two values are not equal") ❌ } ``` ---- #### 避免混和型別的比較 ```diff= const x = 1 const s = "1" - if(x === s) { + if(x === Number(s)) { console.log("Two values are equal") ✅ } else { console.log("Two values are not equal") } ``` ---- #### 注意編譯器的警告 (DEMO) [![play-button](https://hackmd.io/_uploads/SydfgiNX0.png)](https://codepen.io/JimHu1492/pen/zYQGmZr?editors=1111) ---- <div style="display: flex; justify-content: center;"> <img src="https://hackmd.io/_uploads/r1J6PoV7R.png" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;"><b>整數</b></li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">整數</span></h3> <ul> <li>檢查整數除法(語言不同有不同結果)</li> <li>檢查整數溢出</li> <li>檢查中間結果溢出</li> </ul> ---- #### 檢查整數除法 ```python= # Python 範例 a = 7 b = 10 result = a // b # 整數除法 print(result) # 結果是 0 ``` ---- <table style="font-size:24px;"> <tr> <th>數據類型</th> <th>最小位元數 (Bits)</th> <th>範圍(假設符號)</th> </tr> <tr> <td>int</td> <td>16</td> <td>-32,768 到 32,767</td> </tr> <tr> <td>unsigned int</td> <td>16</td> <td>0 到 65,535</td> </tr> <tr> <td>short int</td> <td>16</td> <td>-32,768 到 32,767</td> </tr> <tr> <td>unsigned short int</td> <td>16</td> <td>0 到 65,535</td> </tr> <tr> <td>long int</td> <td>32</td> <td>-2,147,483,648 到 2,147,483,647</td> </tr> <tr> <td>unsigned long int</td> <td>32</td> <td>0 到 4,294,967,295</td> </tr> <tr> <td>long long int</td> <td>64</td> <td>-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807</td> </tr> <tr> <td>unsigned long long int</td> <td>64</td> <td>0 到 18,446,744,073,709,551,615</td> </tr> </table> ---- #### 檢查整數溢出、檢查中間結果溢出 ``` function willAdditionOverflow(a, b) { if (typeof a !== 'number' || typeof b !== 'number') { throw new Error("Both arguments must be numbers"); } if (!Number.isSafeInteger(a) || !Number.isSafeInteger(b)) { return true; // 任何一個數值超出安全範圍 } let result = a + b; if (!Number.isSafeInteger(result)) { return true; // 結果超出安全範圍 } return false; } let a = Number.MAX_SAFE_INTEGER; let b = 1; if (willAdditionOverflow(a, b)) { console.log("Addition will cause overflow!"); } else { let result = a + b; console.log("Result: " + result); } ``` ---- <div style="display: flex; justify-content: center;"> <img src="https://upload.wikimedia.org/wikipedia/commons/4/4d/Float_mantissa_exponent.png" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">浮點數</span></h3> <ul> <li>避免相差過大的數之間的加減運算(需排序處理)</li> <li>避免等量判斷</li> <li>處理捨入誤差問題</li> <li>檢查語言對特定資料型別的支援(VB, Currency 的型別)</li> </ul> ---- #### 避免相差過大的數之間的加減運算 ```python= # 排序 VS. 未排序 正確性比較 # 假設的浮點數數組 numbers = [10000000.0, 0.0001, 0.0002, 0.0003, 0.0004] # 從小到大排序 numbers_sorted = sorted(numbers) # 進行加法運算 total = 0 for number in numbers_sorted: total += number # 輸出結果 print("加總結果(排序後):", total) # 沒有排序直接加總,作為比較 total_unsorted = sum(numbers) print("加總結果(未排序):", total_unsorted) ``` ---- #### 避免等量判斷 ```python= # 將0.1相加10次 result = 0.1 * 10 nominal = 1.0 # 初始化結果變量 result = 0.0 # 使用for循環將0.1加10次 for _ in range(10): result += 0.1 # 輸出結果 print('結果數字為:', result) //結果數字為: 0.9999999999999999 print('nominal == result:', nominal == result) //nominal == result: False ``` ---- #### 避免等量判斷(解決辦法) - 使用精度範圍進行比較 - 使用 math.isclose 函數 - 使用固定點數表示法或高精度數學庫 [參考 chatGPT 解答](https://chat.openai.com/share/42dac35e-17bd-4eb1-90ac-63ea832ec76c) ---- #### 處理捨入誤差問題 - 換更高精準度的變數型別(同相差過大的數之間的加減運算問題) - 換成二進為編碼的十進位變數(BCD) ---- <iframe height="500" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/JimHu1492/embed/PovYRvE?default-tab=" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href="https://codepen.io/JimHu1492/pen/PovYRvE"> Untitled</a> by Jim Hu (<a href="https://codepen.io/JimHu1492">@JimHu1492</a>) on <a href="https://codepen.io">CodePen</a>. </iframe> ---- #### 檢查語言對特定資料型別的支援 VB 有 Currency 這樣內建的型別支援 ---- <div style="display: flex; justify-content: center;"> <img src="https://hackmd.io/_uploads/r1ezlIPXA.png" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li>浮點數</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">字元和字串</span></h3> <ul> <li>避免魔術字元和魔術字串</li> <li>避免 off-by-one 錯誤</li> <li>了解你的語言和開發環境是如何支援 Unicode 的</li> <li>在程式生命其中儘早決定國際化/本地化策略</li> <li>如果你知道只需要支持一種文字的語言,請考慮使用 ISO 8859 字元集</li> <li>如果你需要支援多種語言,請使用 Unicode 與 ISO 8859</li> <li>採用一致的字串型別轉換策略</li> </ul> ---- #### 避免魔術字元和魔術字串(Anti-pattern) ```C= #include <stdio.h> int main(void){ char i = 'A'; //宣告字元變數 i char j = 'z'; // 告字元變數 j printf("字元 A 的 ASCII 碼為 %d\n", (int)i); printf("字元 z 的 ASCII 碼為 %d\n", (int)j); return 0; } ``` ---- #### 避免魔術字元和魔術字串(修正) ``` #include <stdio.h> int main(void) { // 使用有意義的常數來替代魔術字元 const char UPPER_CASE_A = 'A'; // 宣告常數 UPPER_CASE_A const char LOWER_CASE_Z = 'z'; // 宣告常數 LOWER_CASE_Z printf("字元 %c 的 ASCII 碼為 %d\n", UPPER_CASE_A, (int)UPPER_CASE_A); printf("字元 %c 的 ASCII 碼為 %d\n", LOWER_CASE_Z, (int)LOWER_CASE_Z); return 0; } ``` ---- #### 避免魔術字元和魔術字串(output) ``` 字元 A 的 ASCII 碼為 65 字元 z 的 ASCII 碼為 122 ``` ---- #### (補)避免使用字面形式的字串的眾多原因如下: - 程式修改,只是修改字串容易造成錯誤 - 多國語系處理翻譯的字串應該存在放資源檔中而非程式變數 - 字串的字面表示形式通常占較多的儲存空間 - 字元和字串的字面表示形式的含意是模糊的(0x1B 使用 ESCAPE 表示) ---- #### (補)多國語系處理實例 ```JSON= { "app_name": "我的應用", "login": "登入", "description": "輸入您的使用者名稱和密碼以登入。" } ``` ---- #### (補)字元和字串的字面表示形式的含意是模糊的 0x1B, U+000A, &nbsp(No-Break Space) [參考資料](https://cloud.magiclen.org/tw/ascii) ---- #### 避免 off-by-one 錯誤 字串處理與陣列相同,要避免邊界取值的錯誤 ```python= words = ["hello", "world", "python", "programming"] # 假設我們想要打印每一個元素,但不小心設置了錯誤的迴圈條件 for i in range(len(words) + 1): # 錯誤:超出範圍 print(words[i]) ``` ---- #### 解你的語言和開發環境是如何支援 Unicode 的 <table style="font-size:24px; width:100%; border: 1px solid black;"> <tr> <th>語言</th> <th>字符表示</th> <th>字符串表示</th> <th>特點與支持</th> </tr> <tr> <td>C</td> <td>依賴實現</td> <td>依賴實現</td> <td>沒有內建 Unicode 支持<br>可使用第三方庫,如 ICU、libutf8<br>編譯器可能提供部分支持</td> </tr> <tr> <td>Java</td> <td>char (16 位 UTF-16)</td> <td>String (UTF-16)</td> <td>內建豐富的 Unicode 支持<br>自動處理多語言情境<br>提供豐富的字符串操作 API</td> </tr> <tr> <td>C#</td> <td>char (16 位 UTF-16)</td> <td>string (UTF-16)</td> <td>.NET 平台原生支持 Unicode<br>自動處理 Unicode 字符串<br>全面的 API 支持</td> </tr> <tr> <td>JavaScript</td> <td>UTF-16 代碼單元</td> <td>UTF-16 字符串</td> <td>ES6 增強 Unicode 支持<br>支持代理對字符<br>Unicode 正則表達式標誌 `u`</td> </tr> <tr> <td>Python</td> <td>Unicode 字符串</td> <td>Unicode 字符串</td> <td>Python 3 所有字符串為 Unicode<br>Python 2 需明確使用 `u'...'`<br>廣泛的 Unicode 操作支持</td> </tr> </table> ---- - 在程式生命其中儘早決定國際化/本地化策略 - 如果你知道只需要支持一種文字的語言,請考慮使用 ISO 8859 字元集 - 如果你需要支援多種語言,請使用 Unicode 與 ISO 8859 ---- <table style="font-size:24px; width:100%; border: 1px solid black;"> <tr> <th>特性</th> <th>Unicode</th> <th>ISO 8859</th> </tr> <tr> <td>支持的語言範圍</td> <td>全球範圍內的幾乎所有語言</td> <td>限定於特定的西歐、中歐等語言群</td> </tr> <tr> <td>字符大小</td> <td>變長(通常為 1 至 4 位元組)</td> <td>固定大小(1 位元組)</td> </tr> <tr> <td>編碼方式</td> <td>多種(如 UTF-8, UTF-16, UTF-32 等)</td> <td>單一(每種 ISO 8859 系列有其編碼方式)</td> </tr> <tr> <td>設計目的</td> <td>為了統一全球範圍內多語言的字符表示</td> <td>為了擴展 ASCII 並支持特定語言的字符集</td> </tr> <tr> <td>兼容性</td> <td>高兼容性,被現代操作系統、瀏覽器和應用廣泛支持</td> <td>兼容性相對較低,現代應用中逐漸被 Unicode 取代</td> </tr> <tr> <td>應用場景</td> <td>適用於需要支持多語言的現代軟件和網路應用</td> <td>適用於只需支持單一語言或特定語言群的較舊系統和應用</td> </tr> </table> ---- ```python= # Python 3 Unicode 字串 s = "Hello, world!" # 自動處理為 Unicode 字串 # Python 3 字節串 b = b"Hello, bytes!" # 轉換 Unicode 字串為字節串 encoded = s.encode('utf-8') # 從 Unicode 編碼為 UTF-8 字節串 # 轉換字節串為 Unicode 字串 decoded = encoded.decode('utf-8') # 從 UTF-8 字節串解碼為 Unicode 字串 ``` ---- #### 採用一致的字串型別轉換策略 1. 保存同一種格式 2. 在輸入輸出中操作轉換為其他格式 ```python= # 從外部來源讀取時,確保使用適當的編碼將字節數據轉換為 Unicode 字串 # 例如,從文件讀取 with open('example.txt', 'r', encoding='utf-8') as file: text = file.read() # text 是 Unicode 字串 # 來自網絡的數據 # 假設 response 是一個 HTTP 響應對象 data = response.content.decode('utf-8') # 將字節數據解碼為 Unicode 字串 ``` ---- #### (補)C 語言中的字串 - 注意字串指標和字元陣列之間的差異 - 把 C 風格字串的長度宣告為 CONSTANT + 1 - 用 null 初始化字串以避免沒有終端的字串 - 用字串陣列取代 C 中的指標 - 用 strncpy()取代 strcpy()以避免無終端的字串 ---- #### (補)注意字串指標和字元陣列之間的差異 ```C= char strArray[6] = "hello"; // 儲存了 'h', 'e', 'l', 'l', 'o', '\0' char *strPtr = "hello"; // 指向 "hello" 字串常數的指標 ``` ---- #### (補)把 C 風格字串的長度宣告為 CONSTANT + 1 ```C= char greeting[8] = "Hello!"; // "Hello!" 需要 7 個字元空間 + 1 個 '\0' ``` ---- #### (補)用 null 初始化字串以避免沒有終端的字串 ```C= char buffer[100] = {0}; // 所有字元都初始化為 '\0' ``` ---- #### (補)用字串陣列取代 C 中的指標 ```C= char *names[] = {"Alice", "Bob", "Charlie", "David", "Eve"}; char names[5][10] = { "Alice", "Bob", "Charlie", "David", "Eve" }; ``` ---- #### (補)用 strncpy()取代 strcpy()以避免無終端的字串 ```C= char src[] = "Hello World"; char dest[6]; strncpy(dest, src, 5); dest[5] = '\0'; // 確保有終止符號 ``` ---- <div style="display: flex; justify-content: center;"> <img src="https://www.freecodecamp.org/news/content/images/2020/01/image-2.png" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li>浮點數</li> <li>字元和字串</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">布林變數</span></h3> <ul> <li>用布林變數對程式加以文件說明</li> <li>用布林變數來簡化複雜的判斷</li> <li>如果需要的話,建立你自己的布林型別</li> </ul> ---- #### 用布林變數對程式加以文件說明 - 可以把判斷用變數存取,以變數命名的方式增加程式碼可讀性 - 可以使用函式的方式 ---- #### 用布林變數對程式加以文件說明 ``` def is_student_eligible(scores, parent_is_alumni): # scores 是一個字典,包含學生的各科成績 # parent_is_alumni 是一個布林值,表示至少有一位父母是校友 # 使用列表推導式來計算超過 60 分的科目數量 passing_count = sum(1 for score in scores.values() if score > 60) # 判斷是否符合入學資格 if (parent_is_alumni and passing_count >= 2) or passing_count >= 3: return True # 符合入學資格 else: return False # 不符合入學資格 # 測試代碼 scores_example = {'國語': 55, '英語': 65, '數學': 70, '物理': 55, '化學': 58} parent_is_alumni_example = True if (is_student_eligible(scores_example, parent_is_alumni_example)) print("符合") else: print("不符合") ``` https://www.online-python.com/QCD7RkbuPj ---- #### 如果需要的話,建立你自己的布林型別 ```C= typedef int BOOLEAN; ``` ```typescript= type IsActive = boolean; function setActive(status: IsActive) { // 做一些事情 } ``` ---- <div style="display: flex; justify-content: center;"> <img src="https://i.ytimg.com/vi/5VyDsO0mFDU/maxresdefault.jpg" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">列舉型別</li> <li>具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">列舉型別</span></h3> <ul> <li>用列舉來提高可靠性</li> <li>用列舉型別來簡化修改</li> <li>將列舉型別作為布林變數的替代方案</li> <li>檢查非法數值</li> <li>定義出列舉的第一項和最後一項,以便用於迴圈限制</li> <li>把列舉型別的第一個元素留做非法值</li> <li>明確定義專案程式碼編寫標準中第一個和最後一個元素的使用規則,並且在使用時保持一致</li> <li>警惕給列舉元素明確賦值帶來的錯誤</li> <li>如果你的語言裡沒有列舉型別</li> </ul> ---- #### (補)用列舉來提高可靠性 物件與列舉差異 <table style="font-size:16px; width:100%; border-collapse: collapse; border: 1px solid black;"> <tr> <th style="border: 1px solid black; padding: 8px;">特性</th> <th style="border: 1px solid black; padding: 8px;">列舉 (Enum)</th> <th style="border: 1px solid black; padding: 8px;">物件 (Object)</th> </tr> <tr> <td style="border: 1px solid black; padding: 8px;">定義</td> <td style="border: 1px solid black; padding: 8px;">資料型別,包含一組命名的整數常量。</td> <td style="border: 1px solid black; padding: 8px;">結構,可以包含多個值(屬性)和方法。</td> </tr> <tr> <td style="border: 1px solid black; padding: 8px;">用途</td> <td style="border: 1px solid black; padding: 8px;">用於定義一組相關的常量,提高代碼清晰度。</td> <td style="border: 1px solid black; padding: 8px;">用於封裝和模型化複雜的數據和行為,使代碼易於理解、擴展。</td> </tr> <tr> <td style="border: 1px solid black; padding: 8px;">特性</td> <td style="border: 1px solid black; padding: 8px;">有限的值集合,整數映射。</td> <td style="border: 1px solid black; padding: 8px;">靈活性和動態性,支持繼承和多態性。</td> </tr> <tr> <td style="border: 1px solid black; padding: 8px;">表示方式</td> <td style="border: 1px solid black; padding: 8px;">簡單,不含方法。</td> <td style="border: 1px solid black; padding: 8px;">複雜,包含數據和行為。</td> </tr> </table> ---- #### 用列舉提高可靠性 ```Ada= -- 定義一個列舉型別 Traffic_Light type Traffic_Light is (Red, Yellow, Green); -- 宣告一個變數來儲存交通燈狀態 signal : Traffic_Light; -- 一個過程來模擬交通燈變化 procedure Switch_Light(S : in out Traffic_Light) is begin case S is when Red => -- 如果燈是紅色,下一個應該是綠色 S := Green; when Yellow => -- 如果燈是黃色,下一個應該是紅色 S := Red; when Green => -- 如果燈是綠色,下一個應該是黃色 S := Yellow; end case; end Switch_Light; -- 使用列舉的例子 begin -- 初始化信號為紅燈 signal := Red; -- 印出當前燈號 Ada.Text_IO.Put_Line("Current Light: " & Traffic_Light'Image(signal)); -- 變換信號 Switch_Light(signal); -- 再次印出變換後的燈號 Ada.Text_IO.Put_Line("Next Light: " & Traffic_Light'Image(signal)); end; ``` ---- #### 用列舉來簡化修改 - yello: 1 - red: 2 - green: 3 => 4 共用列舉只要修改列舉就能全部修改定義 ---- #### 將列舉型別作為布林變數的替代方案 ``` from enum import Enum # 定義一個列舉型別 ApiResponseStatus class ApiResponseStatus(Enum): SUCCESS = 200 NOT_FOUND = 404 BAD_REQUEST = 400 UNAUTHORIZED = 401 FORBIDDEN = 403 SERVER_ERROR = 500 # 這裡是一個模擬的 API 回應函數 def mock_api_call(): # 模擬一個錯誤回應,例如 401 Unauthorized return ApiResponseStatus.UNAUTHORIZED # 使用例子 response_status = mock_api_call() if response_status != ApiResponseStatus.SUCCESS: print(f"Error occurred: {response_status.name}") else: print("API call successful!") ``` ---- #### 檢查非法數值 ``` from enum import Enum # 定義一個列舉型別 ApiResponseStatus class ApiResponseStatus(Enum): SUCCESS = 200 NOT_FOUND = 404 BAD_REQUEST = 400 UNAUTHORIZED = 401 FORBIDDEN = 403 SERVER_ERROR = 500 # 模擬一個 API 回應函數 def mock_api_call(): # 模擬一個未定義的錯誤狀態,例如 418 I'm a teapot return 418 # 檢查回應是否在 ApiResponseStatus 中 def check_response(status_code): for status in ApiResponseStatus: if status.value == status_code: return status # 如果未找到匹配的列舉項,則返回 None return None # 使用例子 response_code = mock_api_call() response_status = check_response(response_code) if response_status is None: print(f"Unknown error occurred with status code: {response_code}") elif response_status == ApiResponseStatus.SUCCESS: print("API call successful!") else: print(f"Error occurred: {response_status.name}") ``` ---- #### 定義出列舉第一項和最後一項,以便用於迴圈限制 ``` from enum import Enum class Weekday(Enum): FIRST = 0 # 用來標記第一筆,非具體一天 MONDAY = 1 TUESDAY = 2 WEDNESDAY = 3 THURSDAY = 4 FRIDAY = 5 SATURDAY = 6 SUNDAY = 7 LAST = 8 # 用來標記最後一筆,非具體一天 # 遍歷 Weekday 中介於 FIRST 和 LAST 之間的值 for day in Weekday: if Weekday.FIRST.value < day.value < Weekday.LAST.value: print(day.name) ``` ---- #### 把列舉型別的第一個元素留做非法值 ``` from enum import Enum class StatusCode(Enum): INVALID = 0 # 非法或無效的狀態 OK = 1 ERROR = 2 NOT_FOUND = 3 # 函數來模擬 API 請求 def mock_api_call() -> StatusCode: # 模擬一個 API 請求,假設這個請求失敗 return StatusCode.ERROR # 使用列舉的例子 status = mock_api_call() if status == StatusCode.INVALID: print("Error: Received an invalid status code.") elif status == StatusCode.OK: print("API call successful!") else: print(f"API call resulted in an error with status: {status.name}") ``` ---- #### 明確定義專案程式碼編寫中第一個和最後一個元素的使用規則 ``` from enum import Enum, auto class ConfigOption(Enum): INVALID = auto() # 第一個元素,用於無效值 AUDIO = auto() VIDEO = auto() NETWORK = auto() LAST = auto() # 最後一個元素,用於界定範圍 # 函數來處理不同的配置選項 def process_config(option: ConfigOption): if option == ConfigOption.INVALID: print("Error: Invalid configuration option selected.") return print(f"Processing {option.name} configuration...") # 遍歷 ConfigOption,略過 INVALID 和 LAST for option in ConfigOption: if option not in (ConfigOption.INVALID, ConfigOption.LAST): process_config(option) ``` ---- #### 如果你的語言裡沒有列舉型別 1. 定義常量 2. 物件封裝 3. 類別和靜態屬性 4. 使用陣列或列表 ---- ##### 物件封裝 ```javascript= const StatusCode = Object.freeze({ INVALID: 0, OK: 1, ERROR: 2, NOT_FOUND: 3 }); ``` ---- ##### 類別和靜態屬性 ```python= class StatusCode: INVALID = 0 OK = 1 ERROR = 2 NOT_FOUND = 3 ``` ---- <div style="display: flex; justify-content: center;"> <img src="https://slidesplayer.com/slide/16398594/95/images/116/%E5%85%B7%E5%90%8D%E5%B8%B8%E6%95%B8+%28Named+Constant%29.jpg" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">具名常數</li> <li>陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">具名常數</span></h3> <ul> <li>在資料宣告中使用具名常數</li> <li>避免使用字面常數,即使是「安全」的</li> <li>用具有適當作用範圍的變數或類別來模擬具名常數</li> <li>統一使用具名常數</li> </ul> ---- #### 在資料宣告中使用具名常數 ```python= class GameSettings: MAX_PLAYERS = 10 MIN_PLAYERS = 2 # 使用具名常數來宣告遊戲的最大玩家數 max_players_allowed = GameSettings.MAX_PLAYERS print(f"Maximum players allowed: {max_players_allowed}") ``` ---- #### 避免使用字面常數,即使是「安全」的 ```javascript= class HTTP { static TIMEOUT = 5000; // 5000 毫秒的超時時間 } // 使用具名常數來設定請求超時,避免直接使用字面常數 fetch('https://api.example.com/data', { timeout: HTTP.TIMEOUT }) .then(response => console.log('Request succeeded')) .catch(error => console.log('Request failed with timeout')); ``` ---- #### 用具有適當作用範圍的變數或類別來模擬具名常數 ```Java= public class Configuration { public static final int DEFAULT_PORT = 8080; } // 在伺服器設定中使用具有適當作用範圍的具名常數 int serverPort = Configuration.DEFAULT_PORT; System.out.println("Server running on port: " + serverPort); ``` ---- #### 統一使用具名常數 ```C# public class Constants { public const string DB_CONNECTION_STRING = "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"; } // 使用具名常數來統一資料庫連接字串 string connectionString = Constants.DB_CONNECTION_STRING; ``` ---- <div style="display: flex; justify-content: center;"> <img src="https://programming.im.ncnu.edu.tw/array.jpg" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">陣列</li> <li>建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- <h3 style="text-align:left;"><img src="https://hackmd.io/_uploads/HJMQOONXC.png" width="45px" style="margin-top: 3px;margin-right: 10px;"><span style="color: #FCD354;">陣列</span></h3> <ul> <li>確認所有的陣列指標都沒有超出陣列的邊界</li> <li>考慮用容器來取代陣列,或者將陣列作為順序化結構來處理</li> <li>檢查陣列的邊界點</li> <li>如果陣列是多維的,確認指標的使用順序是正確的</li> <li>提防指標交互干擾</li> </ul> ---- #### 確認所有的陣列指標都沒有超出陣列的邊界 ``` numbers = [1, 2, 3, 4, 5] index = 5 # 這個索引是超出範圍的,因為最大索引應該是 4 if index < len(numbers): print(numbers[index]) else: print("Index is out of bounds.") ``` ---- #### 考慮用容器來取代陣列,或者將陣列作為順序化結構來處理 ``` # 陣列容器相對於 Stack, Queue, Map, Set 等不同的容器,具有順序化的特色, 應該藉由順序化結構來處理。(討論後補充) items = [] for i in range(10): # 動態添加元素 items.append(i ** 2) print(items) ``` ---- #### 檢查陣列的邊界點 ``` # 檢查列表的首尾元素 numbers = [1, 2, 3, 4, 5] first = numbers[0] last = numbers[-1] # Python 允許使用負索引來從列表末尾訪問元素 print(f"First: {first}, Last: {last}") ``` ---- #### 如果陣列是多維的,確認指標的使用順序是正確的 ``` # 多維列表 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for row in matrix: for item in row: print(item, end=' ') print() ``` ---- #### 提防指標交互干擾 ``` # 指標交互干擾的例子 original = [1, 2, 3] copy = original # 這裡不是創建一個新的列表,而是引用同一個列表 copy[0] = 99 # 修改 copy 會影響 original print(f"Original: {original}") ``` ---- <div style="display: flex; justify-content: center;"> <img src="data:image/jpeg;base64,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" width="50%" style="margin-right: 50px;background: white; padding: 10px" /> <div width="50%"> <h4>基本資料型態®</h4> <ul style="text-align: left; margin-left: -120px; font-size:24px; list-style: none"> <li>數值概論</li> <li><b>整數</b></li> <li>浮點數</li> <li>字元和字串</li> <li>布林變數</li> <li>列舉型別</li> <li>具名常數</li> <li>陣列</li> <li style="color: #FCD354; list-style-image: url('https://hackmd.io/_uploads/Bk5lGONQC.png');background-size: 5px;">建立型別</li> <li>...</li> </ul> <img src="https://hackmd.io/_uploads/HkCAKsWQC.png" width="200px" style="position: absolute;right:20px;bottom: 10px;" /> </div> <div> ---- #### 建立型別實例(資料定義有跨型別的需要?) ```C++= typedef float Coordinate; // for coordinate variables Routine1( ... ) { Coordinate latitude; Coordinate longitude; Coordinate elevation; ... } Routine2( ... ) { Coordinate x; Coordinate y; Coordinate z; ... } ``` ---- #### 建立自己型別的原因 - 易於修改 - 避免過多的資訊分發 //Const NAME_LENGTH = 30; - 增加可靠性 //Ada type Age is range 0..99 - 彌補語言的不足 // typedef in t Boolean; ---- #### 建立自訂義資料型別的指導原則 - 給所建立的型別取功能導向的名稱 - 避免使用預定義型別 - 不要重訂義一個預定義的型別 - 定義替代型別以便於移植 - 考慮建立一個類別而不是使用 typedef ---- 其他: ---- #### (補充)「靜態型別 vs. 動態型別」與「強型別 vs. 弱型別」 [![12_type_system](https://hackmd.io/_uploads/HJWUlh-mC.jpg)](https://blog.tarswork.com/post/programming-language-type-system/) ---- #### 思考:自定義型別如何管理? ----
{"title":"基本資料型別®","description":"12.1 數值概論12.2 整數12.3 浮點數12.4 字元和字串12.5 布林變數12.6 列舉型別12.7 具名常數12.8 陣列12.9 建立你自己的型別(型別別名)要點","contributors":"[{\"id\":\"166114a0-368f-4432-b369-5d1bdfcf0880\",\"add\":70593,\"del\":30665}]"}
    187 views