---
# System prepended metadata

title: Structure

---

# Structure

structure 結構
是可以自訂義資料"結構"的方式
基本的宣告方式為:
```cpp=
#include<bits/stdc++.h>
using namespace std;
struct str{
    //type anything you want here
}; //注意分號

int main(){
    str var;//宣告變數
}
```
以上自訂義出的"str"為<font color="#FA0606">一種資料型態，並不是變數名稱</font>，所以定義變數時先打型態再打變數名稱。

:::info
:bulb: 大括號後面記得打分號
:::

## Member
成員
分為成員變數與成員函數，利用"."來進行呼叫
```cpp=
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x, y;//兩名型態為int的成員變數
    
    void print(){ //一名回傳void的成員函數
        cout << "HI!" << endl;
    }
    node dot(node a){ //一名回傳node的成員函數
        node ans;
        ans.x = x*a.x;
        ans.y = y*a.y;
        return ans;
    }
};
int main(){
    node var;
    var.x = 1;
    var.y = 2;
    var.print();
}
```
要注意struct的成員變數的型態不能跟原本同名(node)，會無法編譯。
在main定義變數後，使用 . 來進行呼叫

#### 與指標連用
 
當想要使用指標來呼叫成員時，有其他的寫法。
包含
struct(自定義結構)指標呼叫成員
map、pair 指標呼叫first,second



```cpp=
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x, y;//兩名型態為int的成員變數
        
    void print(){ //一名回傳void的成員函數
        cout << "HI!" << endl;
    }
};
int main(){
    node *var;//創建一名為node指標的變數
    vector<pair<int, int>> arr(10);//pair陣列
    map<int, int> mp;
    
    var->x = 3;
    var->y = 5;
    var->print();

    for(auto it = arr.begin(); it != arr.end(); it++){
        cin >> it->first >> it->second;
    }
    
    for(auto it = mp.begin(); it != mp.end(); it++){
        cout << it->first << it->second;
    }
}
```
## Constructor
建構式
是用來快速建構變數(初始化)的工具，可以在宣告變數的同時設定好成員的狀態。
```cpp=
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x, y;
    node(int a, int b){ //Constructor
        x = a;
        y = b;
    }
    void print(){ 
        cout << x << " " << y << endl;
    }
};
int main(){
    int n = 10;
    node var = node(3, 5);
    vector<node> arr;
    for(int i = 0; i < n; i++){
        arr.push_back(node(i, i+3));
    }
    var.print();
    for(int i = 0; i < n; i++){
        arr[i].print();
    }
}
```
建構式的名稱一定要與資料名稱同名，且建構式不一定只能有一個。
建構式也有另一種打法:
```cpp=
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x, y;
    node(){} //???
    // node() = default;
    node(int a, int b): x(a), y(b){}//Constructor
    void print(){ 
        cout << x << " " << y << endl;
    }
};
int main(){
    int n = 10;
    node var = node(3, 5);
    vector<node> arr(n); //n項node,長什麼樣子?
    for(int i = 0; i < n; i++){
        arr[i] = node(i, i+3);
    }
    var.print();
    for(int i = 0; i < n; i++){
        arr[i].print();
    }
}
```
要注意空建構式有時也是不可被省略的

## Operator
用來定義運算子，當自訂義資料結構要與其他變數(無論類型)做運算時，需要對運算子定義出詳細的運算規則。

概念: a+b的過程


```cpp=
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x, y;
    node(){}
    node(int a, int b): x(a), y(b){}
    node operator*(const node &b) const {
        return node(x*b.x, y*b.y);
    }    
    void print(){ 
        cout << x << " " << y << endl;
    }
};
int main(){
    node a(3,5), b(4,6);
    node c = a*b;
    c.print();
}
```



# Lambda

就是函數，一個酷酷的語法糖

## 語法
```cpp=
[](int i){
    return i + 1;
}
```

其中的[]裡面可以放=或&這兩種，=代表的是pass by value，&代表的是pass by reference。

如果這樣打的話就是全部pass by reference
```cpp=
[&](int i){
    return i + 1;
}
```
如果這樣打的話就是全部pass by value
```cpp=
[=](int i){
    return i + 1;
}
```

也可以限定只要pass by reference(value)某些東西，像是下面的就是只reference a和b兩個變數，c用pass by value
```cpp=
[&a, &b, c](int i){
    return i + 1;
}
```

常用範例 : 
像是你要按照某個特定的順序排序的時候
```cpp=
vector<int> a, b;
sort(a.begin(), a.end(), [](int i, int j){
    return i > j;
});
sort(a.begin(), a.end(), [&](int i, int j){
    return b[i] > b[j];
});
```

## 賦值

```cpp=
auto foo = [&](int i){
    return i + 1;
};
cout << foo(1);
```

可以打一個auto然後打一個變數代表這個函數，這樣這個變數就代表一個lambda function

:::info
:bulb: 大括號後面記得打分號
:::

因為真正的變數型態很長，所以通常都會打auto，後面會提到不能打auto的情況

## 指定回傳

```cpp=
auto foo = [&](int i) -> int {
    return i + 1;
};
cout << foo(1);
```

像這樣在後面打一個箭頭，然後再打回傳型態就可以指定要回傳什麼，上面的範例為回傳int

常用範例 : 
像是遇到條件很長的時候

```cpp=
auto bound = [&](int i, int j) -> bool {
    return 0 <= i && i < n && 0 <= j && j < m;
};
```

## 資料型態

```cpp=
function<void(int)>
```

function<> 代表你要宣告一個lambda function，裡面放的是資料型態，void代表這是一個void function，()裡面放的是你要傳入的變數型態，像是void(int)代表一個void的函數，然後要傳入一個變數int
 


## 遞迴

不能使用auto的情況來了

如果你要函數遞迴的話，因為編譯器不知道函數會回傳什麼，所以要先給那個函數一個型態才能使用

```cpp=
function<void(int)> foo = [&foo](int i){
    if (i > 10){return;}
    cout << i << endl;
    foo(i + 1);
};
```
**程式碼範例變數名稱常用foo 跟bar
根本是父權遺毒
應該要用
mu 跟ma**


常用範例 : 

如果要做dfs的時候
```cpp=
function<void(int)> dfs = [&](int p){
    vis[p] = true;
    for (int x: g[p]){
        if (vis[x]){continue;}
        dfs(x);
    }
};
```
