亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語(yǔ)言數(shù)組和指針,內(nèi)存之間的關(guān)系

 更新時(shí)間:2022年02月03日 10:52:51   作者:伴你永居我憶i ?  
這篇文章主要介紹了C語(yǔ)言數(shù)組和指針,內(nèi)存之間的關(guān)系,首先論證一維數(shù)組和一級(jí)指針之前的關(guān)系,我們常常使用一級(jí)指針指針的方式訪問(wèn)一維數(shù)組,只有對(duì)內(nèi)存的理解到位才能理解它們直接的關(guān)系。需要的小伙伴可以參考一下

首先論證一維數(shù)組和一級(jí)指針之前的關(guān)系,我們常常使用一級(jí)指針指針的方式訪問(wèn)一維數(shù)組,只有對(duì)內(nèi)存的理解到位才能理解它們直接的關(guān)系。

  • 1.數(shù)組名是數(shù)組的首地址
  • 2.對(duì)數(shù)組名取地址得到的還是數(shù)組的首地址
  • 3.數(shù)組的訪問(wèn)方式其實(shí)就是首地址+偏移的尋址訪問(wèn)

我們?cè)诔绦蛑袝?huì)定義很多變量,有基本類(lèi)型和自定義類(lèi)型
在進(jìn)行開(kāi)發(fā)的時(shí)候我對(duì)內(nèi)存的訪問(wèn)訪問(wèn)就是通過(guò)變量名賦值的方式讀寫(xiě)內(nèi)存
但是如果你看到的直接變量的符號(hào)名你將不可能理解內(nèi)存。
每一種類(lèi)型都有字節(jié)寬度,
char 1字節(jié) short 2字節(jié) int 字節(jié)float 4 double 8,其他的自定義類(lèi)型也有一個(gè)對(duì)應(yīng)的大小,對(duì)于通過(guò)變量名讀寫(xiě)操作內(nèi)存,我們需要自動(dòng)在腦子里面形成一個(gè)映射關(guān)系。

int a=10;// 往某段內(nèi)存地址位x的內(nèi)存 寫(xiě)入4個(gè)字節(jié)的數(shù)據(jù)10
intp =(int)20; //往某段內(nèi)存地址位x1的內(nèi)存 寫(xiě)入4個(gè)字節(jié)的數(shù)據(jù)20
int** p =(int**)30;// 往某段內(nèi)存地址位x2的內(nèi)存 寫(xiě)入4個(gè)字節(jié)的數(shù)據(jù)30
int b = a; //讀取某段內(nèi)存地址為x的內(nèi)存 讀取4給字節(jié)數(shù)據(jù)值 寫(xiě)入首地址為b的某段內(nèi)存 寬度為4,

對(duì)于賦值讀寫(xiě)需要腦子里面自動(dòng)分割成一塊塊內(nèi)存然后將變量符號(hào)名字與對(duì)于的首地址(還有寬度)對(duì)于起來(lái),忽略數(shù)據(jù)類(lèi)型的概念,對(duì)于一個(gè)變量只關(guān)注首地址+數(shù)據(jù)寬度。

對(duì)于使用指針訪問(wèn)數(shù)組如圖下所示
基本上有點(diǎn)基礎(chǔ)的都可以看出來(lái)使用直接使用數(shù)組arr和使用指針p相比少了
arr是首地址+偏移 然后直接往這個(gè)地址里面讀或者寫(xiě)
指針的操作方式首先需要得到p對(duì)象 所占的空間里面存放的值(這里是數(shù)組首地址)然后再通過(guò)存放的值+偏移的方式 讀寫(xiě)內(nèi)存
int* p =arr; 把p這個(gè)對(duì)象 賦值數(shù)組首地址 任何指針類(lèi)型32位下4個(gè)字節(jié) 64位下8個(gè)字節(jié),p這個(gè)對(duì)象需要4個(gè)字節(jié)的空間存儲(chǔ)arr值,因?yàn)閜是一個(gè)變量,占4個(gè)字節(jié) int* p=arr;就是 往p所占的4個(gè)字節(jié)里面存儲(chǔ)arr值首地址
而通過(guò)p[_i]下標(biāo)訪問(wèn)的時(shí)候 首先就需要 取出來(lái)p里面存的四個(gè)字節(jié)值y
然后y+偏移的方式 訪問(wèn)讀或者寫(xiě)該指針指向數(shù)組中的內(nèi)容

從上面的結(jié)果我們可以得到,別看到一級(jí)指針操作一維數(shù)組 和數(shù)組直接訪問(wèn)問(wèn)之前只多了一層指針變量的尋址,但是含義就完全的變了。
如有些書(shū)上說(shuō)數(shù)組作為實(shí)參會(huì)退化為指針
lea eax,[arr] 是數(shù)組首地址保存到eax寄存器中
push eax 參數(shù)入棧 此時(shí)esp寄存器的值減4,push eax相當(dāng)與啥?相當(dāng)于創(chuàng)建了一個(gè)零時(shí)對(duì)象 占4個(gè)字節(jié)的指針,傳遞過(guò)去,首地址值訪問(wèn)一塊4個(gè)字節(jié)的內(nèi)存后這段4個(gè)字節(jié)的內(nèi)存后編譯器認(rèn)為這是一個(gè)指針,所以funtion里面使用sizeof可以看到占4個(gè)字節(jié)(可以私下去測(cè)試),所以把編譯器給的類(lèi)型去掉后 。
int a = (int)arr; 往a占的4個(gè)字節(jié)內(nèi)存中寫(xiě)入數(shù)組首地址,從匯編的角度來(lái)看,是不是找到一絲熟悉的感覺(jué)了,沒(méi)錯(cuò)下面這兩個(gè)除了編譯器附加的一些類(lèi)型的限制之外沒(méi)有區(qū)別,甚至可以說(shuō)是完全一樣的,我們完全可以使用一個(gè)int a;操作任何基本類(lèi)型和抽象類(lèi)型對(duì)象

int a= (int)arr;
int* p =arr;

函數(shù)傳遞一級(jí)指針和二級(jí)指針
下圖可以看到傳遞一級(jí)是將p的地址ebp-0x3c里面存儲(chǔ)的內(nèi)容 push到棧中傳參
而傳遞二級(jí)指針的時(shí)候是lea 得到ebp-0x3c這個(gè)值 p的地址傳遞進(jìn)去
所以對(duì)于二級(jí)指針而言 我們很容易在funtion2函數(shù)里面改變被調(diào)用函數(shù)里面p指向的內(nèi)容
(這種方式多與一些庫(kù)的設(shè)計(jì) 如ffmpeg 的一些函數(shù)設(shè)計(jì)傳遞一個(gè)一級(jí)指針的地址進(jìn)去(指向NULL)函數(shù)里面可以創(chuàng)建某些對(duì)象然后然后改變被調(diào)函數(shù)的指針,釋放的時(shí)候同理,這樣可以減少開(kāi)發(fā)者所作的工作

可以用一級(jí)指針指針引用一位數(shù)組,以前剛學(xué)習(xí)的時(shí)候我自認(rèn)而然的使用二級(jí)指針引用二維數(shù)組,發(fā)現(xiàn)是不可以。
進(jìn)程的內(nèi)存就是線性的32位可以尋址00000000-0xffffffff 4gb,從內(nèi)存的角度看沒(méi)有二維數(shù)組的概念,也沒(méi)有多維數(shù)組的概念,對(duì)于任何一個(gè)變量,關(guān)注的應(yīng)該都是首地址,寬度
int arr[4][3] ; 在內(nèi)存布局上可以 int arr[12];是完全一樣的沒(méi)有任何區(qū)別
二維數(shù)組或者多維數(shù)組的設(shè)計(jì)知識(shí)為了理解的方便,比如使用二維數(shù)組可以更加直觀的表示一個(gè)nm地圖的狀態(tài),使用一維度的話沒(méi)有那么的直觀。三維數(shù)組可以讓我們更直觀的表示一個(gè)空間的概念,其實(shí)它們內(nèi)存也就是一個(gè)一線性的一維數(shù)組
int arr[4][3] 我們通過(guò) arr[_i][_j]的訪問(wèn)方式
mov eax,[_i];首先得到_i的值保存到eax寄存器中
lea ecx,arrtow[eax4]; lea指令是得到[]里面的地址 arrtow首地址 + _i41(char占1個(gè)字節(jié)如果是其他類(lèi)型需要對(duì)應(yīng)大小)
mov edx ,[_j] ;edx寄存器保存_j的值
movsx eax.byte ptr[ecx+edx] 就是arrtow+_i41+_j1 取出這個(gè)內(nèi)存編號(hào)中的值取一個(gè)字節(jié)放入eax寄存器中 char到int有一個(gè)轉(zhuǎn)換
mov [a],eax 放入a變量所在的地址中 四個(gè)字節(jié)
可以看到二維數(shù)組其實(shí)也是一個(gè)一維數(shù)組 首地址+_im寬度+j*寬度的尋址方式
三維數(shù)組同理

二級(jí)指針不能引用二維數(shù)組是因?yàn)槭且驗(yàn)槎?jí)指針操作內(nèi)存的方式和二維數(shù)組的完全不同,一級(jí)指針可以引用一維數(shù)組是因?yàn)樗鼈儾僮鲀?nèi)存的方式是相同的

lea eax,[arrtow]
mov dword ptr [pp],eax //這兩行把char** pp = (char**)arrtow arrtow值給 pp變量
mov eax,dword ptr [_i]; //_i的值保存在eax寄存器中
mov ecx.dword ptd[pp]; //得到pp中存儲(chǔ)的值 就是arrtow值(數(shù)組首地址)
mov edx,dword ptr [ecx+eax4] // 數(shù)組首地址+_i4的值 指針寬度占4個(gè)字節(jié), 將arrtow+_i 4位首地址讀取四個(gè)字節(jié) 到edx寄存器 (這里就尋址了一次)
mov eax.dword ptr [_j]; //讀取_j的值存放在eax寄存器中
movsx ecx,byte ptr [edx+eax]//把在arrtow+_i4地址處取的四個(gè)字節(jié)數(shù)據(jù)當(dāng)做首地址 +_j再次當(dāng)作首地址取一個(gè)字節(jié) 當(dāng)如ecx寄存器
mov dword ptr [a],ecx, 放入a變量中

通過(guò)二級(jí)指針和二維數(shù)組訪問(wèn)內(nèi)存的方式不同,可以明白為啥不能使用二級(jí)指針直接訪問(wèn)二維數(shù)組,同理三級(jí)指針尋址3次,四級(jí)指針4次,不管多少維數(shù)組都是和一維數(shù)組一樣一次,所以如果我把斷點(diǎn)繼續(xù)指行就會(huì)應(yīng)為訪問(wèn)未知地址掛掉。

再次將論點(diǎn)移到內(nèi)存,我們所作的一切都只是對(duì)內(nèi)存的訪問(wèn),而C/C++一不小心就會(huì)出現(xiàn)對(duì)內(nèi)存的非法的訪問(wèn),所以了解內(nèi)存是一件非常重要的事情,而指針只是訪問(wèn)操作內(nèi)存的一種靈活的方式。和前面說(shuō)的一樣,任何指針占,所以任何一個(gè)4個(gè)字節(jié)的內(nèi)存單元 一個(gè)int的大小 可以以任何的指針的方式訪問(wèn)內(nèi)存,極度的靈活(如果對(duì)內(nèi)存沒(méi)有足夠的理解同時(shí)就會(huì)導(dǎo)致極度的不安全),

到此這篇關(guān)于C語(yǔ)言數(shù)組和指針,內(nèi)存之間的關(guān)系的文章就介紹到這了,更多相關(guān)數(shù)組和指針,內(nèi)存之間的關(guān)系內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論