深入理解C語(yǔ)言指針及占據(jù)內(nèi)存空間
原文鏈接:https://www.cnblogs.com/l-hh/p/12288613.html
第一、了解內(nèi)存空間
本文章文字有點(diǎn)多,會(huì)有點(diǎn)枯燥,配合圖文一起看可以緩解枯燥,耐心閱讀哦!?。?/p>
先了解內(nèi)存地址,才更好的理解指針!
我們可以把內(nèi)存想象為成一列很長(zhǎng)很長(zhǎng)的貨運(yùn)火車,有很多大小相同的車廂,而每個(gè)車廂正好相當(dāng)于在內(nèi)存中表示一個(gè)字節(jié)
。這些車廂裝著不同的貨物,就像我們的內(nèi)存要存著各式各樣的數(shù)據(jù)。
多啰嗦一下
我們平時(shí)在電腦上能夠聽音樂、看視頻和文章,其實(shí)看到的這些東西就是內(nèi)存中每個(gè)“車廂”里面的數(shù)據(jù),這些數(shù)據(jù)最終還是由二進(jìn)制0/1演變而成。
雖然視頻、文章、音樂等這些信息在我們眼里是不同的,但對(duì)于計(jì)算機(jī)來(lái)說它們?cè)趦?nèi)存中都是以二進(jìn)制的形式來(lái)表示。
因?yàn)槲覀円廊ツ拇婊蛉?shù)據(jù),所以內(nèi)存中每個(gè)字節(jié)都有對(duì)應(yīng)的編號(hào),就像火車上的車廂編號(hào)一樣。而這個(gè)內(nèi)存中每個(gè)字節(jié)的編號(hào)就是我們常說的內(nèi)存地址,是按一個(gè)字節(jié)接著一個(gè)字節(jié)的次序進(jìn)行編址。如下圖所示:
凡事多問幾個(gè)為什么?
1. 為什么內(nèi)存地址都有0x開頭?
0x 開頭代表以十六進(jìn)制來(lái)表示的意思。
2. 為什么我們平時(shí)看到內(nèi)存地址是這樣的呢?如圖:
因?yàn)閮?nèi)存容量很大,容量大字節(jié)數(shù)自然也多了,所以需要更多位來(lái)編址內(nèi)存地址。上圖的(0x00 ...)內(nèi)存地址這里只是便于理解!
3. 為什么我那么菜呢?
哈哈哈......你心里沒點(diǎn)*數(shù)嗎?
關(guān)于內(nèi)存字節(jié)
- 1個(gè)內(nèi)存地址只存1個(gè)字節(jié) (Byte);
- 1個(gè)字節(jié)等于8位二進(jìn)制,每一位二進(jìn)制的0或1,叫“比特”(bit);
- 比特是最小單位,字節(jié)是比特的集合,也是一個(gè)單位;
內(nèi)存給數(shù)據(jù)類型地址分配如下:
- char:占一個(gè)字節(jié)分配一個(gè)地址;
- int: 占四個(gè)字節(jié)分配四個(gè)地址;
- 還有l(wèi)ong、float、double等類型,等著你來(lái)動(dòng)手測(cè)試。
可以使用sizeof進(jìn)行驗(yàn)證:
#include<stdio.h> int main () { printf("sizeof(char)=%u\n",sizeof(char)); printf("sizeof(int)=%u\n",sizeof(int)); return 0; }
結(jié)果如下:
第二、理解指針
不要把指針想得太復(fù)雜,指針的實(shí)質(zhì)就是內(nèi)存“地址”,可以說指針就是地址,其實(shí)指針就是保存地址的變量。
拿普通變量跟指針變量做比較:
char a; // 定義一個(gè)變量a,用于保存char類型的數(shù)據(jù); char *b; // 定義一個(gè)指針變量b,用于保存一個(gè)內(nèi)存地址,這個(gè)內(nèi)存地址上的數(shù)據(jù)必須是char類型的。
舉個(gè)例子,給指針變量進(jìn)行賦值:
#include<stdio.h> int main () { char a = 5; // char 類型占一個(gè)字節(jié); char *b = &a; // “&”是取變量的地址,取出a在內(nèi)存中的地址; // 賦值給b指針,此時(shí)b變量存儲(chǔ)的就是a地址。 printf("我是a變量的值:%d\n",*b); // *b表示輸出b里面存儲(chǔ)的地址上的數(shù)據(jù); // 證明b上存儲(chǔ)的是a的地址; printf("我是a的地址:%p\n",&a); printf("我是b變量的值:%p\n",b); return 0; }
輸出結(jié)果為:
我是a變量的值:5 我是a的地址:000000000062FE17 我是b變量的值:000000000062FE17
通過畫圖來(lái)理解:
通過指針間接性修改變量的值
char a = 5; char *b = &a; printf("初始值:a=%d,*b=%d\n",a,*b); *b = 12; // 其實(shí)操作的就是變量a本身的值; printf("修改后:a=%d,*b=%d\n",a,*b); ------------------------------------------ 輸出結(jié)果為: 初始值:a=5,*b=5 修改后:a=12,*b=12
指針類型的概念
我們知道char類型的數(shù)據(jù)只占一個(gè)字節(jié),有很多類型是需要多個(gè)字節(jié)來(lái)存儲(chǔ)的,像int類型的數(shù)據(jù)就需要四個(gè)字節(jié)來(lái)存儲(chǔ)(根據(jù)平臺(tái)不同,長(zhǎng)度也有可能不一致)。
對(duì)于int類型的指針從當(dāng)前字節(jié)(地址)開始共四個(gè)字節(jié)(地址)都是屬于該變量的值, 而對(duì)于char類型則只表示當(dāng)前字節(jié)(地址)。代碼如下:
int a = 259; int * p1 = &a; char * p2 = (char *)&a; // 這里需要強(qiáng)制轉(zhuǎn)換一下類型 printf("*p1=%d,*p2=%d\n",*p1,*p2); ----------------------- 輸出:*p1=259,*p2=3
通過畫圖來(lái)便于理解:
通過上文我們已經(jīng)對(duì)int類型指針有所了解了,*p1的輸出是在我們預(yù)算范圍之內(nèi)的,但是為什么*p2輸出的值是3呢?
重點(diǎn),敲黑板?。?!
因?yàn)橛?jì)算機(jī)是使用二進(jìn)制來(lái)表示數(shù)字的,上面(259)十進(jìn)制轉(zhuǎn)換二進(jìn)制是 [100000011],由于一個(gè)int類型變量占用四個(gè)字節(jié),8位二進(jìn)制為一個(gè)字節(jié),補(bǔ)齊高位的0后,則 [00000000 00000000 00000001 00000011],每8位二進(jìn)制(一個(gè)字節(jié))換算為十進(jìn)制,則 [0 0 1 3]。
相關(guān)文章
淺理解C++ 人臉識(shí)別系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了淺理解C++ 人臉識(shí)別系統(tǒng)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03C語(yǔ)言位運(yùn)算和sizeof運(yùn)算符詳解
這篇文章主要介紹了C語(yǔ)言位運(yùn)算和sizeof運(yùn)算符詳解的相關(guān)資料,這里提供了詳細(xì)的知識(shí)要點(diǎn),并附簡(jiǎn)單代碼示例,需要的朋友可以參考下2016-11-11C++?ffmpeg實(shí)現(xiàn)將視頻幀轉(zhuǎn)換成jpg或png等圖片
有時(shí)播放實(shí)時(shí)流的時(shí)候有截圖的需求,需要將解碼出來(lái)的圖片保存本地或上傳服務(wù)器,這時(shí)就需要將avframe中的數(shù)據(jù)編碼成png、jpg等格式的圖片,我們使用ffmpeg的相關(guān)編碼器就可以實(shí)現(xiàn)功能,下面就來(lái)講講具體實(shí)現(xiàn)方法吧2023-03-03使用C語(yǔ)言生成圖片的base64編碼的代碼實(shí)現(xiàn)
Base64編碼是一種廣泛使用的編碼方案,將任意二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為可打印的ASCII字符字符串,在實(shí)際應(yīng)用中,Base64編碼常見于電子郵件附件、數(shù)據(jù)庫(kù)中存儲(chǔ)非文本數(shù)據(jù)等多種場(chǎng)景,本文將給大家介紹使用C語(yǔ)言生成圖片的base64編碼的代碼實(shí)現(xiàn),需要的朋友可以參考下2024-08-08用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易通訊錄
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02C++實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01