變數 Variable

在這章中,我們會來了解什麼是變數、他為什麼那麼重要、以及我們該如何使用變數。

了解變數是了解程式語言的基礎,雖然變數的概念很簡單,但常常有時候會因為不起眼的小錯誤而造成整個程式碼的崩壞。所以清楚了解變數以及他不同的資料型別是非常重要的!

接下來就讓我們來看看到底什麼是變數吧!

什麼是變數

所以什麼是變數呢?首先我們要先知道程式是如何產生我們想要的結果的。簡而言之,程式是透過讀取、儲存、改寫資料來產生結果。

讀取資料的方法有很多,比如說從一個檔案讀取其中文字、從網站上下載文件、或是使用者自己輸入給程式的資料。

改寫則包括更改檔案中的文字或是上傳文件到網站。

儲存更是執行程式時必不可少的一個步驟,因此必須有一個地方可以存放我們的資料。這個地方,在電腦中我們把它叫做 RAM (random access memory),中文叫做「隨機存取記憶體」。

隨機存取記憶體

在這裡我們不會仔細講解什麼是 RAM,因為這不是這章的重點。我們只會稍稍講一下 RAM 是拿來幹嘛的。

在程式一開始執行時,電腦就會自動提供一小塊 RAM 給那個程式進行資料儲存,而一但程式結束,這塊記憶體就會自動歸還給電腦。

我們可以把 RAM 想像成是由一個一個大小相同的格子組成的,並且每個格子都有獨特的數字編號。在程式執行時,資料就會被儲存在這一個一個格子當中。

而當程式需要這些資料時該怎麼辦呢?沒錯,就是透過變數來讀取!每個變數都會有一個獨特的名字,而變數都會存放著一些資料。

因此,當程式需要特定的資料時,他就會跟 RAM 說:「嘿請給我在變數 XXX 裡面的資料!」。

所以說,RAM 是電腦儲存資料的地方,而變數就是電腦拿取這些資料的手段!

宣告變數

這裡先提供一個非常簡單的範例:

int x;

這上面的程式碼告訴了我們,我們創建了一個叫做 x 的變數,而這個變數裡面存放的資料型別 data type int

這個變數 x,就會在 RAM 中佔據了一些格子,每當程式使用 x 時,就會到 RAM 中讀取儲存在其中的資料。

資料型別

資料型別的目的,就是在告訴我們的編譯器 compiler,現在這個變數是儲存著哪一種資料,例如整數、字串、單一字母等等。

回想一下前面所講的,每一個變數都會在 RAM 中佔據了一些格子,而不同的資料型態因為所要儲存的資料不相同,也會導致變數佔據的格子數不同,。

這裡先介紹幾種常見的資料型態:

  • int:整數 integer,專門來儲存整數,比方說 30、77、-18、0。
  • floatdouble:這兩個都是專門儲存有小數點的數字,比方說 3.14、-10.58。差別在於 double 所佔據的格子比 float 來得多,因此可以儲存更精準的數字(小數點後面的數字更多)。
  • bool:這個非常簡單,所儲存的只有兩種值,true (真) 或是 false (假)。
  • char:專門儲存一個字母,比方說 A、c、F。

宣告多個變數

若我們要同時新增很多相同型別的變數,我們可以這樣做:

int x, y, z; 
double a, b, c;

變數初始化與指派

在上面的程式碼中我們宣告了三個整數型態與三個浮點數型態的變數。

但我們並不知道他們的值是什麼。這邊我們有兩種方法可以賦予變數一個值。

  1. 初始化 (Initialization)
  2. 指派 (Assignment)

初始化

初始化的意思就是在宣告變數的當下就給予變數一個值,有以下兩種方式:

int x = 5; 
int x{5};

這兩種方式的差別在哪呢?在這個例子中是沒有差別的,但若是以下的例子:

int x = 10.5; // x會是10 
int x{10.5};  // 編譯器會丟出警告或錯誤

第一種的初始化方式會讓變數變為 10。雖然我們設的值為 10.5,但編譯器會看到說這個變數的資料型態為 int,因此會將10.5自動轉換為整數10,這會造成資料流失。一般情況下,我們是不會希望有資料流失的。

因此,使用第二種初始化方式會讓我們的程式碼多了一層保護。

指派

指派其實就是在宣告一個變數後,再賦予變數一個值。

我個人是比較喜歡初始化的方式,因為這樣比較直觀而且少了多餘的程式碼。

int x; 
x = 10;

測試

這邊我們來寫幾段程式碼,並試著編譯並將結果印出來看有沒有和我們想的一樣。

程式碼ㄧ:

int main() {
    int x = 5, y = 6;
    int z;
    z = 7.5;
    std::cout << "x: " << x << std::endl;
    std::cout << "y: " << y << std::endl;
    std::cout << "z: " << z << std::endl;
    return 0;
}

程式碼二:

int main() {
    int x{5.5};
    std::cout << "x: " << x << std::endl;
    return 0;
}

有注意到什麼嗎?程式碼一應該可以通過編譯,但程式碼二則不會通過。這是為什麼呢?

而在程式碼一中,z印出來的數字是什麼呢?跟你想的一樣嗎?

總結

在這篇文章中,我們了解到什麼是變數,他的用途以及我們該怎麼用它。

在下一章,我們會來討論運算子的概念,然後看看變數和運算子是如何一起運作的!