1. 前言 C 語言中變數與資料型別的重要性 C 語言是一種廣泛用於系統程式設計與嵌入式系統開發的程式語言。在學習 C 語言時,「變數」與「資料型別」 是最基本且重要的概念。程式是透過操作資料而成立,為了適當管理這些資料,需要正確使用變數,並選擇適當的資料型別 。 例如,當考慮用於儲存數值的變數時,處理整數與處理小數時所使用的資料型別不同。此外,為了節省記憶體與提升處理速度,選擇最適的資料型別也是很重要的。本文的目的 本文將針對 C 語言的「變數」 與「資料型別」 ,以初學者也能易於理解的方式說明。為了能系統性地學習從基本概念到實務用法,將依照以下重點說明。什麼是變數? - 說明宣告與初始化的方法、命名規則等資料型別的分類 - 基本資料型別(int、float、char 等)與衍生資料型別(結構體、陣列、指標 等)型別轉換(轉型) - 隱式型別轉換與顯式型別轉換變數的作用域與生命週期 - 區域變數與全域變數的差異實務上資料型別的選擇方式 - 考慮記憶體使用量與計算精度的最佳選擇在什麼情況下需要注意變數與資料型別? 在 C 語言程式設計中,以下情況下變數與資料型別的選擇相當重要。記憶體最佳化 在嵌入式系統與低階程式中,需要將記憶體使用量降至最低。因此,適當選擇資料型別即可防止不必要的記憶體消耗。short num1 = 100; // 2 位元組(16 位元)
int num2 = 100; // 4 位元組(32 位元) 在上述例子中,使用 short 可比 int 節省記憶體。提升計算精度 在處理浮點數時,float 不如 double 精度高,但會消耗更多記憶體。float pi = 3.141592; // 單精度浮點數(32 位元)
double pi_high = 3.14159265358979; // 雙精度浮點數(64 位元) 在需要高精度的計算中,通常會使用 double。透過型別轉換防止錯誤 在 C 語言中,不同資料型別之間的運算可能會自動進行型別轉換。若未適當進行轉型,可能會產生非預期的結果。int a = 10;
float b = 3.5;
int result = a + b; // 隱式型別轉換(結果會被截斷為 int 型別) 在此情況下,result 的值會變成 13,小數點以下會被截斷。為了防止此情況,需要使用顯式型別轉換(轉型)。float result_correct = (float)a + b; // 正確的型別轉換總結 在 C 語言程式設計中,變數與資料型別的選擇極為重要 。考慮記憶體效率、計算精度與型別轉換的影響,適當選擇資料型別即可防止錯誤,並撰寫高效能的程式 。
2. 什麼是變數? 變數的基本概念 在 C 語言中,變數(Variable) 是程式用來暫時保存資料的「具名記憶區域」。在程式內進行計算或保存資料時,適當使用變數即可撰寫彈性的程式碼。變數的特徵 用於保存資料的記憶區域 在程式執行期間可變更其值 根據資料類型(型別)分配記憶空間 例如,有用來保存整數、浮點數、字元等的變數。變數的宣告與初始化 在 C 語言中使用變數,首先需要 變數的宣告 。在變數宣告時,需要指定 資料型別(型別)與變數名稱 。變數的基本宣告方式 資料型別 變數名;變數的初始化 僅僅宣告變數,值仍未定義。因此,透過 初始化(設定初始值) 可防止意外的行為。int num = 10; // 整數型變數 num 以 10 初始化
float pi = 3.14; // 浮點型變數 pi 以 3.14 初始化
char letter = 'A'; // 字元型變數 letter 以 'A' 初始化C 語言的變數型別 在 C 語言中,需要明確定義變數的型別。主要的資料型別如下。資料型別 說明 使用範例 int整數型 int a = 10;float單精度浮點數 float b = 3.14;double雙精度浮點數 double c = 3.1415926535;char字元型 char d = 'A';
關於整數型與浮點型的差異,將在後續「資料型別概述」章節中詳細說明。變數名稱的命名規則與最佳實踐 C 語言的變數名稱規則 變數名稱可以自由設定,但必須遵守以下規則。
✅ 可使用的字元 英文字母(A-Z、a-z) 數字(0-9) ※但 變數名稱開頭不可使用 底線(_) 🚫 不可使用的項目 保留字(例:int、float、return 等) 特殊字元(例:@, #, $ 等) 變數名稱開頭為數字 int _value = 10; // OK
int number1 = 20; // OK
int 1st_number = 30; // NG(數字開頭的變數名稱不可)
int return = 100; // NG(保留字不可使用)考慮可讀性的命名(最佳實踐) 在 C 語言中,適當命名變數可提升程式碼的可讀性。
✅ 良好範例 int userAge; // 使用者的年齡
float circleArea; // 圓的面積
char firstLetter; // 最初的字元 🚫 不良範例 int a; // 意義不明
float b1; // 不知道什麼資料
char x_y_z; // 過於複雜 👉 提升可讀性的要點 變數名稱要具備意義 多個單詞使用camelCase(例:userAge)或snake_case(例:user_age) 盡量避免縮寫(例:如 numOfStudents 具體化) 變數的使用方式(簡易程式) 以下程式使用變數進行簡單計算,並顯示結果。範例程式碼 #include <stdio.h>
int main() {
int a = 5;
int b = 10;
int sum = a + b; // 使用變數計算
printf("a = %d, b = %d, sum = %dn", a, b, sum);
return 0;
}執行結果 a = 5, b = 10, sum = 15 透過使用變數,可將計算結果儲存並再次利用。總結 變數是暫時保存資料的記憶區域 在 C 語言中,宣告變數時必須指定資料型別 變數命名有規則,建議以可讀性為考量命名 使用變數可讓資料更易於管理 3. C語言的資料型概述 資料型是什麼? C語言中,資料型(Data Type) 透過明確指定,可決定變數所處理的資料類型與記憶體使用量。選擇適當的資料型,可實現記憶體效能化 與型別轉換導致的錯誤防止 。C語言的資料型特點 ✅ 明確資料的種類 (整數、浮點數、字元等)
✅ 最佳化記憶體使用量 (每種型別使用的記憶體大小不同)
✅ 決定型別轉換與運算時的行為 (整數之間的計算、小數的計算等) 例如,如下整數型與浮點型可處理的資料不同。int age = 25; // 整數(只能儲存整數值)
float pi = 3.14; // 浮點數(可處理小數)
char letter = 'A'; // 字元型(只能儲存單一字元)C語言的資料型分類 C語言的資料型大致可分為 基本資料型 與 衍生資料型 兩類。資料型的種類 概述 基本資料型 變數的基本型別(int, float, char 等) 衍生資料型 由基本資料型組合而成(陣列、結構體、指標等)
基本資料型 基本資料型是 C 語言程式中最常使用的資料型別。整數型(Integer) 用於處理整數的資料型別,可儲存正負值。資料型 記憶體大小(標準) 可儲存值的範圍(32 位元環境) int4 位元組(32 位元) -2,147,483,648 ~ 2,147,483,647 short2 位元組(16 位元) -32,768 ~ 32,767 long4~8 位元組 依環境而定(範圍比 int 更廣) unsigned int4 位元組 0 ~ 4,294,967,295
int number = 100;
short smallNumber = 10;
unsigned int positiveOnly = 300;浮點型(Floating Point) 用於處理小數的資料型別,依精度不同分為 float 與 double。資料型 記憶體大小 精度 float4 位元組 約 6~7 位數 double8 位元組 約 15 位數 long double10~16 位元組 約 18 位數以上
float pi = 3.14f; // 加上 "f" 可為 float 型別
double precisePi = 3.1415926535;字元型(Character) 用於儲存單一字元的資料型別,實際上會被視為 整數(ASCII 碼) 。資料型 記憶體大小 可儲存的資料 char1 位元組 ‘A’, ‘b’, ‘9’ 等單一字元
char letter = 'A';
printf("%c", letter); // 輸出 A 因被視為 ASCII 碼,可將 char 作為數值進行運算。char letter = 'A';
printf("%d", letter); // 65('A' 的 ASCII 碼)衍生資料型 衍生資料型用於定義結合基本資料型的高階資料結構。資料型 說明 陣列(Array) 連續儲存相同型別的資料 結構體(struct) 將不同型別的資料作為一個單位處理 共用體(union) 共享記憶體的資料結構 列舉型(enum) 定義有意義的常數 指標(Pointer) 儲存記憶體位址的變數
資料型的選擇基準 選擇適當的資料型會影響程式的效能與記憶體管理 。使用情境 建議資料型 理由 迴圈計數器 unsigned int不需要符號且效率佳 高精度計算 double比 float 精度更高 想節省記憶體 short / char以最小必要尺寸管理 處理字串的單一字元 char以 1 位元組管理字元
for (unsigned int i = 0; i < 100; i++) {
printf("%d ", i);
}總結 C語言的資料型包括 基本資料型 (整數型、浮點型、字元型)與 衍生資料型 (陣列、結構體、指標 等)。 選擇適當的資料型可提升程式的效能。 整數型通常使用 int,浮點型則常用 double。 善用衍生資料型,可更容易處理複雜的資料結構。
4. 基本資料型(原始型) 什麼是基本資料型? C 語的基本資料型(原始型),是 表示最基本資料類型的型別 ,是所有變數與資料結構的基礎。了解這些型別並適當選擇,可實現 程式的效能提升與記憶體管理的最佳化 。
C 語主要有以下 3 種基本資料型 。資料型別 說明 使用範例 整數型(Integer) 處理整數的型別 int, short, long浮點型(Floating Point) 處理小數的型別 float, double字元型(Character) 處理單一字元的型別 char
接下來將詳細說明各個資料型別。1. 整數型(Integer) 整數型是 用於儲存整數的資料型別 ,也是程式中最常使用的型別之一。整數型的種類與記憶體大小 整數型有 有號(signed) 與 無號(unsigned) 之分。資料型別 記憶體大小(標準) 可儲存值的範圍(32 位元環境) int4 位元組(32 位元) -2,147,483,648 ~ 2,147,483,647 short2 位元組(16 位元) -32,768 ~ 32,767 long4~8 位元組 依環境而定(範圍比 int 更廣) unsigned int4 位元組 0 ~ 4,294,967,295
整數型的使用範例 #include <stdio.h>
int main() {
int num = 100; // 一般的整數型
short smallNum = 10; // 小型整數(節省記憶體)
long bigNum = 1000000; // 大的整數
unsigned int positiveOnly = 300; // 只允許正整數
printf("num: %d, shortNum: %d, bigNum: %ld, positiveOnly: %un", num, shortNum, bigNum, positiveOnly);
return 0;
}2. 浮點型(Floating Point) 浮點型是 處理小數的資料型別 。與整數型不同,能精確表示小數。浮點型的種類 資料型別 記憶體大小 精度(有效位數) float4 位元組 約6~7位 double8 位元組 約15位 long double10~16 位元組 約18位以上
浮點型的使用範例 #include <stdio.h>
int main() {
float pi = 3.14f; // 加上 "f" 則為 float 型別
double precisePi = 3.1415926535; // 更高精度的 double 型別
printf("pi (float): %.7fn", pi);
printf("precisePi (double): %.15lfn", precisePi);
return 0;
}3. 字元型(Character) 字元型(char)是 用於儲存單一字元的資料型別 ,實際上會被當作 整數(ASCII 碼) 處理。字元型的特徵 使用 1 位元組(8 位元)的記憶體 char 型使用 ASCII 碼,內部以整數方式處理字元型的使用範例 #include <stdio.h>
int main() {
char letter = 'A'; // 儲存字元
printf("letter: %c", letter);
printf("ASCII碼: %d", letter); // 'A' 為 65
return 0;
}適當選擇基本資料型 使用哪種基本資料型,取決於 程式的目的與記憶體限制 。使用情境 建議資料型別 原因 迴圈計數器 unsigned int不需要負數且效率較佳 小數計算 double比 float 精度更高 記憶體節省 short / char以最小必要大小管理 處理字串的單一字元 char可用 1 位元組管理
short smallNum = 32767; // 節省記憶體總結 基本資料型是 C 語程式的基礎 ,用於處理整數、小數與字元整數型(int, short, long)處理整數,亦可使用無號(unsigned) 浮點型(float, double)處理小數,依精度選擇使用 字元型(char)處理單一字元,內部以整數儲存 適當選擇資料型別可提升程式效能,並節省記憶體
5. 派生資料型(Derived Data Types) 什麼是派生資料型? C 語的派生資料型(Derived Data Types) 是指將基本資料型結合以建立更複雜資料結構的型別 。它用於簡潔地處理僅靠基本資料型難以表達的資料結構。 以下是常見的派生資料型。資料型 說明 陣列(Array) 儲存多個相同型別的資料 結構體(struct) 將不同型別的資料作為一個單位管理 共用體(union) 共享記憶體的資料結構 列舉型(enum) 定義有意義的常數 指標(Pointer) 儲存記憶體位址
1. 陣列(Array) 陣列是指將相同型別的資料儲存在連續的記憶體區域中的資料結構 。陣列的宣告與初始化 資料型 陣列名[元素數];範例(整數型陣列) int numbers[5] = {10, 20, 30, 40, 50};陣列元素的存取 printf("%dn", numbers[0]); // 輸出 10
numbers[1] = 25; // 更新第2個元素多維陣列(2D 陣列) int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
}; ✅ 用途: 資料的批次管理、矩陣運算、緩衝區管理等2. 結構體(struct) 結構體是指能將不同型別的資料作為一個單位管理的資料型別 。結構體的定義與使用 struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person person1 = {"Taro", 25, 175.5};
printf("Name: %s, Age: %d, Height: %.1f cmn", person1.name, person1.age, person1.height);
return 0;
} ✅ 用途: 學生資料、商品資訊、遊戲角色資訊等3. 共用體(union) 共用體是指共享記憶體的特殊資料型別 ,且可以以不同型別使用相同的記憶體區域 。共用體的定義與使用 union Data {
int i;
float f;
};
int main() {
union Data data;
data.i = 10;
printf("Integer: %dn", data.i);
data.f = 3.14;
printf("Float: %.2fn", data.f); // 此時 data.i 的值不確定
return 0;
} ✅ 用途: 需要記憶體節省的情況(例如,以單一變數管理不同資料格式)4. 列舉型(enum) 列舉型是指用於定義有意義常數的資料型別 。列舉型的定義與使用 enum Color { RED, GREEN, BLUE };
int main() {
enum Color favoriteColor = GREEN;
printf("Favorite Color: %dn", favoriteColor); // 1(GREEN 預設從 0 開始依序編號)
return 0;
} ✅ 用途: 狀態管理(例如:紅綠燈的顏色、星期、遊戲狀態)5. 指標(Pointer) 指標是指儲存變數位址的特殊資料型別 。指標的基本 int a = 10;
int *ptr = &a; // 將 'a' 的位址儲存於指標
printf("Address of a: %pn", &a);
printf("Pointer Value: %pn", ptr);
printf("Dereferenced Value: %dn", *ptr); // 10指標的用途 ✅ 動態記憶體管理(malloc / free) ✅ 函式的陣列傳遞 ✅ 字串操作(char *str) 總結 陣列 用於將相同型別的資料集中管理 結構體 用於將不同型別的資料作為一個單位處理 共用體 是共享記憶體的特殊資料型別 列舉型 用於定義有意義的常數 指標 用於處理變數的位址
6. 型別修飾子(Type Modifiers) 型修飾子是什麼? C 語言的型修飾子(Type Modifiers) 是用來修改基本資料型別特性的關鍵字。
適當使用型修飾子,可實現記憶體最佳化、資料安全性、處理速度提升 等。
C 語言的主要型修飾子如下。型修飾子 說明 const變數的值無法更改(常數) volatile防止最佳化,讓變數的值每次都從記憶體取得 restrict提升指標的最佳化 signed包含負值的整數型(預設) unsigned只處理正值的整數型
1. const(宣告常數) const 修飾子,變數的值將無法被更改 。
這有助於防止錯誤的賦值,提升程式碼的安全性 。const 的使用範例#include <stdio.h>
int main() {
const int MAX_USERS = 100; // 宣告為常數
printf("Max Users: %dn", MAX_USERS);
// MAX_USERS = 200; // 錯誤!因為 const 無法更改值
return 0;
}將 const 套用於函式參數 void printMessage(const char *message) {
printf("%sn", message);
// message[0] = 'H'; // 錯誤!因為 const 無法修改
} ✅ 效果: 使用 const 可防止函式內的資料被更改2. volatile(防止最佳化) volatile 用於防止編譯器的最佳化 。
主要在硬體暫存器、全域變數、割中斷處理 中使用。volatile 的使用範例#include <stdio.h>
volatile int flag = 0; // 防止最佳化
int main() {
while (flag == 0) {
// 某些處理(迴圈直到 flag 被更改)
}
printf("Flag changed!n");
return 0;
} ✅ 用途: 在多執行緒處理中偵測變數的變更 讀取硬體暫存器 監視在割中斷處理中被更改的變數 3. restrict(指標最佳化) restrict 是自 C99 起引入的修飾子,保證一個指標指向的記憶體區域不會與其他指標共享。
因此可提升最佳化,讓處理速度加快 。restrict 的使用範例#include <stdio.h>
void add_arrays(int *restrict a, int *restrict b, int *restrict result, int size) {
for (int i = 0; i < size; i++) {
result[i] = a[i] + b[i];
}
} ✅ 用途: 指標運算的最佳化 數值計算的效能提升 向量運算(SIMD 最佳化) 4. signed 與 unsigned(有號與無號整數) C 語言的整數型別有兩種:有號(signed) 與 無號(unsigned) 。修飾子 說明 signed包含負值的整數(預設) unsigned僅正整數(0 以上)
signed(有號整數)的使用範例int a = -10; // 可儲存負值
printf("%dn", a); // 輸出 -10unsigned(無號整數)的使用範例unsigned int b = 250;
printf("%un", b); // 輸出 250
unsigned int c = -10; // 錯誤!負值無法儲存 ✅ 用途: 不使用負值的計數器(迴圈變數等) 二進位資料處理(位元運算) 有效利用記憶體大小 ⚠ 注意: 使用 unsigned 時無法賦予負值,需留意意外的溢位。int x = -1;
unsigned int y = x; // 錯誤或產生意外結果總結 型修飾子 用途 優點 const宣告不可變更的變數 防止錯誤的更改 volatile防止最佳化 正確取得割中斷處理與硬體暫存器的值 restrict指標最佳化 防止記憶體競爭,實現高速處理 signed包含負值的整數型 在處理負數計算時有效 unsigned只處理正值的整數型 節省記憶體,適用於計數器與位元運算
7. 型變換(轉型) 什麼是型變換? C語言中,當在不同資料型別之間執行運算或賦值時,會產生型變換(Type Conversion) 。
型變換分為隱式型變換(自動型變換) 與顯式型變換(轉型) 兩種。
如果不正確理解型變換,可能會導致資料精度遺失或產生非預期的錯誤 ,因此正確區分使用非常重要。1. 隱式型變換(自動型變換) 在 C 語言中,當對不同資料型別進行運算或賦值時,編譯器會自動執行型變換 。
這稱為隱式型變換(Implicit Type Conversion) 。隱式型變換的規則 小型資料型別 → 大型資料型別 會自動轉換整數型 → 浮點型 會被轉換char → int(作為 ASCII 碼處理)隱式型變換的範例 #include <stdio.h>
int main() {
int a = 10;
float b = a; // int → float 自動轉換
printf("b: %.2fn", b); // 輸出: b: 10.00
char letter = 'A';
int asciiValue = letter; // char → int 轉換(ASCII 碼)
printf("ASCII value of A: %dn", asciiValue); // 輸出: ASCII value of A: 65
return 0;
}2. 顯式型變換(轉型) 顯式型變換(Explicit Type Conversion) 中,開發者會有意地轉換資料型別。
此轉換稱為轉型(Casting) 。轉型的基本語法 (轉換後的資料型別) 值或變數轉型的使用範例 #include <stdio.h>
int main() {
int a = 10, b = 3;
float result = (float)a / b; // int 轉換為 float
printf("Result: %.2fn", result); // 輸出: Result: 3.33
return 0;
} ✅ a 透過 (float) 轉型,可防止整數相除時的截斷 。3. 需要轉型的情況 (1) 整數相除 int a = 5, b = 2;
float result = a / b; // 結果為 2(仍為整數)
float correctResult = (float)a / b; // 正確得到 2.5
✅ 要點: 只要將其中一個轉為 float,結果也會是 float! (2) 浮點 → 整數(小數部分截斷) float pi = 3.14159;
int truncatedPi = (int)pi; // 變成 3(小數部分被截斷)
⚠ 注意: 轉型後小數點以下會被截斷! (3) char → int(將字元轉為 ASCII 碼) char letter = 'B';
int ascii = (int)letter;
printf("ASCII Code: %dn", ascii); // 輸出: ASCII Code: 66
✅ char 型在內部被視為整數(ASCII 碼) 。(4) 從 void * 轉型(指標) 指標可以使用 void * 型以通用方式處理,但若不將其轉為適當的型別,會導致誤動作。void *ptr;
int num = 10;
ptr = #
int *intPtr = (int *)ptr; // 從 void * 轉型為 int *
printf("Value: %dn", *intPtr); // 輸出: Value: 10
4. 型變換的注意事項 (1) 資料精度遺失 在執行型變換時,可能會遺失資料精度 。float num = 3.9;
int rounded = (int)num; // 結果: 3(小數點以下被截斷)
解決方案: 若要四捨五入,請使用 round() #include <math.h>
int rounded = round(num); // 變成 4
(2) 注意 unsigned 與 signed 的轉換 unsigned int x = -1;
printf("%un", x); // 輸出: 4294967295(32 位元環境)
⚠ 將負值賦給無號型(unsigned)會產生非預期的結果! (3) 從較大型別轉為較小型別(溢位風險) long bigNum = 100000;
short smallNum = (short)bigNum; // 可能無法正確儲存資料
⚠ 解決方案: 事先使用 sizeof() 確認資料大小printf("Size of short: %lu bytesn", sizeof(short));
總結 型變換的種類 說明 範例 隱式型變換 編譯器自動轉換型別 int → float顯式型變換(轉型) 開發者有意轉換型別 (float)a / b整數相除 int / int 時小數會被截斷(float)5 / 2 → 2.5浮點 → 整數 小數部分會被截斷 (int)3.9 → 3指標的轉型 將 void * 轉為適當的型別 (int *)ptr
適當運用型變換,您可以撰寫安全且錯誤較少的程式 。
8. 變數的範圍與壽命 變數的範圍(有效範圍)是什麼? 在 C 語言中、變數的範圍(Scope) 指的是,「該變數可以從哪裡被參照(有效範圍) 」。
範圍會影響程式的設計,如果未適當管理,會成為意外行為或錯誤的原因 。C 語言的變數範圍類型 範圍類型 說明 有效範圍 區域變數 僅能在函式內使用 在宣告的函式或區塊內 全域變數 在整個程式中皆可使用 整個程式 區塊範圍 {} 內僅有效在宣告的區塊內 檔案範圍 無法從其他檔案存取 在定義的檔案內
1. 區域變數(Local Variables) 區域變數 是在函式或區塊 {} 內部宣告,且 僅在函式內有效 。區域變數的使用範例 #include <stdio.h>
void myFunction() {
int localVar = 10; // 區域變數
printf("Local variable: %dn", localVar);
}
int main() {
myFunction();
// printf("%d", localVar); // 錯誤!區域變數無法從函式外存取
return 0;
} ✅ 優點: 可防止函式間的影響(安全性高) 節省記憶體(函式結束時自動釋放) ⚠ 注意事項: 無法從函式外存取 每次呼叫函式時都會重新初始化(資料不會保留) 2. 全域變數(Global Variables) 全域變數 是在函式外宣告,且 在整個程式中皆可存取 。全域變數的使用範例 #include <stdio.h>
int globalVar = 100; // 全域變數
void myFunction() {
printf("Global variable: %dn", globalVar);
}
int main() {
myFunction();
globalVar = 200; // 可從任何地方修改
printf("Updated global variable: %dn", globalVar);
return 0;
} ✅ 優點: ⚠ 缺點: 可能發生意外的修改(錯誤的原因) 持續佔用記憶體 不易模組化 👉 解決方案: 使用 static 來限制全域變數(在下一節說明)3. 靜態變數(Static Variables) 加上 static,即使是區域變數也能持續保留值 。此外,對全域變數加上 static,則僅在該檔案內有效 。static 的使用範例(保留區域變數)#include <stdio.h>
void counter() {
static int count = 0; // static 保持值
count++;
printf("Count: %dn", count);
}
int main() {
counter(); // 輸出: Count: 1
counter(); // 輸出: Count: 2
counter(); // 輸出: Count: 3
return 0;
} ✅ 優點: ⚠ 缺點: static 的使用範例(限制全域變數)static int fileVar = 100; // 僅在此檔案內有效 ✅ 更易模組化,安全性提升 4. 外部變數(Extern) 使用 extern 關鍵字,可參照其他檔案中的變數。extern 的使用範例file1.c #include <stdio.h>
int sharedVar = 50; // 全域變數
void printSharedVar() {
printf("Shared Variable: %dn", sharedVar);
}file2.c #include <stdio.h>
extern int sharedVar; // 參照 file1.c 的變數
int main() {
printf("Accessing sharedVar: %dn", sharedVar);
return 0;
} ✅ 優點: ⚠ 缺點: 5. 變數的壽命(Lifetime) 變數的壽命(Lifetime)指的是 變數在記憶體上存在的期間 。變數類型 壽命(Lifetime) 釋放時機 區域變數 函式執行期間 函式結束時 全域變數 整個程式 程式結束時 靜態變數 (static) 整個程式 程式結束時 動態記憶體配置 (malloc) free() 直到呼叫free() 直到呼叫
總結 變數類型 範圍(有效範圍) 壽命(Lifetime) 區域變數 僅在函式內 直到函式結束 全域變數 整個程式 程式結束時 靜態變數 (static) 在宣告的範圍內 程式結束時 外部變數 (extern) 可從其他檔案參照 在宣告的範圍內
透過適當管理變數的範圍與壽命,可防止記憶體浪費,並製作較少錯誤的程式 。
9. 實務資料型的選擇方法 資料型選擇重要的原因 C 語言中,透過適當選擇資料型別,可實現記憶體最佳化、確保計算精度、提升效能 等好處。
若選擇不適當的資料型別,可能會產生 記憶體浪費、溢位、資料遺失 等問題。1. 想要節省記憶體時 在嵌入式系統或受記憶體限制的環境中,盡可能選擇 較小的資料型別 是很重要的。整數的記憶體大小與選擇方式 資料型別 記憶體大小 範圍(32 位元環境) char1 位元組 -128 ~ 127 short2 位元組 -32,768 ~ 32,767 int4 位元組 -2,147,483,648 ~ 2,147,483,647 long4~8 位元組 int 更廣的範圍unsigned int4 位元組 0 ~ 4,294,967,295
記憶體節省的範例 short temperature; // 為了節省記憶體而使用 short ✅ 適用情境: 感測器資料、迴圈計數器、處理小範圍值的變數 ⚠ 注意: 超出範圍會有溢位的危險!2. 需要精度時 在計算精度重要的情況下,使用 double 可以 防止捨入誤差 。浮點數的選擇方式 資料型別 記憶體大小 有效位數 float4 位元組 約 6~7 位 double8 位元組 約 15 位 long double10~16 位元組 約 18 位以上
確保精度的範例 double distance = 1234567.1234567; // 需要高精度計算的情況 ✅ 適用情境: 科學計算、金融計算、測量資料 ⚠ 注意: 由於 float 誤差較大,在需要精度的情況下應使用 double。3. 不處理負值時 使用 unsigned 可以 擴大正值範圍並提升記憶體效率 。不處理負值的範例 unsigned int score = 250; ✅ 適用情境: 計數器、大小指定、位元運算 ⚠ 注意: 使用 unsigned 後無法賦予負值,需留意意外的溢位。int x = -1;
unsigned int y = x; // 會產生錯誤或非預期結果4. 適合迴圈計數器的資料型別 迴圈計數器使用 int 之上,unsigned int 更為適合。for (unsigned int i = 0; i < 1000; i++) {
// 迴圈處理
} ✅ 優點: 由於 unsigned 不考慮負值,處理較易最佳化。5. 處理文字時 char 只能 儲存單一字元 ,但若處理字串則需使用 char 陣列。char letter = 'A'; // 只能單一字元
char str[] = "Hello"; // 字串 ✅ 適用情境: 單一字元處理(char)、字串處理(char 陣列)6. 使用列舉型讓程式碼更易懂 若想以 有意義的名稱管理整數值 ,使用 enum 可提升可讀性。enum Color { RED, GREEN, BLUE };
enum Color favoriteColor = GREEN; ✅ 適用情境: 狀態管理(例如:信號顏色、星期、遊戲狀態)7. 使用指標靈活管理記憶體 若要靈活管理資料的存放位置,會 使用指標 。int num = 10;
int *ptr = &num
printf("Value: %dn", *ptr); // 10 ✅ 適用情境: 動態記憶體管理、大量資料處理8. 最佳資料型的選擇方式(總結) 使用情境 建議資料型別 原因 迴圈計數器 unsigned int不需要負數且易於最佳化 小整數 short節省記憶體 高精度計算 double較 float 誤差少 無號資料 unsigned int可擴大範圍 字元處理 char儲存單一字元資料 狀態管理 enum易讀且減少錯誤 彈性資料管理 pointer記憶體管理更容易
✅ 重點總結 需要節省記憶體時使用 short 或 char 需要精度時選擇 double 若不需要負值則活用 unsigned 為提升可讀性活用 enum 活用指標即可實現彈性記憶體管理 選擇適當的資料型別,可使 程式的最佳化與安全性提升 成為可能。
10. 總結 C語言中變數與資料型別的重要性 在 C 語言中,變數與資料型別的理解是程式設計的基礎 。
選擇適當的資料型別,記憶體最佳化、處理速度提升、避免錯誤 成為可能。 本文將詳細說明以下重點。1. 什麼是變數? 變數是儲存資料的箱子 ,用於在程式中保持可變的值。需要宣告與初始化變數 ,且選擇適當的資料型別很重要。int age = 25; // 整數型變數
float pi = 3.14; // 小數型變數
char letter = 'A'; // 字元型變數2. C語言的資料型別概述 基本資料型別(整數型・浮點型・字元型) 衍生資料型別(陣列・結構體・共用體・列舉型・指標) 透過選擇適當的資料型別,可防止記憶體浪費,提升程式效率 。 3. 基本資料型別(原始型別) 資料型別 記憶體大小 特徵 int4位元組 整數 float4位元組 可處理小數但精度較低 double8位元組 高精度小數 char1位元組 儲存1個字元
4. 衍生資料型別(陣列・結構體・共用體・列舉型・指標) 陣列(Array) → 儲存多個相同型別的資料結構體(struct) → 將不同型別的資料作為一個單位管理共用體(union) → 共享記憶體的特殊資料型別列舉型(enum) → 定義有意義的常數指標(Pointer) → 儲存記憶體位址,實現彈性資料管理5. 型別修飾子 使用型別修飾子可以變更資料型別的特性。修飾子 說明 const常數(值不可變更) volatile防止最佳化(用於硬體處理) restrict指標的最佳化 unsigned僅正值
const int MAX_USERS = 100; // 值不可變更6. 型別轉換(轉型) 當需要在不同資料型別之間轉換時,隱式型別轉換(自動)與顯式型別轉換(轉型) 會發生。int a = 10;
float b = (float)a / 3; // 轉型7. 變數的作用域與生命週期 區域變數 → 僅在函式內有效全域變數 → 在整個程式中有效(但需注意管理)static → 可保持值,但作用域受限extern → 可從其他檔案參照變數static int counter = 0; // 保持值的區域變數8. 實務上資料型別的選擇方式 使用情境 建議資料型別 理由 迴圈計數器 unsigned int不需要負數且有效率 小整數 short節省記憶體 高精度計算 doublefloat 比較誤差少狀態管理 enum易讀且減少錯誤 彈性資料管理 指標動態記憶體管理適用
9. FAQ(常見問題) Q1. int 與 long 的差異是? A: long 能儲存比 int 更廣範圍的值。但依環境大小可能不同。long num = 1000000;Q2. float 與 double 該使用哪一個? A: 需要高精度時使用 double,需要節省記憶體時使用 float。double distance = 3.1415926535;Q3. 使用 unsigned 有何不同? A: unsigned 不處理負值,能儲存更大的正值 。unsigned int positive = 250;Q4. char 型也能作為數值使用嗎? A: 可作為 ASCII 碼進行整數運算 。char letter = 'A';
int ascii = (int)letter; // 65Q5. 使用 const 的好處是? A: 防止誤改值,提高安全性。const int MAX_VALUE = 100;總結 在 C 語言中,適當的資料型別選擇能提升程式品質 善用型別修飾子與轉型,可撰寫安全且高效的程式 了解作用域與生命週期,即可適當管理變數 掌握實務上資料型別的選擇,可進行更佳的程式設計 熟練運用 C 語言的資料型別,目標是撰寫高效且錯誤少的程式!