指針解析(一)(原)


    指針這個話題好沉重,思量了好久,不知道如何下筆?下筆的時候手好抖啊尷尬,各位大牛看到我這只小菜鳥寫的東東可能會笑掉大牙吐舌笑臉,但是,不管了!我要寫下來惡魔!!!這東東確實太重要了,無數人對其折腰,無數的bugs隱匿於此。對它是又愛,又痴,又疼,又牙癢癢。有些看官以為我會寫“又恨”,說實話,我和指針無仇,我敬佩它紅心,崇拜它。它要是女生,我立馬娶它紅玫瑰

    我想指針的話題應該可以分成以下幾個部分:

    1. 指針的基本內容及應用

    2. 指針與數組的聯系與區別

    3. 函數指針

    4. 智能指針

    就先以上四部分內容吧,我的能力也就知道這些了。各位大牛看過之后,想補充的可以發表評論。寫的差的,可以咆哮一下咬牙切齒,我很能接受。因為大家看了肯定要花時間,花了時間之后看到一篇爛文,我也覺得不好意思尷尬

1. 指針的基本內容及應用

(一)基本內容

    說到指針,我們立馬想到這東西和地址有關。說到地址,我們會聯想到內存。思維正常點應該可以往這方面聯想。計算機內存由很多很多位(bit)組成,這些位上放的不是1,就是0。例如:100010010101110%……&&%¥,我靠,這個東西鬼看的懂啊。所以就要划分字節(byte),每個字節包含八個位,可以表示:0~255。可是這也不夠用啊,太小了。於是,出現了字(word),一般由兩個字節組成。

    現在你可能會問,划分成這樣也白搭啊。我也不知道這是要干嘛的(”100010010101110%……&&%¥“),也不知道這如何才能娶到?首先,坦白講,我也不知道這是干嘛的。例如以下代碼:

int a = 100;
float f = 2.11;

    這些值在內存中是由0和1組成,我們不能通過檢查位來檢查類型。太陽必須要放在程序中來它的實際使用方式,再來確定類型問題。

    內存的事情嘮叨完了,可以說地址了。大家的家里都有門牌號,這樣我們在網上買東西,快遞就可以寄到我們家里。同樣,我們在程序定義一個變量,不是聲明哦捧腹大笑!這個變量在內存中就有一席之地,它在內存里面就是有一個位置給它,組織上給它分了一個地址。我們通過地址來找這個變量,當然,期間也是經歷千辛萬苦,現在我不想扯那些os的東西在里面。地址長什么樣子呢?可以通過以下代碼和圖片顯示:

#include <iostream>
 
int main()
{
    int a = 100;
    int *pa = &a;
 
    std::cout << "這是a的值:" << a << std::endl;
    std::cout << "這是a的地址:" << pa << std::endl;
 
    return 0;
}

程序運行的結果太陽

d460a796230fe0ee4bc42eba682f551a

    看到了吧,0x0016FCEC,這是“a = 100”在內存中地址。具體這個地址在內存條的中部,前部,尾部,這個我就不知道了。“0x“代表了十六進制,0016FCEC說明了總共有32位,4個字節,2個字。此時,我發現了兩個奇怪的符號:”&“和”*“。以下代碼中解釋:

int a = 100;    
int *pa = &a;    // *pa表示int類型的指針,*表示間接尋址或間接引用運算符
                    // &表示獲取值的地址的地址運算符

如圖太陽

c72149730c7f2e733594b2e0732d68d0

(二)基本應用

    ① 指針,間接訪問和左值

    以下用代碼顯示:

int a = 100;         // a的左值為100
int *pa = &a;        // pa的左值為a的地址
int b = *pa - 10;    // b的左值為90,*pa是對pa指針的解引用,代表a的值

    來點詭異點的,”*&a = 100“這是神馬意思呢忍者?答案應該是和”a = 100“相同。我們分析以下,”&a“是產生a的地址,這是一個指針常量。”*(&a)“,應該看得比較的清楚。”*“解引用了,表示訪問操作數所表示的地址。

    接下來,我們來看看指針的指針。這個說起來有點拗口!看以下的代碼吧:

#include <iostream>
 
int main()
{
    int a = 100;
    int *pa = &a;
    int **ppa = &pa;    // 這個就是指針的指針。二級指針
    std::cout << "這是a的值:" << a << std::endl;
    std::cout << "這是a的值:" << *pa << std::endl;
    std::cout << "這是a的值:" << **ppa << std::endl;
    std::cout << "這是a的地址:" << pa << std::endl;
    std::cout << "這是pa的地址:" << ppa << std::endl;
    
    return 0;
}

程序運行的結果太陽

6c39a69502d9b1ee87a8a14b70a39b4e

② 指針表達式

    是該來點腦力訓練了吐舌笑臉

char ch = 'a';
char *pch = &ch;

    有以下幾個問題惡魔

    1. &ch 代表什么?

    2. pch 代表什么?

    3. &pch 代表什么?

    4. *pch 代表什么?

    5. *pch + 1 代表什么?

    6. *(pch + 1)代表什么?

    7. ++pch 代表什么?

    8. *++pch 代表什么?

    9. *pch++ 代表什么?

    10. ++*pch 代表什么?

    11. (*pch)++ 代表什么?

    12. ++*++pch 代表什么?

    13. ++*pch++ 代表什么?

    這幾個問題來源於《C和指針》中指針部分的內容。

③ 未初始化,非法指針

int  *a;
....
*a = 12;

    看出上面的錯誤了嗎?當你將這段代碼敲進電腦之后,執行一下是不是以下這樣呢?

1391ef2ef79a913e2a912a532690e377

    這就是我們在使用指針的時候,非常容易犯下的錯誤。未初始化指針,就拿來使用了。結果就破碎的心。。。。解決這個問題的方法很簡單,使用的時候,先定義,非聲明,后使用。

    時間有點晚了,沒有涉及的內容下一篇在慢慢講來。睡覺去了沉睡的彎月。。。

    第二篇的鏈接吐舌笑臉

參考文獻

1. 《C語言程序設計》

2. 《C和指針》

3. 《C專家編程》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM