---
# System prepended metadata

title: Brainfuck 學習筆記

---

# Brainfuck 學習筆記

:::info
:information_source: 作者
@bloodnighttw @WavJaby
:::

{%hackmd BJrTq20hE %}
<style>
.ui-comment-app .open-comments{
    background-color: #1e1e1e;
}
pre{
    margin-bottom: 0 !important;
}
p{
    margin: 10px 0 !important;
}
</style>

:::danger 
:warning: 警告 :warning: 
此語言相當的簡單 但是可讀性相當的差
腦波弱的相當建議不要來學
另外 可以搭配以下 IDE使用

https://github.com/wmww/BrainfuckIDE
:::

## 基本的語法

- ``+`` 
    - 在當前所在的記憶體值+1
      例如: 今天我的brainfuck程式碼如下
        ```=
        ++++
        ```
        記憶體則會出現以下狀況

        ```
        |3|0|0|0|0|0|0|0|0|......
         ↑
        ```
        
        因為沒有移目標記憶體 所以會在第0位加


- ``-`` 
    - 當前所在的記憶體值-1
        例如 今天我的brainfuck程式碼如下
        ```=
        ++++--
        ```
        記憶體會出現以下狀況

        剛開始有四個+，因為沒有移記憶體，所以會在第0位加到四。
        ```
        |4|0|0|0|0|0|0|0|0|......
         ↑
        ```

        接著，因為有兩個 - 且沒有移記憶體，所以會把第0位減到二。
        ```
        |2|0|0|0|0|0|0|0|0|......
         ↑
        ```
- ``>`` 
    - 把目標的記憶體向右移
        例如 我的brainfuck程式碼如下
        ```=
        >+++
        ```
        
        會先將目標記憶體往右移一格，在+1三次，所以結果會如下
        ```
        |0|3|0|0|0|0|0|0|0|......
           ↑
        ```
        
- ``<`` 
    - 記憶體向左移
        跟 ``＞`` 很像，不過是向左移，假如我的程式如下
        ```=
        >+++<++
        ```
        會先將目標記憶體往右移一格，在+1三次，所以結果會如下
        ```
        |0|3|0|0|0|0|0|0|0|......
           ↑
        ```
        接著向左移一格，並加上一兩次
        
        ```
        |2|3|0|0|0|0|0|0|0|......
         ↑
        ```

        
- ``.`` 
    - 印出當前的值 (對應到 ascii code)
        這邊請參考 ascii code所對應到的字元
        ![](https://i.imgur.com/ms7kR4y.png)
    
        假如今天的記憶體狀況長這樣
        ```
        |33|0|0|0|0|0|0|0|0|......
         ↑
        ```
        今天再加個``.``，就會印出驚嘆號``!``
        Example code here:
        ```=
        ++++++++++ ++++++++++ ++++++++++ +++ . 這邊有33個加號
        ```
        


- ``[`` 和 ``]`` 
    - 相當於while loop
      `[`如果當前記憶體為非零則執行`[]`內程式，否則跳過。
      `]`如果當前記憶體為非零則回到他的`[`，否則跳出迴圈。
      


- ``,`` 
    - 把當前input的東西存入當前記憶體



## 當程式碼過長的解法

<!-- :::spoiler Hello World -->

:::success
使用 `.` 印出來的值是使用當前記憶體位置對應的Ascii Code。

像是 `++++++++++ ++++++++++ ++++++++++ +++.` 會印出 `!` ，因為在當前記憶體位置的數值是 *33*，對應的ASCII就是 `!` 。

但是如果我們要列印 `e` 的時候寫 101 個 ``+`` 是非常不實際的，所以我們需要用Brainfuck的loop功能。
:::
### 乘法的概念
```= 
++++++++++[>++++++++++<-]>
```
這段程式碼會將記憶體0的位置設置為10，接著執行`[]`內的內容
1. `[` 如果記憶體0(當前位置)之數值大於0，執行 `[]` 內的程式；否則跳過 `[]` 。
2. `>` 記憶體位置+1
3. `++++++++++` 將記憶體1的值增加10
4. `<-` 向左移動，將記憶體0的值-1
5. `]` 如果記憶體0(當前位置)之數值大於0，回到他的`[`，否則跳出迴圈

結果:每次執行記憶體0數值-1，記憶體1數值+10，當記憶體0數值為0跳出迴圈，迴圈總共執行10次，故記憶體1數值為100。

所以當我們要印出`e`的時候就只要10x10+1就可以完成了
```=
++++++++++[>++++++++++<-]>+. 輸出 e
```

## 練習

### 印出 hello world

:::spoiler Hello world 解答

:warning: 最佳解參考維基百科 :D
```javascript=
//建立ASCII 10 30 100 7
++++++++++[>+>+++>++++++++++>+++++++<<<<-]>
//Hello
>>>++.
<+.
+++++++..
+++.
//space
<++.
//World
>>>+++++[<+++>-]<.
<.
+++.
------.
--------.
//!
<+.
```




