Loops

黃祥陞 @Sprout 2024 C/C++語法班

Modified from @Sprout 2021 & 2023

直接上菜

       #
      ##
     ###
    ####
   #####
  ######
 #######
########

範例

  • 輸入
3
  • 輸出
  #
 ##
###

範例

  • 輸入
5
  • 輸出
    #
   ##
  ###
 ####
#####

如果這樣做...

int n;
std::cin >> n;

if (n == 3) {
	std::cout << "  *" << std::endl
    		  << " **" << std::endl
                  << "***" << std::endl;
} else if (n == 5) {
	std::cout << "    *" << std::endl
    		  << "   **" << std::endl
                  << "  ***" << std::endl
                  << " ****" << std::endl
                  << "*****" << std::endl;
}

如果這樣做...

怎麼處理?

  • 輸入
6
  • 輸出
     #
    ##
   ###
  ####
 #####
######

Review

判斷一下輸入的數字是不是偶數

#include <iostream>
using namespace std;
int main () {
    int input;
    cin >> input;
    if (input % 2) {
        cout << input << " is odd\n";
    }
    else {
        cout << input << " is even\n";
    }
}

簡單啦

輸出 1~9 裡面的 3 的倍數

???

#include <iostream>
using namespace std;
int main () {
    cout << "3 6 9\n";
}

輸出 1568963~48978451 裡面的 45631 的倍數?

#include <iostream>
using namespace std;
int main () {
    if (!(1568963 % 45631)) {
        cout << "1568963\n";
    }
    if (!(1568964 % 45631)) {
        cout << "1568964\n";
    }
    if (!(1568965 % 45631)) {
        cout << "1568965\n";
    }
    if (!(1568966 % 45631)) {
        cout << "1568966\n";
    }
    /* ... */
}

??????????

While Loop

while (/* condition */) {
  /* body */
}
當 (/* 條件為真 */) {
  /* 執行程式 */
}

While Loop

e.g. 印出 1 到 10

int i = 1;
while (i <= 10) {
  std::cout << i << std::endl;
  i++;
}

While Loop

e.g. 算出 1~100 的偶數和

int i = 2;
int sum = 0;

while (i <= 100) {
  sum += i;
  i += 2;
}

std::cout << sum << std::endl;

While Loop

e.g. 計算輸入是幾位數

int input, cnt = 0;
cin >> input;

while (input) {
  input /= 10;
  cnt++;
}

std::cout << cnt << std::endl;

While Loop

注意事項:終止條件

int i = 1;
while (i <= 100) {
  std::cout << i << std::endl;
}
int i = 1;
while (i > 0) {
  std::cout << i << std::endl;
  i++;
}

While Loop

無窮迴圈

while (true) {
  /* run forever */
}
while (1) {
  /* run forever */
}

While Loop

注意事項:生命週期

int cnt = 0;

while (cnt < 5) {
  int i = 0;
  cnt++;
}

cout << i << '\n'; // error

生命週期的概念也適用於迴圈喔!

每次迴圈宣告的 i 在該輪結束後就不再可用了

Do-While Loop

do {
  /* body */
}
while (/* condition */);

先執行 body,再判斷 condition

Do-While Loop

e.g. for do-while

int answer = 127;
int number = 0;

do {
  std::cout << "Enter a number" << std::endl;
  std::cin >> number;
}
while (number != answer);

std::cout << "number is 127" << std::endl;

Do-While Loop

While vs. Do-While

For Loop

for (/* init */; /* condition */; /* update */) {
  /* body */
}
  1. 先執行 init
  2. 檢查 condition 是否成立
  3. 執行 body
  4. 做更新 update
  5. 重複 condition body update  

離開迴圈

break: 常見寫法

while (/* condition */) {
  /* body */
  if (/* another condition */)
  	break;
}

使用 break 離開當前的迴圈

離開迴圈

break: 範例

int answer = 127;
int guess;
while (true) {
  std::cout << "Enter a number" << std::endl;
  std::cin >> guess;
  if (guess == answer) {
    std::cout << "You've got it!" << std::endl;
    break;
  } else {
    std::cout << "Wrong..." << std::endl;
  }
}

繼續迴圈

continue: 常見寫法

while (/* condition */) {
  /* body 1 */
  if (/* another condition */)
  	continue;
  /* body 2 */
}

使用 continue 跳過 body 2,直接進入下一次迴圈

繼續迴圈

continue: 範例

int a = 0;
int b = 0;
while (true) {
  std::cin >> a >> b;
  if (b == 0)
    continue;
  std::cout << "a / b = " << a / b << std::endl;
}

Nested Loop

範例:99乘法表

int i = 1;
while (i < 10) {
  int j = 1;
  while (j < 10) {
    std::cout << i << " * " << j << " = " << i * j << " ";
    j++;
  }
  std::cout << std::endl;
  i++;
}

Back to Mario

  • 輸入
3
  • 輸出
  #
 ##
###

觀察:當輸入為     時,總共會有     層

n
n

聯想到用迴圈執行     次

n

Back to Mario

int n;
std::cin >> n;

int i = 1;
while (i <= n) {
  /* 印出第i層 */
  i++;
}

第一個步驟:用一個執行     次的迴圈來印出每一層

n

下一個步驟:在每一次的迴圈內,印出那一層

Back to Mario

  • 第一層
  #
  • 第二層
 ##
  • 第三層
###

觀察:在第     層,有     個#,以及                個空白在前面

用一個                 次的迴圈印出空白

接著用     次的迴圈印出#

i
n-i
n-i
i
i

Back to Mario

int j = 0;
while (j < n - i) {
  std::cout << " ";
  j++;
}
j = 0;
while (j < i) {
  std::cout << "#";
  j++;
}
std::cout << std::endl;

第二個步驟:利用迴圈印出第     層 

下一個步驟:將前後兩個部分連接

i

Back to Mario

int n;
std::cin >> n;

int i = 1;
while (i <= n) {
  int j = 0;
  while (j < n - i) {
    std::cout << " ";
    j++;
  }
  j = 0;
  while (j < i) {
    std::cout << "#";
    j++;
  }
  std::cout << std::endl;
  i++;
}

執行了幾次?

int n = 10;
while (n--) {
  std::cout << n << std::endl;
}
int n = 10;
while (--n) {
  std::cout << n << std::endl;
}

課堂練習

Sprout 2024 Loops

By gtcoding

Sprout 2024 Loops

  • 26