C++ 課程 [1]

講師介紹

  • 張庭瑋
  • 建中資訊 35 屆學術

條件判斷

if 判斷式

#include <iostream>
using namespace std;
int main(){
    int a;
    cin >> a;
    if(a<0){
        cout << "ERROR\n";
    }
    else if(a>=60){
        cout << "PASS\n";
    }
    else{
        cout << "FAIL\n";
    }
    return 0;
}

if

if(A){
    B;
}

如果 A 成立的話 就執行 B

else if

if(A){
    B;
}
else if(C){
    D;
}

如果 A 成立的話 就執行 B
否則
如果 C 成立的話 就執行 D

else

if(A){
    B;
}
else{
    E;
}

如果 A 成立的話 就執行 B
否則執行 E

可以混搭

if(A){
    B;
}
else if(C){
    D;
}
else if(E){
    F;
}
else{
    G;
}

如果 A 成立的話 就執行 B
否則
如果 C 成立的話 就執行 D
否則
如果 E 成立的話 就執行 F
否則執行 G

現在應該能看得懂這個 code 在幹嘛了吧

#include <iostream>
using namespace std;
int main(){
    int a;
    cin >> a;
    if(a<0){
        cout << "ERROR\n";
    }
    else if(a>=60){
        cout << "PASS\n";
    }
    else{
        cout << "FAIL\n";
    }
    return 0;
}

switch 判斷式

switch(A){
    case 1: //A==1
        B;
        break;
    case 4: //A==4
        C;
        break;
    default: //A!=1 && A!=4
        D;
}

switch

判斷 A 這個東西的長相
A=1 的話執行 B
A=4 的話執行 C
其他狀況執行 D

switch(A){
    case 1: //A==1
        B;
    case 4: //A==4
        C;
        break;
    default: //A!=1 && A!=4
        D;
}

break


要記得 break; 否則他會繼續走到下一個
例如這段會變成 A=1 的話執行 B 跟 C
A=4 的話執行 C
其他狀況執行 D

補充:三元運算子

(X)?Y:Z

如果 X 成立的話 就執行 Y
否則執行 Z

也可以長得像這樣

a=(X)?Y:Z

只要 Y 跟 Z 型態相同且 X 是邏輯式就可以

迴圈

for

#include <iostream>
using namespace std;
int main(){
    for(int i=0;i<=5;i++){
        cout << i << " ";
    }
    cout << "\n";
    return 0;
}

print: 0 1 2 3 4 5

for

for(A; B; D){
    C;
}

1. 一開始會執行 A
2. 不斷重複:判斷 B 是不是正確的,如果是正確的就執行 C,然後執行 D
 

注意事項

1. 中間是用分號隔開
2. 有些人會這樣寫:
這樣的好處是比較省時,壞處是容易造成閱讀困難

for(A; B; D) C;

continue

for(A;B;D /*continue to here*/){
    if(E){
        continue;
    }
    C;
}

 continue 代表直接跳到 D

break

for(A;B;D){
    if(E){
        break;
    }
    C;
}
//break to here

break 代表跳出迴圈之外

while

#include <iostream>
using namespace std;
int main(){
    int i=0;
    while(i<10){
        cout << i << " ";
        i++;
    }
    cout << "\n";
    return 0;
}

print: 0 1 2 3 4 5 6 7 8 9

while

while(A){
    B;
}

不停重複:檢查 A 是不是對的,如果是就執行 B
whlie 迴圈也可以用 continue 跟 break

do while

#include <iostream>
using namespace std;
int main(){
    int i=0;
    do{
        cout << i << " ";
        i++;
    }while(i<10);
    cout << "\n";
    return 0;
}

print: 0 1 2 3 4 5 6 7 8 9

do whlie

本質上跟 while 幾乎一樣

只是會先執行一次裡面的東西再判斷

無窮迴圈

while(1){
    //do something
}

不停執行一個動作
記得要 break 否則程式會無限運行下去直到當機

多重迴圈

#include <iostream>
using namespace std;
int main(){
    for(int i=1;i<=9;i++){
        for(int j=1;j<=9;j++){
            cout << i*j << " ";
        }
        cout << "\n";
    }
    cout << "\n";
    return 0;
}
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 

題單

陣列

array

就是一個連續的記憶體區域

array

#include <iostream>
using namespace std;
int main(){
    int a[10]={0};
    for(int i=0;i<10;i++){
        cin >> a[i];
    }
    return 0;
}

陣列從 0 開始,大小為宣告好的正整數
假設是 int a[n] 代表陣列是 a[0] ~ a[n-1]

初始化

#include <iostream>
 
using namespace std;
 
int main() {
    int a[] = {0,1,2,3,4,5,6,7,8,9};
    int b[10] = {0,1,2,3,4,5,6,7,8,9};
    int c[10] = {0};
 
    int d[10];
    cout << d[4] << '\n'; // what will happen here?
 
    int e[] = {0};
}

print: something strange

陣列的東西在初始化之前都是不確定的

多重陣列

#include <iostream>
using namespace std;
int main(){
    int b[10][10]={0};
    int c[5][4][3][19];
    //...
    return 0;
}

用變數當陣列大小

#include <iostream>
using namespace std;
int main(){
    int n;
    cin >> n;
    int a[n];
    return 0;
}

盡量不要這樣用
能當陣列大小的只有數字跟 const int

其他酷酷的方法

#include <iostream>
#include <cstring>
#include <numeric>
using namespace std;
int main(){
    int a[100];
    fill(a,a+100,0);
    memset(a,0,sizeof(a)); // 需 include <cstring>
    iota(a,a+100,0); // 需 include <numeric>, 用來將陣列設為 0,1,2,3,...
    return 0;
}

題單

AtCoder Problems
基本上 ABC 前三題大部分用今天教的概念就可以過了
ZJ 的基礎題庫上面也有很多

函式

function

#include <iostream>
using namespace std;

int f(int x){
    return x*x; 
}
int main(){
    int a=f(2);
    cout << f(4)+f(5) << "\n";
    return 0;
}

function

需要有函式名稱 傳入引數 回傳型態

缺一不可

傳回型態 函式名稱(傳入引數){
	//do something
}

函式名稱

  • 跟變數名稱遵循一樣的限制
  • 但是可以允許重複命名,只要傳入引數不同即可
#include <iostream>
using namespace std;

int add(int x,int y){
    return x+y;
}
int add(int x,int y,int z){
    return x+y+z;
}
int main(){
    cout << add(2,3) << " " << add(3,4,50) << "\n";
    return 0;
}

print: 5 57

傳入引數

  • 必須是變數
  • 可以有多個

回傳型態

  • 跟變數型態類似
  • 有一個特殊的型態是 void
    在不回傳任何東西時使用
#include <iostream>
using namespace std;

int cnt=0;
void add(){
    cnt++;
}
int main(){
    add();
    add();
    cout << cnt << "\n";
    return 0;
}

傳入的東西是被複製的

#include <iostream>
using namespace std;

int cnt=0;
void swap(int x,int y){
    int z=x;
    x=y;
    y=z;
}
int main(){
    int a=1;
    int b=2;
    swap(a,b);
    return 0;
}

print: 1 2

想要讓他傳進去的東西是一樣的話
有個語法叫參考 (reference) 可以去查看看

函式可以完全不使用 只是可能會使整支程式長度暴增

適當使用可以減少撰寫時間

實作時間:井字遊戲

#include <bits/stdc++.h>
using namespace std;

int main(){
    int board[3][3]={0};
    int nowplayer=1;
    int tie=1;
    int empty=9;
    while(1){
        if(empty==0){
            break;
        }
        cout << "Player " << nowplayer << "\'s turn\n";
        cout << "Please input your choice (X: 1 to 3, Y: 1 to 3)\n";
        int x,y;
        cin >> x >> y;
        x--;
        y--;
        if(x<0 || x>2 || y<0 || y>2){
            cout << "Error: Invalid input\n";
            continue;
        }
        if(board[x][y]!=0){
            cout << "Error: your choice is occupied\n";
            continue;
        }
        board[x][y]=nowplayer;
        nowplayer=3-nowplayer;
        empty--;
        cout << "-------\n";
        for(int i=0;i<7;i++){
            if(i%2==0){
                cout << "-";
            }
            else{
                if(board[0][i/2]==0){
                    cout << " ";
                }
                else if(board[0][i/2]==1){
                    cout << "X";
                }
                else{
                    cout << "O";
                }
            }
        }
        cout << "\n";
        cout << "--+-+--\n";
        for(int i=0;i<7;i++){
            if(i%2==0){
                cout << "-";
            }
            else{
                if(board[1][i/2]==0){
                    cout << " ";
                }
                else if(board[1][i/2]==1){
                    cout << "X";
                }
                else{
                    cout << "O";
                }
            }
        }
        cout << "\n";
        cout << "--+-+--\n";
        for(int i=0;i<7;i++){
            if(i%2==0){
                cout << "-";
            }
            else{
                if(board[2][i/2]==0){
                    cout << " ";
                }
                else if(board[2][i/2]==1){
                    cout << "X";
                }
                else{
                    cout << "O";
                }
            }
        }
        cout << "\n";
        cout << "-------\n";
        int whowin=0;
        for(int i=0;i<3;i++){
            if(board[i][0]==board[i][1] && board[i][0]==board[i][2] && board[i][0]!=0){
                whowin=board[i][0];
                break;
            }
        }
        for(int i=0;i<3;i++){
            if(board[0][i]==board[1][i] && board[0][i]==board[2][i] && board[0][i]!=0){
                whowin=board[0][i];
                break;
            }
        }
        if(board[0][0]==board[1][1] && board[0][0]==board[2][2] && board[0][0]!=0){
            whowin=board[0][0];
        }
        if(board[0][2]==board[1][1] && board[0][2]==board[2][0] && board[0][2]!=0){
            whowin=board[0][2];
        }
        if(whowin!=0){
            cout << "Player " << whowin << " wins!\n";
            tie=0;
            break;
        }
    }
    if(tie){
        cout << "Tie!" << "\n";
    }
    return 0;
}

C++ 課程 [1]

By alvingogo

C++ 課程 [1]

  • 522