當前位置:首頁 > 公眾號精選 > 嵌入式大雜燴
[導讀]關注「嵌入式大雜燴」,星標公眾號,一起進步!來源:網(wǎng)絡指針對于C來說太重要。然而,想要全面理解指針,除了要對C語言有熟練的掌握外,還要有計算機硬件以及操作系統(tǒng)等方方面面的基本知識。所以本文盡可能的通過一篇文章完全講解指針。為什么需要指針?指針解決了一些編程中基本的問題。第一,指針...

關注「嵌入式大雜燴」,星標公眾號,一起進步!

來源:網(wǎng)絡

針對于C來說太重要。然而,想要全面理解指針,除了要對C語言有熟練的掌握外,還要有計算機硬件以及操作系統(tǒng)等方方面面的基本知識。所以本文盡可能的通過一篇文章完全講解指針。


為什么需要指針?

指針解決了一些編程中基本的問題。

第一,指針的使用使得不同區(qū)域的代碼可以輕易的共享內(nèi)存數(shù)據(jù)。當然小伙伴們也可以通過數(shù)據(jù)的復制達到相同的效果,但是這樣往往效率不太好。

因為諸如結構體等大型數(shù)據(jù),占用的字節(jié)數(shù)多,復制很消耗性能。

但使用指針就可以很好的避免這個問題,因為任何類型的指針占用的字節(jié)數(shù)都是一樣的(根據(jù)平臺不同,有4字節(jié)或者8字節(jié)或者其他可能)。

第二,指針使得一些復雜的鏈接性的數(shù)據(jù)結構的構建成為可能,比如鏈表,鏈式二叉樹等等。

第三,有些操作必須使用指針。如操作申請的堆內(nèi)存。

還有:C語言中的一切函數(shù)調(diào)用中,值傳遞都是“按值傳遞”的。

如果我們要在函數(shù)中修改被傳遞過來的對象,就必須通過這個對象的指針來完成。

計算機是如何從內(nèi)存中進行取指的?

計算機的總線可以分為3種:數(shù)據(jù)總線,地址總線和控制總線。這里不對控制總線進行描述。數(shù)據(jù)總線用于進行數(shù)據(jù)信息傳送。數(shù)據(jù)總線的位數(shù)一般與CPU的字長一致。一般而言,數(shù)據(jù)總線的位數(shù)跟當前機器int值的長度相等。例如在16位機器上,int的長度是16bit,32位機器則是32bit。這個計算機一條指令最多能夠讀取或者存取的數(shù)據(jù)長度。大于這個值,計算機將進行多次訪問。這也就是我們說的64位機器進行64位數(shù)據(jù)運算的效率比32位要高的原因,因為32位機要進行兩次取指和運行,而64位機卻只需要一次!
地址總線專門用于尋址,CPU通過該地址進行數(shù)據(jù)的訪問,然后把處于該地址處的數(shù)據(jù)通過數(shù)據(jù)總線進行傳送,傳送的長度就是數(shù)據(jù)總線的位數(shù)。地址總線的位數(shù)決定了CPU可直接尋址的內(nèi)存空間大小,比如CPU總線長32位,其最大的直接尋址空間長232KB,也就是4G。這也就是我們常說的32位CPU最大支持的內(nèi)存上限為4G(當然,實際上支持不到這個值,因為一部分尋址空間會被映射到外部的一些IO設備和虛擬內(nèi)存上?,F(xiàn)在通過一些新的技術,可以使32位機支持4G以上內(nèi)存,但這個不在這里的討論范圍內(nèi))。

一般而言,計算機的地址總線和數(shù)據(jù)總線的寬度是一樣的,我們說32位的CPU,數(shù)據(jù)總線和地址總線的寬度都是32位。

計算機訪問某個數(shù)據(jù)的時候,首先要通過地址總線傳送數(shù)據(jù)存儲或者讀取的位置,然后在通過數(shù)據(jù)總線傳送需要存儲或者讀取的數(shù)據(jù)。一般地,int整型的位數(shù)等于數(shù)據(jù)總線的寬度,指針的位數(shù)等于地址總線的寬度。?計算機的基本訪問單元?學過C語言的人都知道,C語言的基本數(shù)據(jù)類型中,就屬char的位數(shù)最小,是8位。我們可以認為計算機以8位,即1個字節(jié)為基本訪問單元。小于一個字節(jié)的數(shù)據(jù),必須通過位操作來進行訪問。?內(nèi)存訪問方式

如圖1所示,計算機在進行數(shù)據(jù)訪問的時候,是以字節(jié)為基本單元進行訪問的,所以可以認為,計算每次都是從第p個字節(jié)開始訪問的。訪問的長度將由編譯器根據(jù)實際類型進行計算,這在后面將會進行講述。?內(nèi)存訪問方式?想要了解更多,就去翻閱計算機組成原理和編譯原理吧。?sizeof關鍵字
sizeof關鍵字是編譯器用來計算某些類型的數(shù)據(jù)的長度的,以字節(jié)為基本單位。例如:
sizeof(char)=1; sizeof(int)=4;
sizeof(Type)的值是在編譯的時候就計算出來了的,可以認為這是一個常量!

指針是什么?

我們知道:C語言中的數(shù)組是指一類類型,數(shù)組具體區(qū)分為 ?int 類型數(shù)組,double類型數(shù)組,char數(shù)組 等等。

同樣指針這個概念也泛指一類數(shù)據(jù)類型,int指針類型,double指針類型,char指針類型等等。

通常,我們用int類型保存一些整型的數(shù)據(jù),如 int num = 97 , 我們也會用char來存儲字符:char ch = 'a'。

我們也必須知道:任何程序數(shù)據(jù)載入內(nèi)存后,在內(nèi)存都有他們的地址,這就是指針。

而為了保存一個數(shù)據(jù)在內(nèi)存中的地址,我們就需要指針變量。

因此:指針是程序數(shù)據(jù)在內(nèi)存中的地址,而指針變量是用來保存這些地址的變量。

?


在我個人的理解中,可以將指針理解成int整型,只不過它存放的數(shù)據(jù)是內(nèi)存地址,而不是普通數(shù)據(jù),我們通過這個地址值進行數(shù)據(jù)的訪問,假設它的是p,意思就是該數(shù)據(jù)存放位置為內(nèi)存的第p個字節(jié)。

當然,我們不能像對int類型的數(shù)據(jù)那樣進行各種加減乘除操作,這是編譯器不允許的,因為這樣錯是非常危險的!

圖2就是對指針的描述,指針的值是數(shù)據(jù)存放地址,因此,我們說,指針指向數(shù)據(jù)的存放位置。?

指針的長度
我們使用這樣的方式來定義一個指針:
Type *p;
我們說p是指向type類型的指針,type可以是任意類型,除了可以是char,short, int, long等基本類型外,還可以是指針類型,例如int *, int **, 或者更多級的指針,也可是是結構體,類或者函數(shù)等。于是,我們說:


int * 是指向int類型的指針;
int **,也即(int *) *,是指向int *類型的指針,也就是指向指針的指針;int ***,也即(int **) *,是指向int**類型的指針,也就是指向指針的指針的指針;…我想你應該懂了
struct xxx *,是指向struct xxx類型的指針;

其實,說這么多,只是希望大家在看到指針的時候,不要被int ***這樣的東西嚇到,就像前面說的,指針就是指向某種類型的指針,我們只看最后一個*號,前面的只不過是type類型罷了。

細心一點的人應該發(fā)現(xiàn)了,在“什么是指針”這一小節(jié)當中,已經(jīng)表明了:指針的長度跟CPU的位數(shù)相等,大部分的CPU是32位的,因此我們說,指針的長度是32bit,也就是4個字節(jié)!注意:任意指針的長度都是4個字節(jié),不管是什么指針?。ó斎?4位機自己去測一下,應該是8個字節(jié)吧。。。)

?于是:

Type *p;
sizeof(p)的值是4,Type可以是任意類型,char,int, long, struct, class, int **…


以后大家看到什么sizeof(char*), sizeof(int *),sizeof(xxx *),不要理會,統(tǒng)統(tǒng)寫4,只要是指針,長度就是4個字節(jié),絕對不要被type類型迷惑!
?為什么程序中的數(shù)據(jù)會有自己的地址?

弄清這個問題我們需要從操作系統(tǒng)的角度去認知內(nèi)存。

電腦維修師傅眼中的內(nèi)存是這樣的:內(nèi)存在物理上是由一組DRAM芯片組成的。


而作為一個程序員,我們不需要了解內(nèi)存的物理結構,操作系統(tǒng)將RAM等硬件和軟件結合起來,給程序員提供的一種對內(nèi)存使用的抽象。

這種抽象機制使得程序使用的是虛擬存儲器,而不是直接操作和使用真實存在的物理存儲器。

所有的虛擬地址形成的集合就是虛擬地址空間。


在程序員眼中的內(nèi)存應該是下面這樣的。


也就是說,內(nèi)存是一個很大的,線性的字節(jié)數(shù)組(平坦尋址)。每一個字節(jié)都是固定的大小,由8個二進制位組成。

最關鍵的是,每一個字節(jié)都有一個唯一的編號,編號從0開始,一直到最后一個字節(jié)。

如上圖中,這是一個256M的內(nèi)存,他一共有256x1024x1024 ?= 268435456個字節(jié),那么它的地址范圍就是 0 ~268435455 ?。

由于內(nèi)存中的每一個字節(jié)都有一個唯一的編號。

因此,在程序中使用的變量,常量,甚至數(shù)函數(shù)等數(shù)據(jù),當他們被載入到內(nèi)存中后,都有自己唯一的一個編號,這個編號就是這個數(shù)據(jù)的地址。

指針就是這樣形成的。

下面用代碼說明

#include int main(void){ ? ?char ch = 'a'; ? ?int ?num = 97; ? ?printf("ch 的地址:%p",
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉