国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】

這篇具有很好參考價(jià)值的文章主要介紹了C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

指針用法簡(jiǎn)單介紹

指針,是內(nèi)存單元的編號(hào)。

內(nèi)存條分好多好多小單元,一個(gè)小單元有 8 位,可以存放 8 個(gè) 0 或 1;也就是說,內(nèi)存的編號(hào)不是以位算的,而是以字節(jié)算的,不是一個(gè) 0 或 1 是一個(gè)編號(hào),而是 8 個(gè) 0 或 1 合在一起是一個(gè)編號(hào)。這個(gè)編號(hào),就是地址。

內(nèi)存條就分為好多小格子,一個(gè)格子一個(gè)編號(hào)(地址),相當(dāng)于房子,一個(gè)房子一個(gè)地址。

[所謂的指針,就是地址。]

*p表示的是以p的內(nèi)容為地址的變量

#include?<stdio.h>

int?main() {

int* p;//p是變量的名字,int*表示變量p存放的是int類型變量的地址

//int* 是p的數(shù)據(jù)類型,p是變量的名字。所謂的int*類型,就是可以存放int類型變量的地址的變量的類型

int?i = 3;

/*

??i是整型int類型的變量,可以把變量i的地址放到變量p里

??&i表示i的地址,&是取址符,表示獲取一個(gè)變量的地址

?*/

p = &i;//把int類型的變量放到int*類型中

/*

??類似的,double* p只能存放double類型的變量的地址,

??而不能存放int類型的變量的地址

?*/

?/*

???關(guān)于對(duì)p=&i的理解:

???p存放了i的地址,所以根據(jù)p可以知道i的位置,進(jìn)而找到i。

???所以說,p指向i。

???p不是i,i也不是p;修改i的值不會(huì)改變p的值,修改p的值也不會(huì)影響i的值

???舉個(gè)例子:[小明](指針變量p)手里拿了一張寫了[小紅家庭地址](變量)的[紙條](指針變量p存儲(chǔ)的i地址&i),

???小紅的家庭發(fā)生任意改變,比如小紅家新買了一輛汽車、丟了一袋垃圾,小明手中的紙條都不會(huì)發(fā)生改變

???(變量i的值發(fā)生任意改變,+1或者-1,都不會(huì)影響指針變量p里存放的值)

???小明在手里原本寫著小紅家庭地址的紙條上進(jìn)行任意修改,小紅的家的位置也不會(huì)發(fā)生任何變化

???(原本存放變量i的地址的指針變量p的值發(fā)生任意變化也不會(huì)影響變量i的值)

??*/

??/*

int* p;int i;

p和i都是變量,p是能存放其他類型的變量的地址的指針變量,i是只能存放其相應(yīng)類型的值的普通的整型變量。

指針和地址是一個(gè)概念,指針變量也可以叫做地址變量

指針變量p存放了變量i的地址---指針變量p指向了變量i

???*/

printf("%d", *p == i);//1-->說明*p和i的值是一樣的

/*

??如果一個(gè)指針指向了某個(gè)變量,則:

??*指針變量<---等價(jià)于--->普通變量

??如:

??如果p是指針變量,p存放了普通變量i的地址,則p指向i

??*p<---等價(jià)于--->i

??*p和i可以彼此之間相互替換使用

?*/

?/*

??*p表示的是以p的內(nèi)容為地址的變量

??*/

return?0;

}

指針和指針變量的區(qū)別:

指針就是地址,地址就是指針。

地址[指針]就是內(nèi)存單元的編號(hào)。

指針變量是存放地址[指針]的變量

指針[地址]和指針變量是兩個(gè)不同的概念

但是,有時(shí)候在敘述的時(shí)候,會(huì)把指針變量簡(jiǎn)稱為指針,但是二者不是一回事兒

指針的重要性

·指針可以表示一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)(比如用鏈表表示的一些數(shù)據(jù)結(jié)構(gòu))

·快速的傳遞數(shù)據(jù)

·使函數(shù)返回一個(gè)以上的值

·能直接訪問硬件

·能夠方便的處理字符串

·是面向?qū)ο笳Z言中引用的基礎(chǔ)

指針是C語言的靈魂

指針的定義

指針就是地址,地址就是指針。那么,指針和地址到底是什么?

地址

·內(nèi)存單元的編號(hào)(就像房門牌號(hào)一樣)

·地址是從0開始的非負(fù)整數(shù)

·[地址的范圍,取決于系統(tǒng)的位數(shù)。在32位系統(tǒng)中,一個(gè)地址的范圍是從0到2^32-1,即從0到4294967295。而在64位系統(tǒng)中,一個(gè)地址的范圍是從0到2^64-1,即從0到18446744073709551615。這些范圍都是基于系統(tǒng)的內(nèi)存大小和尋址能力來確定的。]

指針

·指針就是地址,地址就是指針

·指針變量就是存放內(nèi)存單元編號(hào)的變量,或者說,指針變量就是存放地址/指針的變量

·指針[地址]和指針變量是兩個(gè)不同的概念。但是,有時(shí)候在敘述的時(shí)候,會(huì)把指針變量簡(jiǎn)稱為指針,但是二者不是一回事兒

·指針的本質(zhì)就是一個(gè)操作受限的非負(fù)整數(shù)

[“非負(fù)整數(shù)”,指地址是“從0開始的非負(fù)整數(shù)”。

“操作受限”,指針之間的運(yùn)算只可以進(jìn)行減法,不能進(jìn)行加乘除運(yùn)算]

指針可以進(jìn)行那些運(yùn)算

為什么指針只可以進(jìn)行減法,不能進(jìn)行加乘除運(yùn)算?

兩個(gè)指針相減的結(jié)果是一個(gè)整數(shù)值,表示兩個(gè)指針之間相隔的元素個(gè)數(shù)或者內(nèi)存單元的數(shù)目。

在數(shù)組中,如果兩個(gè)指針指向同一個(gè)數(shù)組的元素,那么它們相減的結(jié)果就是它們之間相隔的元素個(gè)數(shù)。這個(gè)結(jié)果是一個(gè)整數(shù),表示兩個(gè)指針之間有多少個(gè)元素。例如,如果一個(gè)指針指向數(shù)組的第i個(gè)元素,另一個(gè)指針指向數(shù)組的第j個(gè)元素,那么它們的差值就是j-i,表示它們之間相隔的元素個(gè)數(shù)。

同樣地,在內(nèi)存中,如果兩個(gè)指針指向不同的內(nèi)存單元,那么它們相減的結(jié)果就是它們之間相隔的內(nèi)存單元數(shù)目。這個(gè)結(jié)果是一個(gè)整數(shù),表示兩個(gè)指針之間有多少個(gè)內(nèi)存單元。例如,如果一個(gè)指針指向內(nèi)存地址A,另一個(gè)指針指向內(nèi)存地址B,那么它們的差值就是B-A,表示它們之間相隔的內(nèi)存單元數(shù)目。

需要注意的是,兩個(gè)指針相減的結(jié)果是一個(gè)整數(shù)值,而不是地址量。這個(gè)整數(shù)值表示兩個(gè)指針之間相隔的數(shù)據(jù)個(gè)數(shù),而不是它們的內(nèi)存地址差值。因此,在計(jì)算兩個(gè)指針相減的結(jié)果時(shí),應(yīng)該將它們的地址值進(jìn)行整數(shù)相減,而不是將它們的內(nèi)存地址直接相減。

總之,兩個(gè)指針相減的結(jié)果是一個(gè)整數(shù)值,表示兩個(gè)指針之間相隔的元素個(gè)數(shù)或者內(nèi)存單元的數(shù)目。這個(gè)結(jié)果是根據(jù)指針?biāo)赶虻臄?shù)據(jù)類型和內(nèi)存布局來確定的。通過計(jì)算指針之間的差值,程序員可以方便地進(jìn)行數(shù)組遍歷、內(nèi)存管理和其他相關(guān)操作。

然而,兩個(gè)指針[地址]相加,就像一個(gè)門牌號(hào)加上另一個(gè)門牌號(hào)一樣,沒有實(shí)際意義。一個(gè)門牌號(hào)在減去另一個(gè)門牌號(hào)得到的整數(shù)就可以表示兩個(gè)房間之間相差了多少個(gè)房間。(比如,房間1006和房間1001之間差了5個(gè)房間;1006-1001=5)。同樣的兩個(gè)指針[地址](門牌號(hào))相乘或相除也沒有實(shí)際意義。

但是指針還可以與整數(shù)進(jìn)行相加減。

指針與整數(shù)的加減表示指針在內(nèi)存空間中向下或向上移動(dòng)整數(shù)個(gè)單位。這個(gè)單位的大小取決于指針?biāo)缸兞康念愋汀@?,如果是指向short型變量的指針,那么每次移動(dòng)2個(gè)字節(jié);如果是指向double型變量的指針,那么每次移動(dòng)8個(gè)字節(jié)。當(dāng)指針變量增加1時(shí),其增加的值等于指向的類型占用的內(nèi)存字節(jié)數(shù)。

指針與整數(shù)的加減運(yùn)算在數(shù)組中位置的移動(dòng)和內(nèi)存地址的偏移中有實(shí)際應(yīng)用。例如,通過將指針變量增加1,可以使其指向下一個(gè)數(shù)組元素,從而實(shí)現(xiàn)數(shù)組的遍歷。同樣地,通過指針與整數(shù)的加減運(yùn)算,可以方便地訪問和操作內(nèi)存中的不同位置,實(shí)現(xiàn)動(dòng)態(tài)內(nèi)存分配、函數(shù)參數(shù)傳遞和數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)等功能。

需要注意的是,指針與整數(shù)的加減運(yùn)算是有單位的,以它所指向數(shù)據(jù)類型的字節(jié)數(shù)為單位進(jìn)行加減。在C語言中,指針加法是以所指向數(shù)據(jù)類型的大小為單位的,例如int類型的指針加1就意味著偏移4個(gè)字節(jié)(假設(shè)int類型占用4個(gè)字節(jié))。

總之,指針與整數(shù)的加減運(yùn)算表示指針在內(nèi)存空間中的移動(dòng)。這種運(yùn)算在數(shù)組索引、指針移動(dòng)和內(nèi)存訪問等操作中具有重要意義,使程序員能夠靈活地操作內(nèi)存和數(shù)據(jù)結(jié)構(gòu),實(shí)現(xiàn)高效的數(shù)據(jù)處理和內(nèi)存管理。

就行門牌號(hào)1003,加上一個(gè)整數(shù)2,就變成了門牌號(hào)1005的房間的地址;減去一個(gè)整數(shù)3,就變成了門牌號(hào)1000的房間的地址。

同樣的,指針和整數(shù)之間不能進(jìn)行乘除運(yùn)算,沒有實(shí)際意義。

【如果兩個(gè)指針變量指向的是同一塊連續(xù)空間中的不同存儲(chǔ)單元,這兩個(gè)指針變量才可以相減】

基本類型指針

[知識(shí)點(diǎn)前面已經(jīng)說了,這里看幾個(gè)代碼示例:]

示例一

注意下面的代碼的錯(cuò)誤:

#include?<stdio.h>

int?main(){
????int*?p;
????int?i=5;
????*p=i;
????printf("%d",*p);
????return?0;
}

*p指針變量只是進(jìn)行了聲明(給變量起名字和確定類型),而沒有進(jìn)行定義(給變量分配空間),沒有給變量分配空間就無法進(jìn)行初始化(賦值)。如果沒有進(jìn)行定義,那么這個(gè)變量的空間就是不確定的、隨機(jī)的。

如果沒有給指針變量分配內(nèi)存空間,那么這個(gè)指針變量所指向的內(nèi)存位置是不確定的、隨機(jī)的。這意味著,當(dāng)你試圖通過這個(gè)指針進(jìn)行讀寫操作時(shí),你可能會(huì)不小心覆蓋了其他重要的數(shù)據(jù),或者訪問了不屬于你的內(nèi)存空間(稱為“越界”)。這會(huì)導(dǎo)致程序出現(xiàn)未定義的行為,可能是程序崩潰、數(shù)據(jù)損壞或其他不可預(yù)測(cè)的結(jié)果。

C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】,C語言學(xué)習(xí)筆記(入門到入神),c++,算法,數(shù)據(jù)結(jié)構(gòu),指針,C語言

示例二

#include?<stdio.h>

int?main() {

int?i = 5;

int* p;

int* q;

p = &i;

//*q=p;

/*

??錯(cuò)誤:*q是int類型的變量,p是int*類型的變量,類型不一樣,不能進(jìn)行賦值

?*/

?//*q=*p;

?/*

???錯(cuò)誤:*q沒有進(jìn)行定義就給他賦值

??*/

??//p=q;

??/*

錯(cuò)誤:q沒定義,q變量存儲(chǔ)的是int*類型的數(shù)據(jù),但是是不確定的、隨機(jī)的、垃圾值

把q存儲(chǔ)的垃圾值賦值給p,p存儲(chǔ)的東西也變成了垃圾值

???*/

return?0;

}

用指針交換兩個(gè)變量的值

#include?<stdio.h>

void?jiaohuan(int?a,int?b){
????int?t=a;
????a=b;
????b=t;
}
int?main(){
????int?a=3;
????int?b=5;
????jiaohuan(a,b);
????printf("%d,%d",a,b);//3,5
????return?0;
}

在這個(gè)代碼中,經(jīng)過jiaohuan(int?a,int?b)函數(shù)后,a、b的值沒有發(fā)生變化。因?yàn)殡m然函數(shù)jiaohuan(int?a,int?b)中的參數(shù)變量的名字是a、b,但是這是形參變量,形參變量不會(huì)影響函數(shù)外的變量。即使jiaohuan(int?a,int?b)中的參數(shù)變量的變量名換成別的c、d等等都是一樣的

上述代碼沒有實(shí)現(xiàn)想要的功能,接下來用代碼實(shí)現(xiàn):

#include?<stdio.h>

void?jiaohuan(int*?p,int*?q){
????int?*?t=p;
????p=q;
????q=t;
}
int?main(){
????int?a=3;
????int?b=5;
????jiaohuan(&a,&b);
????printf("%d,%d",a,b);//3,5
????return?0;
}

對(duì)于函數(shù)jiaohuan(),傳參數(shù)的時(shí)候傳的是&a,&b,不能是a和b。因?yàn)楹瘮?shù)的形參列表里面的參數(shù)是int*類型的。所以這個(gè)函數(shù)傳遞的參數(shù)也只能是指針(地址),而不能是一個(gè)值。

之前不太明白。我想:如果傳參數(shù)的時(shí)候傳的是a,b,為什么函數(shù)的形參列表里面的參數(shù)變量的類型不能是*p、*q類型的?[原理,*p是表達(dá)式而不是變量。對(duì)于int* p,只能是int*類型的p變量而不是int類型的*p變量]

但是,上面這個(gè)代碼也不能實(shí)現(xiàn)交換兩個(gè)變量的值的功能。

因?yàn)椋汉瘮?shù)jiaohuan()交換的不是a、b的值而是p、q的值。p、q是形參,不會(huì)改變實(shí)際的實(shí)參a、b的值。

開始的時(shí)候把a(bǔ)的地址傳遞給了p,把b的地址傳遞給了q。函數(shù)結(jié)束后,p存儲(chǔ)的是b的地址,q存儲(chǔ)的是a的地址。函數(shù)使得p和q存儲(chǔ)的地址進(jìn)行了交換,不會(huì)影響a和b。

沒有任何一個(gè)語言可以改變靜態(tài)變量的位置。變量就相當(dāng)于一個(gè)房子,可以改變房子里的東西,但是無法把房子連根拔起換到別的地方。

形參的變化不會(huì)影響到實(shí)參

#include?<stdio.h>

void?jiaohuan(int*?p,int*?q){
????int??t=*p;
????*p=*q;
????*q=t;
}
int?main(){
????int?a=3;
????int?b=5;
????jiaohuan(&a,&b);
????printf("%d,%d",a,b);//5,3
????return?0;
}

這個(gè)代碼就可以實(shí)現(xiàn)交換兩個(gè)變量的值的功能了。

在函數(shù)中,p存儲(chǔ)的是a的地址,*p表示的是int類型的以p的內(nèi)容(a的地址)為地址的“變量”。所以,p指向a,同理,q指向b。

*p等價(jià)于a,*q等價(jià)于b

所以,在變量中,變量(盒子)里的東西(值)進(jìn)行了交換,而不是(盒子)的地址進(jìn)行了交換。

*的三種含義

  1. 乘法
  2. 定義指針
    1. int * p;定義了一個(gè)名字叫p的變量,int*表示p只能存放int類型的變量的地址
  3. 指針運(yùn)算符
    1. 該運(yùn)算符放在已經(jīng)定義好的指針變量的前面
    2. 如果p是一個(gè)已經(jīng)定義好的指針變量,則*p表示以p的內(nèi)容為地址的變量

int* p;

*p = a;

這兩行代碼中,兩個(gè)*的含義是不一樣的?。?!

如何通過被調(diào)函數(shù)修改主函數(shù)中普通變量的值

#include?<stdio.h>

void?f(int*?p,int*?q){
????*p=1;
????*q=2;
}
int?main(){
????int?a=3;
????int?b=5;
????f(&a,&b);
????printf("%d,%d",a,b);//1,2
????return?0;
}

  1. 實(shí)參必須為該普通變量的地址
  2. 形參必須是指針變量
  3. 在被調(diào)函數(shù)中通過[*形參名=…]的方式可以修改主函數(shù)相關(guān)變量的值

指針和數(shù)組

一維數(shù)組名

一維數(shù)組名是個(gè)指針常量,存放的是一維數(shù)組的第一個(gè)元素的地址

C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】,C語言學(xué)習(xí)筆記(入門到入神),c++,算法,數(shù)據(jù)結(jié)構(gòu),指針,C語言

第六行錯(cuò)誤,因?yàn)橐痪S數(shù)組名是常量,不能把一個(gè)值賦值給一個(gè)常量

#include?<stdio.h>

int?main(){
????int?a[5];
????printf("%#x\n",&a[0]);
????printf("%#x\n",a);
????return?0;
}

地址在內(nèi)存中以十六進(jìn)制形式存儲(chǔ)

一維數(shù)組名是個(gè)指針常量,存放的是一維數(shù)組的第一個(gè)元素的地址

那么,以上代碼輸出的十六進(jìn)制應(yīng)該是一樣的

C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】,C語言學(xué)習(xí)筆記(入門到入神),c++,算法,數(shù)據(jù)結(jié)構(gòu),指針,C語言

如果一個(gè)函數(shù)要處理一個(gè)一維數(shù)組,則需要接收該數(shù)組的哪些信息?

(確定一個(gè)一維數(shù)組需要幾個(gè)參數(shù)?)

兩個(gè)參數(shù):數(shù)組名、數(shù)組長(zhǎng)度

#include?<stdio.h>

void?f(int?*pArr,int?len){
????for(int?i=0;i<len;i++){
????????printf("%d?",*(pArr+i));
????}
}
int?main(){
????int?a[5]={1,2,3,4,5};
????f(a,5);
????return?0;
}

看下面的例子:

#include?<stdio.h>

void?f(int?*pArr,int?len){
????pArr[3]=999;
}
int?main(){
????int?a[5]={1,2,3,4,5};
????f(a,5);
????printf("%d",a[3]);//999
????return?0;
}

a存放的是一維數(shù)組第一個(gè)元素的地址

*a等價(jià)于a[0]

*(a+1)等價(jià)于a[1]

*(a+2)等價(jià)于a[2]

……

上面的代碼中,函數(shù)f()改變了主函數(shù)中數(shù)組的值:將a傳進(jìn)了函數(shù),*pArr和*a是一樣的,相當(dāng)于兩個(gè)變量都指向了相同的位置。

一個(gè)指針變量占幾個(gè)字節(jié)

假設(shè)p指向char類型變量(1個(gè)字節(jié))

假設(shè)q指向int類型變量(4個(gè)字節(jié))

假設(shè)r指向double類型變量(8個(gè)字節(jié))

p、q、r本身所占字節(jié)數(shù)是否一樣?

#include?<stdio.h>

int?main(){
????char?ch='a';
????int?w=1;
????double?d=1.2;
????
????char*?p=&ch;
????int*?q=&w;
????double*?r=&d;
????
????printf("%d\n",sizeof(p));//8
????printf("%d\n",sizeof(q));//8
????printf("%d\n",sizeof(r));//8
????
????return?0;
}

這段代碼中,指針的大小是固定的,不管它是指向哪種類型的變量。在大多數(shù)現(xiàn)代的64位系統(tǒng)上,一個(gè)指針的大小是8字節(jié)(64位)。所以,不論是指向字符、整數(shù)還是雙精度浮點(diǎn)數(shù)的指針,它們的大小都是8字節(jié)。32位系統(tǒng)是4字節(jié)

傳統(tǒng)數(shù)組(靜態(tài)內(nèi)存分配)的缺點(diǎn)

  1. 數(shù)組長(zhǎng)度必須事先指定,且只能是常整數(shù),不能是變量
  2. 傳統(tǒng)形式定義的數(shù)組,該數(shù)組的內(nèi)存程序員無法手動(dòng)釋放

數(shù)組一旦定義,系統(tǒng)為該數(shù)組分配的空間就會(huì)一直存在,除非該數(shù)組所在的函數(shù)終止。

在一個(gè)函數(shù)運(yùn)行期間,系統(tǒng)為該函數(shù)中數(shù)組所分配的空間會(huì)一直存在,直到該函數(shù)運(yùn)行完畢,數(shù)組的空間才會(huì)被系統(tǒng)釋放。

  1. 數(shù)組的長(zhǎng)度不能在函數(shù)運(yùn)行的過程中動(dòng)態(tài)的擴(kuò)充或縮?。〝?shù)組的長(zhǎng)度一旦定義就不能再改變了)
  2. A函數(shù)定義的數(shù)組,在A函數(shù)運(yùn)行期間可以被其他函數(shù)使用,但A函數(shù)運(yùn)行完畢之后,A函數(shù)中的數(shù)組將無法被其他函數(shù)使用

傳統(tǒng)方式定義的數(shù)組不能跨函數(shù)使用

使用動(dòng)態(tài)內(nèi)存分配的動(dòng)態(tài)數(shù)組很好的解決了傳統(tǒng)數(shù)組(靜態(tài)數(shù)組)的這四個(gè)缺陷

malloc函數(shù)

#include?<stdio.h>

#include?<malloc.h>//使用malloc函數(shù)需要這個(gè)頭文件

int?main() {

int?i = 5;//分配了4個(gè)字節(jié) 靜態(tài)分配

int* p = (int*)malloc(4);

/*

* 對(duì)于這句代碼,有以下理解:

1、malloc函數(shù)只有一個(gè)形參,這個(gè)形參是整型

2、malloc(4)是請(qǐng)求系統(tǒng)分配4個(gè)字節(jié)的內(nèi)存,

這個(gè)函數(shù)會(huì)返回系統(tǒng)所分配的內(nèi)存的起始地址。

malloc(4)會(huì)返回系統(tǒng)分配的這4個(gè)字節(jié)的第一個(gè)字節(jié)的地址

3、(int*)malloc(4) 強(qiáng)制類型轉(zhuǎn)換,將 malloc 返回的 void* 類型轉(zhuǎn)換為 int* 類型。

malloc函數(shù)會(huì)返回一個(gè) void* 類型的指針[地址],這個(gè)指針指向分配的內(nèi)存的起始地址。

由于 void* 是一個(gè)泛型指針類型,它不包含任何關(guān)于所指向數(shù)據(jù)類型的信息,因此在使用前需要進(jìn)行類型轉(zhuǎn)換。

在 (int*)malloc(4) 中,將 malloc 返回的 void* 指針轉(zhuǎn)換為 int* 類型。

這意味著我們告訴編譯器,我們希望這塊內(nèi)存能夠存儲(chǔ)整數(shù)類型的變量。

4、int* p 定義了一個(gè)名為 p 的指針變量,所以p用于存放int類型的數(shù)據(jù)的地址[指針]

5、最后p指向了4個(gè)字節(jié),但本質(zhì)上p里面只保存了這4個(gè)字節(jié)中的第一個(gè)字節(jié)的地址。

這4個(gè)字節(jié)在用的時(shí)候是作為一個(gè)整體來用的

6、int* p = (int*)malloc(4);

一共分配了12個(gè)字節(jié):其中系統(tǒng)為指針變量p分配了8個(gè)字節(jié)(64位系統(tǒng))

還分配了4個(gè)字節(jié)的空間,這4個(gè)字節(jié)被p指向(本質(zhì)上p指向的是這4個(gè)字節(jié)的第一個(gè)字節(jié)的地址)

其中,p本身的8個(gè)字節(jié)是靜態(tài)分配的,p指向的4個(gè)字節(jié)是動(dòng)態(tài)分配的

7、p本身的8個(gè)字節(jié)p具有擁有權(quán),而他指向的4個(gè)字節(jié)只具有使用權(quán)

8、*p不是變量,是表達(dá)式。但是*p可以作為變量來使用。*p所指向的內(nèi)存是通過動(dòng)態(tài)分配的

如果int a=*p; 則可以使用變量a代替表達(dá)式*p來使用

*/

free(p);

//表示把p所指向的內(nèi)存給釋放掉而不會(huì)把p本身所占用的內(nèi)存釋放,所謂釋放內(nèi)存,就是系統(tǒng)收回這段內(nèi)存的使用權(quán),而不會(huì)清空這塊內(nèi)存中的數(shù)據(jù)。被釋放后,整個(gè)程序都失去了對(duì)這段內(nèi)存的使用權(quán)而不僅僅是某個(gè)變量

return?0;

}

C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】,C語言學(xué)習(xí)筆記(入門到入神),c++,算法,數(shù)據(jù)結(jié)構(gòu),指針,C語言?

#include?<stdio.h>

#include?<malloc.h>//使用malloc函數(shù)需要這個(gè)頭文件

void?f(int* q) {

*q?= 200;

//free(q);

}

int?main() {

int* p = (int*)malloc(sizeof(int));

*p = 10;

printf("%d\n", *p);//10

f(p);

printf("%d\n", *p);//200

return?0;

}

這段代碼:

第一次輸出*p的值,10

第二次輸出*p的值,200

經(jīng)過f()函數(shù),將p中存儲(chǔ)的地址復(fù)制給了q,所以在函數(shù)f()中,*q和*p是一樣的

如果執(zhí)行了free(q),將起不到修改*p的值的作用,還把p指向的空間給釋放掉了,最后輸出的時(shí)候不會(huì)輸出200,而是一個(gè)不確定的隨機(jī)的垃圾值

動(dòng)態(tài)一維數(shù)組的構(gòu)造

#include?<stdio.h>

#include?<malloc.h>//使用malloc函數(shù)需要這個(gè)頭文件

int?main() {

int?a[5];//int占4個(gè)字節(jié),則本數(shù)組總共包含20個(gè)字節(jié),每4個(gè)字節(jié)被當(dāng)做一個(gè)int變量來使用

//把系統(tǒng)所分配的20個(gè)字節(jié)的前4個(gè)字節(jié)當(dāng)做a[0]來使用,第5~8個(gè)字節(jié)當(dāng)做a[1]來使用……

//只有所在的函數(shù)終止的時(shí)候這20個(gè)字節(jié)才會(huì)被釋放

int?len;

printf("請(qǐng)輸入要?jiǎng)?chuàng)建的數(shù)組長(zhǎng)度:\n");

scanf("%d", &len);

int* p = (int*)malloc(sizeof(int) * len);

//在使用上,和靜態(tài)數(shù)組的使用是一樣的,相當(dāng)于int p[len],只是靜態(tài)定義的數(shù)組不能用len這個(gè)變量

/*

這句代碼分配了20個(gè)字節(jié)的內(nèi)存,p指向了因?yàn)槭菑?qiáng)轉(zhuǎn)成了int*類型,

所以p表示前4個(gè)字節(jié),p+1表示第5~8個(gè)字節(jié),p+2表示第9~12個(gè)字節(jié)……

*p等價(jià)于p[0],*(p+1)等價(jià)于p[1],*(p+2)等價(jià)于p[2]……

類似的,對(duì)于靜態(tài)定義的數(shù)組,也可以有這樣的寫法

*/

return?0;

}

動(dòng)態(tài)內(nèi)存和靜態(tài)內(nèi)存的比較

靜態(tài)內(nèi)存和動(dòng)態(tài)內(nèi)存的區(qū)別主要表現(xiàn)在以下幾個(gè)方面:

1. 分配時(shí)間:靜態(tài)內(nèi)存在程序編譯開始階段分配,動(dòng)態(tài)內(nèi)存在程序運(yùn)行時(shí)分配。

2. 分配位置:靜態(tài)內(nèi)存分配在棧區(qū)或全局/靜態(tài)存儲(chǔ)區(qū),動(dòng)態(tài)內(nèi)存分配在堆區(qū)。

3. 分配方式:靜態(tài)內(nèi)存由編譯器自動(dòng)分配,動(dòng)態(tài)內(nèi)存由程序員手動(dòng)分配。

4. 分配大?。红o態(tài)內(nèi)存大小明確,分配時(shí)就確定;動(dòng)態(tài)內(nèi)存無法確定大小,需要指針來指示位置。

5. 管理方式:靜態(tài)內(nèi)存由編譯器在程序開始運(yùn)行時(shí)分配,并在程序結(jié)束時(shí)釋放;動(dòng)態(tài)內(nèi)存由程序員在運(yùn)行時(shí)分配和釋放。

6. 運(yùn)行速度:靜態(tài)內(nèi)存分配速度快,但占用空間大;動(dòng)態(tài)內(nèi)存分配速度慢,但節(jié)省空間。

7. 安全性:靜態(tài)內(nèi)存由編譯器管理,安全性較高;動(dòng)態(tài)內(nèi)存管理需要程序員手動(dòng)管理,容易出錯(cuò),安全性較低。

綜上所述,靜態(tài)內(nèi)存和動(dòng)態(tài)內(nèi)存的區(qū)別主要表現(xiàn)在分配時(shí)間、分配位置、分配方式、分配大小、管理方式、運(yùn)行速度和安全性等方面。在實(shí)際編程中,根據(jù)需要選擇使用哪種類型的內(nèi)存,以提高程序的效率和安全性。

多級(jí)指針

C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】,C語言學(xué)習(xí)筆記(入門到入神),c++,算法,數(shù)據(jù)結(jié)構(gòu),指針,C語言

無論是幾級(jí)指針變量,都是之占8個(gè)字節(jié)文章來源地址http://www.zghlxwxcb.cn/news/detail-811063.html

到了這里,關(guān)于C語言/c++指針詳細(xì)講解【超詳細(xì)】【由淺入深】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 由淺入深Netty代碼調(diào)優(yōu)

    由淺入深Netty代碼調(diào)優(yōu)

    序列化,反序列化主要用在消息正文的轉(zhuǎn)換上 序列化時(shí),需要將 Java 對(duì)象變?yōu)橐獋鬏數(shù)臄?shù)據(jù)(可以是 byte[],或 json 等,最終都需要變成 byte[]) 反序列化時(shí),需要將傳入的正文數(shù)據(jù)還原成 Java 對(duì)象,便于處理 目前的代碼僅支持 Java 自帶的序列化,反序列化機(jī)制,核心代碼如

    2024年02月05日
    瀏覽(23)
  • React - redux 使用(由淺入深)

    React - redux 使用(由淺入深)

    中文文檔: http://www.redux.org.cn/ 英文文檔: https://redux.js.org/ Github: https://github.com/reactjs/redux 可直接參照 目錄十 進(jìn)行使用 react-redux redux 是一個(gè)專門用于做狀態(tài)管理的JS庫(kù)(不是react插件庫(kù))。 它可以用在 react, angular, vue 等項(xiàng)目中, 但基本與 react 配合使用。 作用: 集中式管理 re

    2024年02月07日
    瀏覽(24)
  • 【個(gè)人筆記】由淺入深分析 ClickHouse

    項(xiàng)目中不少地方使用到ClickHouse,就對(duì)它做了一個(gè)相對(duì)深入一點(diǎn)的了解和研究。并對(duì)各種知識(shí)點(diǎn)及整理過程中的一些理解心得進(jìn)行了匯總并分享出來,希望對(duì)其他同學(xué)能有幫助。 本文主要講解ClickHouse的特點(diǎn)、讀寫過程、存儲(chǔ)形式、索引、引擎、物化視圖等特性。 適合 入門和

    2024年01月20日
    瀏覽(29)
  • 由淺入深理解C#中的事件

    本文較長(zhǎng),給大家提供了目錄,可以直接看自己感興趣的部分。 前面介紹了C#中的委托,事件的很多部分都與委托類似。實(shí)際上,事件就像是專門用于某種特殊用途的簡(jiǎn)單委托,事件包含了一個(gè)私有的委托,如下圖所示: 有關(guān)事件的私有委托需要了解的重要事項(xiàng)如下: 1、事

    2024年02月03日
    瀏覽(30)
  • Springboot3+EasyExcel由淺入深

    Springboot3+EasyExcel由淺入深

    環(huán)境介紹 技術(shù)棧 springboot3+easyexcel 軟件 版本 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3 EasyExcel是一個(gè)基于Java的、快速、簡(jiǎn)潔、解決大文件內(nèi)存溢出的Excel處理工具。 他能讓你在不用考慮性能、內(nèi)存的等因素的情況下,快速完成Excel的讀、寫等功能。 官網(wǎng)https://easyexcel.opensource.ali

    2024年01月16日
    瀏覽(28)
  • 【由淺入深學(xué)習(xí)MySQL】之索引進(jìn)階

    【由淺入深學(xué)習(xí)MySQL】之索引進(jìn)階

    本系列為:MySQL數(shù)據(jù)庫(kù)詳解,為千鋒資深教學(xué)老師獨(dú)家創(chuàng)作 致力于為大家講解清晰MySQL數(shù)據(jù)庫(kù)相關(guān)知識(shí)點(diǎn),含有豐富的代碼案例及講解。如果感覺對(duì)大家有幫助的話,可以【關(guān)注】持續(xù)追更~ 文末有本文重點(diǎn)總結(jié),技術(shù)類問題,也歡迎大家和我們溝通交流! 從今天開始本系列

    2024年02月05日
    瀏覽(22)
  • 手拉手Vue組件由淺入深

    手拉手Vue組件由淺入深

    組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一,它是html、css、js等的一個(gè)聚合體,封裝性和隔離性非常強(qiáng)。 組件化開發(fā): ??? 1、將一個(gè)具備完整功能的項(xiàng)目的一部分分割多處使用 ??? 2、加快項(xiàng)目的進(jìn)度 ??? 3、可以進(jìn)行項(xiàng)目的復(fù)用 組件注冊(cè)分為:全局注冊(cè)和局部注冊(cè) 目錄

    2024年01月18日
    瀏覽(22)
  • 由淺入深介紹 Python Websocket 編程

    由淺入深介紹 Python Websocket 編程

    1.1 websocket 協(xié)議簡(jiǎn)介 Websocket協(xié)議是對(duì)http的改進(jìn),可以實(shí)現(xiàn)client 與 server之間的雙向通信; websocket連接一旦建立就始終保持,直到client或server 中斷連接,彌補(bǔ)了http無法保持長(zhǎng)連接的不足,方便了客戶端應(yīng)用與服務(wù)器之間實(shí)時(shí)通信。 適用場(chǎng)景 html頁(yè)面實(shí)時(shí)更新, 客戶端的html頁(yè)面

    2024年02月03日
    瀏覽(22)
  • 由淺入深剖析 Apollo(阿波羅)架構(gòu)

    由淺入深剖析 Apollo(阿波羅)架構(gòu)

    目錄 一、介紹 二、架構(gòu)和模塊 三、架構(gòu)剖析 1.最簡(jiǎn)架構(gòu) ?2. 高可用保障 ?3.多接口擴(kuò)展 四、總結(jié) Apollo(阿波羅)是攜程框架部研發(fā)并開源的一款生產(chǎn)級(jí)的配置中心產(chǎn)品,它能夠集中管理應(yīng)用在不同環(huán)境、不同集群的配置,配置修改后能夠?qū)崟r(shí)推送到應(yīng)用端,并且具備規(guī)范的

    2024年02月13日
    瀏覽(24)
  • 【由淺入深學(xué)MySQL】- MySQL連接查詢

    【由淺入深學(xué)MySQL】- MySQL連接查詢

    本系列為:MySQL數(shù)據(jù)庫(kù)詳解,為千鋒教育資深Java教學(xué)老師獨(dú)家創(chuàng)作 致力于為大家講解清晰MySQL數(shù)據(jù)庫(kù)相關(guān)知識(shí)點(diǎn),含有豐富的代碼案例及講解。如果感覺對(duì)大家有幫助的話,可以【點(diǎn)個(gè)關(guān)注】持續(xù)追更~ 文末有重點(diǎn)總結(jié)和福利內(nèi)容! 技術(shù)類問題,也歡迎大家和我們溝通交流!

    2024年02月05日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包