# 基本資料型別®
導讀人: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)錯誤

<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)
[](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,
 (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. 弱型別」
[](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}]"}