目錄
1. 數組名與地址
2.?指針訪問數組
3.一維數組傳參本質
4.二級指針
5. 指針數組
6.?指針數組模擬二維數組?
1. 數組名與地址
我們先看下面這個代碼:
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];
這里我們使用 &arr[0] 的方式拿到了數組第?個元素的地址,但是其實數組名本來就是地址,而且是數組首元素的地址
??
數組名就是數組首元素(第?個元素)的地址,但是有兩個例外:
1. sizeof(數組名):sizeof中單獨放數組名,這?的數組名表示整個數組,計算的是整個數組的大小,單位是字節
#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;
}
?
?
2. &數組名:這?的數組名表示整個數組,取出的是整個數組的地址(整個數組的地址和數組?元素的地址是有區別的)
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%p\n", &arr);printf("%p\n", &arr + 1);//增加了40個字節,也就是整個數組的大小return 0;
}
除此之外,任何地?使?數組名,數組名都表示首元素的地址
#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("&arr[0] = %p\n", &arr[0]);printf("&arr[0]+1 = %p\n", &arr[0] + 1);printf("arr = %p\n", arr);printf("arr+1 = %p\n", arr + 1);printf("&arr = %p\n", &arr);printf("&arr+1 = %p\n", &arr + 1);return 0;
}
?
我們發現&arr[0]和&arr[0]+1相差4個字節,arr和arr+1 相差4個字節,是因為&arr[0] 和 arr 都是?元素的地址,+1就是跳過?個元素
? ??
但是&arr 和 &arr+1相差40個字節,這就是因為&arr是數組的地址,+1 操作是跳過整個數組的
2.?指針訪問數組
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int arr[10] = { 0 };//輸?int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//輸?int* p = arr;for (i = 0; i < sz; i++){scanf("%d", p + i);//scanf("%d", arr+i);//也可以這樣寫}//輸出for (i = 0; i < sz; i++){printf("%d ", *(p + i));//printf("%d ", p[i]);也可以這樣寫}return 0;
}
將 *(p+i) 換成 p[i] 也是能夠正常打印的,在這里解引用操作符和下標引用符產生的效果相同
? ? ?
同理arr[i] 應該等價于 *(arr+i),數組元素的訪問在編譯器處理的時候,也是轉換成?元素的地址+偏移量求出元素的地址,然后解引?來訪問的
?
?
3.一維數組傳參本質
?個問題:我們之前都是在函數外部計算數組的元素個數,那我們可以把函數傳給?個函
數后,函數內部求數組的元素個數嗎?
#include <stdio.h>void test(int arr[])
{int sz2 = sizeof(arr) / sizeof(arr[0]);printf("sz2 = %d\n", sz2);
}int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz1 = sizeof(arr) / sizeof(arr[0]);printf("sz1 = %d\n", sz1);test(arr);return 0;
}
我們發現在函數內部是沒有正確獲得數組的元素個數
??
我們都知道:數組傳參的本質是傳遞首元素地址,所以函數形參的部分理論上應該使?指針變量來接收?元素的地址
? ??
那么在函數內部我們寫sizeof(arr) 計算的是?個地址的大小(單位字節)而不是數組的大小(單位字節),因為函數的參數部分是本質是指針,所以在函數內部是沒辦法求的數組元素個數的
總結:?維數組傳參,形參的部分可以寫成?int * arr 的指針形式,也可以寫成 arr[ ] 的數組形式
?
4.二級指針
指針變量也是變量,是變量就有地址,那指針變量的地址存放在哪??答案是?級指針
??
一個常見的指針是一級指針,那么在一個指針里面再嵌套一個指針就是二級指針
?
*ppa 通過對ppa中的地址進?解引?,這樣找到的是 pa , *ppa 其實訪問的就是 pa?
int b = 20;
*ppa = &b;//等價于 pa = &b;
?**ppa 先通過 *ppa 找到 pa ,然后對 pa 進?解引?操作: *pa ,那找到的是 a?
**ppa = 30;
//等價于*pa = 30;
//等價于a = 30;
5. 指針數組
?
指針數組就是存放指針的數組
指針數組的每個元素都是?來存放地址(指針)的?
?
指針數組的每個元素是地址,?可以指向?塊區域?
6.?指針數組模擬二維數組?
#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數組中int* parr[3] = { arr1, arr2, arr3 };int i = 0;int j = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ", parr[i][j]);}printf("\n");}return 0;
}
?
?
parr[i]是訪問parr數組的元素,parr[i]找到的數組元素指向了整型?維數組,parr[i][ j]就是整型?維數組中的元素?
完結撒花~?