指針的使用
時間:2023-04-21 來源:華清遠(yuǎn)見
什么是指針?
在C語言中,操作系統(tǒng)屏蔽掉所有的硬件存儲器,為程序員提供了一個類似數(shù)組的內(nèi)存空間;
這個內(nèi)存空間的基本單位是字節(jié),也是程序員能夠操作的基本單位。
指針就是每塊基本單位大小的內(nèi)存的地址,通常被叫做地址或者地址編號。將字節(jié)大小的內(nèi)存
分別進(jìn)行編號,有助于我們對于內(nèi)存的使用。
用來存放指針的變量就是指針變量,這也是程序員通常所說的指針。以下所有的指針變量統(tǒng)稱
為指針。
聲明指針的格式:
存儲類型指針類型*指針名;
eg:char*p;
int*p;等
存儲類型:
不單獨(dú)聲明時,有兩種情況
情況1:局部定義指針時,默認(rèn)為auto類型。表示當(dāng)進(jìn)入代碼塊時,系統(tǒng)為自動變量分配內(nèi)存.
在塊內(nèi),這些變量被定義,并被認(rèn)為他是局部于本塊的.當(dāng)退出塊時,系統(tǒng)釋放分配給自動變量的
內(nèi)存,因此,變量值就丟失了.重新進(jìn)入塊,系統(tǒng)會為自動變量再次分配內(nèi)存,原先的值已經(jīng)沒有
了。
情況2:全局定義指針時,默認(rèn)為extern類型。表示為該變量永久的分配存儲,直到當(dāng)前進(jìn)程
運(yùn)行結(jié)束。全局變量在整個程序執(zhí)行期間都是存在的。
指針類型:
由于指針保存的是地址,所以地址相關(guān)的變量或者結(jié)構(gòu),都可以作為指針的類型;
如:char、short、int、long等基本類型所定義的指針類型就是char*、short*、int*、
long*等
指針也可以保存數(shù)組的地址,該指針就變成了數(shù)組指針;指針也可以保存結(jié)構(gòu)體變量的地址,
該指針就變成了結(jié)構(gòu)體指針;指針也可以保存函數(shù)的地址,該指針就變成了函數(shù)指針;
*號:
*號有兩個作用:
作用1:在定義時,和普通變量做區(qū)分,如果沒有*號,那就和普通變量的定義格式一致,沒
有任何的區(qū)別了;
作用2:在使用時,*變量名這個形式表示拿到指針保存的地址上的數(shù)據(jù);后面詳細(xì)說;
指針名:
指針名是一個標(biāo)識符,要符合標(biāo)識符的命名規(guī)范;
注:標(biāo)識符的命名規(guī)范:
1、由數(shù)字、字母、下劃線組成
2、不能以數(shù)字開頭
3、不能和關(guān)鍵字沖突,嚴(yán)格區(qū)分大小寫
指針的大�。�
指針的大小和類型沒有關(guān)系,和CPU的運(yùn)行時的尋址位數(shù)有關(guān)系;
在32位操作系統(tǒng)中,32位CPU一次最大能夠訪問32位數(shù)據(jù),所以指針的大小就是32位,即4
字節(jié);
在64位操作系統(tǒng)中,64位CPU一次最大能夠訪問64位數(shù)據(jù),所以指針的大小就是64位,即8
字節(jié);
驗證:
使用64位編譯器:
linux@ubuntu:~$gcc01test.c
linux@ubuntu:~$./a.out
sizeof(char*)=8
sizeof(short*)=8
sizeof(int*)=8
sizeof(long*)=8
linux@ubuntu:~$cat01test.c
#include<stdio.h>
intmain(intargc,constchar*argv[])
{
printf("sizeof(char*)=%ld\n",sizeof(char*));
printf("sizeof(short*)=%ld\n",sizeof(short*));
printf("sizeof(int*)=%ld\n",sizeof(int*));
printf("sizeof(long*)=%ld\n",sizeof(long*));
return0;
}
使用32位編譯器:
linux@ubuntu:~$gcc01test.c-m32
linux@ubuntu:~$./a.out
sizeof(char*)=4
sizeof(short*)=4
sizeof(int*)=4
sizeof(long*)=4
linux@ubuntu:~$cat01test.c
#include<stdio.h>
intmain(intargc,constchar*argv[])
{
printf("sizeof(char*)=%d\n",sizeof(char*));
printf("sizeof(short*)=%d\n",sizeof(short*));
printf("sizeof(int*)=%d\n",sizeof(int*));
printf("sizeof(long*)=%d\n",sizeof(long*));
return0;
}
指針類型有什么作用?
由于一個指針只能保存一個地址,一個地址僅僅代表一個字節(jié)內(nèi)存,而通常情況下,程序員定
義變量都不不止使用一個字節(jié);所以如何讓指針訪問到占有多個字節(jié)內(nèi)存的變量的其他數(shù)據(jù),
就是通過指針類型;
指針類型決定著指針一次能夠訪問的最大內(nèi)存空間;
舉例:
linux@ubuntu:~$./a.out
a=0x12345678
p=0x7fff5eec899c
*p=0x12345678//當(dāng)指針類型和指針?biāo)4孀兞康念愋拖嗤瑫r,能夠正常獲取到變
量的數(shù)據(jù)
linux@ubuntu:~$cat01test.c
#include<stdio.h>
intmain(intargc,constchar*argv[])
{
inta=0x12345678;//定義一個變量a,保存16進(jìn)制數(shù)0x1234567,總共占4字節(jié)
int*p=&a;//定義一個指針,保存變量a的地址
printf("a=%#x\n",a);//#號表示數(shù)字前導(dǎo)符,16進(jìn)制的前導(dǎo)符,是0x,%x表示打印
16進(jìn)制數(shù)
printf("p=%p\n",p);//由于指針p中保存的是地址,打印地址用%p
printf("*p=%#x\n",*p);//*p表示取到指針保存的地址上的數(shù)據(jù),*p<==>a
return0;
}
這是我們正常使用指針,保證使用的指針類型和保存的數(shù)據(jù)類型一致,防止數(shù)據(jù)丟失;以上示
例中,指針能夠正常取到變量a的4個字節(jié)內(nèi)存上的所有數(shù)據(jù);
如果將上述示例修改:
linux@ubuntu:~$./a.out
a=0x12345678
p=0x7ffe4b4f344c
*p=0x78//當(dāng)指針類型和指針?biāo)4孀兞康念愋筒煌瑫r,不能夠正常獲取變量的數(shù)據(jù)
linux@ubuntu:~$cat01test.c
#include<stdio.h>
intmain(intargc,constchar*argv[])
{
inta=0x12345678;//定義一個變量a,保存16進(jìn)制數(shù)0x1234567,總共占4字節(jié)
char*p=(char*)&a;//定義一個char*類型的指針,保存int類型的變量a的地址,
由于類型不一致,編譯器會報警告,所以將&a的類型強(qiáng)制轉(zhuǎn)換為char*類型。消除警告;
printf("a=%#x\n",a);
printf("p=%p\n",p);
printf("*p=%#x\n",*p);
return0;
}
由上述示例得知,當(dāng)指針類型和指針?biāo)4孀兞康念愋筒煌瑫r,不能夠正常獲取變量的數(shù)據(jù),
指針?biāo)@取到的數(shù)據(jù)大小由指針決定;
0x78總共占1個字節(jié),和char*類型的指針,所能訪問的數(shù)據(jù)長度一致;
如何使用指針?
指針的使用只需要記住兩點
1、指針保存的是已定義的變量地址,不能保存未經(jīng)定義的常量和地址;
2、指針提供另一種操作變量數(shù)據(jù)的方法,主要和*號有關(guān);
指針是怎么進(jìn)行偏移的?
指針的偏移,就是指針的運(yùn)算,指針和普通變量一樣,也是可以進(jìn)行運(yùn)算的,但是和普通變量
不一樣的是,普通變量的運(yùn)算是對普通變量中保存的數(shù)據(jù)繼續(xù)寧運(yùn)算,而指針的運(yùn)算和指針類
型有關(guān)。
最常使用的指針偏移操作為:p++或者p--等
示例:
linux@ubuntu:~$./a.out
p=0x7ffddc670170//這是指針p中保存的地址
*p=10//這是指針p中保存的地址上的數(shù)據(jù),發(fā)現(xiàn)為*p==str[0]
p=0x7ffddc670174//這是指針p進(jìn)行偏移,即p++之后,指針p中保存的地址
*p=20//這是指針p中保存的地址上的數(shù)據(jù),發(fā)現(xiàn)為*p==str[1]
p=0x7ffddc670178//這是指針p再次進(jìn)行偏移,即p++之后,指針p中保存的地址
*p=30//這是指針p中保存的地址上的數(shù)據(jù),發(fā)現(xiàn)為*p==str[2]
linux@ubuntu:~$cat01test.c
#include<stdio.h>
intmain(intargc,constchar*argv[])
{
intstr[5]={10,20,30,40,50};//定義一個數(shù)組,有5位元素,每位元素都是int類型
的
int*p=str;//定義一個int*類型的指針,當(dāng)前保存的是數(shù)組的首地址,也是數(shù)字首位
元素的地址,str作為數(shù)組名,也表示數(shù)組的首地址
printf("p=%p\n",p);//打印當(dāng)前首元素的地址
printf("*p=%d\n",*p);//打印首位元素
p++;//指針進(jìn)行偏移,等價于p=p+1;表示指針p像后偏移1次,并不是表示p中的
地址加1,地址怎么變化取決于指針類型
printf("p=%p\n",p);
printf("*p=%d\n",*p);
p++;
printf("p=%p\n",p);
printf("*p=%d\n",*p);
return0;
}
由示例可以發(fā)現(xiàn),對于int*類型的指針,雖然只是進(jìn)行p++操作,但是真正的地址的運(yùn)算卻是
+4;和指針類型有關(guān);
綜上所述:
1、指針保存的是地址,地址是內(nèi)存中每一個字節(jié)大小空間的編號
2、指針的*號可以幫助指針獲得指針保存地址上的數(shù)據(jù)內(nèi)容
3、指針的類型決定指針?biāo)軌蛟L問的內(nèi)存大小,指針類型還和指針偏移有關(guān)
4、指針大小固定,32位系統(tǒng)中占4字節(jié),64位系統(tǒng)中占8字節(jié)
5、指針不能使用常量和未使用的地址進(jìn)行初始化,會出現(xiàn)野指針
華清遠(yuǎn)見上海中心喬遷新居,開啟全新發(fā)展篇章!
華清遠(yuǎn)見連續(xù)9年獲ISO9001質(zhì)量管理體系認(rèn)證,匠心做產(chǎn)
華清遠(yuǎn)見關(guān)于教育部高教司2023年產(chǎn)學(xué)合作協(xié)同育人項目
華清遠(yuǎn)見再獲兩項計算機(jī)軟件著作權(quán)登記證書,行業(yè)實力
華清遠(yuǎn)見嵌入式師資班圓滿收官,虛擬仿真全面構(gòu)建系統(tǒng)
華清遠(yuǎn)見被授予中國電子學(xué)會“電子信息人才能力提升工
企校協(xié)同創(chuàng)新大賽全國總決賽在清華大學(xué)圓滿收官,華清
華清遠(yuǎn)見教育集團(tuán)再次入選教育部供需對接就業(yè)育人項目
華清遠(yuǎn)見關(guān)于提醒學(xué)員謹(jǐn)防網(wǎng)絡(luò)詐騙的嚴(yán)正聲明
華清遠(yuǎn)見協(xié)辦“技能興魯”職業(yè)技能大賽人工智能賽項圓
