# 記憶體與指標
## 10/28社課
---
## 記憶體
電腦中儲存資料的地方
用圖片表示的話就是超長紙帶
----

一格的空間是1 bit (0 or 1的二進位制)
8格組成1 byte
----
int的組成是4bit
把數字轉成2進位制後
不能超過int的空間
可用longlong替代(8 bit)
----
int 變數 821091 轉成二進位制
位置 0xC8763
##### (~~星光流連擊~~)

----
### '='的運用
使用 '=' 賦值會改變原本存入變數的數
----
函數(Function)引用變數時
引入變數中存的值而非變數本身
這被稱為Call By Value
----
```cpp=
void add(int a, int b) {
a = a+b;
}
int main() {
int a = 1;
int b = 1;
add(a, b); //a應該等於2
cout<<a<<endl; //1+1=1
return 0;
}
```
眾所周知 1+1=1 (誤
----
```cpp=
void add(int *a, int *b) {
*a = *a + *b;
}
int main() {
int a = 1;
int b = 1;
add(a, b);
cout<<a<<endl; //1+1=2 a=2
return 0;
}
```
----
這裡的參數型態為 int*
也就是指向型態為 int 的 "指標"
也就是Call By Reference
----
reference沒有實際的記憶體空間
宣告reference變數時需初始化(參照其他變數)
初始化後就無法再參照到其他變數
```cpp=
int a=123;
int &reference=a;
```
----
Reference紀錄的是"值的位置"
值本身放在其他位置上
修改時會改到"紀錄位置"的值
---
## 指標 (Pointer)
----
記錄記憶體上位置的工具
與Reference很像 但能改變參照變數
也不需初始化 (比較好用)
----
```cpp=
int a = 1;
int *b = &a;
cout<< *b; //*b=1
*b = 2;
cout<< *b; //*b=2
```
----
指標也能讓函數修改變數
```cpp=
void add(int *a, int *b) {
*a = *a + *b;
}
int main() {
int a = 1;
int b = 1;
add(a, b);
cout<<a<<endl; //這裡的 a=2 被add函數修改了
return 0;
}
```
----
已宣告但還沒指向任何東西的指標為
空指標(Null Pointer)
空指標"不會"和任何有值的指標相等(無法比較)
---
### '*' 和 '&'的功能統整
----
## *
- 乘法運算(a*b)
- 指標宣告 (int *a)
- 複合指標 (int **a)(int ***a)
**a指的是指向(指向int變數的指標)的指標
----
## &
- 邏輯運算(and)
- 給指標位置(*a = &b)
- 位置運算(a &= b)
"a &= b"即為 a = a&b,以二進位制做運算
(ex 3 & 5 ----> 011 & 101 = 001 )
---
## 陣列和指標
----
陣列在記憶體上呈現連續的一段
實際上陣列紀錄了這段的開頭
也就是說 陣列 = 指標
----
```cpp=
int a[5] = {1, 2, 3, 4, 5};
cout << *(a + 3) << " " << a[3] << "\n"; // 輸出 4 4
*(a + 3) = 6; // a[3]=6
cout << *(a + 3) << " " << a[3] << "\n"; // 輸出 6 6
```
----
### 練習
[b964](https://zerojudge.tw/ShowProblem?problemid=b964)
可以試著用指標的方式去做
會比較懂怎麼用
{"title":"指標","description":"電腦中儲存資料的地方用圖片表示的話就是超長紙帶","contributors":"[{\"id\":\"f73e3593-2b30-4cf8-89e6-dc544aaab97d\",\"add\":2044,\"del\":41}]"}