iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0

接下來要講的是指標(pointer),其實之前在講陣列的時候,就已經有出現過 pointer 的應用,現在我們要來真的說說什麼是 pointer!

Pointer 是一種可以儲存 memory address 的變數,可以指向任何一種型態,不論 int、float。

其宣告方式為:

type pointed* pointer name;

常常與pointer搭配的還有&,我們稱&為 address-of operator,可以用這個符號來取得指標指向的變數之地址。

其使用方式為:

pointer name = &variable name;

要注意的是,當賦予 pointer 一個 address 的時候,那個變數與指標的 type 要相同。

例如:

int a = 5;
int* aPtr = &a;

其中的aPtr就是指向a,存著a的 address,而aaPtr的型態皆為 int。

double b = 10.5;
double* bPtr = &b;

其中的bPtr就是指向b,存著b的 address,而bbPtr的型態皆為 double。

兩個 pointer不能相加,但可相減。例如:

double a[3] = {10.5, 10.6, 10.7};
double* b = &a[0];
double* c = &a[2];

cout << c - b;	// 2

這個2代表bc差兩格。

Address operators

所以到目前為止,整理一下:
&:address-of operator ->回傳 variable’s address
*:dereference operator -> 回傳 pointed variable

舉例來說:

int a = 5;
a:5
&a:回傳`a`的地址
int* aPtr = &a;
aPtr:存`a`的地址
&aPtr:回傳’aPtr’的地址
*aPtr:回傳`a`

其實有點像是邏輯問題,搞懂需要一點時間....

如果搞懂的話,這邊再補充一下:

int a = 10;
int* ptr = &a;
*ptr = 5;

若程式碼長這樣,a的值就會變成 5。

Null pointers

宣告的時候,我們可以將一個指標初始化為nullptr,也就是他並沒有指向任何東西:

int* ptr = nullptr;

此時若cout << *ptr,會發生 run-time error到情況!

接下來要說説傳值的兩種方法:
Call by reference
什麼是“reference”呢?其實就是一個變數的別名!

例如我們寫

int &d = c;

就是宣告 d 是 c 的 reference,也就是說,d = 20 的話,c 就是 20。

但是不能寫

int &d = 10;

Call by pointers
其實就是 call by address,舉個例,我們寫一個叫swap的函數,若將兩數值傳入,就能將其交換:

void swap(int *ptrA, int *ptrB) {
    int temp = *ptrA ; 
    *ptrA = *ptrB;
    *ptrB = temp;
}

int main() {

    int a = 1;
    int b = 0;

    cout << a << "," << b << "\n";		// 1, 0

    swap(&a, &b);	// 傳入a, b的address進行交換

    cout << a << "," << b << "\n";	// 0, 1

    return 0;
}

輸出後,我們可以看到ab值交換了,這是將ab傳入的address進行交換,之後在main 裡面利用&符號傳入 address。

最後,要介紹前面就提過的動態陣列(dynamic memory allocation)。

Dynamic memory allocation

int* a = new int[5];

我們都知道這是宣告一長度為5的動態陣列,不過我到現在才知道,原來其中的new是代表:配一塊空間並回傳其 address。

Memory leak
在動態陣列中,且還在 run time 時,系統不會自己釋放動態陣列的記憶體(若是固定的陣列就會),因為這個空間是沒有名字的。

因此,為了避免 code 佔太多記憶體空間,下面要寫 delete statement,來手動釋放記憶體空間:


int* a = new int[5];

// statements

delete [] a;

二維動態陣列
若我們要宣告一個 n X m 的二維陣列,裡面各項都是 0:

int** array = new int*[n];
for (int i = 0; i < n; i++) {
    array[i] = new int[m];
    for (int j = 0; j < m; j++) {
	array[i][j] = 0;
    }
}

// statements

delete [] array;

最後也要記得加上 delete statement。

Pointer 的筆記就到此為止,對於 pointer 的概念我還是有點似懂非懂,希望再多練習幾題題目後,我能更熟悉!


上一篇
【DAY 22】Algorithm - Insertion sort 插入排序法
下一篇
【Day 24】Pointer - Practice 1
系列文
C++ 三十天學習紀錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言