CPP[1]

基礎語法

INDEX

I/O 優化

指標

參考

 

位元運算

函式

遞迴

Struct

I/O 優化

1. 實例

2. 使用方法

3. 原理 (也沒那麼重要啦)

實例

怎麼寫都被卡 TLE

$$10^6$$

輸入量 >

使用方法

I/O 優化

寫在 main() 裡面

#include <iostream>
using namespace std;

int main() {
	ios::sync_with_stdio(0);
    cin.tie(0);
}

原理

ios::sync_with_stdio(0);

關閉 cin cout 與 scanf printf 的同步

以達到效能優化

#include <iostream>
using namespace std;

int main() {
	ios::sync_with_stdio(0);
    cin.tie(0);
}

原理

cin.tie(0);

關閉 cin 前先清空緩存區

減少清空時的效能浪費

#include <iostream>
using namespace std;

int main() {
	ios::sync_with_stdio(0);
    cin.tie(0);
}

指標

1. 基本介紹

2. 使用方法

3. 指標小測驗

基本介紹

指標 (Pointer) 是啥?

一個變數

存一個記憶體地址

指向另一個變數

基本介紹

記憶體地址?

舉個🌰

變數名稱 value_1 value_2
型態 int string
48763 "kea so dian"
記憶體地址 0x4041 0x4042

每個變數都有自己的 "記憶體地址"

使用方法

宣告一個指標

T* a = &b;

T 為要指的變數型態

#include <iostream>
using namespace std;

int main() {
	int n = 100;
    int* pt_1 = &n;
}

int* pt_1 = &n;

宣告一個 int 指標 pt_1 指向一個 int 變數 n

使用方法

&

取址符號,獲取某個變數的記憶體地址

#include <iostream>
using namespace std;

int main() {
	int n = 100;
    cout << &n; // 0x7fff198e18a4
}

使用方法

*

取值符號,獲取某個指標存的值

#include <iostream>
using namespace std;

int main() {
	int n = 100;
    int* pt_1 = &n; // 這裡的 * 是宣告指標的符號
    cout << *pt_1; // 100,這裡的 * 是取值符號
}

(第 6 行跟第 7 行的 * 是不同的意思)

複習一下

宣告指標變數: *

符號: &

符號: *

指標是一個變數另一個變數記憶體地址

指標小測驗

變數名稱 val_1 pt_1 val_2 pt_2
型態 int string
100 "abc"
記憶體地址 0x4041 0x4043
#include<iostream>
using namespace std;

int main() {
	int val_1 = 100;
	int* pt_1 = &val_1;
	string val_2 = "abc";
	string* pt_2 = &val_2;
}

int*

0x4041

0x4042

string*

0x4043

0x4044

題外話

指標的指標

#include<iostream>
using namespace std;

int main() {
	int val_1 = 100;
	int* pt_1 = &val_1;
	int** pt_pt_1 = &pt_1;
	cout << pt_pt_1 << ' ' << *pt_pt_1 << ' ' << **pt_pt_1;
}

你也可以

1. 宣告指標的指標的指標

 

2. 宣告指標的指標的指標的指標

3. 宣告指向剛剛那個指標的指標指向的的指標的指標

參考

1. 基本介紹

2. 使用方法

基本介紹

參考 (Reference) 是啥?

用來參考別人的值的東西

使用方法

宣告參考

T& a = b;

T 為要參考的變數型態

#include <iostream>
using namespace std;

int main() {
	int n = 100;
    int& ref_1 = n;
}

int& ref_1 = n;

宣告 ref_1 參考一個 int 變數 n

使用方法

那它到底是個啥

如果你還記得我幾分鐘前講過的取址,我們可以對一個參考取址來看看它是個啥

#include<iostream>
using namespace std;

int main() {
	int n = 100;
	int& ref_n = n;
	cout << &ref_n << ' ' << &n;
}

n跟ref_n的地址一樣欸?

本質上它們是同個東西

再複習一次

宣告指標:*

宣告參考:&

取址符號:&

取值符號:*

乘法:*

大測驗時間

int a = 10;
int *b = &a;
int &c = a;
int **d = &b;

哈哈,以為用不到吧

  1. cout << a;
  2. cout << &a;
  3. cout << b;
  4. cout << *b;
  5. cout << &b;
  1. cout << c;
  2. cout << &c;
  3. cout << *c;
  4. cout << d;
  1. cout << *d;
  2. cout << **d;
  3. cout << &d;
  4. cout << &*d;
  5. cout << &**d;
  1. 10
  2. 0x8701
  3. 0x8701
  4. 10
  5. 0x8702
  1. 10
  2. 0x8701
  3. CE
  4. 0x8702
  1. 0x8701
  2. 10
  3. 0x8703
  4. 0x8702
  5. 0x8701

題外話

上一張是參考一四學術世宗參考一三學術長AaW的簡報

參考真好用

位元運算

1. 位元

2. 運算子

3. 使用方法

位元

位元

Bit

位元(英語:bit,亦稱二進制位)指二進制中的一位,是資訊的最小單位。bit是binary digit(二進制數位)的混成詞

- 維基百科

簡單來說,就是拿來存 1 或 0 的一個單位

在此 cue 個 10

位元

位元怎麼存數字

二進制!

value 128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 0
87 0 1 0 1 0 1 1 1
255 1 1 1 1 1 1 1 1

所以只要8個bit,我們就可以儲存 0~255 的所有數字

順帶一提 int 的範圍是 32 位元能存的數字喔

$$2^7$$

$$2^6$$

$$2^5$$

...

$$2^0$$

位元運算

位元運算

Bitwise Operation

對很多個位元做各種操作,就是位元運算la

  • 因為位元是記憶體的最小單位,操作非常快速
  • 許多演算法實作運用位元運算就可以變快!
  • 另外,APCS 會考,所以要學 :>

位元運算子

位元運算子

Bitwise Operators

你好奇為啥 && || 都要打兩個嗎?

 

因為被 位元且/或 用掉了

& |

欸 真眼熟

value_1 1 1 0 0 1
value_2 0 1 1 0 1
& 結果: 0 1 0 0 1

位元運算子

位元運算子

Bitwise Operators

value_1 1 1 0 0 1
value_2 0 1 1 0 1
| 結果: 1 1 1 0 1

位元運算子

位元運算子

Bitwise Operators

英文 符號 範例 結果
位元或 bitwise or | 6 | 11 15
位元和 bitwise and & 6 & 11 2
位元異或 bitwise xor ^ 6 ^ 11 13
左移運算 left shift << 5 << 3 40
右移運算 right shift >> 1243 >> 3 155

函式

1. 基本介紹

2. 使用方法

3. 使用實例

基本介紹

函式

Function

一個自己定義好的程式碼區塊讓你能多次呼叫相同的功能

基本介紹

舉個🌰

Example

#include <iostream>
using namespace std;

int main() {
	int a = 10, b = 100;
    int biggerone;
    if (a>b) {
    	biggerone = a;
    }
    else {
    	biggerone = b;
    }
}

只使用一次可能還好,如果要用很多次呢?

基本介紹

你可以

把他寫成一個函式

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

int bigger_one(int a, int b) {
    if (a > b) {
        return a;
    }
    else {
        return b;
    }
}

int main() {
    int a = 10, b = 100;
    int bigger1 = bigger_one(a, b);
    int c = 100, d = 10;
    int bigger2 = bigger_one(c, d);
}

真好,可以一直用

使用方法

函式的結構

int bigger_one(int a, int b) {
	if (a > b) {
    	return a;
    } 
    else {
    	return b;
    }
}

函式名稱

function name

回傳型別

return type

回傳值

return value

參數

arguments

使用方法

函式的結構

函式名稱

function name

回傳型別

return type

回傳值

return value

參數

arguments

你要用什麼名字呼叫他

最後回傳的是什麼型別 e.g. int char string long long

比較特別的void 此代表本函式不會回傳任何值

呼叫此函式要傳入哪些變數,可以是各種不同型別的變數

變數名稱不一定要跟呼叫時傳入的一樣

函式算完最後回傳時的值,用 return 回傳值; 來結束函式

來看個例子

我想交換兩個變數的值怎麼辦

寫個 swap() !

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

void swap(int a, int b) {
    int c;
    c = a;
    a = b;
    b = c;
}

int main() {
    int a = 10, b = 100;
    cout << a << ' ' << b << endl;
    swap(a, b);
    cout << a << ' ' << b;
}

What?

阿怎麼沒換?

這就要提,變數作用域了

變數作用域

變數作用域

 

  • 變數分為 全域變數 與 區域變數
  • 全域變數
    • 宣告在任何程式碼區塊(e.g. function, struct)外的變數
    • 不管在哪裡都可以存取這個變數
  • 區域變數
    • 宣告在某個區塊裡面的變數 宣告在main裡面也是喔 因為他是個函式main()
    • 只能在這個區塊裡面存取這個變數

繼續看例子

問題在哪?

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

void swap(int a, int b) {
    int c;
    c = a;
    a = b;
    b = c;
}

int main() {
    int a = 10, b = 100;
    cout << a << ' ' << b << endl;
    swap(a, b);
    cout << a << ' ' << b;
}

swap() 底下的 區域變數修改不會影響到 main() 底下的區域變數 !

繼續看例子

怎麼改?

還記得指標/參考嗎?

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

void swap(int &a, int &b) {
    int c;
    c = a;
    a = b;
    b = c;
}

int main() {
    int a = 10, b = 100;
    cout << a << ' ' << b << endl;
    swap(a, b);
    cout << a << ' ' << b;
}

參考 a, b

遞迴

1. 基本介紹

2. 使用方法

3. 使用實例

基本介紹

遞迴是啥?

在執行一個函式的時候,呼叫函式自己

蝦?

請看圖

阿動畫好麻煩

所以我們鬼轉學長簡報 (X

遞迴的動畫太難做了,謝謝學長

Struct

1. 基本介紹

2. 使用實例

基本介紹

我想要存一個人的資訊

身高

體重

性別

專長

學校

座號

地址

...

反正一大堆東西

啊我要存一群人,我變數會多到哭欸

使用方法

Struct 拿出來!

Struct 就是可以讓你自訂義的資料結構

以剛剛的例子來舉例

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

struct person{
    int height,weight;
    string gender; 
    string interest,expertise,name;
};

int main(){
    person Ian;
    Ian.name = "Ian Wen";
    Ian.height = 200;
    Ian.weight = 100;
    Ian.gender = "AH-64E"; // 現在是 2024,我是一架武裝直升機不行嗎
    Ian.interest = "sleep";
    Ian.expertise = "大燒雞";

    cout << Ian.name << endl;
    cout << Ian.expertise << endl;
}

使用方法

阿你也可以開個陣列

比如說:

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

struct person {
    int height,weight;
    string gender; 
    string interest,expertise,name;
};

int main(){
    person people[100]; // 真好,人群 = 人的陣列
}

使用方法

你也可以在裡面寫 function

比如說:

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

struct person {
    double height,weight;
    string gender; 
    string interest,expertise,name;
    	
   	float bmi(){
     	return weight/(height*height);
   	}
};

int main(){
    person Ian;
    Ian.weight = 100;
    Ian.height = 1; // 1 是公尺
 	cout << "Ian's bmi : " << Ian.bmi();
}

講完了

希望大家有聽懂la

C++ 基礎語法 第二堂

By wen Ian

C++ 基礎語法 第二堂

  • 396