詳解指標與陣列(😉學不會退學費😉)
- 一、?指標基本概念?
- 二、🎃為什么要有指標🎃
- 三、🎠如何理解編址🎠
- 四、👑指標的記憶體布局、解參考👑
- 五、🎮如何將數值存盤到指定的記憶體地址🎮
一、?指標基本概念?
先從一個小例子開始
#include <stdio.h>
int main()
{
//定義一個變數并做初始化
//開辟空間 賦值
int a = 10;
//使用的是a的空間:左值
a = 20;
//使用的是a的內容:右值
int b = a;
//同樣一個a,在不同運算式中,名稱雖然一樣,但是含義完全不同
return 0;
}
結論:
定義一個變數,本質是在記憶體中根據型別來進行開辟空間
有了空間,就必須具有地址來標識空間,來方便CPU進行尋址
有了空間,就可以把資料保存起來
| 指標是什么 |
指標:指標就是地址!
地址的本質:資料,可以被保存在變數空間里面
指標變數:保存指標(地址)資料的變數
| 指標與指標變數區別 |
左值:左值是用來指明一個物件的運算式,最簡單的左值就是變數名稱,它可以出現在賦值運算子的左邊
右值:可以出現在賦值運算子右邊而不是左邊的運算式,例如,常量和算術運算式

只有指標變數被用為右值的時候,此時指標變數才等于指標
解釋一下下面各個陳述句表達的意思
int a = 10;
int *p = &a;
p = 10;
int *q = p;
*p = 10;
int b = *p;

結論:
1、指標就是地址值
2、指標變數在C中是變數,要在特定區域開辟空間,用來保存地址資料,還可以被取地址
3、嚴格意義上來說兩者不同,但是我們一般在說時,一般將指標誤認為指標變數
二、🎃為什么要有指標🎃
| 在32位機器下,最多能夠識別多大的物理記憶體 |

| CPU按位元組尋址 |

結論:
指標存在的作用簡單來說就是提高查找定位效率
三、🎠如何理解編址🎠
計算機中有很多硬體單元,各個硬體單元之間都是協同作業,所謂協同就是相互之間要能夠進行資料傳遞
硬體與硬體之間都是相互獨立的,我們需要用線連起來
CPU與記憶體之間也是相互獨立的,但是要進行資料的互動,需要用資料總線、地址總線等其他線連起來
CPU在訪問記憶體中某個位元組空間時,由于記憶體中的位元組很多,所以必須要對記憶體進行編址
計算機中的編址,并不需要對每個位元組的地址進行記錄,其實在設計計算機硬體電路的時候就已經完成了
| CPU與記憶體的資料傳輸 |

簡單來理解:
32位機器有32跟地址總線,每根線有兩種狀態,表示1、0(有無電脈沖)
一根線就能表示2種含義,兩根線就能表示4種含義,32根地址線就能表示2^32種含義,每一種含義代表一個地址
地址資訊被下達給記憶體,在記憶體內部,就可以找到該地址對應的資料,該資料通過資料總線傳入CPU內暫存器
四、👑指標的記憶體布局、解參考👑
| 指標的記憶體布局 |
int a = 10;
int* p = &a;

&a取出的是低處的地址,一定不是中間的地址
| 指標解參考 |

*p,取出p中的地址,訪問該地址指向的記憶體單元(通過指標變數訪問,本質是一種間接尋址的方式)
總結:
在相同型別情況下,對指標進行解參考,代表指標所指向的目標(這里*p指向的目標是a)
我們進入更進一步的思考,*p中的p變數代表的是左值,還是右值???

*p對p變數進行解參考操作,訪問的是p的右值
| int* p = NULL 和*p=NULL的區別 |
int* p = NULL;
- 定義一個指標變數p,這個指標的資料型別是int
- 在定義變數的同時,將p的值設定為NULL(0)
- 這里只是指標p的值為NULL,但是*p沒有賦值
int* p;
*p = NULL;
- 定義了一個指標變數p,這個指標的資料型別為int
- p本身為多少并不知道,p有可能是保存的非法的地址,那么將*p設定為NULL,將是訪問非法地址
五、🎮如何將數值存盤到指定的記憶體地址🎮
堆疊隨機化
#include <stdio.h>
int main()
{
int a = 0;
printf("%p\n", &a);
return 0;
}



可以發現每一次對a(區域變數)取地址,列印出來的地址不同,這就是堆疊隨機化
總結:
使用C語言定義的區域變數,在每次運行的時候,地址都是不同的,經過試驗發現, 定義全域變數,每次更改代碼,地址也會發生變化,所以
我們不可以直接通過地址資料對變數進行訪問
#include <stdio.h>
int main()
{
int a = 100;//假設100的地址為0x11223344
*((int*)0x11223344) = 200;
printf("%d\n", *((int*)0x11223344));
return 0;
}

這里我們使用了直接尋址,發生了報錯
#include <stdio.h>
int main()
{
int a = 100;
int* p = &a;
*p = 200;
printf("%d\n", *p);
return 0;
}

這里使用了間接尋址,程式運行正常
目前主流的編譯器和作業系統,為了安全,已經有了很多記憶體保護的機制,利用堆疊隨機化的技術來防止黑客對用戶資料的預測
😁😁😁覺得對自己有幫助的小伙伴可以點個贊哦😁😁😁
👉👉👉有誤的地方也可以在評論區討論哦👈👈👈
離開前,別忘了👍關注💡收藏💖
希望本文能夠對大家有幫助~!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/304988.html
標籤:其他
