Try   HackMD
tags: 大一程設-下 東華大學 東華大學資管系 基本程式概念 資管經驗分享

指標 pointer 基礎認識(一)

前言

指標可以說是 C++ 的超級大魔王,指標變數怎麼指、到底指到誰身上、記憶體位置到底存誰的,概念是有點難理解的,到了大四我仍沒辦法完全搞懂他,但我一定會盡全力把該學到的講給你們聽,同時去看 reference 多參考網路上多位大神的解釋會更好。

參考資料二非常建議閱讀!!

講解影片(還沒錄)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

基本觀念釐清: 何為變數、何為變數值、何為指標、如何取址

甚麼樣的資料型態(變數型態)存什麼樣的資料,這個大前提請千萬不要忘記

變數

變數由四個最重要的東西所組成,分別是變數型態、變數值、變數名稱、變數位址,請看以下表格與說明。

變數型態 變數位址 變數值 變數名稱
int 0x6ffe08 9 a1
string 0x6ffe00 Orange s1
double 0x6ffdf8 7.3 d1
float 0x6ffdf4 6.5f f1

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 變數位址
    • 在你程式執行後,變數儲存在記憶體的位置
  • 變數值
    • 該變數儲存的值,int 存整數,string 存字串
  • 變數名稱
    • 使用者對變數做一個自定義名字的動作

而根據你的型態不同,所需的記憶體用量也不同,以整數為例,一個整數就是佔 4 bytes 的空間。

指標

變數位址負責讓你找到你的這個變數在電腦的哪裡,而變數位址就是變數的指標!簡單的說,變數的位址就是「指向該變數的指標」。這句話很重要!!

而這邊說的是指標,而不是指標變數,請不要把兩者混為一談哦!!!

取址與參考變數大不同!!

那既然我們這麼大費周章地跟你說了變數位址,自然就是可以被拿來用的東西,未來我們可以親自的來操控記憶體,那既然要操控,我們就要取得他。

要做到取得記憶體位址,需要利用取址運算子「&」,透過在變數前面加上這個符號以取得變數的記憶體位址。

  • 要取得位置,取址運算子請一定是與宣告分開的哦!

    int a = 5; ​cout << &a; //印出 a 的記憶體位址
  • 請注意,請千萬不要像下面這樣寫!!!

    int &a = 5; // 程式會報錯,Error

    還記得我們有教過如何宣告參考變數 (reference variable),你可以為變數取一個別 名,所以你在變數宣告的時候這樣寫,是告訴程式說你宣告一個參考變數,並不是取 得一個變數所在的記憶體位置哦!
    然而上面這樣寫也不是正確的參考變數宣告,參考變數是為「一個變數」取別名,然而你指派常數給他,是錯誤的,參考變數的宣告一定要接受「變數」,像這樣。

    int a = 5;int &a_new = a;

何為指標變數(pointer variable)?

上面都可以的話接下來來真的談談指標變數吧!

前面已經強調,指標(pointer)就是某個變數的記憶體位址,而指標變數(pointer variable),則是「用來存放指標的變數」。

有點文字遊戲對吧,所以我們先從前面來。

整數變數儲存整數
浮點數變數儲存浮點數
字串變數儲存字串
字元變數儲存字元

那指標變數儲存甚麼?
儲存指標!!!
Orange

如何宣告、初始化、設值給指標變數

如果對於指標變數儲存的東西到底是甚麼你已經理解了,接下來來看看如何宣告他。

  • 全新符號 * ,其有兩種意義
    • 指標
      • 變數宣告時出現,是為了宣告指標
      • 告訴程式此變數是一個「指標變數」
      • 其內容存的是一個記憶體位址
    • 取值運算子(Dereference operator)
      • 宣告以外的場合出現,是為了取出指標所指向的位址的值
      • 依照變數所存的記憶體位址,去那個位址把資料取出來
int a = 5; // 假設位於 0x6ffe0c int *p1; // 宣告不給值,之後才給值 p1 = &a; // 把 a 變數的位址 0x6ffe0c 存到 p1 內 **-----------我是分隔線------------** int *p1 = &a; // 宣告即給值,把 a 變數的位址 0x6ffe0c 存到 p1 內

指標變數的宣告方式呢,是在變數型態跟名稱中間加上一個 * 號,這樣就是宣告指標變數,而因為他必須接受一個記憶體位址,所以你只能要傳位址給他。

透過上文我們已經知道指標變數儲存指標,而指標又是指一個變數的記憶體位址,所以對於 p1 這個指標變數,就是存變數 a 的記憶體位址。示意圖如下:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

而今天一個變數如果他被宣告,他會需要記憶體去儲存他,所以指標變數本身需要一個記憶體,而他裡面儲存的是一個指標(記憶體位址)。

學這邊真的在玩繞口令
Orange

如何取值? 取出誰的值?

針對一般的整數變數、字串變數,要取值時我們都只要打他的名字即可,指標變數也同理,如果要取出他儲存的變數值,也是打他的名字。

int a = 5; cout << "[整數]變數 a 所儲存的[整數]: " << a << endl; //印出 a 就是一種取值了哦! cout << "[整數]變數 a 所處的記憶體位址(也就是指標): " << &a << endl; int *p1 = &a; cout << "[指標]變數 p1 所儲存的[指標](指標變數存記憶體位址): " << p1 << endl; cout << "[指標]變數本身所屬的記憶體位址: " << &p1 << endl; cout << "[指標]變數 p1 所儲存的[指標]指向的值: " << *p1 << endl;

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

相信看到這裡你已經知道我們說的指標變數取值是取出誰的值了!就是指標變數所儲存的指標指向的值!!! 用一張圖可以這樣解釋(紅筆對紅筆,藍筆對藍筆)。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

最後一個最重要的提醒,指標指標變數是兩個完全不一樣的東西,請你一定要搞清楚,不然進入雙重指標就再見了哦!

指標是_________?
指標變數是__________?
大家自己填空想想看吧,忘了麻煩一定要往上回去看!
Orange

小總結整理

  • 指標的宣告
    • type *name;
    • type *name = address;
    • type *name1, *name2, *name3;
  • 指標的取值
    1. 指標變數如同一般的變數,取值就是打名字(取出這個指標變數儲存的位址(指標))
      • name
    2. 存取指標變數儲存的位址所指向的記憶體空間所儲存的值,在前面加上米字號,切記與宣告不同!
      • *name
  • 如何取址
    • 在任何的變數面前加上 &
      • 切記不能在宣告的時候加
    • 可以把一個指標變數儲存的指標給另一個指標變數
      • name1 = name2
      • 把 name2 指標變數儲存的記憶體位址也給 name1
        所以現在兩個指標變數內都存相同的記憶體位址

Reference 由淺入深

越上面越簡單

參考 - 1
參考 - 2 雖然是用 C 語言(不是 C++),但概念一模一樣,可專注在內文
參考 - 3

比較難的參考資料
丁培毅老師