變數、位址、指標


  1. 何謂變數?

    每一個變數就是一個盒子

    請參考 address.c

    1. 只有向系統要來的盒子才能用.
    2. 向系統要盒子最簡單方式, 就是定義變數, 順便也給盒子取了一個名字.
    3. 不同 type (型別) 的變數, 就是可以裝不同東西的盒子, 如 int, char, double, long, float, ...
    4. 編譯器會對我們使用的變數作 type checking (型別檢查), 例如 ++, --, 和 % 都不可以用在 double 或 float 上.
    5. 陣列變數: 例: int dm[13] 向系統要了 13 個盒子, 分別是 dm[0], dm[1], ... dm[12]. 每個盒子可以裝一個整數. Q: 有沒有一個盒子叫做 dm 可以裝東西?
  2. 請先參考 r-value 與 l-value
    1. Q: 如果有 int dm[13];, 則 dm[3] 扮演什麼角色? dm 在這裡又扮演什麼角色?
  3. 位址與指標變數
    1. 把電腦的記憶體想像成一座大樓, 每一層樓的大小正好是一個 char, 也就是一個 byte, 八個 bits.
    2. 向系統要來的每一個盒子就是你可以用的樓層. 有些型別的每個盒子只佔一個樓層, 例如 char; 有些型別的每個盒子佔了許多樓層, 例如 double.
    3. 可以用 sizeof(double) 得知你的系統中每個 double 型別變數究竟佔了幾層樓.
    4. 沒有向系統要來的盒子就不能用, 如宣告 double a[3]; 卻用到 a[3]
    5. 所謂一個變數的位址, 就是這個盒子所佔據樓層當中, 最低那一層的樓層. 例如有 int count, 且 count 佔據第 0x20c8 層至 0x20cb 層, 則變數 count 的位址為 0x20c8.
    6. & 運算子: 取得某個盒子的位址.
    7. 一個盒子可以沒有名字, 但它一定會有位址, 例如陣列裡的元素.
    8. 指標變數: 裡面放著「第 xxxx 樓」這種紙條的盒子 (存放位址).
    9. 宣告/定義指標變數: int *p; 讀作: "p 是一個指標變數, 它指到一個 int 變數" (它是一個專門存放 int 變數位址的盒子)
    10. 指標變數的型別檢查非常嚴格, 例如指到 int 的指標變數一定要存放 int 變數的位址, 不可以存放 char 或 double 變數的位址. Q: 如果有 int *p; 的宣告, 則 p = & p; 是否合法?
    11. 使用指標變數: *p 讀作 "p 所指到的盒子" 或 "p 所指到的盒子裡面的東西"
    12. 例:
      int x, y, *p; /* 要兩個整數盒子 x,y, 和一個裝位址的盒子 p */
      p = &x; /* 把 x 這個盒子的位址寫在紙條上放入 p 這個盒子裡 */
      *p = 3; /* 把 3 存到 p 所指到的盒子裡面去 */
      y = *p; /* 把 p 所指到的盒子裡面的東西拷貝到 y 這個盒子去 */
    13. & 的參數必須可以扮演 l-value; 其運算結果只能當做 r-value
    14. * 需要一個 r-value 當參數; 其運算結果可當做 l-value 或 r-value
    15. Q: 上例中的 *p 扮演什麼角色? p 扮演什麼角色?
    16. Q: 假設有 int * * p; 這樣的變數宣告, 請畫圖分析 ++ * ++ * ++ p;
    17. 注意: "宣告/定義變數" 中不會有 & 出現. 例:
                      宣告/定義變數   |       運算式當中使用變數
                      char c, d;      |       p = &c;
                      int i;          |       d = *p;
                      int a[3];       |       *p = d;
                      char *p;        |
                      int *q;         |
                      
      

    18. Q: int *p; char *q; p 和 q 那一個盒子比較大?
    19. 指標變數的大小限制了能夠存取記憶體的大小, 例如 DOS 下的 "small model" 每個指標佔 2 bytes 故只可存取 64K; Windows 95, Windows NT 下的 32-bit mode 以及 Linux 下, 每個指標佔 4 bytes 故可存取 4G
    20. 空指標: 其值為 0L, 程式中以 NULL 稱之, 習慣上以接地符號圖示, 是唯一代表 false 的指標值. 也就是說 if (p) { ... } 相當於 if (p != NULL) { ... }

其他參考資料

  1. Efficient Use Of Memory
  2. Intro to Linked Data Structures