柚子快報(bào)激活碼778899分享:C語言之指針的奧秘(二)
柚子快報(bào)激活碼778899分享:C語言之指針的奧秘(二)
一、數(shù)組名的理解
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int *p=&arr[0];
這里使用?
&arr[0]
的?式拿到了數(shù)組第?個(gè)元素的地址,但是其實(shí)數(shù)組名本來就是地址,而且是數(shù)組首元素的地址。如下:
?我們發(fā)現(xiàn)數(shù)組名和數(shù)組?元素的地址打印出的結(jié)果?模?樣,數(shù)組名就是數(shù)組?元素(第?個(gè)元素)的地址。
數(shù)組名如果是數(shù)組首元素的地址,那下?的代碼怎么理解呢?
#include
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", sizeof(arr));
return 0;
}
輸出的結(jié)果是:40。?如果arr是數(shù)組?元素的地址,那輸出應(yīng)該的應(yīng)該是4/8才對。
其實(shí)數(shù)組名就是數(shù)組首元素(第?個(gè)元素)的地址是對的,但是有兩個(gè)例外:
①sizeof(數(shù)組名),sizeof中單獨(dú)放數(shù)組名,這里的數(shù)組名表示整個(gè)數(shù)組,計(jì)算的是整個(gè)數(shù)組的大小,單位是字節(jié)
②&數(shù)組名,這里的數(shù)組名表示整個(gè)數(shù)組,取出的是整個(gè)數(shù)組的地址(整個(gè)數(shù)組的地址和數(shù)組首元素的地址是有區(qū)別的)
除此之外,任何地方使用數(shù)組名,數(shù)組名都表示首元素的地址。
這里我們發(fā)現(xiàn)&arr[0]和&arr[0]+1相差4個(gè)字節(jié),arr和arr+1 相差4個(gè)字節(jié),是因?yàn)?arr[0] 和 arr 都是首元素的地址,+1就是跳過一個(gè)元素。但是&arr 和 &arr+1相差40個(gè)字節(jié),這就是因?yàn)?arr是數(shù)組的地址,+1 操作是跳過整個(gè)數(shù)組的。
二、使用指針訪問數(shù)組
數(shù)組在內(nèi)存中是連續(xù)存放的
指針的加減運(yùn)算,方便我們獲得每一個(gè)元素的地址
#include
int main()
{
int arr[10] = { 0 };
//使用指針來訪問數(shù)組
int sz = sizeof(arr) / sizeof(arr[0]);
//輸入10個(gè)值
int* p = arr;
int i = 0;
for (i = 0; i < sz; i++)
{
//輸入
scanf("%d", p + i);//p+i == &arr[i]
}
//輸出10個(gè)值
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
數(shù)組名arr是數(shù)組首元素的地址,可以賦值給p,數(shù)組名arr和p這里是等價(jià)的。
p[i]等價(jià)于*(p+i),arr[i]等價(jià)于*(arr+i),數(shù)組元素在訪問編譯器處理的時(shí)候,也是轉(zhuǎn)換成首元素的地址?+偏移量求出元素的地址,然后解引用來訪問。
1.數(shù)組就是數(shù)組,是一塊連續(xù)的空間(數(shù)組的大小和數(shù)組元素類型都有關(guān)系)
2.指針(變量)就是指針(變量),是一個(gè)變量(4/8個(gè)字節(jié))
3.數(shù)組名是地址,是首元素的地址
4.可以使用指針來訪問數(shù)組
拓展:?
三、一維數(shù)組傳參的本質(zhì)
我們之前都是在函數(shù)外部計(jì)算數(shù)組的元素個(gè)數(shù),那我們可以把函數(shù)傳給一個(gè)函數(shù)后,函數(shù)內(nèi)部求元素個(gè)數(shù)嗎?
我們發(fā)現(xiàn)在函數(shù)內(nèi)部沒有正確獲得數(shù)組的元素個(gè)數(shù)。?
這就要學(xué)習(xí)數(shù)組傳參的本質(zhì)了,上篇文章寫道:數(shù)組名是數(shù)組?元素的地址;那么在數(shù)組傳參的時(shí)候,傳遞的是數(shù)組名,也就是說本質(zhì)上數(shù)組傳參本質(zhì)上傳遞的是數(shù)組首元素的地址。
所以函數(shù)形參的部分理論上應(yīng)該
使用指針變量來接收首元素的地址
。那么在函數(shù)內(nèi)部我們寫
sizeof(arr)
計(jì)算的是?個(gè)地址的大?。▎挝蛔止?jié))而不是數(shù)組的大小(單位字節(jié))。正是因?yàn)?/p>
函數(shù)的參數(shù)部分是本質(zhì)是指針
,所以在函數(shù)內(nèi)部是沒辦法求的數(shù)組元素個(gè)數(shù)的。
1. 數(shù)組傳參的本質(zhì)是傳遞了數(shù)組首元素的地址,所以形參訪問的數(shù)組和實(shí)參的數(shù)組是同一個(gè)數(shù)組。
2.形參的數(shù)組是不會(huì)單獨(dú)再創(chuàng)建數(shù)組空間的,所以形參的數(shù)組是可以省略數(shù)組大小的。
結(jié)論:一維數(shù)組傳參,形參的部分可以寫成數(shù)組的形式,也可以寫成指針的形式。本質(zhì)上是指針變量?。
四、二級指針?
指針變量是變量,是變量就有地址,那指針變量的地址存放在哪里呢?這就是二級指針。
int**就是二級指針:
*pp通過對pp中的地址解引用,這樣找到的是p,*pp其實(shí)訪問的就是p;
**pp先通過*pp找到p,然后對p進(jìn)行解引用操作,找到的就是a。
?
五、指針數(shù)組
整型數(shù)組是存放整型的數(shù)組,字符數(shù)組是存放字符的數(shù)組,那么,指針數(shù)組是存放指針的數(shù)組。
?
指針數(shù)組的每個(gè)元素是地址,又可以指向一塊區(qū)域。
六、指針數(shù)組模擬二維數(shù)組
#include
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* parr[3] = { arr1,arr2,arr3 };
//打印數(shù)組
int i = 1;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}
?畫圖演示:
*(arr1+j)==arr1[j]
*(*(arr+i)+j)==arr[i][j]
parr[i]是訪問parr數(shù)組的元素,parr[i]找到的數(shù)組元素指向了整型?維數(shù)組,parr[i][j]就是整型?維數(shù)組中的元素。
上述的代碼模擬出二維數(shù)組的效果,實(shí)際上并非完全是二維數(shù)組,因?yàn)槊恳恍胁⒎鞘沁B續(xù)的。
柚子快報(bào)激活碼778899分享:C語言之指針的奧秘(二)
精彩內(nèi)容
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。