{C++}

pointer 指標

記憶體的位址

什麼是位址?

# POINTER

由 Jirka Matousek from Brussels Taipei Hong Kong Singapore Prague Shenzhen - Taipei, Taiwan, CC BY 2.0,

https://commons.wikimedia.org/w/index.php?curid=125896874

名稱:臺北市立第一女子高級中學

地址:臺北市中正區重慶南路一段165號

變數的名稱

變數的記憶體位置

變數的值

(指標裡存的東西)

位址

  • 記憶體可以看成許多連續排列的位元組
  • 每個變數會對應到一個記憶體位址
  • 變數的資料型態決定它分配到多大
    的記憶體
    • int n = 10,4 bytes
    • char c = 'A',1 byte
0
0 1 0 1 1 0 0 0

= 1 bit

= 1 byte

# POINTER

& 取址運算子

  • 可以取得變數的位址
    • &n = 2001
    • &c = 2007
  • 無法對運算式取址
# POINTER

& 參考(別名)

int a = 10;
int& b = a;
  • b 的位址 = a 的位址
  • 改變其中一個的值,另一個也會改變

指標

什麼是指標?

在電腦科學中,指標(英語:Pointer),

是在許多程式語言中用來儲存記憶體位址的變數。

指標變數的值直接指向(points to)存在該位址的對象的值。

簡單來說

指標就是儲存變數位址的變數

# POINTER

指標

# POINTER

指向

int n = 10;
int *ptr = &n;

宣告指標

# POINTER
int* ptr;
int *ptr;
  • 資料型態* 變數名;
  • 資料型態 *變數名;
  • 宣告多個指標
int* a, b, c;
int* a;
int b;
int c;
int* a, * b, * c;
int *a, *b, *c;
int* a;
int* b;
int* c;

* 取值運算子

# POINTER
int n = 10;
int *ptr = &n;
cout << *ptr;  // 10
  • *指標變數
  • 可以取得指標所指向的變數的值
  • 可用於運算式
  • 優先權低於++--,高於算術運算子
*ptr++;   // *(ptr++)
*ptr + 1; // (*ptr) + 1

為了避免搞混,建議都加上()

初始化

# POINTER
int n;
int *ptr = &n;
  • 指標資料型態要和指向變數的資料型態一致
double n;
int *ptr = &n;
// error: cannot initialize a variable of type 'int *' with an rvalue of type 'double *'
  • 不指向任何位址的指標(空指標)
int *ptr = 0;
int *ptr = NULL; 	// C
int *ptr = nullptr; // C++

初始化

# POINTER
int *ptr;
int n;
ptr = &n;
*ptr = 10; // n = 10;
  • 指定一個「存在」的變數位址給指標
  • 1、3 可合併
int n;
int *ptr = &n;

指標與陣列

陣列指標

# POINTER
  • 陣列名稱是陣列第一個元素的位址
    可用指標指向陣列名稱
int arr[10];
int *ptr;
ptr = arr; // ptr = &arr[0];
  • 陣列元素位址可用「指標 + 數字」表示
    • ptr 指向 arr[0],ptr+1 指向 arr[1],以此類推
  • 指標的加減 = 紀錄的位址 +(-) 該資料型態的位元組數
    • int 大小為 4 bytes+1 等於向後移動 4 個位元組

陣列指標

# POINTER
int arr[10];
int *ptr;
ptr = arr; // ptr = &arr[0];
ptr++;     // ptr = &arr[0] + 1;
  • ptr 可修改,arr 不可修改
  • 修改 arr 會移動到陣列初始位置,造成資料遺失
arr++;
arr += 2;

傳遞函式參數

#include <iostream>
using namespace std;

void swap(/* 你要寫的地方 */) {
  // 你要寫的地方
}

int main() {
  int a = 1, b = 2;
  cout << "a = " << a << ", b = " << b << endl;
  swap(/* 你要寫的地方 */);
  cout << "a = " << a << ", b = " << b << endl;
  return 0;
}

設計一個函式 swap,交換傳入的兩個數值

# POINTER

參數傳遞

# POINTER
  • 傳值呼叫 (call by value)
  • 傳址呼叫 (call by address)
  • 傳參考呼叫 (call by reference)

傳值呼叫 (call by value)

# POINTER
  • 將要傳遞的引數值,複製一份傳給被呼叫函式的參數
int main() {
  swap(a, b);
}
void swap(int x, int y) {
  
}
int x = a;
int y = b;

傳址呼叫 (call by address)

# POINTER
  • 將引數位址 (&n),傳遞給被呼叫函式的指標參數
int main() {
  swap(&a, &b);
}
void swap(int *x, int *y) {
  
}
int *x = &a;
int *y = &b;

傳參考呼叫 (call by reference)

# POINTER
  • 將參數宣告成參考型態,因此會隨函式參數而變
int main() {
  swap(a, b);
}
void swap(int &x, int &y) {
  
}
int &x = a;
int &y = b;
void swap(int a, int b) {
  int temp = a;
  a = b;
  b = temp;
  return;
}

int main() {
  int a = 1, b = 2;
  cout << "a = " << a << ", b = " << b << endl;
  swap(a, b);
  cout << "a = " << a << ", b = " << b << endl;
  return 0;
}

/*
結果:
a = 1, b = 2
a = 1, b = 2
*/

傳值呼叫

# POINTER
void swap(int *a, int *b) {
  int temp = *a;
  *a = *b;
  *b = temp;
  return;
}

int main() {
  int a = 1, b = 2;
  cout << "a = " << a << ", b = " << b << endl;
  swap(&a, &b);
  cout << "a = " << a << ", b = " << b << endl;
  return 0;
}

/*
結果:
a = 1, b = 2
a = 2, b = 1
*/

傳址呼叫

# POINTER
void swap(int &a, int &b) {
  int temp = a;
  a = b;
  b = temp;
  return;
}

int main() {
  int a = 1, b = 2;
  cout << "a = " << a << ", b = " << b << endl;
  swap(a, b);
  cout << "a = " << a << ", b = " << b << endl;
  return 0;
}

/*
結果:
a = 1, b = 2
a = 2, b = 1
*/

傳參考呼叫

# POINTER

社慶&聖誕節

社慶 & 聖誕節活動

活動日期:12/27(五)
活動時間:16:30 ~ 17:10
活動地點:學珠樓 B2 表演中心
活動內容:交換禮物 & 小遊戲!

 

https://forms.gle/ahY2uKWebrPvQfuF6

pointer

By cloudream

pointer

  • 155