PJ高一資訊上機考講義

(by林修民&賴竑斌)

1. 基本程式碼

#include <bits/stdc++.h>           //一個個標頭檔記太麻煩,而且記錯就完蛋,直接含入萬用標頭檔<bits/stdc++.h>就好
using namespace std;               //使用命名空間std,如果你只是要上機考,你不用知道他什麼意思,只要記得這東西不能少
int main()                         //宣告主函式
{                                  //多行的程式大括號一定要記得加,每行記得加分號
    ios_base::sync_with_stdio(false);     //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                           //cin IO加速
    cout << "字串巴拉巴拉" << endl;        //輸出<<跟<<中間的東西,endl為換行+印出來,等同於cout << '\n' << flush;
    cout << '\n';                         //輸出換行字元
    cout << flush;                        //在c++中,cout的東西不會馬上被印出來,而是先存在緩衝區,flush的用意就是清空緩衝區,通通印出來
    return 0;                             //主函式回傳0,很重要,絕對不能少
}                                  //下面的大括號記得也要加

2. 進階輸出

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    cout << setprecision(n) << /*要輸出的東西*/ ;                //輸出d取n位數字
    cout << fixed << setprecision(n) << /*要輸出的東西*/ ;       //輸出d到小數點以下n位
    (char)(/*ACSII字元碼*/)            //表示該字元碼所表示的字元
    '字元'                             //表示該字元的ACSII碼

3. 變數與運算子

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    int t;                                 //宣告int變數t
    int m=3,n=4;
    double d;                              //宣告double變數(有小數的)
    long long b;                           //宣告long long變數b,通通宣告long long也沒關系,不會爆
    int a[t];                              //宣告有n項的int陣列a,第i項為a[i-1]
    int c[m][n]={{1,2,3,4},                //宣告m橫行、n直列的二維陣列c,第i行第j個為c[i-1][j-1]
                 {5,6,7,8},
                 {9,10,11,12}};
    //(條件判斷式 ? A : B)                    代表若條件判斷成立,此行就是A,反之則為B
    //(條件判斷式1 ? A : 條件判斷式2 ? B : C)  代表若條件判斷1成立,此行就是A,反之則判斷條件2,成立的話就是B,反之就是C
    
    n++;                               //將n+1
    n+=t;                              //將n加上t
    sqrt(n)                            //表示n的平方根
    abs(n)                             //表示n的絕對值
    __gcd(m,n)                         //表示m,n的最大公因數
    floor(d)                           //表示d的無條件捨去(d須為浮點數),floor(d)為浮點數
    round(d)                           //表示d的四捨五入(d須為浮點數),round(d)為浮點數
    ceil(d)                            //表示d的無條件進位(d須為浮點數),ceil(d)為浮點數
    return 0;
}

4. 條件判斷

1. if

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    if(條件1)                              //若條件1成立,執行程式碼1,否則判斷條件2,成立就執行程式碼2,否則執行程式碼3
    {
        /*程式碼巴拉巴拉1*/
    }
    else if(條件2)
    {
        /*程式碼巴拉巴拉2*/
    }
    else
    {
        /*程式碼巴拉巴拉3*/
    }
    return 0;
}

2. switch條件判斷

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    int n;
    switch(n)                              //注意!!switch時,case裡的多行不用加{}
        case 1:                            //如果n=1,執行程式碼1
        /*程式碼1*/
        break;
        case 2:                            //如果n=2,執行程式碼2
        /*程式碼2*/
        break;
        case 5:                            //如果n=5,執行程式碼3
        /*程式碼3*/
        break;
        default:                           //如果n!=1,2,5,執行程式碼4
        /*程式碼4*/
        break;
    return 0;
}

5. 迴圈

1. while

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    while(條件判斷)                        //若條件成立就一直反覆執行直到條件不成立為止
    {
        /*程式碼*/
    }
    return 0;
}

2. do while

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    do                        //先執行一次,之後若條件成立就一直反覆執行直到條件不成立為止
    {
        /*程式碼*/
    }while(條件判斷);
    return 0;
}

3. for

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    for(/*單句程式碼A*/;1條件判斷;/*單句程式碼B*/)
    {
        /*程式碼C*/
    }
    return 0;
}

等同於

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    /*單句程式碼A*/
    while(條件判斷)
    {
        /*程式碼C*/
        /*單句程式碼B*/
    }
    return 0;
}

6. 執行n次

1. for 常見寫法

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    int n;                                 //宣告變數n,表示要執行幾次,也可以直接設定初值
    cin >> n;                              //讀入n(題目常見)
    for (int i = 0; i < n ; i++)           //執行程式碼n次
    {
        /* 程式碼 */
    }
    
   /*-------------------------分隔線-------------------------*/
    
    for (int i = 1; i <= n ; i++)          //這也是執行程式碼n次,即將i從1代入到n
    {
        /* 程式碼 */
    }
    return 0;
}

7. while 常見寫法

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    int n;                                 //宣告變數n,表示要執行幾次,也可以直接設定初值
    cin >> n;                              //讀入n(題目常見)
    while(n--)                             //執行程式碼n次
    {
        /*程式碼*/
    }
    return 0;
}

8. 陣列 array

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    int n;                                 //宣告變數n,表示陣列有n項次
    cin >> n;                              //讀入n(題目常見)
    int a[n];                              //建立有n項的陣列a
    memset(a,0,sizeof(a));                 //將陣列a的每一項設定為0(不限於一維陣列)
    memset(a,-1,sizeof(a));                //將陣列a的每一項設定為-1(不限於一維陣列)
    for(int i=0;i<n;i++)
    {
        cin>>a[i];                         //將陣列a從a[0]讀入到a[n-1](題目超常見!!)
    }
    return 0;
}

9. 字串 string

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    char c;                                //宣告字元c
    string s;                              //宣告字串s
    cin >> s;                              //讀入字串s(會被space隔開)
    getline(cin,s);                        //將整行讀入字串s(不受space影響)
    s.size()                               //表示字串s的字元數
    s.clear();                             //清空字串s內的所有字元
    reverse(s.begin(),s.end());            //將字串的字元倒過來(倒著唸的概念)
    toupper(c)                             //表示字元c(需代表英文字母)的大寫字母的ACSII碼
    tolower(c)                             //表示字元c(需代表英文字母)的小寫字母的ACSII碼
    isalpha(c)                             //若字元c是英文字母,則代表0以外的整數,反之則代表0

    /*---------------------------------------------分隔線---------------------------------------------*/

    /*    若s有16個字元,則s[0]表示第1個字元,s[1]表示第2個字元,s[16]為字串結束字元'\0'    */
    return 0;
}

10. 函式

只補了這一塊的協作人:賴竑斌  (ps:修民是電神)
  函式,是一個聽起來跟函數很像的東西。事實上,他們概念上是相同的。只不過,函數輸入之後會跑出對應值,但函式則不一定。
  事實上,C++ 中內建了許多好用的函式(在標頭檔裡),我們舉絕對值 abs()為例。

cout << abs(2) << endl;
cout << abs(-3) << endl;
2
3

  我們會用到的函式有兩種,一種是 void,另一種是可傳回值的函式。
  先說說可以傳回值的函式好了:

bool name (int k)
{
    if(k)
        return 1;
    else
        return 0;
}

以 bool為例,這是個會傳回布林值(true or false)的函式。什麼意思呢?事實上,bool 的函式就像函數一樣,丟入一個值(或單純執行),就可以傳出布林值。
  程式碼印出了絕對值,我們看起來很簡單。
  但輸入值其實經過了這個過程:

#include <bits/stdc++.h>
using namespace std;
int abs(int t) //abs是函式名稱,而int函式會傳回int型態的值
//後面的int k代表只能輸入一個int值
{
    if(t>=0)
        return t; //傳回值
    else
        return -t;
}
int main(){
    int k=-4;
    cout << abs(k); //abs裡只能輸入int
}

  那如果只是作動作,沒有要回傳呢?我們就會用 void函式。

#include <bits/stdc++.h>
using namespace std;
void name (int a, bool b) //name是函式名字,自己取,但是最好有意義。
//括號裡面的輸入變數值自己令,以逗號隔開。
{
    if(b)
        cout << a;     //只執行動作,不傳回數字。
}
int main()
{
    int j;
    bool k=0;
    cin >> j;
    name(j,k); //輸入j,k
}

  我們可以發現,他就真的只把 a 印出來,而不會傳回值。至於函式可以幹嘛呢?遞迴是一個常見的應用。
  例如要算階乘的話,我們可以寫成:

int f(int k)
{
    if(k>1)
        return k*f(k-1);
    else
        return 1;
}

  輸入 3之後,會先回傳 3×f(31)。而f(2)會回傳 2×f(1)f(1)回傳 1
最後就成了:f(3)=f(2)×3=f(1)×2×3=1×2×3=6。以上是關於函式的簡介。

11. 補充資料

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);      //IO加速,無論如何,先寫進去就對了,只有一定要寫的,沒有不能寫的
    cin.tie(0);                            //cin IO加速
    int m,n;
    int a[n];
    INT_MAX                                //可直接用來表示int的最大值2147483647
    INT_MIN                                //可直接用來表示int的最小值-2147483648
    LONG_LONG_MAX                          //可直接用來表示long long的最大值9223372036854775807
    LONG_LONG_MIN                          //可直接用來表示long long的最小值-9223372036854775808
    max(m,n)                               //表示m,n中較大者的數值(只能有兩項)
    min(m,n)                               //表示m,n中較小者的數值(只能有兩項)
    swap(m,n);                             //交換m,n的值(須為同類型的變數)
    sort(a,a+n);                           //將陣列a內的資料由小到大排序(僅限於一維陣列)
    return 0;
}

12. 友善連結

受資研社副社長威脅放上的Koying資訊講義(內容較深入)
https://hackmd.io/@Koying/B1Ocazx7K/https%3A%2F%2Fhackmd.io%2F%40Koying%2FH1hI3Ovwt