欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報(bào)激活碼778899分享:c語言 C:初識(shí)指針—學(xué)習(xí)筆記

柚子快報(bào)激活碼778899分享:c語言 C:初識(shí)指針—學(xué)習(xí)筆記

http://yzkb.51969.com/

目錄

前言:

1、內(nèi)存和地址

1.1 理解內(nèi)存和地址

1.2 理解編址

2、指針變量和地址

2.1 取地址操作符:&

2.2 指針變量

2.3 如何拆解指針類型

2.4 解引用操作符(*)

2.5 指針變量的大小

3、指針變量類型的意義

3.1 指針的解引用

3.2 指針+-整數(shù)

4、void* 指針

結(jié)語:

前言:

談及指針,大部分人只有一個(gè)感覺:太難學(xué)了,好抽象??!但是,請(qǐng)不要著急,今天當(dāng)你看完這一篇后,相信你肯定能夠理解什么是指針了。

1、內(nèi)存和地址

1.1 理解內(nèi)存和地址

在介紹指針前,我們需要先了解什么是內(nèi)存和地址。

關(guān)于內(nèi)存和地址,生活中有一個(gè)例子可以很好的解釋它們

比如說你住在一棟宿舍樓,大樓內(nèi)有100個(gè)房間,但是房間并沒有編號(hào)。這時(shí),你的一個(gè)朋友來找你玩,如果想找到你,就得一個(gè)房間一個(gè)房間的尋找,這樣效率很低。但是,如果我根據(jù)樓層和樓層的房間的情況,給每一個(gè)房間都編上號(hào),比如:

1樓:101 102 103……

當(dāng)有了門牌號(hào),這時(shí)候你只需要將門牌號(hào)告訴你朋友,他就可以很快速的找到房間,找到房間里的你。

如何將上面的例子抽象到計(jì)算機(jī)里呢?你可以理解宿舍樓就是內(nèi)存,房間就是內(nèi)存中的一個(gè)內(nèi)存單元,房間里的你就是數(shù)據(jù),而門牌號(hào)就是地址。

所以內(nèi)存就是存儲(chǔ)數(shù)據(jù)的空間

我們知道計(jì)算機(jī)上CPU(中央處理器)在處理數(shù)據(jù)的時(shí)候,需要的數(shù)據(jù)是在內(nèi)存中讀取的,處理后的數(shù)據(jù)也會(huì)放回內(nèi)存中,那我們買電腦的時(shí)候,電腦上內(nèi)存是8GB/16GB/32GB等,那這些內(nèi)存空間如何高效的管理呢?

cpu從內(nèi)存中讀取數(shù)據(jù),就好比是你朋友要在宿舍樓里找到你,而你朋友找你,也只是在一個(gè)個(gè)房間尋找。大樓里的一個(gè)一個(gè)房間的劃分,讓人們對(duì)大樓內(nèi)的面積能夠充分利用,而計(jì)算機(jī)中也是如此。內(nèi)存的空間只有8GB/16GB/32GB,因此對(duì)于內(nèi)存的合理運(yùn)用也變的很重要。

計(jì)算機(jī)中把內(nèi)存也劃分為一個(gè)個(gè)的內(nèi)存單元,每個(gè)內(nèi)存單元的大小取1字節(jié)。

(補(bǔ)充)計(jì)算機(jī)中常見的單位:

一個(gè)bit可以存儲(chǔ)一個(gè)2進(jìn)制位的1和0

地址(門牌號(hào))內(nèi)存(大樓)其中,每個(gè)內(nèi)存單元,相當(dāng)于?個(gè)學(xué)?宿舍,一 個(gè)字節(jié)空間里面能放8個(gè)比特位,就好比同學(xué)們住 的八?間,每個(gè)人是?個(gè)比特位。0xFFFFFFFF(16進(jìn)制)1個(gè)字節(jié)0xFFFFFFFE1個(gè)字節(jié)1個(gè)字節(jié) 每個(gè)內(nèi)存單元也都有?個(gè)編號(hào)(這個(gè)編號(hào)就相當(dāng) 于宿舍房間的門牌號(hào)),有了這個(gè)內(nèi)存單元的編 號(hào),CPU就可以快速找到?個(gè)內(nèi)存空間。 (內(nèi)存單元) 生活中我們把門牌號(hào)也叫地址,在計(jì)算機(jī)中我們 把內(nèi)存單元的編號(hào)也稱為地址,C語言中給地址起了新的名字叫:指針 1個(gè)字節(jié)0x000000011個(gè)字節(jié)0x000000001個(gè)字節(jié)

所以我們可以理解為:內(nèi)存單元的編號(hào) == 地址 == 指針

1.2 理解編址

生活中關(guān)于我們可以看到通過宿舍門上的門牌號(hào),直接找到我們想去的地方。門牌號(hào)是真實(shí)存在與宿舍門上的。而內(nèi)存中的地址我們?cè)撛趺蠢斫饽兀?/p>

計(jì)算機(jī)中的編址,并不是把每個(gè)字節(jié)的地址記錄下來,而是通過硬件設(shè)計(jì)完成的。

這就像鋼琴,吉他上面沒有刻上“剁、來、咪、發(fā)、 唆、拉、西”這樣的信息,但演奏者照樣能夠準(zhǔn) 確找到每?個(gè)琴弦的每?個(gè)位置,這是為何?因?yàn)橹圃焐桃呀?jīng)在樂器硬件層面上設(shè)計(jì)好了,并且 所有的演奏者都知道。本質(zhì)是?種約定出來的共識(shí)!

有點(diǎn)抽象,舉個(gè)例子:

圖書館里有一排排的書架,每個(gè)書架又有一層層的格子,這些格子就好比內(nèi)存中的存儲(chǔ)單元。

給每個(gè)格子編上號(hào),也就是編址,就像是要給圖書館里的每個(gè)格子都貼上標(biāo)簽。

那這個(gè)標(biāo)簽是怎么貼上去的呢?這就得靠圖書館的“硬件設(shè)計(jì)”了。

比如說,書架的排列方式、格子的劃分規(guī)則,就像是硬件的設(shè)計(jì)。

想象一下,書架是固定的,它們的位置和大小決定了格子的位置和數(shù)量,這就好比硬件決定了內(nèi)存有多少個(gè)可以存儲(chǔ)數(shù)據(jù)的地方。

然后,有一套專門的標(biāo)記系統(tǒng),就像特殊的機(jī)器或者裝置,按照書架和格子的排列,給每個(gè)格子都印上編號(hào),這就是通過硬件實(shí)現(xiàn)了編址。

那硬件設(shè)計(jì)又是怎么實(shí)現(xiàn)的呢?

首先,必須理解,計(jì)算機(jī)內(nèi)是有很多的硬件單元,而硬件單元是要互相協(xié)同工作的。所謂的協(xié) 同,至少相互之間要能夠進(jìn)?數(shù)據(jù)傳遞。 但是硬件與硬件之間是互相獨(dú)立的,那么如何通信呢?答案很簡單,用"線"連起來。 ?CPU和內(nèi)存之間也是有大量的數(shù)據(jù)交互的,所以,兩者必須也用線連起來。通過地址總線,我們就可以了解什么是硬件編址了。

32位機(jī)器有32根地址總線, 每根線只有兩態(tài),表示0,1【電脈沖有無】,那么?根線,就能表示2種含義,2根線就表示4種含義,依次類推。32根地址線,就能表示2^32種含義,每?種含義都代表?個(gè)地址。?地址信息被下達(dá)給內(nèi)存,在內(nèi)存上,就可以找到 該地址對(duì)應(yīng)的數(shù)據(jù),將數(shù)據(jù)在通過數(shù)據(jù)總線傳入CPU內(nèi)寄存器。

內(nèi)存編址這件事,是靠計(jì)算機(jī)里面那些實(shí)實(shí)在在的硬件設(shè)備,按照一定的規(guī)則和辦法來做好的。

簡單來說,計(jì)算機(jī)的編址是通過硬件設(shè)計(jì)把每一個(gè)內(nèi)存單元的地址都固定好了,不需要把地址額外的存起來。

知識(shí)補(bǔ)充:

32位機(jī)器有32根地址總線,64位機(jī)器有64根地址總線。?地址總線是實(shí)際存在的物理電線

2、指針變量和地址

當(dāng)我們了解了內(nèi)存和地址的關(guān)系后,就可以開始對(duì)指針的學(xué)習(xí)啦!

在C語言中變量創(chuàng)建的本質(zhì)是向內(nèi)存申請(qǐng)空間

比如說:int a = 10;

這串代碼就相當(dāng)于向內(nèi)存內(nèi)申請(qǐng)了4個(gè)字節(jié),一個(gè)整型占4個(gè)字節(jié),這串空間我們想存放的數(shù)據(jù)便是變量10。

2.1 取地址操作符:&

int main()

{

int a = 0x11223344;//16進(jìn)制數(shù)字

return 0;

}

16進(jìn)制0x11223344,一個(gè)16進(jìn)制位可以改寫為4個(gè)二進(jìn)制位,因此,11223344可以改寫為32個(gè)二進(jìn)制位表示,剛好一個(gè)整型可以放下。

我們可以調(diào)試來看一下內(nèi)存:

打開后,輸入&a 并敲下回車鍵,列改為一行(記得在x86環(huán)境下觀察,比較方便)

我們可以看到44,33,22,11都各占一個(gè)字節(jié),每一個(gè)字節(jié)都有一個(gè)地址。

我們將列數(shù)改為4列再觀察

從上面我們可以看到a確實(shí)向內(nèi)存申請(qǐng)了4個(gè)空間。

讀到這我們可能會(huì)有一個(gè)新的問題,欸,4個(gè)字節(jié)都有地址,那我們?cè)趺粗繿的地址是哪一個(gè)呢?

還記得前面調(diào)試的時(shí)候我們是怎么觀察地址的嗎?我們通過輸入&a按下回車后出現(xiàn)了0x00E2FEC4,因此0x00E2FEC4便是a的地址,我們也可以發(fā)現(xiàn)這個(gè)地址和 44 所占字節(jié)的地址一樣。

總結(jié)一下,&a取出的是a所占4個(gè)字節(jié)中地址較小的字節(jié)的地址

雖然整型變量占用4個(gè)字節(jié),但是我們只要知道了第一個(gè)字節(jié)地址,順藤摸瓜訪問到4個(gè)字節(jié)的數(shù)據(jù)也是可行的。

代碼展示一下,怎么打印地址

int main()

{

int a = 0x11223344;

printf("&a=%p\n", &a);

return 0;

}

知識(shí)補(bǔ)充:

&是取地址操作符,想要得到地址,就需要使用這個(gè)操作符?%p:用來打印地址的占位符

結(jié)果展示:

和前面調(diào)試的結(jié)果不是一樣,是因?yàn)樵诖蛴〉臅r(shí)候又申請(qǐng)了新的空間。

2.2 指針變量

在我們之前學(xué)習(xí)的過程中,我們?nèi)绻胍獙⒁粋€(gè)整數(shù)存儲(chǔ)起來,就會(huì)創(chuàng)建一個(gè)整型變量,比如我們想存儲(chǔ)數(shù)字10,如下代碼:

int main()

{

int a = 10;

return 0;

}

我們通過創(chuàng)建了一個(gè)整型變量 a 來存儲(chǔ)10。

那么如果我們想要將我們通過&得到的地址存儲(chǔ)起來,有沒有什么辦法呢?我們可以將地址存儲(chǔ)在指針變量中。比如我們想要存放 n 的地址

int main()

{

int a = 10;

int * pn = &n;

return 0;

}

解讀:int * pn = &n;

1、pn被稱為指針變量

為什么呢?

&n——n的地址——地址就是指針

pn = &n;

pn就是用來存放地址的,也可以說是用來存放指針的

指針變量就是存放指針的變量。

可以通過和整型變量來理解指針變量,

整型變量:a就是用來存放整數(shù)的。

2、int * 被稱為指針類型

int a = 10; int * pn = &n;

對(duì)比就可以發(fā)現(xiàn),int是整數(shù)的類型,int*是指針的類型。

2.3 如何拆解指針類型

上文說到了之指針的類型是(int *),那么我們?cè)撊绾卫斫庵羔橆愋湍兀?/p>

pn的類型是int *,我們需要分別理解

*:說明pn是指針變量int:說明pn指向的對(duì)象是int類型

char ch = 'x';

如果我們想要存放x的地址該怎么寫呢?

?char * pc = &ch;

這樣我們就存放了x的地址

*?告訴我們pc是指針

char則告訴我們指針指向的對(duì)象是char類型。

2.4 解引用操作符(*)

當(dāng)我們將地址保存起來后,是為了后面能夠使用,那么我們?cè)撛趺词褂媚兀?/p>

在現(xiàn)實(shí)生活中,我們使用地址要找到?個(gè)房間,在房間里可以拿去或者存放物品。

C語言中其實(shí)也是?樣的,我們只要拿到了地址(指針),就可以通過地址(指針)找到地址(指針) 指向的對(duì)象,這里必須學(xué)習(xí)?個(gè)操作符叫解引用操作符(*)。

int main()

{

int n = 10;

int * pn = &n;

//解引用操作符(間接訪問操作符)

*pn = 100;

printf("%d", n);

return 0;

}

上述代碼中的*pn就使用了解引用操作符, *pn?的意思就是通過pn中存放的地址,找到指向的空間, *pn其實(shí)就是n變量了;所以*pn=100,這個(gè)操作符是把n改成了100.

從結(jié)果上看,n的值的確被改為了100

或許通過這個(gè)例子你會(huì)覺得指針有是什么用?如果只是想修改n的值,為什么不直接寫一個(gè)n=100呢?這樣不是更方便嗎?

其實(shí)這里是把n的修改交給了pn來操作,這樣對(duì)n的修改,就多了?種的途徑,寫代碼就會(huì)更加靈活, 后期慢慢就能理解了。

其實(shí)這里有一個(gè)很好的例子能說明指針的作用,生活中,有些事情是不方便自己去做的,因此呢,就需要委托別人來代替你做,比如說一個(gè)老板想要喝奶茶,但是他不會(huì)自己頂著大太陽出去買,而是會(huì)吩咐他的秘書取幫他完成,差不多就是這樣,可能有些不恰當(dāng),見諒哈!

2.5 指針變量的大小

我們知道我們創(chuàng)建一個(gè)整型變量int的大小是4個(gè)字節(jié),字符變量char的大小是1個(gè)字節(jié),那么指針變量的大小又是多少呢?

思考過程:

指針變量存放的是地址,地址的存放需要多大的空間呢?知道地址存放的空間就是指針變量的大小

也就是說指針變量的大小取決與地址的大小

通過前面的內(nèi)容我們了解到,32位機(jī)器假設(shè)有32根地址總線,每根地址線出來的電信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)后 是1或者0,那我們把32根地址線產(chǎn)生的2進(jìn)制序列當(dāng)做?個(gè)地址,那么?個(gè)地址就是32個(gè)bit位,需要4個(gè)字節(jié)才能存儲(chǔ)。

如果指針變量是用來存放地址的,那么指針變的大小就得是4個(gè)字節(jié)的空間才可以。

同理64位機(jī)器,假設(shè)有64根地址線,?個(gè)地址就是64個(gè)二進(jìn)制位組成的?進(jìn)制序列,存儲(chǔ)起來就需要 8個(gè)字節(jié)的空間,指針變量的大小就是8個(gè)字節(jié)。

int main()

{

int n = 10;

int * pn = &n;

printf("%zd\n", sizeof(pn));

return 0;

}

在32位機(jī)器上: 可以看到打印的大小是4個(gè)字節(jié)

在64位機(jī)器上: 可以看到打印的大小是8個(gè)字節(jié)

那么指針類型是否會(huì)影響指針變量的大小呢?我們來測(cè)試一下

int main()

{

printf("%zd\n", sizeof(int*));//整型

printf("%zd\n", sizeof(char*));//字符

printf("%zd\n", sizeof(short*));//短整型

printf("%zd\n", sizeof(double*));//雙精度浮點(diǎn)型

return 0;

}

在32位系統(tǒng)上結(jié)果:

在64位系統(tǒng)上結(jié)果

我們可以看到,不管指針類型是什么,都不會(huì)影響指針變量的大小,指針類型的變量大小,在相同平臺(tái)下,大小都是相同的。

總結(jié):

?32位平臺(tái)下地址是32個(gè)bit位,指針變量大小是4個(gè)字節(jié)?64位平臺(tái)下地址是64個(gè)bit位,指針變量大小是8個(gè)字節(jié) X64環(huán)境輸出結(jié)果?注意指針變量的大小和類型是無關(guān)的,只要指針類型的變量,在相同的平臺(tái)下,大小都是相同的。

3、指針變量類型的意義

既然指針變量大小與指針類型無關(guān),那么為什么還要搞指針的變量類型呢?

3.1 指針的解引用

int main()

{

int n = 0x11223344;

int* pi = &n;

*pi = 0;

return 0;

}

調(diào)試過程:(注意觀察內(nèi)存里的值)

運(yùn)行到292行時(shí)內(nèi)存展示44 33 22 11

當(dāng)經(jīng)過*pi = 0 之后

內(nèi)存里4個(gè)字節(jié)全部變?yōu)榱?0?

如果我們不用int *的指針類型,改為char *的類型,結(jié)果又是如何呢?

我們可以看到只是將n的第?個(gè)字節(jié)改為0。

我們可以看到int類型指針可以訪問4個(gè)字節(jié),而char類型指針只訪問了1個(gè)字節(jié)。

通過對(duì)比,我們可以得到一個(gè)結(jié)論:

結(jié)論:指針的類型決定了,對(duì)指針解引用的時(shí)候有多大的權(quán)限(一次能操作幾個(gè)字節(jié))。

3.2 指針+-整數(shù)

int main()

{

int n = 0x11223344;

int* pi = &n;

char* pc = &n;

printf("&n = %p\n", &n);

printf("pi = %p\n", pi);

printf("pi+1 = %p\n", pi+1);

printf("pc = %p\n", pc);

printf("pc+1= %p\n", pc+1);

return 0;

}

結(jié)果:?

我們可以發(fā)現(xiàn), char* 類型的指針變量+1跳過1個(gè)字節(jié), int* 類型的指針變量+1跳過了4個(gè)字節(jié)。 這就是指針變量的類型差異帶來的變化。指針+1,其實(shí)跳過1個(gè)指針指向的元素。指針可以+1,那也可以-1。

結(jié)論:指針的類型決定了指針向前或者向后走一步有多大(距離)。

4、void* 指針

void的意思是無,或者空

所以void*指針是無具體為無具體類型的指針(或者叫泛型指針),這種類型的指針可以用來接受任意類型地址。但是也有局限性, void* 類型的指針不能直接進(jìn)行指針的+-整數(shù)和解引用的運(yùn)算。?

int main()

{

int n = 10;

char* pc = &n;

return 0;

}

在上面的代碼中,將?個(gè)int類型的變量的地址賦值給?個(gè)char*類型的指針變量。編譯器給出了?個(gè)警告(如下圖),是因?yàn)轭愋筒患嫒荨6怯胿oid*類型就不會(huì)有這樣的問題。

使用void*類型的指針接收地址就不會(huì)出現(xiàn)警告

void* 類型的指針不能直接進(jìn)行指針的+-整數(shù)和解引用的運(yùn)算

int main()

{

int n = 10;

void* pc = &n;

*pc = 20;

return 0;

}

當(dāng)我們想運(yùn)行的時(shí)候,就會(huì)報(bào)下面這個(gè)錯(cuò)誤?

?void* 類型的指針可以接收不同類型的地址,但是無法直接進(jìn)行指針運(yùn)算。

這是因?yàn)関oid*是一個(gè)無具體類型的指針,當(dāng)進(jìn)行解運(yùn)算的時(shí)候,沒法確定訪問幾個(gè)字節(jié)。

既然如此,那void*有什么作用呢?

專門用來存放別人傳送過來的地址,當(dāng)你不知道別人給你傳的是什么類型的指針的時(shí)候,就可以使用void*來存放,當(dāng)需要進(jìn)行解運(yùn)算的時(shí)候,在使用強(qiáng)制類型轉(zhuǎn)換來實(shí)現(xiàn)。

比如:

int main()

{

int n = 10;

void* pc = &n;

*(int*)pc = 20;

return 0;

}

?這樣就將類型強(qiáng)制轉(zhuǎn)換成了整型指針,結(jié)果就可以打印出來了

結(jié)語:

本篇文章主要講了指針的基本知識(shí),通過本篇文章能夠了解什么是指針,指針變量,指針類型是什么。后面會(huì)繼續(xù)更新指針相關(guān)知識(shí),希望能夠幫助大家攻克指針這一模塊。

柚子快報(bào)激活碼778899分享:c語言 C:初識(shí)指針—學(xué)習(xí)筆記

http://yzkb.51969.com/

推薦閱讀

評(píng)論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19305119.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄