Lecture 6-2: Array & String (1)
What is Array?
將一個變數能夠儲存多個值,並且用數字進行編號 (index) 並且利用數字存取 (i.e. random access)

Fibonacci number
$$ \begin{align} F_0 &= 0 \\ F_1 &= 1 \\ F_n &= F_{n-1} + F_{n-2}, n \ge 2 \end{align}$$
Modified from fibonacci-time-analysis/fib.cpp at master · christopher-siewert/fibonacci-time-analysis (github.com)
#include <iostream>
int main()
{
int n = 0;
std::cout << "fib number: ";
std::cin >> n;
unsigned long long int f[100000]; /// array for values
f[0] = 0;
f[1] = 1;
/// Loop from 2 to n
for (int i = 2; i <= n; i++)
{
f[i] = f[i - 1] + f[i - 2]; /// Equals sum of previous 2
}
std::cout << f[n] << std::endl;
return 0;
}
character array (C String)
Credit: htchen/i2p-nthu by 陳煥宗老師
#include <iostream>
#include <iomanip>
#include <cstring>
int main(void)
{
float minutes, distance;
const float SPEED = 0.083;
int size, letters;
char name[10];
std::cout << "Hi! What's your first name? ";
std::cin >> name;
std::cout << std::endl
<< name
<< ", how many minutes does it take to walk from"
<< std::endl;
std::cout << "your dormitory to the CS building? ";
std::cin >> minutes;
size = sizeof(name);
letters = strlen(name);
distance = minutes * SPEED;
std::cout << std::endl
<< "The distance from your dormitory to the CS building"
<< std::endl;
std::cout << "is about "
<< std::setprecision(3) << distance
<< " kilometers.\n\n";
std::cout << "By the way, your first name has "
<< letters
<< " letters,\n";
std::cout << "and we have "
<< size
<< " bytes to store it in.\n";
return 0;
}
我們來看看這個程式做了哪些事情以及用到了哪些新的東西。 執行這個程式會得到類似下面的結果:
$ ./a.out
Hi! What's your first name? Stevie⏎
Stevie, how many minutes does it take to walk from
your dormitory to the CS building? 10⏎
The distance from your dormitory to the CS building
is about 0.83 kilometers.
By the way, your first name has 6 letters,
and we have 10 bytes to store it in.
程式先用 std::cout 顯示訊息,詢問使用者的名字,然後用 std::cin 來讀取使用者輸入的 "字串",把字串儲存在變數name 裡面。
再來就可以用儲存起來的字串稱呼使用者,並且問一個簡單的問題,再把計算結果顯示在螢幕上。
程式裡面用到的新東西首先是 #include <cstring>。
回想當初程式需要 #include <iostream> 是因為要用到 std::cout,同樣地,引入 cstring 是為了要用到其中相關的 function,在這個例子用到的是 strlen() 這個 function,它可以計算字串變數裡面所儲存的字串的長度。
傳入的參數是字串,傳回的整數值就是字串長度,以 Stevie 為例,長度是 6。
字串其實是靠所謂的character array 來儲存。
char name[10];
表示 name 會佔用到十個 bytes 的記憶體,等於是有十個空位,每個空位的大小是一個 byte,每個 byte 的空間可以存放一個字元。
字元陣列 character arrays 與字串
| S | t | e | v | i | t | \0 |
|---|
字串裡的字元必須連續地存放在記憶體中,所以剛好可以用陣列來儲存,因為陣列就是一連串的記憶體空間。字元陣列的每一格空間可以存放一個字元 (char),當我們宣告 char name[10]; 表示要保留十格空間存放十個字元,每一格可以容
納一個 char 型別的資料。當然除了 char 之外,也可用其他型別如 int 來宣告陣列,目前我們先專心探討字元陣列。為了標記整個字串究竟在哪裡算是結尾,c++ 語言使用一個特殊的字元 \0 來表示字串結尾。字元 \0 對應到的 ASCII 值是 0。我們也可以用整數 0 來代替字元 \0,但為了有所區別,當字元使用時最好寫成 \0。
宣告一個字元變數和宣告一個陣列的差別可以用下圖來表示。
char ch; // 佔用一個 byte,型別為 char
char name[10]; // 佔用十個 bytes,型別為 char
宣告陣列產生一個可以容納十個字元的 array,準備用來記錄使用者輸入的字串 (使用者的名字)。
因為要保留一格給 \0 字元來標示字串結尾,所以其實真正能用來記錄的人名長度,最多只能包含九個字元。
如何把字串存入陣列中呢?在前面的例子裡用的方法是 std::cin >> name; 讀取使用者輸入的字串。
參數 name 就是要存放字串的陣列名稱,這個名稱所代表的意義是整個字串的開頭位址。
因此 std::cin就能由 name 找到陣列開頭位址,一格一格把字元填進去,而且會自動在最後加上 \0 當作結束。
再回到範例,裡面用到 sizeof,它可以計算型別 (譬如 sizeof(float)) 或資料 (譬如 sizeof(name) 或 sizeof("Stevie")) 的 byte 數。
若把它用在宣告過的陣列上,它會告訴我們陣列有多少個bytes,如果是 char name[10]; 就是 10 bytes。另外 #include <cstring> 是為了用 strlen() 這個 function,它是針對字串而設計的function,可以算出字串長度。
字串長度是靠 \0 來界定,所以如果把某個字串當參數傳給 strlen(),它就會一個字元一個字元地數,直到遇到 \0'就停下來,然後回報字串長,看看底下例子中的差異:
#include <iostream>
#include <cstring>
int main(void)
{
std::cout << "The length of string is "
<< strlen("Stevie")
<< ", but "
<< sizeof("Stevie")
<< " bytes are occupied.\n";
return 0;
}
Reference: