首頁>Club>
16
回覆列表
  • 1 # 大學生程式設計指南

    從事C語言開發已經超過10個年頭,越來越覺得指標的方便之處,但在初學者來看指標就是拿下這門程式設計最大的攔路虎,畢竟很多人開始學習C語言都是激情四射結果遇上了指標貓變成了老鼠變得畏首畏尾。對於指標的不理解主要還是意識上缺乏計算機思維,思維的鍛鍊不是靠一兩天的勤奮能夠到位的,需要長時間的堅持。

    要理解指標還是需要掌握一些基礎,計算機組成原理,瞭解計算機內部結構以及記憶體管理,明白進位制之間如何轉化,然後再去看如何使用指標,指標本質就是一個變數的地址,指標使用起來有很多規則,而且一般人都經常容易忘記,有個程式設計高手同事,程式設計的基本功特別紮實,問他怎麼練成的他說剛入行的時候遇到一個特別負責的技術主管,主要下屬犯一些技術錯誤直接在辦公室通報批評,每次操作字串或者指標出現問題就通報,在指標的初始化方面特別容易出問題,所以現在這種錯誤幾乎不會再出,這也是普通初學者經常出的一些問題,指標還沒初始化拿去用直接就導致系統崩潰了,來回折騰幾次就開始怕了指標了,所以很多人開始學習指標不見得就是怕指標,就是弄了幾次錯誤之後就覺得這玩意不好惹。

    可能覺得指標的初始化很簡單的事情,但在實際操作過程中幾乎每個人都會遇到,特別是結構體指標如果結構體裡面再有指標,陣列,結構體等等複雜的資料結構,這樣在函式操作過程中什麼時候什麼時候釋放指標,如何進行指標之間賦值等等操作就能看到功底了,所以初學者開始做專案經常寫出導致系統崩潰或者記憶體洩漏的程式碼,這些經驗都需要慢慢來總結,當然最重要的時候不能被嚇到堅持下去。

    學習指標推薦一本林銳博士寫的《高質量C/C++程式設計》對於指標的常見的漏洞有一些非常透徹的講述,想快速掌握指標的使用技巧還是要以實際專案為基礎,記得曾經做一個機頂盒專案遇到一個問題在耐久測試過程中,只要是執行超過48小時很快就宕機,從經驗上判斷是記憶體洩漏但要找到那個記憶體申請導致,最後用了鉤子函式不停的折騰,找到了動態申請記憶體的一行程式碼,不停的在申請但一直沒有釋放,做了釋放的動作了,但指標的釋放方向不同,因為這個事情專案晚了三天釋出,由於經歷過這些過程所以在寫程式碼的時候就會讓自己小心。

    如何熟練掌握指標?

    1.首先要正確認識指標,不能因為指標給自己帶給來過麻煩就不敢去使用了,去年寫了一個專案,由於下邊的技術人員大部分都是剛入行的,所以在設計框架的時候刻意減少了指標的使用,大部分使用的陣列來代替,在專案結束的時候,專門佈置了個任務,把裡面的陣列全部換成指標來操作,結果大家苦不堪言,真正的意識到指標不是那麼好玩,但大家都堅持下去,經過一段時間大家基本上都掌握的差不多了,所以從心裡上就要做到越挫越勇。

    2.多注意總結平時遇到的一些錯誤,特別是指標使用的場景,不同的場景表現形式不一樣,要把記憶體管理機制搞清楚,只有弄清本質才能更好的掌握,特別是多級指標的使用過程中如何保證腦子不亂,就要多去總結,歸納的時候要懂得變通,用程式碼去實現。

    3.最快的方式還是要多做專案,專案是檢驗能力的唯一試金石,做的次數多了,積累的經驗也就多了,當然在實踐過程中還要回過頭來看看基礎。

    要有堅持到底的勇氣,更要有堅實的基礎。

  • 2 # 少賠多賺

    想了解指標就要了解系統管理記憶體的方法,還有彙編也要了解下,還有暫存器等,說白了就是要了解電腦工作方法!學習指標時候實踐固然重要,但是理論也很重要!

  • 3 # 雁塔菜農

    菜農認為學習C語言的指標非常簡單,指標乃地址也!

    C語言的指標可以歸結為兩類,其一為資料指標,其二為函式指標。

    前者的型別眾多,基本為不同長度的資料資料指標和結構指標之分。

    後者的函式指標,實際應用多為函式指標陣列。

    除了C/C++外,其他程式語言極少有指標,大多的程式語言都取締了指標,如同反對goto語句一般。

    而在嵌入式領域程式設計時,指標幾乎是必備的,例如中斷向量即為函式指標陣列。

    由函式指標和函式別名構成的結構體,就是“COM介面技術”之核心。

    所以目前甚至以後很長時間裡,在嵌入式領域裡,最多的編譯器就是C/C++編譯器,其他程式語言無法撼動C/C++在嵌入式領域的地位。

  • 4 # C語言答疑課堂

    C語言指標概念說白了就兩字:“己他”!其中的“己”就是指標變數的“己址”、“己值”等,“他”就是“他值”、“他址”等,

    “己址”。C語言指標變數作為一個變數,也很普通啊,它要在記憶體中佔用一塊“地皮”,那麼這塊地皮就有地址。所以C語言指標變數也有自己的地址。“己值”。C語言指標變數作為一個普通變數,也有自己的值,就是在這塊地皮上也儲存了一個值。這些跟一般的普通變數沒啥區別。“他址”。C語言指標變數的自己的值看上去是一個16進位制,沒啥意義,但是它可是別人的地址哦。指標變數是指向某一個物件的,C語言指標變數的自己的值就是這個物件的地址。“他值”。C語言指標變數指向的那個物件的值,就是指標的“他值”。初學C語言的同學們經常會搞混了指標變數的己值和他值,這也是一個難點。

    另外,C語言指標還有“己型”、“他型”等概念,這些都是指標的核心概念,所以與其抱著書本啃,還不如換個角度來看C語言指標,其實真的不難。

  • 5 # 大翔

    不需要太多言語,我們來一個簡單的比喻,馬上掌握指標!

    指標指向一個地址,好比張三家住在北京XX街道,那麼訪問門牌號是北京XX街道,裡面住的人就是張三。在程式中地址一般都是0x22223333這樣的十六進位制數,是唯一的!我們就可以理解為是門牌號。0x22223333裡面的值比如是整數50,我們可以理解為是張三。

    接下來說明兩種情況:

    1.指標指向了門牌號:北京XX街道,那指標的值就是這個家裡住的人。如果把指標指到另一個門牌號天津XX街道,那指的地方就是不同的房子了,不同的房子裡住的當然是不同的人,比如天津XX街道住著李四。這種情況可以說指標指向的地址變了,導致指標的值也變了。

    2.如果指標指在門牌:北京XX街道,但是這家裡本來住著張三,結果張三搬走了,王五住了進來,這房子裡現在住的人是王五了!這種情況我們可以理解為指標指向的地址沒變,但是值被改變了。

    關於C語言的知識,我的文章中有很多幹貨,初學者可以很快掌握,可以來看看哦。

  • 6 # 程式設計老大叔

    C語言指標就是這門語言的靈魂,說難學,那肯定是有難度的,畢竟這是業界公認的。但是如果你熟練掌握了指標的話,它又將會成為你手中的一柄利器。下面就詳細的分享一下指標該如何深入的去理解它以及如何熟練的應用它

    理解指標

    首先,你需要掌握兩個運算子“*”和“&”;

    “&”運算子:取物件在記憶體中的地址

    “*”運算子:取記憶體中地址上的物件(值);

    大家一定要深刻的理解上面兩個運算子,然後才能去進一步理解指標;

    int a = 100 ;這一行程式碼我想大家都沒問題。那麼“&a”返回的就是物件(變數)a在記憶體中的地址,它是一個16進位制數。

    然後用“*”號去a的地址去取物件:“*(&a)”,,就能取到物件a,也就就是100 ;

    接下來進入重點了,指標,本身也是一個變數(物件),它本身佔用記憶體,但是它只存地址(別人的地址),它存的誰的地址我們就稱它為指向誰的指標;

    int* p = &a ;int* p_2 = new int(200) ;先不管他的型別申明,只看變數本身p和p_2。前面講到指標存放的是物件的地址,那麼可以理解為指標是一個地址變數,那麼賦值的話就需要也賦一個地址給它一個地址。int* 和char*都可以表示地址型別,它們的區別就是地址所存的值得型別不同,一個是存整型,一個是存字元型;

    對指標取值的話,就是用“*”號,後面接物件地址,也就是指標變數,所以*p和*p_2就分別是a和200;

    指標的運用

    指標並不是C/C++獨有的,像C#和java等其實也是有指標的,只不過都被語言本身用其他的方式替代和封裝了一般程式設計師接觸不到,C/C++就不一樣,它是直接將指標暴露給開發者,因為大部分牽涉到指標的都與記憶體有關,而計算機記憶體很重要,萬一出什麼問題可能系統都會崩潰,下面就簡單來看一下程式在執行時指標與記憶體之間到底是個什麼樣的關係:

    先看一段程式碼:

    #include <stdio.h>

    #include <string>

    #include <iostream>

    #include <time.h>

    using namespace std;

    class people

    {

    public:

    people();

    ~people();

    string Name ;

    int age ;

    bool sex ;

    char info[1024] ;

    void run(){}

    void eat(){}

    private:

    };

    people::people()

    {

    }

    people::~people()

    {

    }

    int main()

    {

    people* p1 = new people();

    cout<<p1<<endl;

    cout<<&p1<<endl;

    cout<<sizeof(p1)<<endl;

    cout<<sizeof(*p1)<<endl;

    system("pause");

    return 0 ;

    }

    直接執行看結果:

    分析

    接下來來一一進行分析:

    首先people* p1 = new people();這一句是類的一個例項化,系統會給people例項化一個物件*p並且給它在堆上開闢空間,注意是在堆上,開闢的空間用來儲存物件的資料。資料包括哪些?就是物件的屬性和虛擬函式指標,但是函式並不儲存在各物件中。因此run()和eat()方法是不存在物件*p指向的記憶體處的。

    cout<<p1<<endl;輸出的是00279360,這是一個地址,是系統給new people()物件分配的地址。

    cout<<&p1<<endl;輸出的是0012FD90,這也是地址,但這是指標變數p本身的地址。

    cout<<sizeof(p1)<<endl;

    cout<<sizeof(*p1)<<endl;

    透過這兩個輸出就能有更清晰的認識了,p1本身只佔用4個位元組的空間,而它所指向的物件的地址所佔的空間就很大,等於類中所有資料型別所佔空間之和。

    接下來在main函數里寫一點邏輯:

    圖解

    我們來看一下程式執行時間,指標和記憶體是怎麼工作的。這裡畫一個圖給大家:

    程式在執行時,資料主要是儲存在棧、堆、程式碼區、全域性區。程式碼區主要就是存程式碼中出現的一些字元常量、方法等,比如這裡程式碼中給物件的Name屬性賦的值“xiaoli”之類的都是存在此處,然後我們透過new出來的物件,都是由堆透過計算好類中各屬性所需空間然後開闢出來的。這裡p3不是透過new開闢出來的,所以他是存在棧上的並且地址是固定的,是不能更改的,而p1和p2是能更改的。

    改變地址

    如此,我們三個物件互相賦值後會發生什麼呢?

    對比程式碼和輸出結果我們發現了什麼?賦值後p1和p2本身的地址並無改變,但是他所指向的記憶體都程式設計p3所在的記憶體了。下面用圖解給大家看一下:

    改變地址的值

    如果我將程式碼中的 p2 = &p3;換成*p2=p3呢?我們看下輸出結果:

    造成這種情況的原因,其實這就牽涉到指標的兩種賦值問題:一種是改變指向的地址,一種是改變本身指向地址的值p2 = &p3是改變指向地址,*p2=p3是改變指向地址的值。

  • 7 # Andy001847

    C語言指標學習是一回事,使用又是另外一回事。學習它的難度不難,但是它卻又非常靈活,不管是基本資料型別,陣列,字串以及函式等等都可以用它操作。我特地在我的專欄裡分三個章節對它進行了講解,更在後續的章節對它進行擴充套件鞏固。特別是萬能指標,很多人壓根就不知道怎麼用更好,所以我也花費比較多示例對它進行講解。說它難,只不過沒有掌握本質,沒有去觀看大神們的優秀程式碼,說它簡單,熟練它卻需要勤加練習。

  • 中秋節和大豐收的關聯?
  • 我家烏龜身上的殼爛了怎麼辦?