通過(guò)指針引用數(shù)組的幾種方法的原理和差異;以及利用指針引用數(shù)組元素的技巧
關(guān)于地址,指針,指針變量可以參考這篇文章:
C語(yǔ)言指針操作(一)地址,指針,指針變量是什么
關(guān)于指針變量作為函數(shù)參數(shù)可以參考這篇文章:
C語(yǔ)言指針操作(二)指針變量作為函數(shù)參數(shù)
目錄
一、數(shù)組元素的指針
1.1引入
1.2實(shí)例
二、在引用數(shù)組元素時(shí)指針的運(yùn)算
2.1引入
2.2實(shí)例
2.3詳細(xì)說(shuō)明
三、通過(guò)指針引用數(shù)組元素
3.1引入
3.2舉例說(shuō)明
3.3拓展
一、數(shù)組元素的指針
1.1引入
一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都占用存儲(chǔ)單元,所以他們都有相應(yīng)的地址,所謂數(shù)組元素的指針就是數(shù)組元素的地址。
1.2實(shí)例
下面用指針變量指向一個(gè)數(shù)組元素
int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; //定義包含10個(gè)數(shù)據(jù)的整型數(shù)組
int* p; //定義1個(gè)整型指針變量
p = &a[0]; //將數(shù)組元素a[0]的地址賦值指針變量
以上是將指針變量 p 指向 a 數(shù)組的第 0 號(hào)元素。
引用數(shù)組元素可以使用下標(biāo)法,也可以使用指針?lè)?,即通過(guò)指向數(shù)組元素的指針找到所需的元素,使用指針?lè)苁鼓繕?biāo)程序質(zhì)量高(占內(nèi)存少,運(yùn)行速度快)。
在 C 語(yǔ)言中,數(shù)組名(不包含形參數(shù)組名)代表數(shù)組中首元素(即序號(hào)為 0 的元素)的地址,所以下面兩個(gè)語(yǔ)句等價(jià)
p = &a[0]; //p的值是a[0]的地址
p = a; //p的值是數(shù)組a首元素(即a[0])的地址
注意:數(shù)組名不代表整個(gè)數(shù)組,只代表數(shù)組首元素的地址。
二、在引用數(shù)組元素時(shí)指針的運(yùn)算
2.1引入
可以對(duì)數(shù)值型數(shù)據(jù)進(jìn)行算數(shù)運(yùn)算,那么可以對(duì)指針型數(shù)據(jù)進(jìn)行算數(shù)運(yùn)算嗎?指針就是地址,顯然對(duì)地址進(jìn)行乘和除是沒(méi)有意義的,只有在一定條件下進(jìn)行的加和減才有意義。
當(dāng)指針指向數(shù)組元素的時(shí)候,能夠?qū)χ羔樳M(jìn)行加和減運(yùn)算;例如指針變量 p 指向數(shù)組元素 a[0],則 p+1表示指向下一個(gè)數(shù)組元素 a[1]。
2.2實(shí)例
在指針已指向一個(gè)數(shù)組元素時(shí),可以對(duì)指針進(jìn)行以下運(yùn)算:
①加一個(gè)整數(shù)( p + i ),如 p += 1;
②減一個(gè)整數(shù)( p -?i ),如 p -= 1;
③自加運(yùn)算,如 p++
④自減運(yùn)算,如 p--
⑤兩個(gè)指針相減,如 p1 - p2 (只有p1和p2都指向同一個(gè)數(shù)組中的元素時(shí)才有意義)
2.3詳細(xì)說(shuō)明
(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é),以使它指向下一元素。p+1所代表的地址實(shí)際上是 p+1×d ,d 是一個(gè)數(shù)組元素所占的字節(jié)數(shù)(在Visual C++ 中,對(duì) int 型,d=4;對(duì) float 和 long 型,d=4;對(duì) char 型,d=1 )。若 p 的值是2000,則 p+1的值不是2001,而是2004。
那么系統(tǒng)怎么知道要把這個(gè) 1 轉(zhuǎn)換為 4,然后與 p 的值相加呢?因?yàn)樵诙x指針變量時(shí)必須要指定基類(lèi)型,如:float* p。
(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 所指向的數(shù)組元素,即 a[i],例如 *(p+5),*(a+5) 和 a[5] 三者等價(jià),實(shí)際上,在編譯時(shí),對(duì)數(shù)組元素 a[i] 就是按 *(a+i) 處理的,即按數(shù)組首元素的地址加上相對(duì)位移量得到要找元素的地址,然后取出存儲(chǔ)單元中的內(nèi)容。
[ ]實(shí)際上是變址運(yùn)算符,即將 a[i] 按 a+i 計(jì)算地址,然后找出此地址單元中的值。
(4)如果指針變量 p1 和 p2 都指向同一數(shù)組中的元素,如執(zhí)行 p2 - p1,結(jié)果是 p2 - p1 的值(兩個(gè)地址之差)除以該數(shù)組元素類(lèi)型所占的字節(jié)長(zhǎng)度。假設(shè),p2 指向?qū)嵭蛿?shù)組元素? a[5],p2 的值為2020;p1 指向?a[3],其值為2012,則 p2-p1 的結(jié)果是 (2020-2012)/4 = 2 。這個(gè)結(jié)果是有意義的,表示 p1 所指向的元素與 p2?所指的元素之間差 2 個(gè)元素。這樣就不需要具體地知道p1和 p2的值,然后去計(jì)算它們的相對(duì)位置,而是直接用 p2-p1 就可知道它們所指元素的相對(duì)距離。
兩個(gè)地址不能相加,如 p1+p2 是無(wú)實(shí)際意義的。
三、通過(guò)指針引用數(shù)組元素
3.1引入
引用數(shù)組元素,存在下面兩種方法:
①下標(biāo)法,如 a[i] ;
②指針?lè)?數(shù)組名法和指針變量法),如 *(a+i) 或 *(p+i) ,其中 a 是數(shù)組名,p 是指向數(shù)組元素的指針變量,其初值為 p=a;
3.2舉例說(shuō)明
有一個(gè)整型數(shù)組 a,有10個(gè)元素,要求輸出數(shù)組的全部元素
(1)下標(biāo)法
#include<stdio.h>
int main()
{
int a[10] = { 1,3,5,7,9,2,4,6,8,10 };
for (int i = 0; i < 10; i++)
{
printf("%d ", a[i]); //通過(guò)下標(biāo)表示
}
printf("\n");
return 0;
}
(2)通過(guò)數(shù)組名和元素序號(hào)計(jì)算數(shù)組元素的地址
#include<stdio.h>
int main()
{
int a[10] = { 1,3,5,7,9,2,4,6,8,10 };
for (int i = 0; i < 10; i++)
{
printf("%d ", *(a + i)); //通過(guò)數(shù)組名和元素序號(hào)計(jì)算
}
printf("\n");
return 0;
}
(3)用指針變量指向數(shù)組元素
#include<stdio.h>
int main()
{
int a[10] = { 1,3,5,7,9,2,4,6,8,10 };
int* p;
for (p = a; p < (a + 10); p++)
{
printf("%d ", *p); //用指針指向當(dāng)前的數(shù)組元素
}
printf("\n");
return 0;
}
三種方法的比較:
①第(1)和第(2)種方法的執(zhí)行效率是相同的,編譯系統(tǒng)將 a[i] 轉(zhuǎn)換為 *a[i+1] 處理的,第(3)種方法比前面兩種更快,用指針直接指向元素,不必每次都重新計(jì)算地址,大大提高執(zhí)行效率。
②用下標(biāo)法比較直觀,能直接知道是第幾個(gè)元素;用地址法或指針變量的方法不直觀,難以很快的判斷出當(dāng)前處理的是哪一個(gè)元素。
需要注意的是:不能通過(guò)改變數(shù)組名a的方式(例如:a++ )來(lái)改變所指向的變量,因?yàn)?a 代表的是數(shù)組首元素的地址,他是一個(gè)指針型常量,它的值是固定不變的。
3.3拓展
(1)指向數(shù)組元素的指針變量也可以帶下標(biāo),如 p[i] ;因?yàn)槌绦蛟诰幾g時(shí),對(duì)下標(biāo)的處理方法是轉(zhuǎn)換為地址,p[i] 處理成 *(p+i) ,需要注意的是此時(shí) p[i] 的指向,若 p 指向 a[0],則 p[2] 代表 a[2],若 p[i] 指向 a[3],則 p[2] 代表 a[5],建議少用,容易出錯(cuò)。
(2)利用指針引用數(shù)組元素,比較靈活方便,可以使用一些技巧使程序更加簡(jiǎn)潔。
① *p++ :由于++和 * 同優(yōu)先級(jí),結(jié)合方向?yàn)樽杂叶?,因此它等價(jià)于 *(p++),即先引用p的值,實(shí)現(xiàn) *p 的運(yùn)算,然后再使 p 自加1。
#include<stdio.h>
int main()
{
int a[3] = { 2,5,8 };
int* p;
for (p = a; p < (a + 3);)
{
printf("%d ", *p++);
}
}
② *(p++) 和 *(++p) 的作用不相同,前者先取 *p 的值,然后再自加 1,后者先使 p+1,再取 *p 的值。
#include<stdio.h>
int main()
{
int a[3] = { 2,5,8 };
int b[3] = { 2,5,8 };
int* p, * q;
for (p = a; p < (a + 3); )
{
printf("%d ", *(p++));
}
printf("\n");
for (q = b; q < (b + 3); )
{
printf("%d ", *(++q));
}
}
后著因?yàn)闆](méi)有定義數(shù)組 b 的第 4 個(gè)元素 b[4],所以指向了一個(gè)不確定的位置。
③ (*p)++ 和 ++(*p) 作用不相同,但都是先得到 (*p) 所指向元素的值,前者先把 (*p) 所指向的元素值作為表達(dá)式的值后,再自加 1;后著是自加 1 后再作為表達(dá)式的值。但需要注意的是:他們都是使 p 所指向的元素加 1 ,而不是使指針 p 的值加 1 。
#include<stdio.h>
int main()
{
int a[3] = { 2,5,8 };
int b[3] = { 2,5,8 };
int* p, * q;
for (p = a; p < (a + 3); p++)
{
printf("%d", (*p)++);
}
printf("\n");
for (q = b; q < (b + 3); q++)
{
printf("%d", ++(*q));
}
}
C語(yǔ)言指針操作系列文章:
C語(yǔ)言指針操作(一)地址,指針,指針變量是什么
C語(yǔ)言指針操作(二)指針變量作為函數(shù)參數(shù)
C語(yǔ)言指針操作(三)通過(guò)指針引用數(shù)組
C語(yǔ)言指針操作(四)用數(shù)組名作函數(shù)參數(shù)
C語(yǔ)言指針操作(五)通過(guò)指針引用多維數(shù)組
C語(yǔ)言指針操作(六)通過(guò)指針引用字符串
C語(yǔ)言指針操作(七)指向函數(shù)的指針
C語(yǔ)言指針操作(八)返回指針值的函數(shù)
C語(yǔ)言指針操作(九)指針數(shù)組和多重指針
C語(yǔ)言指針操作(十)動(dòng)態(tài)內(nèi)存分配與指向它的指針變量文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-759154.html
C語(yǔ)言指針操作(十一)有關(guān)指針的小結(jié)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-759154.html
到了這里,關(guān)于C語(yǔ)言指針操作(三)通過(guò)指針引用數(shù)組的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!