一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言中的指針解析

dyquk4xk2p3d ? 來源:碼農(nóng)的荒島求生 ? 2023-11-21 09:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

大家好,有很多同學(xué)問能不能發(fā)下之前的文章,后續(xù)我會找一些之前閱讀量不錯(cuò)的發(fā)下,本文首發(fā)于2021年12月,以下是正文。

假定給你一塊非常小的內(nèi)存,這塊內(nèi)存只有8字節(jié),這里也沒有高級語言,沒有操作系統(tǒng),你操作的數(shù)據(jù)單位是單個(gè)字節(jié),你該怎樣讀寫這塊內(nèi)存呢?

wKgZomVcDWWARKLQAACL_JnoXgg180.png

注意這里的限定,再讀一遍,沒有高級語言,沒有操作系統(tǒng),在這樣的限制之下,你必須直面內(nèi)存讀寫的本質(zhì)

這個(gè)本質(zhì)是什么呢?

本質(zhì)是你需要意識到內(nèi)存就是一個(gè)一個(gè)裝有字節(jié)的小盒子,這些小盒子從0到N編好了序號。

這時(shí)如果你想計(jì)算1+2,那么你必須先把1和2分別放到兩個(gè)小盒子中,假設(shè)我們使用Store指令,把數(shù)字1放到第6號小盒子,那么用指令表示就是這樣:

store 1 6

注意看這條指令,這里出現(xiàn)了兩個(gè)數(shù)字:1和6,雖然都是數(shù)字,但這兩個(gè)數(shù)字的含義是不同的,一個(gè)代表數(shù)值,一個(gè)代表內(nèi)存地址。
與寫對應(yīng)的是讀,假設(shè)我們使用load指令,就像這樣:
load r1 6

現(xiàn)在依然有一個(gè)問題,這條指令到底是數(shù)字6寫入r1寄存器還是把第6號小盒子中裝的數(shù)字寫入r1寄存器?
可以看到,數(shù)字在這里是有歧義的,它既可以表示數(shù)值也可以表示地址,為加以區(qū)分我們需要給數(shù)字添加一個(gè)標(biāo)識,比如對于前面加上$符號的就表示數(shù)值,否則就是地址:
store $1 6
load r1 6
這樣就不會有歧義了。
現(xiàn)在第6號內(nèi)存中裝入了數(shù)值1:

a2bb2bbe-880d-11ee-939d-92fbcf53809c.png


即地址6代表數(shù)字1:

地址6 -> 數(shù)字1

但“地址6”對人類來說太不友好了,人類更喜歡代號,也就是起名字,假設(shè)我們給“地址6”換一個(gè)名字,叫做a,a代表的就是地址6,a中存儲的值就是1,用人類在代數(shù)中直觀的表示就是:
a = 1

就這樣所謂的變量一詞誕生了。

a2e8e842-880d-11ee-939d-92fbcf53809c.png



我們可以看到,從表面上看變量a等價(jià)于數(shù)值1,但背后還隱藏著一個(gè)重要的信息,那就是變量a代表的數(shù)字1存儲在第6號內(nèi)存地址上,即變量a或者說符號a背后的含義是:



表示數(shù)值1



該數(shù)值存儲在第6號內(nèi)存地址


到現(xiàn)在為止第2個(gè)信息好像不太重要,先不用管它。

既然有變量a,就會有變量b,如果有這樣一個(gè)表示:

b = a

把a(bǔ)的值給到b,這個(gè)賦值在內(nèi)存中該怎么表示呢?

很簡單,我們?yōu)樽兞縝也找一個(gè)小盒子,假設(shè)變量b放在第2號小盒子上:

a313f19a-880d-11ee-939d-92fbcf53809c.png




可以看到,我們完全copy了一份變量a的數(shù)據(jù)。
現(xiàn)在有了變量,接下來讓我們升級一下,假設(shè)變量a不僅僅可以表示占用1個(gè)字節(jié)的數(shù)據(jù),也可以表示占用任意多內(nèi)存的數(shù)據(jù),就像這樣: a345399e-880d-11ee-939d-92fbcf53809c.png

現(xiàn)在變量a占據(jù)5個(gè)字節(jié),足足占用了整個(gè)內(nèi)存的一大半空間,此時(shí)如果我們依然想要表示b = a會怎樣呢?

如果你依然采用copy 的方法會發(fā)現(xiàn)我們的內(nèi)存空間已經(jīng)不夠用了,因?yàn)檎麄€(gè)內(nèi)存大小就8字節(jié),采用copy的方法僅這兩個(gè)變量代表的數(shù)據(jù)就將占據(jù)10字節(jié)。
怎么辦呢?

不要忘了變量a背后可是有兩個(gè)含義的,再讓我們看一下:


表示數(shù)值1



該數(shù)值存儲在第6號內(nèi)存地址



重點(diǎn)看一下第2個(gè)含義,這個(gè)含義告訴我們什么呢?

它告訴我們不管一個(gè)變量占據(jù)多少內(nèi)存空間,我們總可以通過它在內(nèi)存中地址找到該數(shù)據(jù),而內(nèi)存地址僅僅就是一個(gè)數(shù)字,這個(gè)數(shù)字和該數(shù)據(jù)占用空間的大小無關(guān)。
啊哈,現(xiàn)在變量的第2個(gè)含義終于排上用場了,如果我們想用變量b也去指代變量a,干嘛非要直接copy一份數(shù)據(jù)呢?直接使用地址就不好了,就像這樣:

a3737cdc-880d-11ee-939d-92fbcf53809c.png



變量a在內(nèi)存中地址為3,因此變量b中我們可以僅僅存儲3這個(gè)數(shù)字即可。
現(xiàn)在變量b就開始變得非常有趣了。

首先變量b沒什么特殊的,只不過變量b存儲的東西我們不可以按照數(shù)值來解釋,而是必須按照地址來解釋。

當(dāng)一個(gè)變量不僅僅可以用來保存數(shù)值也可以保存內(nèi)存地址時(shí),指針誕生了。

有很多資料僅僅說指針就是地址,但小風(fēng)哥認(rèn)為這是一種偷懶的解釋,僅僅停留在匯編層面來理解,有失偏頗,在高級語言中,指針首先是一個(gè)變量,只不過這個(gè)變量保存的恰好是地址而已,指針是內(nèi)存地址的更高一級抽象。

如果僅僅把指針理解為內(nèi)存地址的話你就必須知道所謂的間接尋址。

這是什么意思呢?
如果使用匯編語言來加載變量a的值該怎么寫呢?

load r1 1


想一想,這是不是會有問題,因此這樣的話該指令會把數(shù)值3加載到r1寄存器中,然而我們想要把內(nèi)存地址1中保存的數(shù)值也解釋為內(nèi)存地址,這時(shí)必須為1再次添加一個(gè)標(biāo)識,比如@:
load r1 @1


這時(shí)該指令會首先把內(nèi)存地址1中保存的值讀取出來發(fā)現(xiàn)是3,然后再次把3按照內(nèi)存地址進(jìn)行解釋,3指向的數(shù)據(jù)就是變了a:
地址1 -> 地址3 -> 數(shù)據(jù)a


這就是所謂的間接尋址,Indirect addressing,在匯編語言下你必須能意識到這一層間接尋址,因?yàn)樵趨R編語言中是沒有變量這個(gè)概念的。

然而高級語言則不同,這里有變量的概念,此時(shí)地址1代表變量b,但使用變量的一個(gè)好處就在于很多情況下我們只需要關(guān)心其第一個(gè)含義,也就是說我們只需要關(guān)心變量b中保存了地址3,而不需要關(guān)心變量b到底存儲在哪里,這樣使用變量b時(shí)我們就不需在大腦里想一圈間接尋址這一問題了,在程序員的大腦里變量b直接指向數(shù)據(jù)a:
b -> 數(shù)據(jù)a
再來對比一下:
地址1->地址3->數(shù)據(jù)a#匯編語言層面
變量b->數(shù)據(jù)a#高級語言層面


這就是為什么我說指針其實(shí)是內(nèi)存地址的更高級抽象,這個(gè)抽象的目的就在于屏蔽間接尋址。

當(dāng)變量不僅僅可以存值也可以存放地址時(shí),一個(gè)全新的時(shí)代到來了:看似松散的內(nèi)存在內(nèi)部竟然可以通過指針組織起來,同時(shí)這也讓程序直接處理復(fù)雜的數(shù)據(jù)結(jié)構(gòu)成為可能,比如就像下圖這樣:

a3b43614-880d-11ee-939d-92fbcf53809c.png



這就是所謂的鏈表了。

a3ef099c-880d-11ee-939d-92fbcf53809c.png



指針這個(gè)概念首次出現(xiàn)在 PL/I 語言中,當(dāng)時(shí)是為了增加鏈表處理能力,大家不要以為鏈表這種數(shù)據(jù)結(jié)構(gòu)是非常司空見慣的,這在1964年左右并不是一件容易的事情,關(guān)于鏈表你還可以參考這篇《徹底理解鏈表》。

值得一提的是,Multics操作系統(tǒng)就是 PL/I 語言實(shí)現(xiàn)的,這也是第一個(gè)用高級語言實(shí)現(xiàn)的操作系統(tǒng),然而Multics操作系統(tǒng)在商業(yè)上并不成功,參與該項(xiàng)目的Ken Thompson, Dennis Ritchie后來決定自己寫一個(gè)更簡單的,Unix以及C語言誕生了,或許是在開發(fā)Multic時(shí)見識到了PL/I語言中指針的威力,C語言中也有指針的概念。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5152

    文章

    19675

    瀏覽量

    317612
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7632

    瀏覽量

    141773
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4381

    瀏覽量

    64893
  • 指針
    +關(guān)注

    關(guān)注

    1

    文章

    484

    瀏覽量

    71197

原文標(biāo)題:徹底理解C語言中的指針

文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    C語言中指針的定義

    上一節(jié)中,我們利用了一個(gè)小知識來介紹了一下指針,在上面這個(gè)例子中,小明和小麗手中的這個(gè)杯子就好比我們C語言中的變量,它確實(shí)是實(shí)實(shí)在在存放一些有具體意義的數(shù)據(jù)。這個(gè)杯套就類似于C
    發(fā)表于 08-15 16:24 ?2044次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言中指針</b>的定義

    C語言中void指針的基本認(rèn)識及典型應(yīng)用

    C語言中,*類型就是指針類型,比如 int *p,double *q,雖然是不一樣的指針,但是大小卻一樣sizeof(p) == sizeof(q),因?yàn)樗鼈兌际峭环N類型*類型的。
    發(fā)表于 02-01 09:26 ?1377次閱讀

    C語言中指針函數(shù)和函數(shù)指針的概念及應(yīng)用示例

    C語言中,指針函數(shù)和函數(shù)指針是強(qiáng)大且常用的工具。它們允許我們以更靈活的方式處理函數(shù)和數(shù)據(jù),進(jìn)而擴(kuò)展程序的功能。
    發(fā)表于 08-16 16:14 ?1590次閱讀

    C語言中多級指針的概念和使用方法

    多級指針C語言中是一種特殊的指針類型,它可以指向其他指針指針。
    發(fā)表于 08-16 16:16 ?1545次閱讀

    C語言中指針和野指針的概念及產(chǎn)生原因

    C語言中指針是一種非常強(qiáng)大和靈活的工具,但同時(shí)也容易引發(fā)一些問題,其中包括空指針和野指針。
    發(fā)表于 08-16 16:18 ?1963次閱讀

    C語言中指針的基本概念和用法

    C語言中,指針是一項(xiàng)重要的概念,它允許我們直接訪問和操作內(nèi)存地址。
    發(fā)表于 08-17 15:30 ?1194次閱讀

    C語言中指針是什么?如何規(guī)避野指針

    C語言中指針是什么?有哪幾種類型?指針有何作用?如何規(guī)避野指針?
    發(fā)表于 02-25 06:47

    C語言中指針的介紹非常詳細(xì)

    C語言中指針的介紹非常詳細(xì) C語言中指針的介紹非常詳細(xì)
    發(fā)表于 12-25 10:39 ?57次下載

    基于C語言中指針的基本用法解析

    C語言中其它的知識都學(xué)得可以,唯獨(dú)指針搞不懂。如果是這樣,我可以很負(fù)責(zé)的告訴你,對于這門編程語言,你等于是沒學(xué)。所以學(xué)好指針對于初學(xué)者是非
    的頭像 發(fā)表于 01-09 15:12 ?5007次閱讀

    C語言中的野指針是怎么來的?

    )、malloc函數(shù)申請堆內(nèi)存返回的地址(但未使用free釋放,是在堆空間動態(tài)申請) 需要注意的是,野指針不是NULL指針,通常NULL指針可以使用if語句來判斷,但是C
    的頭像 發(fā)表于 06-01 16:43 ?2787次閱讀

    C語言中指針(重點(diǎn))超詳細(xì)

    C語言中指針1、指針是什么2、指針指針類型2.1、指針
    發(fā)表于 01-13 14:10 ?11次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言中</b>的<b class='flag-5'>指針</b>(重點(diǎn))超詳細(xì)

    C語言中的char數(shù)組和char指針有什么區(qū)別?

    讓我們通過下面的例子,來了解 C語言中字符數(shù)組和字符指針之間的區(qū)別。
    的頭像 發(fā)表于 01-29 16:35 ?3218次閱讀

    底層解析C指針(一)

    指針C語言中的精髓部分,同樣也是C語言的難點(diǎn)所在,下面從最底層來分析C
    的頭像 發(fā)表于 02-15 14:47 ?1161次閱讀
    底層<b class='flag-5'>解析</b><b class='flag-5'>C</b><b class='flag-5'>指針</b>(一)

    C語言中什么是指針數(shù)組

    C語言中一個(gè)數(shù)組,若其元素均為指針類型數(shù)據(jù),稱為指針數(shù)組,也就是說,指針數(shù)組中的每一個(gè)元素都存放一個(gè)地址,相當(dāng)于一個(gè)
    的頭像 發(fā)表于 03-10 15:26 ?2242次閱讀

    簡述C語言中指針重點(diǎn)

    C語言中一個(gè)函數(shù)可以返回一個(gè)整型值、字符值、實(shí)型值等,也可以返回指針型的數(shù)據(jù),即地址,其概念與以前類似,只是返回的值的類型是指針類型。
    的頭像 發(fā)表于 03-10 15:28 ?839次閱讀