?? 前言
?? ??hello! 各位寶子們大家好啊,前面給大大家介紹了指針的基礎(chǔ)知識(shí)。那么這一章就來(lái)給大家介紹下一部分內(nèi)容!
?? ??指針的運(yùn)算 以及 數(shù)組與指針的關(guān)系 也是我們?cè)谥羔樀膶W(xué)習(xí)過(guò)程中非常重要的!
?? ??本期文章收錄在《C語(yǔ)言初階篇》,大家有興趣可以看看吶!
???? 歡迎鐵汁們 ?? 點(diǎn)贊 ?? 收藏 ?留言 ??!
?? 注:前一章的指針講解是《指針的概念》
?? 指針運(yùn)算
?? 指針±整數(shù)
其實(shí)在上一章我們就見(jiàn)過(guò)指針加減整數(shù)了對(duì)于 type * p 的指針想要加
n
減n
是這樣計(jì)算的
- n*sizeof(type)
?? 代碼演示:
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = &arr[0];
//不用下標(biāo)訪問(wèn)
int sz = sizeof(arr) /sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
*p = i;
p = p+1;
}
p = &arr[0];
for (i = 0; i < sz; i++)
{
printf("%d\n",*(p+i));
}
return 0;
}
這里我們就使用指針加減整數(shù)的方式來(lái)進(jìn)行訪問(wèn)數(shù)組進(jìn)行賦值
- 每次讓指針p 向前指4個(gè)字節(jié),然后進(jìn)行賦值!
- 之后再把指針p 歸位到最開(kāi)始的指向位置進(jìn)行訪問(wèn)
![]()
前面的例子懂了我們?cè)賮?lái)看這個(gè)例子大家看看!
?? 代碼演示:
#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指針+-整數(shù);指針的關(guān)系運(yùn)算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}
這個(gè)例子其實(shí)和前面很像,數(shù)組中是從地址值向高地址使開(kāi)辟的一份連續(xù)的空間!這里我們把 數(shù)組的第一個(gè)地址賦給指針
p
- 所以指針
p
肯定沒(méi)有 &values[5]的地址大!- 而
p++
每次向前指向下一個(gè)元素給每個(gè)元素賦值,直到把前五個(gè)都賦完!![]()
?? 指針-指針
指針加減整數(shù)的例子我們了解完了,下面就來(lái)了解了解指針加減指針的應(yīng)用把!
- 不知道大家了解個(gè)庫(kù)函數(shù)strlen 的實(shí)現(xiàn)嘛/
- 今天就用指針-指針的方法實(shí)現(xiàn)一下!
?? 注:庫(kù)函數(shù)的模擬實(shí)現(xiàn)鏈接,大家感興趣可以看看呢!《strlen的三種實(shí)現(xiàn)方法》
?? 代碼演示:
#include <stdio.h>
int my_strlen(char* s)
{
char* p = s;
while (*p != '\0')
p++;
return p - s;
}
int main()
{
char arr[] = "abcdef\0";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
?? 誒這里就巧妙的應(yīng)用了指針里面存放的地址來(lái)進(jìn)行減法運(yùn)算,用差做取值。剛好能求字符的長(zhǎng)度的。
- 因?yàn)橐粋€(gè)字符也就只能只能存放一個(gè)字節(jié)
- 而每一個(gè)字節(jié)都有地址連續(xù)的空間地址就是遞增的!
?? 指針的關(guān)系運(yùn)算
指針減指針的運(yùn)算我們學(xué)了其實(shí)指針的運(yùn)算還有一條規(guī)定:
C語(yǔ)言標(biāo)準(zhǔn)規(guī)定:
- 允許指向數(shù)組元素的指針與指向數(shù)組最后一個(gè)元素后面的那個(gè)內(nèi)存位置的指針比較,但是不允許與指向第一個(gè)元素之前的那個(gè)內(nèi)存位置的指針進(jìn)行比較。
- 我們來(lái)看一下這段代碼:
?? 代碼演示:
for(vp = &values[5-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
這段代碼有什么問(wèn)題呢?其實(shí)這段代碼是倒著往回賦值的從數(shù)組 values[4],一直向后賦值但是
- 當(dāng)最后一個(gè)元素 values[0] 賦完值的時(shí)候
- 循環(huán)調(diào)整部分
vp--
還會(huì)執(zhí)行一次導(dǎo)致vp
成為野指針- 所以,當(dāng)我們?cè)诖蜗胗?
vp
的是就需出現(xiàn)訪問(wèn)越界的問(wèn)題!![]()
?? 代碼改進(jìn):
for(vp = &values[5-1]; vp > &values[0];)
{
*--vp = 0;
}
這樣當(dāng)指針 vp 賦完值之后就不會(huì)再進(jìn)行減減的動(dòng)作了。因?yàn)楦揪瓦M(jìn)不來(lái)循環(huán)里面所以想前面的錯(cuò)誤我們就避免了。
?? 但是:這并不符合C語(yǔ)言的標(biāo)準(zhǔn),所以我們盡量不要這樣寫(xiě)以免有些編譯器跑不過(guò)去。
?? 指針和數(shù)組
?? 代碼演示:
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}
?? 代碼結(jié)果:
???? 誒這里就可以看到,其實(shí)數(shù)組名和數(shù)組第一個(gè)元素的地址是一樣,所以可見(jiàn)數(shù)組名和數(shù)組首元素的地址是一樣的。
- 那么這樣寫(xiě)代碼是可行的:
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是數(shù)組首元素的地址
//等同于 *p= &arr[0];
?? 指針和數(shù)組變種推演
而指針是用來(lái)存放地址的,數(shù)組又是一塊連續(xù)的空間。所以我們可以拿指針變量來(lái)接收數(shù)組首元素的地址,用來(lái)遍歷數(shù)組!
- 所以我們對(duì)指針解引用 和 數(shù)組下標(biāo)是相等的。
- ??? arr[ i ] == *(p+i)
- 而 ?? *(i+p) == arr[ i ]
- 所以 ? *(i+p) == i[ arr ]
- 而 :?p == arr == &arr[ 0 ]
- 所以 ? *() 操作符 等同于 [ ]
?? 代碼演示:
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
int* p = arr; //指針存放數(shù)組首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
arr[i] = i;
printf("%d %d %d %d\n",arr[i],i[arr],*(p+i),p[i]);
}
return 0;
}
?? 代碼結(jié)果:
- 既然這倆個(gè)操作符是相等的那么又能推演出:
-
*(arr+i) == arr[ i ] == *(i+arr)
?? 注:這里就不給大家演示了,大家可以自己去試著練一下呢。
?? 指針和數(shù)組的關(guān)系
????前面我們看到了,數(shù)組和指針的應(yīng)用也給大家?guī)?lái)不一樣的數(shù)組寫(xiě)法是不是很有趣!那么他們究竟有什么關(guān)系?既然指針和數(shù)組使用使用起來(lái)一樣的效果那么我們可以把指針理解為數(shù)組嘛?
- 其實(shí)我們可以這樣理解
- 指針變量就是指針變量,不是數(shù)組。指針變量的大小是4/8個(gè)字節(jié),是用來(lái)專門(mén)存放地址的.
- 數(shù)組就是數(shù)組,不是指針,數(shù)組是一塊連續(xù)的空間??梢源娣乓粋€(gè)或,多個(gè)類型相同的數(shù)據(jù)。
?? 那么他們的聯(lián)系是什么?
-
?? 數(shù)組中,數(shù)組名其實(shí)是數(shù)組首元素的地址,數(shù)組名 == 地址 == 指針
-
?? 當(dāng)我們知道數(shù)組首元素地址的時(shí)候,因?yàn)閿?shù)組又是連續(xù)存放的,所以通過(guò)指針就可以來(lái)遍歷訪問(wèn)我們的數(shù)組。
?? 二級(jí)指針
???? 指針變量也是變量,是變量就有地址,那指針變量的地址存放在哪里?答案是二級(jí)指針,存放指針變量的地址我們叫做二級(jí)指針!
?? 代碼演示:
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;//p是一級(jí)指針變量,指針變量也是變量,
//變量是在內(nèi)存中開(kāi)辟空間的,是變量就有地址
int** pp = &p;//pp就是二級(jí)指針變量,
//二級(jí)指針變量就是用來(lái)存放一級(jí)指針變量的地址
return 0;
}
?? 二級(jí)指針變量就是用來(lái)存放一級(jí)指針的地址,那么怎么來(lái)理解 int**
- int** 第一個(gè) int* 說(shuō)明了
pp
是個(gè)指針變量- 而第二個(gè)
*
則說(shuō)明了pp
里面存放的是指針變量的地址![]()
?? 二級(jí)指針的運(yùn)算
所以我們對(duì) pp 指針解引用一次是找到一級(jí)指針的內(nèi)容
- 所以:*pp 等價(jià)于 p == &a
所以我們想用二級(jí)指針找到一級(jí)指針?biāo)赶虻膶?duì)象 a 就需要進(jìn)行倆次解引用
?? 代碼演示:
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;
int** pp = &p;
**pp = 100;
printf("%d", a);
return 0;
}
?? 代碼結(jié)果:
??全篇總結(jié)
? 歸納:
好了以上就是關(guān)于指針的運(yùn)算 數(shù)組和指針的關(guān)系 以及 二級(jí)指針的概念我們就全講解完畢了!
??指針的運(yùn)算
??數(shù)組和指針的關(guān)系
??二級(jí)指針
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-602312.html
?? 本章的內(nèi)容就是這么多啦!不知道大家了解了沒(méi)有呢?有不懂的可以私信評(píng)論嗷!
看到這里了還不給博主扣個(gè):
?? 點(diǎn)贊
??收藏
?? 關(guān)注
!
?? ?? ?? ?? ???? ?? ?? ?? ?? ??
拜托拜托這個(gè)真的很重要!
你們的點(diǎn)贊就是博主更新最大的動(dòng)力!
有問(wèn)題可以評(píng)論或者私信呢秒回哦。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-602312.html
到了這里,關(guān)于【C語(yǔ)言初階】指針的運(yùn)算or數(shù)組與指針的關(guān)系你了解嗎?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!