千層麵

千層麵

學習練習

簡介

基礎

為了展開 C++ 之旅,我們先從變數、函式呼叫和註解開始吧。

註解

註解有兩種:單行和多行。 同一行中//之後的所有內容都會被編譯器忽略。 多行註解又稱為 C 風格註解。 它們以/*和*/包圍。 介於兩者之間的任何內容也同樣會被忽略。

變數

C++ 是一種具有型別的語言。 所有型別都必須在編譯時期確定,而且通常需要明確寫出來。 變數的型別無法改變。 名為years的整數變數可以像這樣宣告:

int years;

在宣告變數時就一併初始化是好習慣。 C++ 提供了幾種不同的機制來這麼做。 使用大括號的版本比較符合現代 C++ 的寫法,不過用等號的版本也很常見。

int tomatoes{80};
int potatoes = 40;
Caution

C++ 確實允許使用未初始化的變數。 在變數被刻意設定之前,它的值是未定義的,可能包含任何內容。 為了避免「使用前未設定」的錯誤和未定義行為,建議一定要初始化。 未定義行為可能會在最糟糕的時刻讓程式當掉,即使它先前運作得好好的。 再怎麼強調都不為過:務必不惜一切代價避免未定義行為。

算術運算

像*、+或-這類算術運算子,可以成為3 * 2或tomatoes + potatoes這類運算式的一部分。

更新變數

只要型別維持不變,你就可以重新指定變數的值:

tomatoes = tomatoes - 5; // tomatoes is now 75
potatoes = (32 * 2) + 11; // potatoes is now 75 as well

函式

函式有名稱、回傳型別,以及(可能為空的)參數列表。 以下是一個名為always_fortyseven的函式範例,它總是回傳 47,看起來會像這樣:

int always_fortyseven() {
    return 47;
}

這裡是vip_fee,它有一個參數:

int vip_fee(int standard_fee) {
    /*
    vip_fee calculates the vip fee based on the standard_fee.
    */
    int vip_multi{3};
    return standard_fee * vip_multi;
}

或是total_fee,一個有三個參數、並會呼叫另一個函式的函式。

int total_fee(int vips, int adults, int kids) {
    /*
    total_fee calculates the total price for a group of VIP and adult guests with kids.
    Kids get a flat discount on the standard fee.
    VIP guest fees are calculated by calling vip_fee.
    */
    int standard_fee{30};
    int kids_discount{15};

    int kids_total_fee = kids * (standard_fee - kids_discount);
    int vips_total_fee = vips * vip_fee(standard_fee);
    int adult_total_fee = adults * standard_fee;

    return vips_total_fee + adult_total_fee + kids_total_fee;
}

C++ 的函式不像某些其他語言那樣,會回傳最後一個敘述的值。 程式碼必須要有return關鍵字才能編譯。

空白

空白用於格式化原始碼,包含空格、定位字元或換行。 由於編譯器會忽略多餘的空白,你可以用它來編排程式碼的結構。 聰明地運用空白可以提升程式碼的可讀性。 格式化的標準有很多種,但這些都只是慣例,編譯器並不會強制要求。

// Formatting makes it easier to find bugs

int eggs_yolks =  3;
int      yeast = 15;

int flour=500;int sugar=200;// compact, but difficult to read

說明

Lucian 的女友正在回家的路上,而他還沒煮好他們的週年紀念晚餐!

在這個練習中,你將寫一些程式碼,幫助 Lucian 依照他最愛的食譜書做出精緻的千層麵。

你有四項任務,全都和烹煮千層麵所花費的時間有關。

1. 定義預期的烘烤時間(分鐘)

定義ovenTime()函式,它不接受任何引數,並回傳千層麵應該待在烤箱裡幾分鐘。 根據食譜書,預期的烘烤時間是 40 分鐘:

ovenTime();
// => 40

2. 計算剩餘的烘烤時間(分鐘)

定義remainingOvenTime(int actualMinutesInOven)函式,它接受千層麵已經待在烤箱裡的實際分鐘數作為引數,並根據上一項任務預期的烘烤時間(分鐘),回傳千層麵還需要在烤箱裡待幾分鐘。

remainingOvenTime(30);
// => 10

3. 計算準備時間(分鐘)

定義preparationTime(int numberOfLayers)函式,它接受你加到千層麵裡的層數作為引數,並回傳你準備千層麵花了幾分鐘,假設每一層需要花 2 分鐘準備。

preparationTime(2);
// => 4

4. 計算經過時間(分鐘)

定義elapsedTime(int numberOfLayers, int actualMinutesInOven)函式,它接受兩個引數:第一個引數是你加到千層麵裡的層數,第二個引數是千層麵已經待在烤箱裡的分鐘數。這個函式應該回傳你烹煮千層麵總共花了幾分鐘,也就是準備時間(分鐘)加上千層麵目前為止待在烤箱裡的分鐘數。

elapsedTime(3, 20);
// => 26
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
C++ Exercism

準備好開始 千層麵 了嗎?

註冊 Exercism,透過 19 個概念100 個練習 和真人引導來學習並精通 C++,全部免費。