1、什么是指針
我們注重客戶提出的每個(gè)要求,我們充分考慮每一個(gè)細(xì)節(jié),我們積極的做好網(wǎng)站制作、網(wǎng)站設(shè)計(jì)服務(wù),我們努力開拓更好的視野,通過(guò)不懈的努力,創(chuàng)新互聯(lián)贏得了業(yè)內(nèi)的良好聲譽(yù),這一切,也不斷的激勵(lì)著我們更好的服務(wù)客戶。 主要業(yè)務(wù):網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),微信平臺(tái)小程序開發(fā),網(wǎng)站開發(fā),技術(shù)開發(fā)實(shí)力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫(kù)的技術(shù)開發(fā)工程師。(1)指針的概念
指針是存放一種變量的地址的變量,其特殊性表現(xiàn)在類型和值上,簡(jiǎn)單來(lái)說(shuō),地址就是指針,指針就是地址。從變量角度講,指針變量也具有變量的要素:
指針變量的命名,與一般變量命名相同,遵循C語(yǔ)言的命名規(guī)則。
指針變量的類型,是針變量所指向的變量的類型,而不是自身的類型。
(2)指針的大小
在64位機(jī),指針變量在內(nèi)存中占8個(gè)字節(jié);在32位機(jī),指針變量在內(nèi)存中占4個(gè)字節(jié)
2、定義指針變量
定義指針變量與定義普通變量非常類似,不過(guò)要在變量名前面加*。格式為:
datatype *name;
datatype *name = value;
在定義指針變量中,*表示這是一個(gè)指針變量,如果不是定義指針變量,*代表的是取出一個(gè)地址中存放的數(shù)值,datatype表示該指針變量所指向的數(shù)據(jù)的類型。
在定義指計(jì)變量的同時(shí)對(duì)它進(jìn)行初始化。并將變量的地址賦予它。此時(shí)指針變量就指向了變量的地址。
3、引用指針變量
在引用指針變量時(shí),有以下3種情況:
(1)給指針變量賦值。如:
p=&a; //把 a的地址賦給指針變量p
指針變量p的值是變量a的地址,p指向a.
(2)引用指針變量指向的變量。
如果已經(jīng)執(zhí)行p=&a;即指針變量p已經(jīng)指向了變量a,則printf("%d" ,*p);其作用是以整數(shù)形式輸出指針變量p所指向的變量的值,即變量a的值。
如果有賦值語(yǔ)句:*p=1;
表示將整數(shù)1賦給p當(dāng)前所指向的變量,如果p指向變量a,則相當(dāng)于把1賦給a,即a=1。
(3)引用指針變量的值。如:
printf("%o",p);
作用是以八進(jìn)制數(shù)形式輸出指針變量p的值,如果p指向了a,就是輸出了a的地址,即&a。
4、指針的偏移
int a=10;
int *p=&a;
p指向a的地址,p+1中的1是指的一個(gè)指向類型的大小,p指向整型變量的地址,整型是4個(gè)字節(jié),所以p+1等于訪問(wèn)了a地址后的4個(gè)字節(jié)地址。
5、野指針
野指針就是指針指向的位置是不可知的(隨機(jī)的、不正確的、沒(méi)有明確限制的)
野指針造成原因:
①指針未初始化
例:int *p;//局部變量指針未初始化,賦給指針變量p的是一個(gè)隨機(jī)地址
②指針越界訪問(wèn)
int a[10]={0};
int *p=a;//p指向數(shù)組首元素地址,也就是&a[0]
p=p+9;//p指向p+9==a[9]
*(++p)=10;//++p==a[10],對(duì)a[10]的地址進(jìn)行操作,已經(jīng)超出數(shù)組a的范圍了,所以p是野指針
③指針指向的空間已經(jīng)被釋放
定義一個(gè)局部變量,將局部變量的地址傳給指針變量,當(dāng)程序閱讀到局部變量作用域,局部變量的內(nèi)存就被釋放,地址也不能再被指針指向。
如何規(guī)避野指針
①定義指針時(shí)就初始化
②小心指針越界
③不知道指針只想哪里就先指向NULL
④避免返回局部變量的地址
⑤指針使用前檢測(cè)其有效性
6、指針和數(shù)組
通過(guò)上面的學(xué)習(xí),我們知道了指針變量是用來(lái)存放一種類型變量的地址,那么我們之前學(xué)習(xí)的數(shù)組是否也能將其地址存到指針變量中呢,答案當(dāng)然是可以啦,為什么呢?數(shù)組名通常就是數(shù)組的首元素地址,我們將指針變量指向數(shù)組的首元素地址,我們就可以通過(guò)*解引用操作符,取出地址中存放的數(shù)據(jù),但是還會(huì)有人問(wèn),那數(shù)組第二、第三等等后面的元素該如何讀取出來(lái)呢,這個(gè)問(wèn)題就問(wèn)得好,我們剛剛不就學(xué)習(xí)了指針的偏移了嘛,+1是移動(dòng)的大小是指針類型,也就是我們指針存放的地址,該地址中的數(shù)據(jù)類型,例如我們下面的兩行代碼,定義的是存放雙精度浮點(diǎn)數(shù)的數(shù)組(當(dāng)我們定義一個(gè)數(shù)組時(shí),系統(tǒng)會(huì)分配一塊連續(xù)的空間(地址),數(shù)組元素類型*元素個(gè)數(shù)=該空間大小,一個(gè)數(shù)組元素后面緊接著下一個(gè)元素),那么我們將p+1,將首元素地址移動(dòng)了8個(gè)字節(jié)(雙精度浮點(diǎn)型),等于移動(dòng)到下一個(gè)元素的首地址,由此我們可以通過(guò)指針間接對(duì)數(shù)組內(nèi)的元素值進(jìn)行訪問(wèn)或修改。
double a[10]={0};//a是雙精度數(shù)組名,是該數(shù)組的首元素地址
double? *p=a;//將數(shù)組的首地址給指針變量
在 C 語(yǔ)言中,數(shù)組名除了以下兩種情況,都是指的首元素地址。第一種情況,sizeof(數(shù)組名),這是計(jì)算數(shù)組中的元素個(gè)數(shù),而不是數(shù)組首元素地址的大?。坏诙N情況,&數(shù)字名,這是整個(gè)數(shù)組的地址,雖然和首元素地址相同,但是對(duì)這兩種地址進(jìn)行+1操作,我們發(fā)現(xiàn)兩者地址截然不同,一個(gè)是移動(dòng)一個(gè)元素類型字節(jié)大小的地址,一個(gè)的移動(dòng)的是整個(gè)數(shù)組占用內(nèi)存大小的地址。除了這兩種情況外,都代表數(shù)組中首元素的地址。
注意點(diǎn):
1)如果指針變量 p 已指向數(shù)組中的一個(gè)元素,則 p+1 指向同一數(shù)組中的下一個(gè)元素,p-1 指向同一數(shù)組中的上一個(gè)元素。注意:執(zhí)行 p+1 時(shí)并不是將 p 的值(地址)簡(jiǎn)單地加 1,而是加上一個(gè)數(shù)組元素所占用的字節(jié)數(shù)。例如,數(shù)組元素是 float 型,每個(gè)元素占 4 個(gè)字節(jié),則 p+1 意味著使 p 的值加 4 個(gè)字節(jié),以使它指向下一個(gè)元素。p+1 所代表的地址實(shí)際上是 p+1*d,d 是一個(gè)數(shù)組元素所占的字節(jié)數(shù)。若 p 的值是 2000,則 p+1 的值不是 2001 而是 2004。
2)如果 p 的初值為 &a[0],則 p+i 和 a+i 就是數(shù)組元素 a[i] 的地址,或者說(shuō),他們指向 a 數(shù)組序號(hào)為 i 的元素,見下圖,這里注意的是 a 代表數(shù)組首元素的地址,a+1 也是地址,它的計(jì)算方法同 p+1,即它的實(shí)際地址為 a+1*d。例如,p+9 和 a+9 的值是 &a[9],它指向 a[9]。
3)p+i)和*(a+i) 是p+i或a+i所指向的元素,即a[i]。例如*(p+5)和*(a+5)就是a[5],三者等價(jià)。
7、指針變量作為函數(shù)參數(shù)
將一個(gè)指針變量p(地址)作為實(shí)參傳到函數(shù)中,函數(shù)中可以對(duì)該地址進(jìn)行解引用操作等。
8、數(shù)組名作為函數(shù)參數(shù)
數(shù)組名除了sizeof(數(shù)組名)和&數(shù)字名兩種情況外,都代表數(shù)組中首元素的地址。所以我們可以將數(shù)組名當(dāng)作指針變量傳到函數(shù)中,供函數(shù)使用。?
下面通過(guò)一個(gè)例子來(lái)學(xué)習(xí)如何將數(shù)組名作為函數(shù)參數(shù),供函數(shù)使用。
輸入某班學(xué)生某門課程的成績(jī)和學(xué)號(hào)(最多不超過(guò)40人),輸入負(fù)值時(shí)表示輸入結(jié)束。用函數(shù)編程通過(guò)返回?cái)?shù)組中大元素下標(biāo),查找并輸出成績(jī)的最高分和所屬學(xué)生學(xué)號(hào)。
#includeint find_max_grade(double a[],int i)//尋找最高分的下標(biāo),并將下標(biāo)作為返回值返回
{
int j,flag=0;
double max=a[0];//將數(shù)組首元素作為擂主,遍歷數(shù)組,當(dāng)有元素值比擂主大的,將該元素賦給擂主,并記錄下標(biāo)
for(j=1;jmax)
{
max=a[j];
flag=j;
}
}
printf("全班最高分:%.2lf\n",max);
return flag;
}
void printf_no(int *p,int k)//該函數(shù)略顯多余,只是用來(lái)再練習(xí)一下數(shù)組名傳參
{
printf("學(xué)生學(xué)號(hào):%d\n",b[k]);
*(p+1)=100;//修改數(shù)組第二個(gè)元素的值
}
int main()
{
double grade[40]={0};
int no[40]={0},i=-1;
do{
i++;
printf("請(qǐng)輸入第%d個(gè)學(xué)生成績(jī)和學(xué)號(hào):",i+1);
scanf("%lf%d",&grade[i],&no[i]);
}while(grade[i]>=0&&no[i]>=0);//輸入的分?jǐn)?shù)或?qū)W號(hào)為負(fù)數(shù)即為停止輸入
int flag=find_max_grade(grade,i);
printf_no(no,flag);
printf("%lf",grade[1]);
return 0;
}
數(shù)組名作為實(shí)參,形參用一個(gè)數(shù)組接收,我們發(fā)現(xiàn)用這種方法無(wú)法對(duì)數(shù)組中的元素進(jìn)行更改,當(dāng)我們?cè)趐rintf_no函數(shù)中,用一個(gè)指針來(lái)接收傳過(guò)來(lái)的數(shù)組首元素地址,最后將*(p+1)也就是grade[1]賦值為100,發(fā)現(xiàn)回到主函數(shù)中打印該值,真的修改了,對(duì)比,我們發(fā)現(xiàn)傳值調(diào)用和傳址調(diào)用的兩者差別還是很大的,前者只是實(shí)參的拷貝(換種說(shuō)法,就是文件只讀,不能對(duì)其進(jìn)行寫操作),所以我們可以將其中的數(shù)據(jù)讀出,打印出來(lái);而后者是真正得到數(shù)組的地址,通過(guò)地址,對(duì)地址中的數(shù)據(jù)進(jìn)行更改。
9、指針變量作為函數(shù)參數(shù)
函數(shù)的參數(shù)不僅可以是整形,浮點(diǎn)型等數(shù)據(jù),也可以是指針類型。他的作用是將一個(gè)變量的地址傳送到另一個(gè)函數(shù)中,其實(shí)剛剛的數(shù)組名作為函數(shù)實(shí)參就是傳址。
下面通過(guò)一個(gè)例子學(xué)習(xí)如何將指針變量作為函數(shù)參數(shù)。
n個(gè)元素的數(shù)組,將數(shù)組所有元素向后移動(dòng)m個(gè)元素單位,最后的m個(gè)元素移到開頭。
例如:? ?原數(shù)組:? ?1 2 3 4 5 6 7 8 9 10
移動(dòng)3個(gè)元素單位:10 9 8 1 2 3 4 5 6 7
#includevoid input_array(int *p,int sz)//輸入數(shù)組元素
{
printf("請(qǐng)輸入數(shù)組元素:");
for(int i=0;i0;j--) //將前面9個(gè)元素依次往后移1位
{
*(p+j)=*(p+j-1);
}
*p=t; //將存入臨時(shí)變量中最后一個(gè)元素存入首個(gè)元素中
}
}
void output_array(int *p,int sz)//打印結(jié)果
{
for(int k=0;k
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
分享文章:C語(yǔ)言的指針學(xué)習(xí)-創(chuàng)新互聯(lián)
文章源于:http://jinyejixie.com/article28/dpsdjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、微信小程序、App開發(fā)、營(yíng)銷型網(wǎng)站建設(shè)、企業(yè)建站、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容