# C++ 的基本知識

# 必須注意的事

  • 英文或阿拉伯數字需使用半形的字,不要使用全形

  • 英文字有大小寫的差別,輸入時務必小心。
    例如: main 被打成 Main MAIN 編譯時都會發生錯誤。

  • 程式中有空白的地方,需用鍵盤上的空白鍵隔開。

  • 在一行或一組程式的結束後面切記加上 「;」,代表該行程式執行結束。

  • { } 、[ ] 、 ( )" "、' ' 的使用時機互不相同。

  • 善用 / /、/* */ 註解功能幫助自己查核時,減少大量時間和心力的消耗。

  • 需善用 Tab 鍵 縮排 Enter 鍵 換行,可使程式更簡單、易讀,這是撰寫程式需養成的習慣。

  • 如果括號內的程式只有一行,則括號可以省略

  • 若寫得程式很長可 分段做 debug 動作,一步一步做出修正,避免最後整個錯亂掉。

# 程式碼的內容

p
#include <iostream>              // 為了要使用 cout 而引入的標頭檔
using namespace std;             // 為了更方便使用 cout 的註明
int main()                       //main () 函數的開始
{
    cout << "初次嘗試C++\n";      // 真正的程式從這樣一行開始
    cout << "要好好加油喔!\n";    // 接下來執行到這一行
    return 0;                    //main () 函數的結束
}

# 常出現的編譯問題 (CE)

  • expected ‘ ; ’ before ‘ ... ’ token
    解決方案:在錯誤出現處的行末尾加上 ;

  • expected ‘ } ’ before ‘ ... ’ token
    解決方案:檢查自己縮排的狀況,並找出遺漏的 } 並補上

  • “變數 / 常量 / 函式” was not declared in this scope
    解決方案:
    1. 檢查變數是否在使用前被宣告,若無則就宣告它 。
    2. 確認使用的預設函式標頭檔是否已被宣告,若無則宣告它。

# 常數、變數與資料

# 資料型態 (data type)

常用型態意義資料範圍
int整數-2147483648~2147483647
long long int長整數-263~263-1
float單經度浮點數±3.4x 10-38 ~ ±3.4x1038
double雙經度浮點數±1.7×10-308~ ±1.7×10308
string字串"World"
char字元'A'
bool布林true (1) 或 false (0)

# 變數名稱 (variable)

  • 用來做為變數的名稱,需注意的事,如下:
    • 使用英文字母、阿拉伯數字、底線連接(_)等,不能使用特殊的符號,例如: sum-1
    • 已保留的關鍵字(keyword) 不可為變數名稱。例如: return、break...
    • 不能用阿拉伯數字作為開頭。例如: 12a、555...
    • 英文字母的大小寫有區別。

# 變數宣告 (declaration)

  int num;                   // 資料型態 變數名稱;
  char a = 'A';              // 資料型態 變數名稱 = 初值;
  int sum, ave, rank, ...;   // 資料型態 變數名稱1, 變數名稱2, 變數名稱3,...;

# 宣告常數 (const)

利用常數給予一個定值可使數值被固定,如果後來再改變它,將發生錯誤

const double pi = 3.141592;    //const 資料型態 變數名稱 = 特定資料 ;
//此後,pi值不會再被改變

# 運算子與基本結構

# 算術運算子

符號功能範例說明
+加號a = x + y
-減號a = x - y
*乘號a = x * y
/除號a = x / y
%取餘數a = x % y
++x運算前增量a = ++x + yx=x+1, a=x+y
x++運算後增量a = x++ + ya=x+y, x=x+1
--x運算前減量a = --x + yx=x-1, a=x+y
x--運算後減量a = x-- + ya=x+y, x=x-1
-x負號a = -x
+x正號a = +x

:::note info
整數整數,結果為整數浮點數浮點數,結果為浮點數
例: 8 / 5 = 1 || 8.0 / 5.0 = 1.6
:::

# 關係與邏輯運算子

符號功能範例說明
>大於a>b若 a>b 則結果為真
>=大於等於a>=b若 a≧b 則結果為真
<小於a<b若 a<b 則結果為真
<=小於等於a<=b若 a≦b 則結果為真
==等於a==b若 a=b 則結果為真
!=不等於a!=b若 a≠b 則結果為真
!邏輯 NOT!(a==1)若 a≠1 則結果為真
&&邏輯 ANDa>2&&a<9若 2<a<9 則結果為真
||邏輯 ORa<2 || a>9若 a<2 或 a>9 則為真

# 複合指定運算子

符號功能範例說明
=簡單指定x = y令 x = y
+=加法指定x += y令 x = x + y
-=減法指定x -= y令 x = x - y
*=乘法指定x *= y令 x = x * y
/=除法指定x /= y令 x = x /y
%=餘數指定x %= y令 x = x % y

:::note warning
指定值 x=y 之後,變數 x 原來的值被覆蓋,而 y 值不變
善用可以使程式碼變得更精簡,不善使用則... 會很困擾
:::

# 運算符號的優先順序

運算符號優先順序
( )1
* , / , %2
+ , -3
==, <, >, <=, >=, !=4

:::note warning
若優先順序並列,則程式會由左至右依序執行
記得先加減後乘除的觀念,善用括號
記得乘號在語言的世界裡,不能省略
:::
:::note primary

# Ex.01 面積 01:

利用海龍公式計算三角形面積 (不討論是否能夠成三角形)
s=a+b+c2s=\frac{a+b+c}{2}area=(s(sa)(sb)(sc))area=\sqrt{(s(s-a)(s-b)(s-c))}
:::

:::note primary

# Ex.02 距離:

輸入四個浮點數 x1,y1,x2,y2x1,y1,x2,y2,計算坐標系上(x1,y1)(x1,y1)(x2,y2)(x2,y2) 的距離
距離公式: distance=((x1x2)2+(y1y2)2)distance=\sqrt{((x1-x2)^2+(y1-y2)^2)}
:::

# 循序式結構 (sequence structure)

程式依序從第一個敘述執行至最後一個敘述

// 循序式結構
#include <iostream>
using namespace std;
int main(){
    string name;                          // 第 1 步
    cin>>name;                            // 第 2 步
    cout<<"Hello, "<<name<<endl;          // 第 3 步
    return 0;                             // 第 4 步
}

# 選擇式結構 (selection structure)

程式運行到條件敘述,當條件成立 (運算式值為 1) 時,重複執行重複區的敘述。
反之,當條件不成立時 (運算式值為 0),則結束重複結構。

// 選擇式結構
#include <iostream>
using namespace std;
int main(){
    int num;                              // 第 1 步
    cout<<"請輸入一個數字";                 // 第 2 步
    cin>>num;                             // 第 3 步
    if(num%2==0){                         // 第 4 步
        cout<<"你輸入的是偶數";             //if 運算值為 1 時的第 5 步
    }                                     //if 運算值為 0 省略第 5 步
    return 0;                             // 第 6 步
}

# 重複式結構 (repetition structure)

程式運行到重複敘述,當條件成立 (運算式值為 1) 時,重複執行重複區敘述。
反之,當條件不成立時 (運算式值為 0),則結束重複結構。

#include <iostream>
using namespace std;
int main(){
    int num,sum=0;                          // 第 1 步
    cin>>num;                               // 第 2 步
    for(int i=1;i<=num;i++)                 // 第 3 步判斷
        sum+=i;                             // 第 4 步,若執行完 i++ 後,仍小於 num 不斷重複
    cout<<"從1加到num的總和為:"<<sum;         // 第 5 步
    return 0;                                // 第 6 步
}

# 條件選擇

# 邏輯運算

# 邏輯運算子

符號功能範例說明
!邏輯 NOT!(a==1)若 a≠1 則結果為真
&&邏輯 ANDa>2&&a<9若 2<a<9 則結果為真
||邏輯 ORa<2 || a>9若 a<2 或 a>9 則為真

# 邏輯 AND 與 OR 運算真值表

運算式 A運算式 BA && BA || B
falsefalsefalsefalse
falsetruefalsetrue
truefalsefalsetrue
truetruetruetrue

# 邏輯 NOT 運算真值表

A!A
truefalse
falsetrue

# 邏輯運算式值

邏輯運算式邏輯運算值
(4.3>3.7) && (7==4+3)true(1)
(9/2==4.5) || (5>3.2)true(1)
!(1.5 * 5 >= 2)false(0)

:::note primary

# Bouns 02 推算下列混合運算式的值 (true || false)

1. !(4.3 > 3.7) && (7 == 5 + 2) || (15 / 3 < 5)
2. (8.2 < 7.3 * 2) || !(1 + 3 * 2 < 5)
3. (96 / 4 + 2 > 20) && !(6 - 2 * 9 > 72 / 9)

:::

# 條件選擇

# if 敘述

if(條件式)
{
    條件「成立」時的敘述;
}

:::note warning
if (條件式) 後面沒有;
:::
made by 葉致宏

# 例 1: 判斷正數

#include <iostream>
using namespace std;
int main(){
    int n;
    cout<<"請輸入一個整數:";
    cin>>n;
    if(n>0){
        cout<<n<<"是正數";
    }
    return 0;
}

# if-else 敘述

if(條件式)
{
    條件「成立」時,敘述1;
}
else
{
    條件「不成立」時,敘述2;
}

made by 葉致宏

:::note primary

# Ex.03 : 面積 02

繼 Ex.01 加上 if 先判斷是否能構成三角形
:::

# if-else if 敘述

if(條件1)
{
    條件1「成立」時程式碼區塊;
}
else if(條件2)
{
    條件1「不成立」,且條件2「成立」時的程式碼;
}
else if(條件3)
{
    條件12「不成立」,且條件3「成立」時的程式碼;
}
....
else
{
    上述條件都「不成立」時的程式碼;
}

image alt

# 例 2: 區分分數等級

#include <iostream>
using namespace std;
int main(){
    int number;
    cout << "請輸入成績 (0 - 100):";
    cin >> number;	                // 輸入數值並存入 number
    if (number >= 90)	                // 若 90<=number,則
    	cout << "成績甲等\n";	        // 輸出甲等並結束 if
    else if (number >= 80)  	        // 其餘若 80<=number,則
    	cout << "成績乙等\n"; 	        // 輸出乙等並結束 if
    else if (number >= 70 ) 	        // 其餘若 70<=number,則
    	cout << "成績丙等\n";	        // 輸出丙等並結束 if
    else if (number >= 60 )            // 若 60<=number,則
    	cout << "成績丁等\n";           // 輸出丁等並結束 if
    else                               // 全部皆不成立,則
        cout << "成績戊等\n"            // 輸出戊等並結束 if
    return 0;
}

:::note primary

# Ex.04 判斷一元二次方程式的根

由鍵盤輸入方程式 ax2+bx+c=0 的 a,b,c,判斷方程式根的狀態

  • 若 b2-4ac>0,則表示方程式具有二個實根
  • 若 b2-4ac=0,則表示方程式具有一個實根
  • 若 b2-4ac<0,則表示方程式具有二個虛根
    :::

:::note primary

# Ex.05 計算折扣價

假設一台電腦單價為 $39,999 元,由鍵盤輸入購買數量,計算並顯示總價
其採購量與折扣對應表如下:

| 數量 | 10~19 | 20~49 | 50~99 | 100 以上 |
|:----😐:-----😐:-----😐:-----😐:-------😐
| 折扣 | 10% | 20% | 30% | 40% |
:::

# 巢狀 if 敘述

if(條件1)
{
    if(條件2)
    {
        條件1「成立」,且條件2「成立」時的程式碼A
    }
    else
    {
        條件1「成立」,且條件2「不成立」時的程式碼B
    }
}
else
{
    條件1「不成立」時程式碼C
}

image alt

# 例 3: 用巢狀 if 判斷閏年年分

#include <iostream>
using namespace std;
int main(){
    int year;
    cin >> year;
    if(year % 4 !=0 )                    // 如果不是 4 的倍數
        cout << year <<"不是閏年";        // 則輸出不是閏年
    else if(year % 100 ==0){             // 其中如果是 100 的倍數
        if(year % 400 ==0)               // 如果又是 400 的倍數
            cout << year <<"是閏年";      // 則輸出是閏年
        else                             // 只是 100 的倍數
            cout << year << "不是閏年";   // 則輸出不是閏年
    }
    else                                 // 只能被 4 整除
        cout << year << "是閏年";         // 則輸出是閏年
    return 0;
}

# switch 敘述

switch (條件運算式)
{
    case 數值1:
        數值1「成立」的敘述區1;
        break; // 中斷 switch
    case 數值2:
        數值2「成立」的敘述區2;
        break; // 中斷 switch
    default:
        以上條件皆「不成立」敘述區n;
}

image alt

# 例 4: 按 + - * / 鍵,執行 + - * / 運算

#include <iostream>
using namespace std;
int main()
{
    char letter;
    int num1 = 90, num2 = 15;
    cout<<"num1 = 90,num2 = 15\n";
    cout<<"從鍵盤上輸入+, -, *, / :";
    cin>>letter;
    switch (letter){
        case '+':
            cout<<"num1 + num2 ="<< num1 + num2 <<endl;
            break;
        case '-':
            cout<<"num1 - num2 ="<< num1 - num2 <<endl;
            break;
        case '*':
            cout<<"num1 * num2 ="<< num1 * num2 <<endl;
            break;
        case '/':
            cout<<"num1 / num2 ="<< num1 / num2 <<endl;
            break;
    }
    return 0;
}

# 迴圈

# for 迴圈

for(變數初值;條件判斷;改變量)
{
    程式碼
}

:::note info
for ( ) 後面也沒有 ;
for 語句的三個部分都是可以省略的
:::

# 例 5: 計算 n! 的值

#include <iostream>
using namespace std;
int main()
{
    int n,sum=1;
    cout << "請輸入n:";
    cin >> n;
    for (int i=1;i<=n;i++)   // 讓 i 從 1~n
        sum*=i;              // 每次迴圈 sum=sum*i
    cout << sum;
    return 0;
}

# 巢狀迴圈

for(變數1初值;條件1判斷;改變量)
{
    for(變數2初值;條件2判斷;改變量)
    {
        程式碼
    }
}

# 例 6: 印出 n 層金字塔

#include <iostream>
using namespace std;
int main() {
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n-i;j++)
            cout<<" ";
        for(int j=1;j<=2*i-1;j++)
            cout<<"*";
        for(int j=1;j<=n-i;j++)
            cout<<" ";
        cout<<endl;
    }
    return 0;
}

:::note primary

# Ex.06: 倒三角形

印出一個高為 10 的顛倒金字塔
我只是個三角形
:::

# while 迴圈

while(條件判斷)    // 條件為「真」的時候繼續執行
{
    程式碼
}

# 例 7: 把數字反轉

(若數字為 100,顛倒後的數表示為 1,不是 001)

#include <iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    if(n==0)
        cout<<0;
    while(n%10==0 && n>0)
        n/=10;
    while(n%10!=0||n>=10)
    {
        cout<<n%10;
        n/=10;
    }
    return 0;
}

# do...while 迴圈

do
{
    程式碼
}while(條件判斷);  // 條件為「真」的時候繼續執行

:::note warning
do...while while 的差別在於 do...while 至少會做一次
do...while 後面要加分號,表示結束
:::

# 例 8: 小算盤開根號 (以牛頓法實作)

#include <iostream>
using namespace std;
int main()
{
    double a, n;
    cin >> n;
    a = n;
    do
    {
        a = (a*a+n)/(2*a);    // 挑出的第 1 個近似值 a 之後,作一切線,切線和 x 軸的交點
    } while ( a*a-n>1e-13 );  // 當 a*a 和 n 的誤差 > 1e-13 時,繼續逼進
    cout << a;
    return 0;
}

# 陣列、字串

# 陣列

陣列(Array),是由相同類型的元素的集合所組成的資料結構,分配一塊連續的記憶體來儲存。利用元素的索引 (index) 可以計算出該元素對應的儲存位址。

p
int arr[5];                      // 宣告一個大小為 5 的 int 陣列
arr[0]=80;                       // 陣列的索引值由 0 開始
arr[5]=90;                       // 索引值 0~4
int arr[5] =  { 1, 3, 5, 7, 9 }; // 宣告陣列時設定初值
int arr[5] =  { 1 };             //arr [0] 初值 1,其餘預設為 0
int arr[] = { 1, 3, 5, 7, 9 };   // 陣列大小依初值自動計算
int arr2D[4][2];                 // 宣告二維陣列 (多維陣列)
int arr2D[4][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

:::note info
如果陣列要用的比較大一些,它就要在全域宣告
:::

# 例 9: 利用泡沫排序法 (bubble sort)

將 {3,2,4,8,9,1,7} 由小至大排列,並依序輸出

#include <iostream>
using namespace std;
int main()
{
    int a[7]={3,2,4,8,9,1,7},t;
    for(int i=0;i<7;i++){
        for(int j=0;j<7-i-1;j++){
                if(a[j]>a[j+1]){
                    t=a[j];
                    a[j]=a[j+1];
                    a[j+1]=t;
                }
        }
    }
    for(int i=0;i<7;i++)
        cout<<a[i]<<" ";
    return 0;
}

:::note primary

# Ex.07 成績單:

3 年 21 班前五號的學測成績如下:

座號國文數學英文自然社會總分平均
110129117
29108911
313811714
481413149
512109109

請利用多維陣列完成表格並完整的印出表格
:::

# 字串

字串實例可以使用 [] 指定索引來存取相對應位置的字元,就有如字元陣列的操作一般

string str1;                 // 內容為空字串
string str2 = "sololearn";   // 內容為指定的字串常量

可使用 str.length()str.size() 得知字串大小

#include <iostream>
using namespace std;
int main()
{
    string s="Hello World";
    
    cout<<s長度為<<s.size()<<endl;
    for(int i=0;i<s.size();i++)
        cout<<s[i];
    return 0;
}
輸出-->s長度為11
    -->Hello World

:::note warning
從字串上的數字,僅是字元。若直接進行運算,計算的依據將為 ASCII 碼,結果會錯誤
若需要進行運算,則必須先減去 '0' 才行
:::

# 例 10: 判別一個數字 N 是否為 3 的倍數 (N>1020)

#include <iostream>
using namespace std;
int main()
{
    string s;
    cin>>s;
    int sum=0;
    for(int i=0;i<s.size();i++)
        sum+=s[i]-'0';
    if(sum%3==0)
        cout<<s<<"是3的倍數";
    else
        cout<<s<<"不是3的倍數";
    return 0;
}

:::note primary

# Ex.08 字串應用:

判別一個數字 N 是否為 11 的倍數 (N>1020)
:::

# 函式

# 自訂函式

有某些程式碼會經常使用,對於程式中出現兩次以上被重覆使用的程式片段,可以將之定義為函式以便重覆呼叫

回傳值的型態 函式名稱(變數型態 參數1,變數型態 參數2...)
{
    程式碼
    return 回傳值或運算式;
}

# 例 11: 寫一函式可以計算 n!,並以之求 C(n,k)=\frac{n!}

#include<iostream>
using namespace std;
int f(int n)
{
    sum=1;
    for(int i=1;i<=n;i++)
        sum*=i;
    return sum;
}
int main()
{
    int n,k;
    cin >> n >> k;
    cout << f(n)/((f(n-k)*f(k))<<endl;
   
    return 0;    
}

:::note primary

# Ex.09 gcd 01:

寫一個函式計算兩數的最大公因數
:::

# void

如果呼叫函式不傳回任何值,則宣告為 void

void 函式名稱(變數型態 參數1,變數型態 參數2...)
{
    程式碼
}

# 遞迴

遞迴(Recursion),是指在函式中使用函式自身的方法。
:::note warning
遞迴函式必須有終止條件,才能被計算。
:::

# 例 12: 利用遞迴函式費氏數列的第 n 項

#include <iostream>
using namespace std;
int fib(int n)
{
    if (n == 0)                 //n==0 時終止,回傳 0。if 後只有一行,可省略 {}
        return 0;
    else if (n == 1)            //n==1 時終止,回傳 1
        return 1;
    else
        return f(n-1)+f(n-2)    // 遞迴呼叫
}
int main()
{
    int n;
    cin >> n;
    cout << fib(n);
   
    return 0;    
}

# 例 13: 利用遞迴函式求 ab的值

made by 葉致宏

#include <iostream>
using namespace std;
int f(int a, int b)
{
    if( b == 0 )
        return 1;
    if( b >= 1 )
        return a * f(a,b-1);
}
int main()
{
    int a, b;
    while( cin >> a >> b )
        cout << f(a,b) << endl;
    return 0;
}

:::note primary

# Ex.10 gcd 02

繼 Ex.09 運用遞迴函式求兩數的最大公因數
:::

更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay