新聞中心
計(jì)算機(jī)中所有的數(shù)據(jù)必須存放在內(nèi)存中,不同的類型的數(shù)據(jù)占用的內(nèi)存字節(jié)也不同,int型占4字節(jié),char型占一字節(jié),為了正確訪問這些數(shù)據(jù),必須為每個(gè)一個(gè)自己都編上號(hào)碼,就像倉庫一樣,每個(gè)倉庫都會(huì)有自己的編號(hào),來定位到具體的倉庫。沒有字節(jié)的編號(hào)都是唯一的,根據(jù)編號(hào)就可以準(zhǔn)確的找到某一個(gè)字節(jié)。
如: char a =‘a(chǎn)’;
這一句話中a就是一個(gè)指針地址他指向了內(nèi)存中一個(gè)char型1字節(jié)的內(nèi)存空間 ,而這個(gè)字節(jié)內(nèi)存儲(chǔ)的數(shù)據(jù)是‘a(chǎn)’,所以char a中a存儲(chǔ)的數(shù)據(jù)并不是‘a(chǎn)’而是內(nèi)存中1個(gè)字節(jié)空間的內(nèi)存地址。是用十六進(jìn)制表示的一個(gè)內(nèi)存地址編號(hào),如:0x1000;
如圖是4G內(nèi)存中每個(gè)字節(jié)的編號(hào)(以十六進(jìn)制表示):
int i ;
0x0000 0x0001 0x0002 0x0003
0xFFFFFFFD 0xFFFFFFFE 0xFFFFFFFF 0xFFFFFFFC
我們將內(nèi)存中字節(jié)的編號(hào)稱為地址(Address)或指針(Pointer)。地址從0開始依次增加,對(duì)于32位環(huán)境中,程序能夠使用的內(nèi)存為4GB,最小的地址為0,大的地址是0XFFFFFFFF.因?yàn)槭M(jìn)制0XFFFFFFFF對(duì)應(yīng)的二進(jìn)制就是11111111111111111111111111111111 。
下面的代碼演示了如何輸出一個(gè)地址:
#include
int main(){
int a=100;
char str[20]=”zheshiyizifuchuan”;
printf(“%#X,%#X\n”,&a,str);
return 0;
}
運(yùn)行結(jié)果:
0XBF80E1E4,0XBF80E1F8.
這里解釋一下為什么他們的間隔是4,因?yàn)閕nt型a在內(nèi)存中占四字節(jié),每個(gè)字節(jié)都會(huì)有自己獨(dú)特編號(hào)指針,a在內(nèi)存中的分布是
0XBF80E1E4 0XBF80E1E5 0XBF80E1E6 0XBF80E1E7
而char str[20]數(shù)組中的內(nèi)存分布是
0XBF80E1F8 0XBF80E1F9 0XBF80E1E2 ……此處省略中間的地址… 0XBF80E1V8
而取str的內(nèi)存地址是,取的是char str[20]數(shù)組中的首元素的地址,所以str的內(nèi)存地址是0XBF80E1F8。
%#X表示以十六進(jìn)制形式輸出,并附帶前綴0X。a是一個(gè)變量,用來存放整數(shù)需要在前面加&來獲取它的地址;str本身就表示字符串的首地址,不需要加&。
C語言中有一個(gè)控制符 %p,專門用來打印出以十六進(jìn)制形式表示的變量內(nèi)存地址,不過,%p的輸出格式并不統(tǒng)一,有的編譯器帶0X前綴,有的不帶,所以此處我們并沒有采用
一切都是地址(指針)
C語言用變量來存儲(chǔ)數(shù)據(jù),用函數(shù)來定義一段可以重復(fù)使用的代碼,他們最終都要放到內(nèi)存中才能供CPU使用。
注釋:C語言中數(shù)據(jù)的存儲(chǔ)都是在聲明的變量中,換句話說就是聲明的變量,變量的指針指向的是內(nèi)存的數(shù)據(jù)存儲(chǔ)層,如果想要存儲(chǔ)一條數(shù)據(jù)就需要聲明一個(gè)變量而變量不存儲(chǔ)數(shù)據(jù),變量只存儲(chǔ)聲明的這個(gè)變量的類型字節(jié)空間在內(nèi)存中的編號(hào),而數(shù)據(jù)存儲(chǔ)在聲明的類型的字節(jié)空間中,變量只是一個(gè)指向這塊空間的指針。變量的指針是指針內(nèi)存數(shù)據(jù)層,而函數(shù)其實(shí)本質(zhì)上也是一個(gè)指針,函數(shù)名也是一個(gè)指針。而函數(shù)名指向的 內(nèi)存空間是代碼層。其實(shí)聲明一個(gè)函數(shù)就是在內(nèi)存的代碼層中聲明了一塊空間在存儲(chǔ)編寫的代碼,而函數(shù)名其實(shí)內(nèi)存儲(chǔ)的其實(shí)就是指向這一塊內(nèi)存空間的地址指針。所以從這一層面上來看的話,程序中不管是變量還是函數(shù)都是存儲(chǔ)在內(nèi)存中的,而我們編寫的變量名,函數(shù)名,數(shù)組名,字符串名,其實(shí)都是指向內(nèi)存空間的字節(jié)編號(hào),而他們的存儲(chǔ)空間在內(nèi)存中也會(huì)在不同的層中,這也是方便cup的讀取。而cup讀取執(zhí)行程序時(shí),會(huì)根據(jù)變量名和函數(shù)名提供的內(nèi)存字節(jié)地址準(zhǔn)備的去不同的內(nèi)存層空間中讀取不同的數(shù)據(jù)。
數(shù)據(jù)和代碼都是以二進(jìn)制的形式存儲(chǔ)在內(nèi)存中,計(jì)算機(jī)無法從格式上區(qū)分某塊內(nèi)存到底存儲(chǔ)的是數(shù)據(jù)還是代碼,當(dāng)程序被加載到內(nèi)存后,程序系統(tǒng)會(huì)給不同的內(nèi)存指定不同的權(quán)限,擁有讀取和執(zhí)行權(quán)限的內(nèi)存塊就是代碼,而擁有讀取和寫入權(quán)限(也可能只有讀取權(quán)限)的內(nèi)存塊就是數(shù)據(jù)。
注釋:程序中聲明的變量和代碼最終都會(huì)轉(zhuǎn)為二進(jìn)制代碼存儲(chǔ)在計(jì)算機(jī)的內(nèi)存中,但是計(jì)算機(jī)無法區(qū)分出哪里的內(nèi)存存儲(chǔ)的數(shù)據(jù)是數(shù)據(jù),哪里的是代碼,所以需要程序系統(tǒng)給不同的內(nèi)存空間設(shè)定不同的權(quán)限,來區(qū)分內(nèi)存空間中存儲(chǔ)的數(shù)據(jù)還是代碼,這也是內(nèi)存出現(xiàn)不同層的原因。
CPU只能通過地址來取得內(nèi)存中的代碼和數(shù)據(jù),程序在執(zhí)行過程中會(huì)告知CPU要執(zhí)行的代碼以及要讀寫的數(shù)據(jù)的地址。如果程序不小心出錯(cuò),或者開發(fā)者有意為之,在CUP要寫入數(shù)據(jù)時(shí),給它的一個(gè)代碼區(qū)域的地址,就會(huì)出現(xiàn)內(nèi)存訪問錯(cuò)誤,這種內(nèi)存訪問錯(cuò)誤會(huì)被硬件和操作系統(tǒng)攔截,強(qiáng)制程序崩潰,程序員沒有挽救的機(jī)會(huì)。
注釋:程序在執(zhí)行時(shí)CPU只能通過地址去內(nèi)存中讀取數(shù)據(jù),而代碼和數(shù)據(jù)是存放在不同的內(nèi)存層中如果程序在編寫中設(shè)置的變量地址或者函數(shù)地址的數(shù)據(jù)層不對(duì)時(shí),那么CPU在讀取數(shù)據(jù)或代碼時(shí)會(huì)因?yàn)闄?quán)限的問題而被硬件和操作系統(tǒng)攔截,從而內(nèi)存數(shù)據(jù)讀取失敗導(dǎo)致程序崩潰,因?yàn)檫@個(gè)過程是編寫好的而且程序執(zhí)行非常快的,所以程序員沒有計(jì)劃挽救。
CPU訪問內(nèi)存時(shí)需要的是地址,而不是變量名和函數(shù)名!變量名和函數(shù)名只是地址的一種助記符,當(dāng)源文件被編譯和連接成可執(zhí)行程序之后,他們都會(huì)被替換成地址。編譯和連接過程的一項(xiàng)重要任務(wù)就是找到這些名稱所對(duì)應(yīng)的地址。
注釋:這句話很重要,這句話也是地址的核心,變量名在聲明時(shí)會(huì)有一個(gè)自己獨(dú)特的地址,而程序在編譯時(shí)也會(huì)把聲明的變量名轉(zhuǎn)換為指針,在CPU訪問內(nèi)存是就是需要的我們之前聲明的變量轉(zhuǎn)換之后的地址指針。而編譯就是負(fù)責(zé)這個(gè)轉(zhuǎn)換的過程。
假設(shè)變量 a b c 在內(nèi)存中的地址分別是0X1000 0X20000 0X30000,那么加法運(yùn)算c=a+b;
將會(huì)被轉(zhuǎn)成類似下面的形式:
0X3000=(0X10000)+(0X20000);
()表示取值操作,整個(gè)表達(dá)式的意思是,取出地址0X10000和0X20000上的值,將他們相加,把相加的結(jié)果賦值給地址為0X30000的內(nèi)存。
變量名和函數(shù)名為我們提供了方便,讓我們?cè)诰帉懘a的過程中,可以使用易于閱讀和理解的英文字符串,不用直接面對(duì)二進(jìn)制地址,那場(chǎng)景簡(jiǎn)直讓人崩潰。
需要注意的是,雖然變量名,函數(shù)名,字符串名,和數(shù)組名,在本質(zhì)上是一樣的,他們都是地址的助記符,但在編寫代碼的過程中,我們認(rèn)為變量名是表示的是數(shù)據(jù)本身,而函數(shù)名和數(shù)組名表示的是代碼塊或數(shù)據(jù)塊的首地址。
注釋:這里的原因是因?yàn)樽兞棵赶虻氖且粋€(gè)一種數(shù)據(jù)類型的內(nèi)存空間地址,而函數(shù)名,字符串名,數(shù)組名,指向的是一塊內(nèi)存中連續(xù)的數(shù)據(jù)類型空間的第一個(gè)字節(jié)的地址。
本文章參考c.biancheng.net.中c語言指針是什么的博文和添加自己的主觀想法完成的編寫。
原文:http://c.biancheng.net/view/1990.html
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
標(biāo)題名稱:C語言指針是什么?C語言指針的概念。-創(chuàng)新互聯(lián)
地址分享:http://www.dlmjj.cn/article/dsceeg.html