1. 程式人生 > >一步一個腳印的往前走!

一步一個腳印的往前走!

  想想自己曾經學習C語言時,初次見到指標、地址,只能死記硬背,經過一段時間的軟磨硬泡,終於有所收穫,在此記錄自己對C語言中地址、指標的理解。
  推薦對C語言有一定理解的程式設計師閱讀。
  學習過C語言的程式設計師們,一定都知道“指標就是地址”的經典描述,到底如何理解指標就是地址。

1. 記憶體長成啥樣?
  實體記憶體條由連續排列晶片組構成,在計算機中記憶體模型也被抽象為一組連續的儲存空間,每個空間都能夠儲存若干位元組的資料,每一塊儲存空間也有一個特定的序號,從0到N。
備註:為了便於理解,此處,將記憶體儲存空間橫向排列(實際橫縱排列的意義相同)。

0000 0001 0002 0003 00FF 0100 0101 …. 01FF ….

2. 地址是什麼?
變數的地址指的實際就是儲存變數資料的記憶體節點序號。

    int a = 10;     //int 佔用4個位元組
    printf("&a = %08X\n", &a);  //列印a的地址 008DF70C

  非常簡單的一段程式碼,列印變數a的地址,008DF70C就是記憶體地址,也是存放資料的起始位置(記憶體序號),數值10就儲存在008DF70C~008DF70F(共4個位元組的記憶體空間),從下圖就能直觀的看出變數和地址的關係。
除錯檢視a的地址
圖中(藍色)選中部分的數值0000000a,就是a的數值10的十六進位制表示。前面7個0是因為儲存的數值過小,資料高位被0填充。

3. 指標是什麼?為什麼說指標就是地址?兩者之間的關係是什麼?
  指標也是變數,不過是與普通的資料型別(int, long, float, double等)不同的變數,因為指標的值記錄的是相同型別變數的地址(記憶體序號)。

    int a = 10;     //int 佔用4個位元組
    printf("&a = %08X\n", &a);   //列印a的地址005DF740

    int *p = &a;    //int*類型的指標p指向int型別變數a的地址
    printf("*p = %08X\n", *p);  //列印指標p指向的值,10
    printf
("p = %08X\n", p); //列印指標p指向的地址,005DF740 printf("&p = %08X\n", &p); //列印p的地址,005DF734

  程式碼中定義int型別指標p,初始化指向變數a的地址,並列印p指向地址的值,p的值,以及p的地址。結合下圖,可以看出,p的值與a的地址相同(廢話,初始化程式碼都已經知道了 v_v),通過下圖可以看出p和&a是同一個地址空間005DF740,記錄的值是10。
變數a的地址與p的值
  
  既然說指標也是變數,指標的地址記錄的是什麼呢?一起接著看下面這張截圖。
指標p的地址
  圖中,檢視p的地址(&p),在005DF734~005DF737的地址(記憶體序號)中保留的數值經過高低位轉換(40 F7 5D 00 -> 005DF740),正是變數a的地址。由此可見,指標是記錄記憶體地址的“特殊”變數
  指標就是地址,其實是指平時使用指標過程中,指標變數記錄的就是地址,如例子中的int指標p,直接列印的結果就是指向a的地址,如果想獲得指向地址的值,需要使用*。
  指標指向一塊儲存變數的地址。

仔細看圖的讀者會發現,指標儲存空間也是4個位元組。可以用sizeof()列印指標的長度確認一下,等長的儲存空間是任意轉換指標型別的基礎。

  每個人對C指標的理解都有差別,我希望我的理解能對初學新手帶來一點點幫助。文中有很多漏洞和不足,望大家提出。