Appearance
變數 (variable)
變數(Variable)是程式中用來儲存數值的「容器」。在 C 語言中,使用變數必須先確定它的型別。
宣告與定義
宣告與定義部分較為硬核,重要性較低,有關 Memory Layout 請看這裡
在C語言中,變數宣告與定義是分開的
- 宣告: 告訴編譯器一個名字,他是哪個類別 (無記憶體區塊)
- 定義: 告訴編譯器這個名字,並在記憶體中儲存數值 (分配記憶體)
也因此,針對同一個變數,宣告可以進行多次,而定義只能有一次,而變數宣告在 Global 和 Local 會有不太一樣的表現。
c
#include<stdio.h>
int global_data_var = 1;
int global_data_var; // 可多次宣告
int global_bss_var;
int main() {
int local_var;
int local_var; // 出錯
}Memory Layout 簡單講解
在 Global 區域,變數宣告有兩種: 有定義(data)和無定義(bss),定義只能有一個,可以在任何地方;無定義的會在進入程式時自動填入0。
而在 Local 區域,變數宣告會立刻劃分一塊記憶體(stack),相當於宣告即定義,因此不能多次宣告。
常見變數型別
在 C 中,有一些比較常使用的變數,參見
| 型別 | 特性 |
|---|---|
| int | -2,147,483,648 - 2,147,483,647 |
| float | 數值越大精度越低 |
| char | 1 byte 的字元,用 '' 包住 |
進階: 不固定的int大小
在整數中有四個類別,int、long、short、long long
只有要求 16 bits <= short <= int <= 32 bits <= long <= 64 bits <= long long 因此 long 與 int 在不同系統常常會有不同的情況,但通常以 int、long 都是 32 bits 為主
進階: float精度
這有關 IEEE 754 的設計方案,float 由 1 sign bit(正負)、8 exponential bit、23 fraction bit 計算方式為 因此讓數字越大,exp bits就越大,fraction bits能表達的小數就越少。
有一些特殊的值,像是inf與NaN這邊不展開說明。
常數宣告 (Constant)
有時候,我們希望某個變數在初始化後就永遠不要被改變(例如:圓周率 const 關鍵字。
c
const float PI = 3.14159f;
PI = 3.14f; // 編譯錯誤!你不能更改常數為什麼要使用 const?
防止意外手殘:
在大型專案中,你可能會不小心在幾百行程式碼後改寫了某個重要數值。const能讓編譯器幫你把關,只要有人試圖修改,程式就無法編譯。增加程式可讀性:
當其他工程師(或未來的你)看到const時,會立刻知道:「喔!這個數值是固定的,我不需要去追蹤它在哪裡被改過。」
const vs define
雖然 #define PI 3.14 也能達到類似效果,但 const 具有型別檢查的功能。#define 只是純粹的文字替換,而 const 是一個真正的變數,能讓 Debugger 與編譯器更容易追蹤錯誤。
型別轉換
型別能夠互相轉換
- float -> int: 去除小數點
- int -> float: 沒變
- char -> int: 沒變
- int -> char: 沒變,注意數值不要超過 char 的邊界
算術與賦值
有時會想要給變數不一樣的數值,來達成各種效果,這時就可以使用 賦值,左邊放變數,右邊放表達式 (Expression)。
Examples:
c
int a = 1, b = 2, c;
c = 0; // expression with a constant
c = a; // expression with a variable
c = a - b; // expression with variable and operators
c = c + a + 1; // expression with above all一個表達式可以包含變數、常數、運算符號來產生一個結果。
這個篇章先介紹運算符號中的 算術運算子 (Arithmetic operator), 有分為一元、二元,也就是算是有幾個元素。
一元:
+: 不做任何事,但通常強調數值為正-: 讓數字變負的
二元:
+: 加法-: 減法*: 乘法/: 除法%: 餘數運算
除了 % 外的二元運算都可以混合型別(int 和 float 一起運算),如果其中一個是 float 的話,餘數運算會是 float 結果