# C++語法, 筆記整理
[toc]
## 語法
### Vector
#### 特性
集合尾端增刪元素很快 : O(1)
集合中間增刪元素比較費時 : O(n)
#### Code Example
* vec.push_back() - 新增元素至 vector 的尾端,必要時會進行記憶體配置。
* vec.pop_back() - 刪除 vector 最尾端的元素。
* [vec.insert() - 插入一個或多個元素至 vector 內的任意位置。](https://vimsky.com/zh-tw/examples/usage/vector-insert-function-in-c-stl.html)
* vec.erase() - 刪除 vector 中一個或多個元素。
* vec.clear() - 清空所有元素。
* 初始化宣告`vector<int> v = {1, 2, 3}`
`vector<int> v(3, 1)\\v={1,1,1}`
```
參數:
size - 多少個數字要被新增
value - 建一個充滿value的1D vector
declare 1D vector
```
```C++=
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> vect{ 10, 20, 30 };
//vector大小
cout<<"vect size:"<<vect.size()<<'\n';
for (int x : vect)
cout << x << " ";
return 0;
}
```
declare 1D vector with initial size
```C++=
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> vect(10);
//vector大小
cout<<"vect size:"<<vect.size()<<'\n';
for (int x : vect)
cout << x << " ";
return 0;
}
```
declare 2D vector
```C++=
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<vector<int> > vect{ { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
// Displaying the 2D vector
for (int i = 0; i < vect.size(); i++) {
for (int j = 0; j < vect[i].size(); j++)
cout << vect[i][j] << " ";
cout << endl;
}
}
```
### Stack
```C++
// CPP program to illustrate
// Implementation of push() function
#include <iostream>
#include <stack>
using namespace std;
int main()
{
// Empty stack
stack<int> mystack;
mystack.push(0);
mystack.push(1);
mystack.push(2);
// 获取并删除栈顶的元素
int topValue = myStack.top(); // 获取栈顶元素的值
myStack.pop(); // 删除栈顶元素
// Printing content of stack
while (!mystack.empty()) {
cout << ' ' << mystack.top();
mystack.pop();
}
}
```
### Array
```C++=
//define
int foo [5] = { 10,5,15,3,7};
//intialize array to zero
int array[10] = {0};
//get array size
//total byte / first byte
int n = sizeof(foo) / sizeof(foo[0]);
```
### Hashmap
```C++=
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map<string, int> umap;
// inserting values by using [] operator
umap["GeeksforGeeks"] = 10;
umap["Practice"] = 20;
umap["Contribute"] = 30;
// Traversing an unordered map
for (auto x : umap)
cout << x.first << " " << x.second << endl;
}
```
#### Hashmap erase
```C++=
#include <iostream>
#include <unordered_map>
struct Node {
int data;
};
int main() {
std::unordered_map<int, Node*> dict;
// 创建一些键值对并插入到unordered_map中
Node* node1 = new Node{1};
Node* node2 = new Node{2};
Node* node3 = new Node{3};
dict.insert({1, node1});
dict.insert({2, node2});
dict.insert({3, node3});
// 删除指定键的元素
int keyToRemove = 2;
size_t numRemoved = dict.erase(keyToRemove);
// 检查是否成功删除了元素
if (numRemoved > 0) {
std::cout << "元素删除成功。" << std::endl;
// 可以在这里释放被删除节点的内存
} else {
std::cout << "未找到要删除的元素。" << std::endl;
}
return 0;
}
```
### Unorderset + vector
//功能與hashmap相同,加速查找
```=C++
int main() {
int n = 4;
vector<vector<int>> roads{{0,1},{1,2},{2,3},{2,0}};
vector<unordered_set<int>> graph(n);
// Building the graph (adjacency list).
for (const auto& road: roads) {
graph[road[0]].insert(road[1]);
graph[road[1]].insert(road[0]);
}
for(int i=0;i<n;i++){
cout<<i<<":"<<graph[i].size()<<endl;
}
}
```
### Tree
```C++=
#include <iostream>
using namespace std;
//定義樹的結構
// root
// / \
// left right
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
int main()
{
//產生一個node,並定義node數值
TreeNode* root = new TreeNode(10);
//產生一個node,並定義node數值
TreeNode* rootleft = new TreeNode(5);
//街上root左邊的node
root->left = rootleft;
//imshow
cout<<root->val<<endl;
//把root移到左方
root = root->left;
//imshow
cout<<root->val<<endl;
return 0;
}
```
### string
```C++=
string s ="ABCD";
int len = s.length();
```
### pointer
```C++=
int b = 2;
//從這個地址中取出變數b的值
//&是取出地址,*是取出地址裡面的值
//*&b == b
printf("變數 b 的值:%d\n", b);
printf("變數 b 的值:%d\n", *&b);
//指標宣告方式 指標指向b的位置
int* pointer = &b
int a; // 一個整型數
int *a; // 一個指向整數的指標
int **a; // 一個指向指標的指標,它指向的指標是指向一個整型數
int a[10]; // 一個有10個整數型的陣列
int *a[10]; // 一個有10個指標的陣列,該指標是指向一個整數型的
int (*a)[10]; // 一個指向有10個整數型陣列的指標
int (*a)(int); // 一個指向函數的指標,該函數有一個整數型參數並返回一個整數
int (*a[10])(int); // 一個有10個指標的陣列,該指標指向一個函數,該函數有一個整數型參數並返回一個整數
```
## ostringstream istringstream
``` C++=
//ostringstream用法
ostringstream out;
out << "123 "
out << "456 "
cout << out.str(); // "123 456 "
//istringstream用法
string data = "123 456 ";
istringstream in(data);
string value = "";
in >> value;
cout <<value; // "123"
in >> value;
cout <<value; // "456"
```
## function
### Selection sort
```C++=
void selectionSort(vector<int>& a,vector<int>& idx, int n) {
int i, j, min, temp,tmp_idx;
for (i = 0; i < n - 1; i++) {
min = i;
for (j = i + 1; j < n; j++)
if (a[j] < a[min] || (a[j]==a[min] && idx[j]>idx[min]))
min = j;
temp = a[i];
a[i] = a[min];
a[min] = temp;
tmp_idx = idx[i];
idx[i] = idx[min];
idx[min] = tmp_idx;
}
}
```
### 判斷奇數(AND應用)
```C++=
int num=10;
if num & 1 ? cout<<"奇數": cout<<"偶數";
```
### 找出數列中的唯一數字(XOR應用)
預設數列內僅有一個數字出現一次,其他都是重複兩次
```C++=
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> nums{4,1,2,1,2};
for(int i=1;i<nums.size();i++){
nums[0] ^= nums[i];
}
cout<<nums[0];
}
```
### swap(XOR應用)
```=C++
void swap(int & a,int & b){
a^=b;
b^=a;
a^=b;
}
```
# C與C++差異與其他語言差異
## C & C++ 與其他新一代語言
* (a)C & C++:
* 透過編譯器和連結器,直接產生原生的機器碼
* (b)新一代的程式語言(Java, C#):
* 透過翻譯轉成 bytecode,然後再由虛擬機器(Virtual Machine)來執行
* 優缺點
* (b)的優點:技術先進,移植性
* 可能的缺點:效率(平台差異)
* 本質上技術相同,C++ Complier可想成虛擬機器
* 虛擬機器的設定標準
* (a)是共同制定的標準
* (b)架構則是 Sun 或 MS 所制定的
* 框架差異
* 只學C/C++不能解決應用問題,因為它只有基本I/O,至少要學會一種GUI框架,或是database框架
* JAVA/C# 函式庫已包含在框架內
* 型別
* (a) 語言都是採用傳統的靜態型別系統
* 不強制改變使用者自訂型別(UDT: User-defined Type)的記憶體佈局
* 允許在 stack 中配置 UDT 變量(也就是「物件」,但由於在 C 語言中,沒有真正物件導向的觀念,因此以「變量」來指稱)
* 你無法在編譯期產生變量,也不可能在執行期產生新的「型別」
* 使得執行期的效率高
* 零成本」原則:「使用者不該為他沒有用到的功能,付出執行期的效率代價」
* (b) 單根繼承的泛化型別系統
* 型別本身也可以當作變量
* 哲學觀點
* (a)把你當大人,給予最高彈性
* (a)不強迫限制或規範
* (a)不內建垃圾回收器(GC: Garbage Collection)
## C與C++差異
* C 語言是 C++ 的一個子集
* C++改進
* 引入 bool 型別
* 鼓勵以 0 而非自行定義的 NULL 巨集等代表空指標。
* 引入 const,讓「常數性」成為與型別不可分割的一部份,除了提升安全,讓編譯器承擔檢核的責任之外,也有助於代碼的優化。
* 引入 const, inline 等用法,減少非必要巨集的使用。(因為展開 巨集是預處理器的動作,沒有通過編譯器,也就沒有型別安全可言)。
* 引入 reference 機制,簡化指標的語法,並有效減少指標(尤其是 兩層以上的複雜指標)的使用。
ref:https://www.ptt.cc/man/C_and_CPP/DB9B/D3B0/M.1475403294.A.F90.html
## bitwise operation
找出Int 第n個bit值
```C++=
int find_bit_val(int num, int bits)
{
int res = (num & (int)pow(2, bits))>>bits;
}
```