---
tags: 2021CRC Extra Resources
title: 社課額外補充教材:判斷結構
---
# 社課額外補充教材 : 判斷結構
如果你覺得社課還算輕鬆,這裡提供你一些額外的補充教材。
這些是我們在備課的時候覺得稍微進階,或是篇幅太多,而沒有放在正式社課的內容。
---
這邊有目錄,左邊也有,可以跳到自己想看的地方
[TOC]
---
建議必看的地方 :
* 有關switch case (110資訊學科能力競賽筆試有考OAO)
* if - else if結構相關
* 三元運算子(Question mark operator)
---
### 有關 switch case
#### 基本架構
```cpp=
switch(a) //a為變數
{
case b:
//write something
break; //選擇性的
case c,d: //也可像這樣進行多個判斷
//write something
break; //選擇性的
.
.
.
default: //如果其他的都不符合才會執行
}
```
* 注意!b ,c ,d只能放值,不可放條件判斷
* 也不可放變數,規定必須為常數值
#### 這裡的break是用來做甚麼的?
如果沒加break,程式會繼續向下一個case執行
:::spoiler Code
```cpp=
int a = 1;
switch(a){
case 1:
std::cout<<"程式";
case 2:
std::cout<<"會";
case 3:
std::cout<<"走";
case 4:
std::cout<<"完";
case 5:
std::cout<<"這";
case 6:
std::cout<<"些";
case 7:
std::cout<<"地";
case 8:
std::cout<<"方";
case 9:
std::cout<<"才會";
default:
std::cout<<"退出";
}
```
:::
#### 所以這到底能用在哪?
用來代替一堆if else
:::spoiler Code
```cpp=
#include<iostream>
int main(){
char a ;
std::cin>>a;
switch(a){
case '0':
std::cout<<'0';
break;
case '1':
std::cout<<'1';
break;
case '2':
std::cout<<'2';
break;
case '3':
std::cout<<'3';
break;
case '4':
std::cout<<'4';
break;
case '5':
std::cout<<'5';
break;
case '6':
std::cout<<'6';
break;
case '7':
std::cout<<'7';
break;
case '8':
std::cout<<'8';
break;
case '9':
std::cout<<'9';
break;
default:
std::cout<<"Not a number.";
break;
}
}
```
希望你們不會用到這東西
:::
---
### if - else if 結構相關
:::spoiler 來源 :
```cpp=
if (a){
}else{
if (b){
}else{
if (c){
}else{
if (d){
}else{
}
}
}
}
//這和下面的結構是相同的
if (a)
else
if (b)
else
if (c)
else
if(d)
else
//在經過適當的調整後
if(a)
else if(b)
else if(c)
else if(d)
else
```
沒錯,就是所謂的if - else if結構
:::
#### 到底什麼時候要用大括號?
大括號的功用是圈出一個空間,作為變數的作用域
```cpp=
#include<iostream>
int main() {
int* pb; //*pb是指標,先知道能和變數存一樣的值就行了
{
int b;
std::cin >> b;
pb = &b; //將pb指定為b,只要b還在或更動pb也會改變
}
//從這開始不能使用b,但b並未被刪除
std::cout << *pb; //會輸出b的值
}
```
而同時,他也會將其中的執行式包含在該作用域之中
if只會執行他下一行的函式或作用域
```cpp=
int a = 1;
if (a == 1)
std::cout<<"a==1";
else
std::cout<<"a!=1"; //這句不會被執行
std::cout<<"這句並不在else裡面,所以會被執行";
```
在上面的例子中,第三個cout並不在else裡,但程式碼的縮排會讓人誤認
所以記得在寫程式時依據不同的作用域縮不同的排
```cpp=
int a = 1;
if (a == 1)
std::cout<<"a==1";
else
std::cout<<"a!=1"; //這句不會被執行
std::cout<<"這句並不在else裡面,所以會被執行";
```
這樣就很清楚了
那如果要讓它包含在裡面就必須創建新的作用域,並掛在else後面
也就是常見的
```cpp=
if(a == 1){
std::cout<<"a==1";
}
else{
std::cout<<"a!=1";
std::cout<<"這句在else裡面,所以不會被執行";
}
```
#### 禁忌
以下是一些容易造成錯誤的用法
1. 在大括號(尤其是if條件判斷中)宣告變數
```cpp=
int a = 1;
if(a == 1){
int b = 1;
}
std::cout << b; //會出現錯誤
//當然,如果只在大括號範圍內使用就沒關係
```
2. 在 if/else/else if後加上';'
這是因為C++會以分號來判斷執行式,這樣容易出錯
```cpp=
if(true);
std::cout<<"這並不在if裡面";
else
//這會出現錯誤,上面會說else找不到if
if(true)
std::cout<<"目前正常";
else;
std::cout<<"這不在else中,所以會被執行";
```
#### 有關編排的常見方式
程式是寫給人看的,只要能讓人看得懂就沒關係
:::spoiler 1. 全部換行
```cpp=
if(a)
{
}
else
{
} //這最為工整但也有點占視覺上的空間
```
:::
:::spoiler 2. 半換行
```cpp=
if(a){
}
else{
}
```
:::
:::spoiler 3. 不換行
```cpp=
if(a){
}else{
} //這應該是最常看到的縮排,只是會有點擠
```
:::
有關只有一行程式碼的縮排
* 可以考慮省略大括號
```cpp=
if(a%2==0)
std::cout<<"a是偶數";
else
std::cout<<"a是奇數";
```
* 如果沒有else,也可以寫在同一行
```cpp=
if(a%2==1) a--;
```
---
### 三元預算子進階使用
如果你想要在三元運算子裡面多做點事,你可能會需要用到逗號的運算,像這樣 :
```cpp=
#include <iostream>
using namespace std;
int main() {
int a;
int b = 100;
cin >> a;
cout << (a%2 ? (b+1, a/2) : (b+2, a+1)) << " " << b << endl;
}
```
* 首先,因為逗號運算的關係,雖然命令都有被執行,但是程式的輸出結果會是**後面那一項**。
後面關於逗號運算子會有更詳細的說明,這邊以下面的 Code 來說明
```cpp=
#include <iostream>
using namespace std;
int main() {
int a;
int b = 100;
cin >> a;
cout << (a%2 ? (b+1, a/2) : (b+2, a+1)) << " " << b << endl;
//三元運算的部分會輸出 a/2 or a+1,而不是 b+1 or b+2
}
```
* **請注意,逗號運算的優先度低於三元運算子**,所以你如果不括號起來,最後一個命令就不會是在else裡面,而是**一定會執行**。以下面的 Code 來說明
```cpp=
#include <iostream>
using namespace std;
int main() {
int a;
int b;
cin >> a;
cout << (a%2 ? (b = 1, a/2) : b = 2, a+1) << " " << b << endl;
//那個a+1一定會執行,因為它不算在三元運算裡面(優先度問題)
}
```
請參閱:
[Microsoft Doc](https://docs.microsoft.com/zh-tw/cpp/cpp/conditional-operator-q?view=msvc-160)
---
### 一元運算子
#### 種類
一元運算子的數量並沒有很多,而且大部分都很直覺
* \+ 會回傳參數的值
* \- 會回傳參數的2的補數(負的參數)
* ~ 會回傳參數的1的補數(負的參數-1)
* ! 會回傳相反的布林值
#### 使用範例
```cpp=
#include<iostream>
int main(){
int a = 5;
std::cout << +a << ' ' << -a << ' ' << ~a << ' ' << !a;
//結果為 5 -5 -6 0
//第四個會是0的原因為5是真,所以相反的是假,也就是0
}
```
---
### 逗號運算子(Comma operator)
逗號運算子比較特別,他和計算或條件判斷沒什麼關係
它的功用在於將多個執行式結合
#### 基本架構
```cpp=
執行式1, 執行式2
//當然也可以像下面那樣多加幾個
(執行式1, 執行式2, 執行式3)
//通常會用小括號括起來
```
會從左到右執行,並回傳最右邊的回傳值
其他的回傳值都會被捨棄,可以用來簡化程式
###### tags: 要記住不可在逗號運算子內宣告變數,會出現語法錯誤
#### 使用範例
```cpp=
#include<iostream>
int main(){
int a;
//std::cin>>a;
///std::cout<<a;
std::cout << ( std::cin >> a, a);
//等同上面註解的部分
//他先將std::cin>>a執行後把回傳的cin丟掉
//再執行a,這動作會回傳a的值,而逗號運算子就會回傳a
}
```
也可以這樣做
```cpp=
#include<iostream>
int main(){
int a;
//std::cin>>a;
//a++;
///std::cout<<a;
std::cout << ( std::cin >> a, a++, a);
//等同上面註解的部分
//會輸出輸入的數字+1
}
```
猜猜看會回傳什麼
```cpp=
#include<iostream>
int main(){
int a;
std::cout << (a = 99, a++, a*100, a+100);
}
```
答案是2\*2\*2\*5\*5,因為在中間的值如果沒被保留下來就會被丟掉
請參閱:
[Microsoft Doc](https://docs.microsoft.com/zh-tw/cpp/cpp/comma-operator?view=msvc-160)