---
title: C++教室第二節社課
slideOptions: # 簡報相關的設定
theme: blood # 顏色主題
transition: 'slide' # 換頁動畫
parallaxBackgroundImage: 'https://c.wallhere.com/photos/a5/a8/Neon_Genesis_Evangelion_mech_EVA_Unit_13-1319035.jpg!d'
---
C++教室教學講義
===
>[name=Howard] [time=September 18th] [color=#333]
###### tags:`tcirc` `社課`
----
[TOC]
第二節社課
===
----
## 複習時間
----
## 運算式與運算子
運算式由運算元及運算子所組成。運算元可以是常數、變數,運算子就是我們在數學中常見的運算符號( +、-、*、/ )等。
C++里也提供許多的運算子,除了一般的數學運算,還可以做邏輯判斷,是判斷式中不可或缺的角色。
----
## 設定運算子( = )
其實在上節社課就有用到了,雖然作為數學式中的等於符號,但當你在C++中用「等於」去解讀設定運算子可能會讓你吃了大虧。
----
先看看下面這行程式碼。
```c++
num = num + 1
```
變數num怎麼會等於num再加上1。
1=1+1,數學世界崩毀:boom:。
<span>當然沒有。<!-- .element: class="fragment" data-fragment-index="1" --></span>
<span>其實「=」的真正意義在於把後面那項的值賦予(asign)給前項。也就是將num的值加1後再賦予num。<!-- .element: class="fragment" data-fragment-index="2" --></span>
----
## 算術運算子
大家都有小學畢業,不多作介紹。
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQUcKn_fRYPsWlhnhNGlZxNUwIB2t77yWQ8RA&usqp=CAU" width="50%" height="50%" />
----
取餘數可能會比較難理解,如果我讓17對5取餘數,就是讓17除以5之後求餘數的意思。
```c++
cout<<17%5;
```
```
/*OUTPUT---
2
------------*/
```
----
## if判斷與關係運算子
if是我們在做條件判斷時常見的語法,實際用法如下
```c++
if(條件判斷)
敘述;
else if(條件判斷)
敘述;
else
敘述;
```
當if後面的括號內容為真,則程式會執行後段的敘述,and vice versa。
當第一個if判斷不成立時便進入else if的判斷,接著還是不成立時才會執行else所含的敘述。
----
補充: 當然也可以只進行一個判斷就好,後面else if和else的部分視情況使用。(if 和else只能在頭尾,而else if 可以一直疊加)
`p.s: 若程式敘述不只一行,需要用大括號把該串程式碼包住`
```c++
if(條件判斷){
敘述;
敘述;
敘述;
}
```
----
常見的關係運算子如下
<img src="https://gblobscdn.gitbook.com/assets%2F-L_r09305cCOiVsKX4GC%2F-LdbqvVPPV8YTT6nTmP5%2F-Ldbr64OK6YfiRlgsfaW%2F9.2.2.png?alt=media&token=d8b0cfb0-af94-4130-aaf0-71948d26c418" width="100%" height="100%" />
千萬注意!判斷是否等價時是「==」,不要搞錯了!
----
看一下範例程式
```c++=
#include<iostream>
using namespace std;
int main(){
bool a=true,b=false;
int x=3,y=2;
if(a) cout<<"a is true"<<"\n";
if(b) cout<<"b is true"<<"\n";
if(x>y) cout<<"x is bigger than y"<<"\n";
if(y>x) cout<<"y is bigger than x"<<"\n";
}
```
```
/*OUTPUT---
a is true
x is bigger than y
------------*/
```
----
###### 小小提醒:if的判斷只發生在一開始
```c++=
#include<iostream>
using namespace std;
int main(){
int x = 100;
if (x == 100){
x = 50;
cout << x;
}
}
```
```
/*OUTPUT---
50
------------*/
```
----
## 邏輯運算子
邏輯運算子可以幫助我們在多個條件判斷中做邏輯運算
| 邏輯運算子 | 意義 | 邏輯 |
| ---------- | ------- | ---- |
| && | And,且 | 交集(∩) |
| \|\| | Or,或 | 聯集(∪) |
----
練習一下吧~
```c++=
#include<iostream>
using namespace std;
int main(){
int a = -50,b = 75;
if (a > 0&&b > 0) cout << "Full positive!\n";
if (a > 0||b > 0) cout << "Half positive!\n";
if (a > b&&b > a) cout << "How???\n";
if (a == b||(a > 0&&(b <= a||a != b))) cout << "Yes.";
else if (a != b||a-b > a+b) cout << "Ok...";
else cout << "No!";
}
```
----
```
/*OUTPUT---
Half positive!
Ok...
------------*/
```
----
## 迴圈
程式是為了做我們做不到的事---多半是一些很花時間的事。與其一個一個給電腦下指令,利用迴圈(loop)可以使電腦重複執行多次指令,節省程式碼的複雜度。以下介紹幾種常用的迴圈:
----
### for loop
``` c++=
for(INITIALIZATION; CONDITION; AFTERTHOUGHT){
code;
code;
...
}
for(初始化;條件;遞增){
code;
code;
...
}
```
初始化:在迴圈開始前執行的指令。(可作宣告、賦值及各種其他指令)
條件:是一個判斷式,每一次迴圈開始時做判斷,如果回傳為false則結束迴圈。
遞增:每次迴圈結束會執行的指令。
----
#### 各式各樣的for loop :)
```c++=
#include<iostream>
using namespace std;
int main(){
for(int a = 0;a < 5;a++){ //a++ -> a = a + 1
cout << "ayy\n";
}
for(int x = 135,y = 35;y != 0;cout << x << ' ' << y << '\n'){
x = x%y;
swap(x,y); //交換x,y的值
}
for(int q = 5;q >= 0;){
q -= 2;
cout << q << ' ';
}
}
```
----
```
/*OUTPUT---
ayy
ayy
ayy
ayy
ayy
35 30
30 5
5 0
3 1 -1
------------*/
```
----
### while loop
``` c++=
while(CONDITION){
code;
code;
...
}
while(條件){
code;
code;
...
}
```
----
```c++=
#include<iostream>
using namespace std;
int main(){
int n = 4;
while(n){
n--;
cout << n << ' ';
}
int t = 9;
cout << '\n';
while(t--){ //check then decrease
cout << t << ' ';
}
int k = 9;
cout << '\n';
while(--k){ //decrease then check
cout << k << ' ';
}
}
```
----
```
/*OUTPUT---
3 2 1 0
8 7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1
------------*/
```
----
### do-while loop
``` c++=
do{
code;
code;
...
}while(CONDITION);
do{
code;
code;
...
}while(條件);
```
----
```c++=
#include<iostream>
using namespace std;
int main(){
int n = 4;
do{
cout << n;
}while(n == 3);
int m = 4;
while(m == 3){
cout << m;
}
}
```
```
/*OUTPUT---
4
------------*/
```
----
### break/continue
#### break:
直接結束迴圈。
#### continue:
跳過此次迴圈的剩餘程式,直接開始下一次迴圈。
----
```c++=
#include<iostream>
using namespace std;
int main(){
for(int a = 0;a < 10;a++){
if (a == 5) continue;
cout << a << ' ';
}
cout << '\n';
int k = 10;
do{
cout << k << ' ';
k--;
if (k == 7) break;
}while(k >= 5);
}
```
```
/*OUTPUT---
0 1 2 3 4 6 7 8 9
10 9 8
------------*/
```
----
## Switch語法
寫很多if是不是有點累?
```c++=
switch(condition){ //must be integer!!!
case number:{
code;
code;
...
break; //IMPORTANT!!!
}
case number2:{
...
}
default:{
...
}
}
```
用法:檢查condition(必須為整數/char/bool!)的數值,並執行相對應的case。(注意:需要加上break,否則所有下面的case都會執行)
default:當所有case都無法對應時執行。
----
```c++=
#include<iostream>
using namespace std;
int main(){
int k;
cin >> k;
switch(k){
case 75:{
cout << "It's 75!\n";
break;
}
case 76:{
cout << "It's 76!\n";
break;
}
default:{
cout << "I only know 75 and 76...\n";
break;
}
}
}
```
----
```
/*INPUT1---
75
------------*/
/*INPUT2---
76
------------*/
/*INPUT3---
77
------------*/
```
```
/*OUTPUT1---
It's 75!
------------*/
/*OUTPUT2---
It's 76!
------------*/
/*OUTPUT3---
I only know 75 and 76...
------------*/
```
----
##### 把break去掉?
```
/*OUTPUT1---
It's 75!
It's 76!
I only know 75 and 76...
------------*/
/*OUTPUT2---
It's 76!
I only know 75 and 76...
------------*/
/*OUTPUT3---
I only know 75 and 76...
------------*/
```
----
### 補充:二元運算子
```c++=
(condition)?(value1):(value2)
```
當condition成立時,回傳value1,否則回傳value2。
value1,value2要是同一個型別(或可做轉換)。
----
```c++=
#include<iostream>
using namespace std;
int main(){
int k;
cin >> k;
cout << ((k < 0)?k:-k);
}
```
```
/*INPUT1---
1023
------------*/
/*INPUT2---
-888
------------*/
```
```
/*OUTPUT1---
-1023
------------*/
/*OUTPUT2---
-888
------------*/
```
----
##### 多層迴圈範例(九九乘法表)
```c++=
#include<iostream>
using namespace std;
int main(){
for(int a = 1;a <= 9;a++){
for(int b = 1;b <= 9;b++){
cout << a << "*" << b << " = " << a*b << ' ';
}
cout << '\n';
}
}
```
----
```
/*OUTPUT---
1*1 = 1 1*2 = 2 1*3 = 3 1*4 = 4 1*5 = 5 1*6 = 6 1*7 = 7 1*8 = 8 1*9 = 9
2*1 = 2 2*2 = 4 2*3 = 6 2*4 = 8 2*5 = 10 2*6 = 12 2*7 = 14 2*8 = 16 2*9 = 18
3*1 = 3 3*2 = 6 3*3 = 9 3*4 = 12 3*5 = 15 3*6 = 18 3*7 = 21 3*8 = 24 3*9 = 27
4*1 = 4 4*2 = 8 4*3 = 12 4*4 = 16 4*5 = 20 4*6 = 24 4*7 = 28 4*8 = 32 4*9 = 36
5*1 = 5 5*2 = 10 5*3 = 15 5*4 = 20 5*5 = 25 5*6 = 30 5*7 = 35 5*8 = 40 5*9 = 45
6*1 = 6 6*2 = 12 6*3 = 18 6*4 = 24 6*5 = 30 6*6 = 36 6*7 = 42 6*8 = 48 6*9 = 54
7*1 = 7 7*2 = 14 7*3 = 21 7*4 = 28 7*5 = 35 7*6 = 42 7*7 = 49 7*8 = 56 7*9 = 63
8*1 = 8 8*2 = 16 8*3 = 24 8*4 = 32 8*5 = 40 8*6 = 48 8*7 = 56 8*8 = 64 8*9 = 72
9*1 = 9 9*2 = 18 9*3 = 27 9*4 = 36 9*5 = 45 9*6 = 54 9*7 = 63 9*8 = 72 9*9 = 81
------------*/
```
----
## 宣告的規則
宣告變數是寫程式很重要的一件事。其中存在一些規則,必須作注意。
1.變數要在宣告後才能使用。
2.宣告的有效範圍是該宣告所在區塊(block),即{ 和 }之間的範圍。所以綜合第一點:宣告的有效範圍為宣告位置~該block的結束。
3.可在main函式外做宣告(又稱全域宣告),全域宣告的變數可在程式的任意位置使用。
4.for loop的初始化宣告在loop進行時皆可使用。
----
```c++=
#include<iostream>
using namespace std;
char k = 'K';
int main(){
cout << x; //NOT OK
cout << k; //OK
int x = 2096;
cout << x; //OK
for(int a = 0;a <= 5;a++){
x += 1; //OK
x += q; //NOT OK
a += x; //OK
int q;
x += q; //OK
cout << k;//OK
}
a = x; //NOT OK
cout << k; //OK
}
```
----

----
### 解題技巧:多點測資
有些時候,題目會要求不斷讀取資料直到檔案結束(EOF),這個時候可以用一個while loop讀取資料,可是要怎麼偵測檔案結束並跳出迴圈呢?其實當我們輸入資料時,資料會送到cin這個物件中,當cin讀取資料時發現無法轉換的資料(ex:在讀取int時遇到英文字母)或是換行,cin會停止讀取資料,並將讀取到的資料放入目標變數中。下一次cin就從該位置開始。**注意讀取失敗的資料不會消失。**
----
當cin讀取失敗,有許多方法可以偵測:
1.cin.fail():當cin讀取失敗時此函式回傳true。
2.cin.good():當cin讀取失敗時此函式回傳false。
3.cin.eof():與前兩者不同,只有在讀取到EOF時回傳true。
4.cin:cin本身可以轉換成bool,在讀取失敗時會回傳false。
----
```c++=
#include<iostream>
int main(){
using namespace std;
while(1){ //infinite loop
int k;
cin >> k;
if (!cin) break; //version 1
if (cin.fail()) break; //version 2
if (!cin.good()) break; //version 3
if (cin.eof()) break; //version 4
}
}
```
----
## 小試身手~
[b018: 可樂成癮患者](https://judge.tcirc.tw/ShowProblem?problemid=b018)
[b015: 數字的顏色](https://judge.tcirc.tw/ShowProblem?problemid=b015)
[b023: 十二生肖](https://judge.tcirc.tw/ShowProblem?problemid=b023)
[b013: 閏年問題](https://judge.tcirc.tw/ShowProblem?problemid=b013)
挑戰題:[b038: 存量問題](https://judge.tcirc.tw/ShowProblem?problemid=b038)
---