折磨了好久的指標,說說自己的一點理解,有不對的地方還希望大佬們多多指正,
CPU是怎么取資料的?
CPU是控制計算機運作的核心部件,但是想讓一個計算機作業必須要向他提供指令和資料,指令和資料是存放在存盤器中的,也就是我們平時所說的記憶體,
存盤器劃分成許多存盤單元,每個存盤單元都有一個編號,也就是地址,當CPU想要訪問資料的時候,它需要先找到這個資料所在的地址,然后再讀取資料,同時還需要知道使用什么器件操作,
由此引出CPU進行資料的讀寫時需要的三個條件:
- 地址資訊(通過地址線操作)
- 控制資訊(通過控制線操作)
- 資料資訊 (通過資料線操作)
CPU通過地址線去到指定的地址取出資料再通過資料線回傳,
什么是指標?
在計算機中,所有的資料都存放在記憶體中,不同的資料存放在不同的記憶體中,不同型別的資料占用記憶體的大小也不一樣,為了計算機能夠正確的訪問到記憶體中的資料,就需要為每塊記憶體編上一個唯一的號碼,類似于門牌號,這樣計算機就可以通過這個唯一的“門牌號”正確的找到存放在記憶體中的資料,而指標的本質就是這些所謂的"門牌號",
取地址符
那么,我們怎么才能看到這些地址("門牌號")呢?
在C語言中有一個運算子叫取地址運算子(&),我們可以嘗試通過取地址符的方式來輸出一個變數在記憶體中的地址:
#include <stdio.h>
int main(void){
int a = 1;
int b = 2;
int c = 3;
printf("%x\n",&a);
printf("%x\n",&b);
printf("%x\n",&c);
return 0;
}
輸出:

因為在計算機中地址是以十六進制表示的,所以這里的輸出采用十六進制的方式,可以看到&a輸出的值是62fe1c,這個62fe1c就是a這個變數在記憶體中的地址,這個a表示的就是1,也就是說,1這個資料存放在記憶體中地址為62fe1c的地方,同理,2存放在62fe18這個地址,3存放在62fe14這個地址,那么他在記憶體中是什么樣的呢?
如圖:

按理來說我們存放的三個變數的存盤地址應該是從小到大,而不是現在的從大到小,這是因為采用了小端存盤模式,資料依次存放的地址是從大到小的,感興趣的可以深究一下,這里就不再贅述,從圖上還可以看到他們的地址之間相差4,這是因為我們宣告的a,b,c都是int型別的,int型別是四個位元組的,所以他們之間相差的值是4,如果我再宣告一個char d,因為他是char型別,占一個位元組,所以他的地址就是62fe13,
指標型別
在C語言中,有許多的資料型別,例如int型別的變數存放的是整型資料,char型別的變數存放的是字符型別,而指標型別的變數,存放的則是地址,換而言之,就是地址一般是存放在指標型別的變數中的,
那么我們怎么定義一個指標型別的變數呢?定義指標型別的變數與定義普通的變數是一樣的,只是需要加上指標運算子------星號(*),例如,int *p,這樣宣告之后,p就是一個指標型別變數,指向一個整型的變數,p中存放的就是這個整型變數的地址,*p是int型別(如果看完有點懵,沒關系,先往下看),例如:

由之前的代碼我們可以知道,&a取的是變數a的地址,然后我們定義了一個指標型別的變數p用來存放這個地址,所以當輸出變數p的時候,也就是輸出p的值時,輸出的就是變數a的地址,
既然p也是一個變數,也是用來存放的值的,那么,他是不是也應該有一個地址呢?
我們可以嘗試用取地址符去取p的地址試試:

通過輸出不難發現,p雖然是指標型別,但是他也是一個變數,也是有地址的,特殊的是,這個變數是用來存放地址的,那么他們在記憶體中是什么樣的呢?如圖:

現在我們知道了指標型別變數p里面存放的是地址,CPU是通過地址取資料,那么既然我們知道了地址,是不是可以通過地址去取資料呢?答案是可以的,
解參考運算子
以int *p為例,既然指標變數p存盤了資料的地址,我們就有辦法取得變數p中存盤的地址上的資料------通過解參考運算子(*),他的作用就是取出這個變數指向的值,以*p為例,就是取出p指向的值,而p中存放的是62fe1c,所以*p可以理解為*62fe1c,也就是取62fe1c這個地址上的值,而62fe1c這個地址上存放的是1,那么*p取出來的就是1,而這個1是int型別,這就解釋了上面的*p是int型別,代碼實作:

那么現在就可以簡單的理解為使用* 地址的方式可以取出地址中的資料,
陣列指標
我們先來看看陣列在記憶體中是什么樣的,
首先,定義一個有五個值的陣列,存放1、2、3、4、5五個數字,然后我們通過取地址符看看他們在記憶體中的地址,

通過輸出不難看出,這五個數字存放在五個連續的地址中,我們定義陣列的時候給陣列定義的變數是arr,用來存放五個數字,那么這個變數是不是也有一個地址呢?我們嘗試輸出arr的地址看看:

通過輸出可以看出,arr的地址和arr[0]的地址是一樣的,其實,arr默認就是指向陣列中第一個地址的位置,后面每一個位置的資料都可以在首地址的基礎上進偏移下標個單位的位置找到,二維陣列也是如此,既然我們知道陣列中第一個數字的地址,而這個陣列中的資料又是連續存放的,那么我們是不是可以通過指標的方式去取陣列中的數字呢?將第一個數字的位置賦給一個指標變數,然后通過首地址進行位置偏移是不是也能夠找到其他數字呢?如圖:

可以發現效果是一樣的,我們將陣列arr的地址賦值給指標變數p,然后將指標變數偏移1,取到的數值就是arr[1],也就是說p[1]和arr[1]的效果是等價的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/45023.html
標籤:C
上一篇:C語言列舉型別的使用及其優越性
下一篇:C語言中定義字串的幾種方式
