---
# System prepended metadata

title: 陣列和指標 Array & Pointer
tags: [C++Book]

---

# 陣列和指標 Array & Pointer
###### tags: `C++Book`

==陣列是指向本身頭元素的位址==
* arr與&arr[0]所指向的 位置是相同的

## 指標的加法

指標的加法代表意義是：前進多少個單位。

因此，指向 int 的指標 p，
`p+1` 代表的是指標 p 指向的位址，再前進一個 int 的位址。

由於前進的是一個 int 的位址，實際位址是前進了 4，
因為位址的單位是 byte，而 int 佔用 4 byte。

同理，若是 char 指標，則實際會前進 1 byte；
long long 指標則會前進 8 byte。 

## 指標
如果宣告指標但不指定初值，存取未知位址的記憶體內容是危險的。如果指標一開始不指向任何的物 件，則可設定初值為0，表示不指向任何物件，例如：
`int *iptr = 0;`
		
		
### void 指標
有時候，不希望關心型態的問題，您可以使用void*來宣告指標，例如： 
void *ptr;
		
由於void型態的指標沒有任何的型態資訊，所以只用來持有位址資訊，您不可以使用*運算子對void型態指標提取
必須轉型：

#### i. 使用 reinterpret_cast作轉型動作至對應的型態
```cpp
    int var = 10; 
    void *vptr = &var ; 

// 下面這句不可行，void型態指標不可取值 
//cout << *vptr << endl;

// 轉型為int型態指標並指定給iptr 
int *iptr = reinterpret_cast<int*>(vptr);
```

#### ii. 舊風格的轉型語法：
```cpp
int var = 10; 
void *vptr = &var ; 
// 轉型為int型態指標並指定給iptr 
int *iptr = (int*)(vptr);
```
### 函數參考

#### 在參數前加上 &
```cpp
swap(int &a, int &b){
    int tmp = a;
    a = b;
    b = tmp;
}
```
#### 用指標實現
```
void swap(int* a, int* b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
// 以 swap(&x, &y) 呼叫
```

#### pointer to pointer, reference to pointer

```cpp
int g_int = 0;
void changePtr(int* pInt){
        pInt = &g_int;
}
void main(){
        int myVar = 1;
        int* myVarPtr = &myVar;
        changePtr(maVarPtr);
}
//localPInt 值並不會改變
```

Pointer to Pointer
```cpp
int g_int = 0;
void changePtr(int **varPtr){    //用來裝指標的指標
        *varPtr = &g_int;  //varPtr 取值 =g_int 取址
}
void main(){
        int localInt = 1;
        int* ptr = &var;
        changePtr(&ptr); //傳入ptr的位址
}
```

refererence to pointer
```cpp
int g_int = 0;
void changePtr(int &*varPtr){   
        varPtr = &g_int;  //varPtr  =g_int 取址
}
void main(){
        int var = 1;
        int* ptr = &var;
        changePtr(ptr);
}
```