---
# System prepended metadata

title: C 筆記

---

# C 筆記
## 標頭檔
- 提供一些已經定義好的函式
- 用 #include 來引入標頭檔
- .h 是C標頭檔的副檔名
#### 範例
```c=
#include <stdio.h> // 提供一些函式，例如：printf()、scanf()
```
Actually, it is legal to compile code without including any header
```c=
int main() {
    int a = 0, b = 1;
    int sum;
    sum = a + b;
}

// 在這個例子裡，使用 scanf() 或 printf() 是不合法的
// 因為我們沒有引入 <stdio.h>.
```
## 簡易程式碼架構
```c=
#include <stdio.h> // 引入標頭檔

// 主函式：編譯器會從這個函式開始執行程式碼
int main() {
    
    // 宣告
    int a, b, sum;
    
    // 輸入
    scanf("%d %d", &a, &b);
    
    // 運算
    sum = a + b;
    
    // 輸出
    printf("%d\n", sum);
    
    // 回傳
    return 0;
}
```

## 變數
- 用來儲存數值的東西
- ***命名要有意義***
- ***不同型別的資料其實都是數字，只是大小不同而已***
- 1 byte = 8 bits
- 以下是C自帶的基本資料型別
### int
- 名稱：整數
- 大小：4 bytes
- 格式字符：%d
### long long
- 名稱：長整數
- 大小：8 bytes
- 格式字符：%lld
### char
- 名稱：字元
- 大小：1 bytes
- 格式字符：%c
- ASCII編碼: [ASCII - 維基百科，自由的百科全書](https://zh.wikipedia.org/zh-tw/ASCII)
### float
- 名稱：浮點數
- 大小：4 bytes
- 格式字符：%f
### double
- 名稱：長浮點數
- 大小：8 bytes
- 格式字符：%lf
### usigned
- 名稱：非負整數
- 大小：4 bytes
- 格式字符：%u
### pointer
- 名稱：指標
- 大小：4 bytes
- 格式字符：%p

### 範例
```c=
#include <stdio.h>

int main() {
    int a = 1;
    long long b = 2;
    char c = 'A';
    float d = 2.3;
    double e = 4.5;
    unsigned f = -1;
    printf("%d, %lld, %c, %f, %lf, %u\n", a, b, c, d, e, f);
}

// output: 1, 2, A, 2.300000, 4.500000, 4294967295
```
### 全域變數 / 區域變數
- 全域變數：宣告在函式與迴圈之外的變數，可以被所有的函式或迴圈使用
- 區域變數：宣告在函式或迴圈之內的變數，只能被特定的函式或迴圈使用
```c=
#include <stdio.h>

int globalVariable;

int main() {
    int localVariable;
}
```
---
### 參考
[Data Types in C](https://www.geeksforgeeks.org/data-types-in-c/?ref=lbp)

## 格式字串
### 簡介
格式字串是一種含有格式字符的特殊字串，可以想像成一個輸入或輸出的模板。例如：
```c=
#include <stdio.h>

int main() {
    char h[6] = "hello";
    char w[6] = "world";
    printf("h is %s.\n", h);
    printf("w is %s.\n", w);
}

// output: h is hello.
//         w is world.
```
### 格式字符
用來告訴電腦該如何看待後面的數字。例如：
```c=
#include <stdio.h>

int main() {
    int a = 48;
    printf("As an integer, a is %d.\n", a);
    printf("As a character, a is %c.\n", a);
    printf("%c + %d = %d\n", a, a, a);
}

// output: As an integer, a is 48.
//         As a character, a is 0.
//         0 + 48 = 48
// 根據ASCII編碼表，字元'0'是48
```
#### 基本的格式字符


| int | char | string | float | long long | double | usigned |
|:---:|:----:|:------:|:-----:|:---------:|:------:|:-------:|
| %d  |  %c  |   %s   |  %f   |   %lld    |  %lf   |   %u    |

---
### 參考
[printf() 格式字串的使用方法](https://dev.to/codemee/printf-ge-shi-zi-chuan-de-shi-yong-fang-fa-n8f)



## 輸出
### printf()

小知識：為什麼是printf()而不是printl()或其他字母呢？因為f代表的是format的意思，即格式化輸出。
```c=
printf(format string, variable1, variable2, ...);
```

#### 範例
```c=
#include <stdio.h>

int main() {
    printf("Zero is %d.\nOne is %d.\n", 0, 1);
}

// output: Zero is 0.
//         One is 1.
```
### putchar()
用來印出字元的函式
```c=
#include <stdio.h>

int main() {
    putchar('a');
    putchar(' ');
    putchar(48);
}

// output: a 0
// 根據ASCII編碼表，字元'0'是48
```
## Input
### scanf()
用法跟printf()很像，但scanf()是用來輸入的
```c=
scanf(format string, address of variable1, address of variable2, ...);
```
#### Example
```c=
#include <stdio.h>

int main() {
    int a, b;
    scanf("%d %d", &a, &b); // & 是取址符號，即取得該變數儲存之位址
    printf("%d %d\n", a, b);
}

// input: 12 13
// output: 12 13
```
### getchar()
跟 scanf("%c") 的功能一模一樣
```c=
#include <stdio.h>

int main() {
    char c = getchar();
    putchar(c);
}

// input: ABC
// output: A
```
### gets() / fgets()
如果想要輸入含有空白的字串，可以使用這兩個函式。

---
### 參考
[fgets函數及其用法，C語言fgets函數詳解](https://tw511.com/a/01/1045.html)

## 運算子
### 數學運算子
#### + : 加
```c=
#include <stdio.h>

int main() {
    int a = 20, b = 3;
    printf("%d\n", a + b);
}

// output: 23
```

#### - : 減
```c=
#include <stdio.h>

int main() {
    int a = 20, b = 3;
    printf("%d\n", a - b);
}

// output: 17
```

#### * : 乘
```c=
#include <stdio.h>

int main() {
    int a = 20, b = 3;
    printf("%d\n", a * b);
}

// output: 60
```

#### / : 除
```c=
#include <stdio.h>

int main() {
    int a = 20, b = 3;
    printf("%d\n", a / b);
}

// output: 6
```

#### % : 取餘數
```c=
#include <stdio.h>

int main() {
    int a = 20, b = 3;
    printf("%d\n", a % b);
}

// output: 2
```
### 比較運算子
#### == : 等於
```c=
#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 20;
    printf("(%d, %d)\n", a == b, b == c);
}

// output: (0, 1)
```

#### != : 不等於
```c=
#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 20;
    printf("(%d, %d)\n", a != b, b != c);
}

// output: (1, 0)
```

#### < : 小於
```c=
#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 20;
    printf("(%d, %d)\n", a < b, b < c);
}

// output: (1, 0)
```

#### > : 大於
```c=
#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 20;
    printf("(%d, %d)\n", a > b, b > c);
}

// output: (0, 0)
```

#### <= : 小於等於
```c=
#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 20;
    printf("(%d, %d)\n", a <= b, b <= c);
}

// output: (1, 1)
```

#### >= : 大於等於
```c=
#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 20;
    printf("(%d, %d)\n", a >= b, b >= c);
}

// output: (0, 1)
```
### 二元運算子
將所有數字以二進位看待來運算

#### & : AND
##### 真值表

|  AND  |  1  |  0  |
|:-----:|:---:|:---:|
| **1** |  1  |  0  |
| **0** |  0  |  0  |
```c=
#include <stdio.h>

int main() {
    int a = 0, b = 1, c = 3;
    printf("(%d, %d)\n", a & b, b & c);
}

// output: (0, 1)
// 在二進制中，a 是 00000000，b 是 00000001，c 是 00000011
// 在二進制中，0 是 00000000，1 是 00000001
```

#### | : OR
##### 真值表

|  OR   |  1  |  0  |
|:-----:|:---:|:---:|
| **1** |  1  |  1  |
| **0** |  1  |  0  |
```c=
#include <stdio.h>

int main() {
    int a = 0, b = 1, c = 3;
    printf("(%d, %d)\n", a | b, b | c);
}

// output: (1, 3)
// 在二進制中，a 是 00000000，b 是 00000001，c 是 00000011
// 在二進制中，1 是 00000001，3 是 00000011
```

#### ^ : XOR
##### 真值表

|  XOR  |  1  |  0  |
|:-----:|:---:|:---:|
| **1** |  0  |  1  |
| **0** |  1  |  0  |
```c=
#include <stdio.h>

int main() {
    int a = 0, b = 1, c = 3;
    printf("(%d, %d)\n", a ^ b, b ^ c);
}

// output: (1, 2)
// 在二進制中，a 是 00000000，b 是 00000001，c 是 00000011
// 在二進制中，1 是 00000001，2 是 00000010
```

#### ~ : 取1的補數 (0、1互換)
Ex: 101101 -> 010010
```c=
#include <stdio.h>

int main() {
    int a = 1, b = 2;
    printf("(%d, %d)\n", ~a, ~b);
}

// output: (-2, -3)
// 在二進制中， a 是 00000001， b 是 00000010
// 在二進制中，-2 是 11111110，-3 是 11111101
```

#### << : 左移
```c=
#include <stdio.h>

int main() {
    int a = 3;
    printf("%d\n", a << 2);
}

// output: 12
// 在二進制中， a 是 00000011
// 在二進制中，12 是 00001100
```

#### >> : 右移
```c=
#include <stdio.h>

int main() {
    int a = 12;
    printf("%d\n", a >> 2);
}

// output: 3
// 在二進制中，a 是 00001100
// 在二進制中，3 是 00000011
```
### Assign
#### = : 賦值
```c=
#include <stdio.h>

int main() {
    int a;
    printf("%d\n", a = 2);
}

// output: 2
```
#### += : 加並賦值

```c=
a += 1 is equal to a = a + 1
```

```c=
#include <stdio.h>

int main() {
    int a = 0, b = 0;
    a + 1;
    b += 1;
    printf("(%d, %d)\n", a, b);
}

// output: (0, 1)
```
#### 我們也可以使用 -=, *=, /=, &=, |=... 如同上面

### 邏輯運算子
0 是 false ，其他數字是 true
true 的預設值是 1 ， false 的預設值是 0
#### && : logic AND
##### 真值表

|    AND    | true  | false |
|:---------:|:-----:|:-----:|
| **true**  | true  | false |
| **false** | false | false |

```c=
#include <stdio.h>

int main() {
    int a = 0, b = 3;
    printf("%d\n", a && b);
}

// output: 0
```

#### || : logic OR
##### 真值表

|    OR     | true | false |
|:---------:|:----:|:-----:|
| **true**  | true | true  |
| **false** | true | false |
```c=
#include <stdio.h>

int main() {
    int a = 0, b = 3;
    printf("%d\n", a || b);
}

// output: 1
```

#### ! : logic NOT
```c=
#include <stdio.h>

int main() {
    int a = 0, b = 3;
    printf("(%d, %d)\n", !a, !b);
}

// output: (1, 0)
```

### ++ / -- --
#### Intro
與 += 1 / -= 1 相同，但是放在變數前後用法會有差別

**放在變數後**
先執行該行再 ++ / -- --
```c=
#include <stdio.h>

int main() {
    int a = 0;
    while (a < 5) printf("%d ", a++);
    printf("\n");
}

// output: 0 1 2 3 4 
```
**放在變數前**
先 ++ / -- -- 再執行該行
```c=
#include <stdio.h>

int main() {
    int a = 0;
    while (a < 5) printf("%d ", ++a);
    printf("\n");
}

// output: 1 2 3 4 5 
```
## if / else
### 簡介
我們可以用 if / else 去控制在特定情況下想做的事
```c=
if (條件１) {
    條件１成立要做的事
}
else if (條件２) {
    條件１不成立且條件２成立要做的事
}
.
.
.
else {
    所有條件都不成立要做的事
}
```

### 範例
```c=
#include <stdio.h>

int main() {
    int a = 4;
    if (a > 4) {
        printf("a > 4\n");
    }
    else if (a < 4) {
        printf("a < 4\n");
    }
    else {
        printf("a == 4\n");
    }
}

// output: a == 4
```
如果在 if / else 後面只有一行程式碼，那可以省略大括號
```c=
#include <stdio.h>

int main() {
    int a = 4;
    if (a > 4) printf("a > 4\n");
    else if (a < 4) printf("a < 4\n");
    else printf("a == 4\n");
}

// output: a == 4
```

## switch
### 簡介
跟 if / else很像，但效率比較高
***要記得加"break"***
```c=
switch(參數) {
    case 常數1:
        要做的事
        break;
    case 常數2:
        要做的事
        break;
    .
    .
    .
    default:
        TODO
        break;
}
```
### 範例
```c=
#include <stdio.h>

int main() {
    int a = 4;
    switch(a) {
        case 2:
            printf("two\n");
            break;
        case 4:
            printf("four\n");
            break;
        default:
            printf("default\n");
    }
}

// output: four
```
如果我們沒打 "break"，會變成下面這種情況：
```c=
#include <stdio.h>

int main() {
    int a = 4;
    switch(a) {
        case 2:
            printf("two\n");
        case 4:
            printf("four\n");
        default:
            printf("default\n");
    }
}

// output: four
//         default
```

## ? : 表達式
### 簡介
```c=
條件 ? 條件成立要做的事 : 條件不成立要做的事;
```
### 範例
```c=
#include <stdio.h>

int main() {
    int a = 1, b = 0;
    printf("%d\n", a + b ? a : b);
}

// output: 1
```

## 迴圈
### 簡介
我們可以使用迴圈來執行重複的動作以精簡程式碼
### while 迴圈
如果目前的狀態符合設定的執行條件，則迴圈會一直重複執行
```c=
while (執行條件) {
    要重複做的事
}
```
#### 範例
```c=
#include <stdio.h>
    
int main() {
    int i = 0;
    while (i < 5) {
        printf("%d ", i);
        i++;
    }
}

// output: 0 1 2 3 4 
```

### for 迴圈
跟while迴圈很像，不過多出了初始值以及迴圈結束後要自動做的事情
```c=
for (初始值; 執行條件; 迴圈結束要做的事情) {
    要重複做的事情
}
```
#### 範例

```c=
#include <stdio.h>
    
int main() {
    for (int i = 0; i < 5; i++) {
        printf("%d ", i);
    }
}

// output: 0 1 2 3 4 
```
如果迴圈內要做的事情只有一行，那麼可以省略大括號{ }
```c=
#include <stdio.h>
    
int main() {
    for (int i = 0; i < 5; i++) printf("%d ", i);
}

// output: 0 1 2 3 4 
```

### break
立刻跳脫迴圈
```c=
#include <stdio.h>

int main() {
    for (int i = 0; i < 5; i++) {
        if (i == 3) break;
        printf("%d\n", i);
    }
}

// output: 0
//         1
//         2
```
### continue
立刻進入下一層迴圈
```c=
#include <stdio.h>

int main() {
    for (int i = 0; i < 5; i++) {
        if (i == 3) continue;
        printf("%d\n", i);
    }
}

// output: 0
//         1
//         2
//         3
```

### 雙重迴圈

## Array
一個可以儲存多個相同型別變數的容器
### 宣告
- 編號從0開始
```c=
變數型別 陣列名稱[長度] = {元素０, 元素１, ...};
```
#### 範例
```c=
int int_arr[10] = {0};
char str[10] = {'\0'};
void* ptr[10] = {NULL};
// and so on...
```

### 初始化
- 如果將陣列宣告成全域變數，那麼陣列所有的值會自動被預設成0。
- 如果宣告成區域變數，則會是隨機數值。
- 如果我們只初始化陣列中的部分元素，則剩下的會被預設成0。

#### 範例
```c=
#include <stdio.h>

int global_arr[5];

int main() {
    int local_arr_init[5] = {1, 2, 3};
    int local_arr_Noinit[5];

    for (int i = 0; i < 5; i++)
        printf("%d ", global_arr[i]);
    printf("\n");

    for (int i = 0; i < 5; i++)
        printf("%d ", local_arr_init[i]);
    printf("\n");

    for (int i = 0; i < 5; i++)
        printf("%d ", local_arr_Noinit[i]);
    printf("\n");
}

// output: 0 0 0 0 0 
//         1 2 3 0 0
//         random value...
```

### 獲取特定的元素
- 利用中括號跟編號 [ 編號 ] 去獲取特定元素
- 編號從0開始
```c=
陣列名稱[編號]
```
#### 範例
```c=
#include <stdio.h>

int main() {
    int arr[3] = {0, 1, 2};
    for (int i = 0; i < 3; i++) {
        printf("%d ", arr[i]);
    }
}

// output: 0 1 2
```

### 費氏數列
費氏數列定義：
$a_n = a_{n-1} + a_{n-2}$ ; $a_{1} = a_{2} = 1$
#### 範例
```c=
#include <stdio.h>

int main() {
    // 宣告
    int arr[10];
    
    // 給定費氏數列頭兩項的值
    arr[0] = arr[1] = 1;

    // 計算剩下項的數值
    for (int i = 2; i < 10; i++) {
        arr[i] = arr[i - 1] + arr[i - 2];
    }

    // 輸出
    for (int i = 0; i < 10; i++) {
        printf("%d", arr[i]);
        printf(i == 9 ? "\n" : " ");
    }
}

// output: 1 1 2 3 5 8 13 21 34 55
```

### 二維陣列
- 搭配雙重迴圈使用
```c=
type name[row_len][col_len] = { {Element00, Element01, ...}, {Element10, ...}, ... };
```


|   | Column 0 | Column 1 |
| -------- | -------- | -------- |
| **Row 0**| arr[0][0]| arr[0][1]|
| **Row 1**| arr[1][0]| arr[1][1]|
 
#### 範例
```c=
#include <stdio.h>

int main() {
    int arr[5][5];
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            arr[i][j] = i * 10 + j;
        }
    }
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            printf("%02d", arr[i][j]);
            printf(j == 4 ? "\n" : " ");
        }
    }
}

//         ij ij ij ij ij
//         --------------
// output: 00 01 02 03 04
//         10 11 12 13 14
//         20 21 22 23 24
//         30 31 32 33 34
//         40 41 42 43 44
```

## Function
Actually we have learned it before in the beginning.
```c=
#include <stdio.h>

// declare the function called "main"
int main() {
    printf("hello world!\n"); // call the function called "printf()"
}

// output: hello world!
```
### Declaration
Note that we can also pass no parameter into function like what we do to main function.
```c=
return_type function_name(parameter1, parameter2, ...) {
    TODO
    return; // depend on your return_type
}
```
### Call Function
```c=
function_name(parameter1, parameter2, ...);
```
#### Example
```c=
#include <stdio.h>

// times 10
int MulBy10(int para) {
    return para * 10;
}

int main() {
    int a = 2;
    a = MulBy10(a);
    printf("%d\n", a);
}

// output: 20
```

### Declaration Order Problem...
#### An Error Example
```c=
#include <stdio.h>

// count doesn't know who are add and minus.
// This causes an error.
int count(int op, int a, int b) {
    if (op == 1) return add(a, b);
    else return minus(a, b);
}

int add(int a, int b) {
    return a + b;
}

int minus(int a, int b) {
    return a - b;
}

int main() {
    int op, a, b;
    scanf("%d %d %d", &op, &a, &b);
    printf("%d\n", count(op, a, b));
}
```
***Recommend that declare the function first and then write the implement below***
#### Solution
```c=
#include <stdio.h>

// Declare functions first.
int count(int op, int a, int b);
int add(int a, int b);
int minus(int a, int b);

int main() {
    int op, a, b;
    scanf("%d %d %d", &op, &a, &b);
    printf("%d\n", count(op, a, b));
}

// Write functions' implement below
int count(int op, int a, int b) {
    if (op == 1) return add(a, b);
    else return minus(a, b);
}

int add(int a, int b) {
    return a + b;
}

int minus(int a, int b) {
    return a - b;
}
```
### Pass Value? Pass Address?
Let's look at the example below
```c=
#include <stdio.h>

void add(int a, int b);

int main() {
    int x = 2, y = 3;
    add(x, y);
    printf("x = %d\n", x);
}

void add(int a, int b) {
    a += b;
    printf("a = %d\n", a);
}

// output: a = 5
//         x = 2
```
You may wonder why x's value doesn't change after running add function.
For this example, we only pass the values of x and y to the add function.
The compiler copies the value of x to a and the value of y to b, and then assign a + b to a.
For this example, we can regard it as below:
```c=
#include <stdio.h>

int main() {
    int x = 2, y = 3;
    int a = x, b = y;
    a += b;
    printf("a = %d\n", a);
    printf("x = %d\n", x);
}

// output: a = 5
//         x = 2
```
So how do we deal with this problem?
Here are two ways to solve it.
- **Solution 1:** Use global variables (Recommend if you don't know pointer)
```c=
#include <stdio.h>

int x = 2, y = 3;

void add();

int main() {
    add();
    printf("x = %d\n", x);
}

void add() {
    x += y;
    printf("x = %d\n", x);
}

// output: x = 5
//         x = 5
```
- **Solution 2:** Use pointer
```c=
#include <stdio.h>

void add(int* a, int* b);

int main() {
    int x = 2, y = 3;
    add(&x, &y); // use & can get the variable's address
    printf("x = %d\n", x);
}

void add(int* a, int* b) {
    *a += *b; // use * can get the pointer's value
    printf("a = %d\n", *a);
}

// output: a = 5
//         x = 5
```

## Recursion
### Intro
A function calls itself again and again.

![](https://hackmd.io/_uploads/rJjn8jzdn.png)
### Example
```c=
#include <stdio.h>

void func_f(int a) {
    if (a > 0) func_f(a - 1);
    printf("%d ", a);
}

int main() {
    func_f(5);
}

// output: 0 1 2 3 4 5 
```

### Count factorial
Note that $n! = n(n-1)(n-2)... 2*1$
```c=
#include <stdio.h>

int countFactorial(int a) {
    if (a <= 1) return 1;             // stop condition
    return a * countFactorial(a - 1); // call itself recursively
}

int main() {
    printf("%d\n", countFactorial(5));
}

// output: 120
// Note that 5 * 4 * 3 * 2 * 1 == 120
```
### Fibonacci sequence
Note that Fibonacci sequence:
$a_n = a_{n-1} + a_{n-2}$ ; $a_{1} = a_{2} = 1$
```c=
#include <stdio.h>

int rec(int a, int b, int k);

int main() {
    int k = 10;
    printf("arr[%d] = %d\n", k, rec(0, 1, k));
}

int rec(int a, int b, int k) {
    if (k == 1) return b;        // stop condition
    return rec(b, a + b, k - 1); // call itself recursively
}

// output: arr[10] = 55
```

### Prefix Calculator
What is prefix calculator?
If we put operator to the front, and we call it prefix expression
For example: (1 + 2) * 4 => * + 1 2 4

![](https://hackmd.io/_uploads/Skpu9EQuh.png)
```c=
#include <stdio.h>

int count() {
    char c;
    scanf("%c", &c);
    if (c == '+') return count() + count();
    if (c == '-') return count() - count();
    if (c == '*') return count() * count();
    if (c == '/') return count() / count();
    return c - '0';
}

int main() {
    printf("%d\n", count());
}

// input: *+124
// output: 12
```

### Minimum Step
Given a maze with '#', '.', 'S', 'E'.
'#': wall
'.': path
'S': start point
'E': end point
Please count the minimum steps to reach the end point from the start point.

**Input**
First row will have two integer H, W, which means the height and the width of the map repectively.
And then there will be H rows, W columns characters with only '#', '.', 'S', 'E'.
It guarantees that the maze will be surrounded by '#'.
5 <= H, W <= 100000

**Output**
Please output the minimum steps from 'S' to 'E'. Please output '\n' in the end.

**Sample Input**
```=
6 7
#######
##S...#
#...#.#
#.##E.#
#.....#
#######
```
**Sample Output**
```=
6

```
<!--**Sample Code**
```c=
#include <stdio.h>
#include <limits.h>

int  R, C, Start[2], min_distance = INT_MAX;
char map[10001][10001]; // 1 <= R, C <= 10000

void walk(int row, int col, int distance);

int main() {

    // get the range of map
    scanf("%d %d", &R, &C);

    // get the map and the index of start
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            scanf(" %c", &map[i][j]);
            if (map[i][j] == 'S') {
                Start[0] = i;
                Start[1] = j;
            }
        }
    }

    // recursion
    walk(Start[0], Start[1], 0);

    // output
    printf("%d\n", min_distance == INT_MAX ? 0 : min_distance);
	
}

void walk(int row, int col, int distance) {

    // more than the result we count before
    if (distance > min_distance) return;

    // reach the end point
    if (map[row][col] == 'E') {
        min_distance = distance;
        return;
    }

    // try four directions
    for (int i = -1; i <= 1; i += 2) {
        for (int j = 0; j <= 1; j++) {
            if (map[row + i * j][col + i * (1 - j)] != '#') {
                map[row][col] = '#';
                walk(row + i * j, col + i * (1 - j), distance + 1);
                map[row][col] = '*';
            }
        }
    }
	
}
```-->

## Pointer
A type of variables that store variable's

```c=
#include <stdio.h>

int main() {
    int a = 5;
    int* ptr = &a;
    printf("The value of a is %d.\n", a);
    printf("The address of a is %p\n", &a);
    printf("The value of ptr is %p\n", ptr);
    printf("The value store in %p is %d\n", ptr, *ptr);
    printf("The address of ptr is %p\n", &ptr);
}

// output: The value of a is 5.
//         The address of a is 0061FF1C
//         The value of ptr is 0061FF1C
//         The value store in 0061FF1C is 5
//         The address of ptr is 0061FF18
```

## struct
### Intro
We can use struct to define our own data types
```c=
struct structure_name {
    // data
};
```
### Example
```c=
#include <stdio.h>

struct _student {
    int number;
    int age;
    int height;
};

int main() {
    struct _student s; // declaration
    s.number = 1; // use '.' to access specific data in the structure you defined
    s.age = 13;
    s.height = 176;
    printf("Number %d is %d years old and %d centimeters tall.\n", s.number, s.age, s.height);
}

// output: Number 1 is 13 years old and 176 centimeters tall.
```

## typedef
### Intro
Assign a name for a specific data type.
```c=
typedef data_type_name your_own_name;
```
### Example
```c=
#include <stdio.h>

typedef int Integer;

typedef struct _node {
    int value;
    struct _node* next;
} Node;

int main() {
    Integer a = 5;
    Node n;
    n.value = 5;
    n.next = NULL;
    printf("%d, %d\n", a, n.value);
}

// output: 5, 5
```

## sizeof()
### Intro
Get how many bytes a variable or a data type is

```c=
sizeof(data_type);
sizeof(variable_name);
```
### Example
```c=
#include <stdio.h>

int main() {
    int a, arr[5];
    printf("%d, %d, %d\n", sizeof(a), sizeof(arr), sizeof(int));
}

// output: 4, 20, 4
```

## malloc()
### Intro
Allocate memories with given size and return the head address back
```c=
malloc(how_many_bytes_of_memories_you_want_to_allocate);
```
### Example
```c=
#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*) malloc(sizeof(int));
    *ptr = 20;
    printf("%d\n", *ptr);
}

// output: 20
```
## Linked List



![](https://hackmd.io/_uploads/S1uN2LTj2.jpg)

