一、數組名的理解
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int *p=&arr[0];
?我們發現數組名和數組?元素的地址打印出的結果?模?樣,數組名就是數組?元素(第?個元素)的地址。
數組名如果是數組首元素的地址,那下?的代碼怎么理解呢?
#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%d\n", sizeof(arr));return 0;
}
輸出的結果是:40。?如果arr是數組?元素的地址,那輸出應該的應該是4/8才對。
其實數組名就是數組首元素(第?個元素)的地址是對的,但是有兩個例外:
①sizeof(數組名),sizeof中單獨放數組名,這里的數組名表示整個數組,計算的是整個數組的大小,單位是字節
②&數組名,這里的數組名表示整個數組,取出的是整個數組的地址(整個數組的地址和數組首元素的地址是有區別的)
除此之外,任何地方使用數組名,數組名都表示首元素的地址。
這里我們發現&arr[0]和&arr[0]+1相差4個字節,arr和arr+1 相差4個字節,是因為&arr[0] 和 arr 都是首元素的地址,+1就是跳過一個元素。但是&arr 和 &arr+1相差40個字節,這就是因為&arr是數組的地址,+1 操作是跳過整個數組的。
二、使用指針訪問數組
數組在內存中是連續存放的
指針的加減運算,方便我們獲得每一個元素的地址
#include<stdio.h>
int main()
{int arr[10] = { 0 };//使用指針來訪問數組int sz = sizeof(arr) / sizeof(arr[0]);//輸入10個值int* p = arr;int i = 0;for (i = 0; i < sz; i++){//輸入scanf("%d", p + i);//p+i == &arr[i]}//輸出10個值for (i = 0; i < sz; i++){printf("%d ", *(p + i));}return 0;
}
數組名arr是數組首元素的地址,可以賦值給p,數組名arr和p這里是等價的。
p[i]等價于*(p+i),arr[i]等價于*(arr+i),數組元素在訪問編譯器處理的時候,也是轉換成首元素的地址?+偏移量求出元素的地址,然后解引用來訪問。
1.數組就是數組,是一塊連續的空間(數組的大小和數組元素類型都有關系)
2.指針(變量)就是指針(變量),是一個變量(4/8個字節)
3.數組名是地址,是首元素的地址
4.可以使用指針來訪問數組
拓展:?
三、一維數組傳參的本質
我們之前都是在函數外部計算數組的元素個數,那我們可以把函數傳給一個函數后,函數內部求元素個數嗎?
我們發現在函數內部沒有正確獲得數組的元素個數。?
這就要學習數組傳參的本質了,上篇文章寫道:數組名是數組?元素的地址;那么在數組傳參的時候,傳遞的是數組名,也就是說本質上數組傳參本質上傳遞的是數組首元素的地址。所以函數形參的部分理論上應該 使用指針變量來接收首元素的地址 。那么在函數內部我們寫sizeof(arr) 計算的是?個地址的大小(單位字節)而不是數組的大小(單位字節)。正是因為 函數的參數部分是本質是指針 ,所以在函數內部是沒辦法求的數組元素個數的。
1. 數組傳參的本質是傳遞了數組首元素的地址,所以形參訪問的數組和實參的數組是同一個數組。
2.形參的數組是不會單獨再創建數組空間的,所以形參的數組是可以省略數組大小的。
結論:一維數組傳參,形參的部分可以寫成數組的形式,也可以寫成指針的形式。本質上是指針變量?。
四、二級指針?
指針變量是變量,是變量就有地址,那指針變量的地址存放在哪里呢?這就是二級指針。
int**就是二級指針:
*pp通過對pp中的地址解引用,這樣找到的是p,*pp其實訪問的就是p;
**pp先通過*pp找到p,然后對p進行解引用操作,找到的就是a。
?
五、指針數組
整型數組是存放整型的數組,字符數組是存放字符的數組,那么,指針數組是存放指針的數組。
?
指針數組的每個元素是地址,又可以指向一塊區域。
六、指針數組模擬二維數組
#include<stdio.h>
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 };//打印數組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數組的元素,parr[i]找到的數組元素指向了整型?維數組,parr[i][j]就是整型?維數組中的元素。上述的代碼模擬出二維數組的效果,實際上并非完全是二維數組,因為每一行并非是連續的。