這篇博文我們來繼續學習指針的其他內容
指針2.0
- 傳值調用與傳址調用
- 傳值調用
- 傳址調用
- 一維數組與指針
- 理解數組名
- 使用指針
- 深入理解一維數組
- 二級指針
- 指針數組
- 二維數組與指針
傳值調用與傳址調用
在開始之前,我們需要先了解這個概念,后面才能夠正常的學習
傳值調用
int add(int x, int y)
{return x + y;
}
int main()
{int a = 10;int b = 20;int c = add(a, b);printf("%d", c);return 0;
}
經典的傳值調用,只需要傳值即可,沒有過多的要求,但如果我們的要求是將ab互換大小,再用這樣的代碼就行不通了
void ecn(int x, int y)
{int tmp = x;x = y;y = tmp;
}
int main()
{int a = 10;int b = 20;ecn(a, b);printf("a = %d\n", a);printf("b = %d\n", b);return 0;
}
我們發現,這樣做交換不了兩者的值,是因為形參是實參的一份臨時拷貝,形參也是有地址的,改變形參影響不了實參,這時我們只能進行傳址調用
傳址調用
void ecn(int* x,int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
int main()
{int a = 10;int b = 20;ecn(&a, &b);printf("a = %d\n", a);printf("b = %d\n", b);return 0;
}
這樣就能進行調換了,改變實參的值
一維數組與指針
理解數組名
int arr[5] = {1,2,3,4,5};
當我們想要訪問arr數組時,我們有一下幾種方法
int i = arr[0];
int* p = &arr[0];
int* p = arr;
第一種不必多說,利用訪問下標操作符對數組進行訪問。第二、三種是我們上一篇文章說的(可移步上一篇:指針初階),通過指針對數組進行訪問,arr與&arr[0]是一樣的,都是數組的首元素地址
那我們可能會有疑問了:那&arr是什么樣的呢,跟這兩個也一樣嗎?下面我們用編譯器來測試下,順便證明一下第二三種是一樣的
打印它們的地址
#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5 };printf("&arr[0] = %p\n", &arr[0]);printf("arr = %p\n", arr);printf("&arr = %p\n", &arr);return 0;
}
我們發現它們的地址都是相同的,那它們都相同嗎?我們再來看一下
#include <stdio.h>
int main()
{int arr[5] = { 1,2,3,4,5 };printf("%d\n", sizeof(arr));return 0;
}
如果它們都相同,那么sizeof(arr)與sizeof(arr【0】)應該相同,那應該在32位下為4,只有整個數組的大小才為20,這與我們之前所看到的相悖,我們最后來看一下區別在哪
#include <stdio.h>
int main()
{int arr[5] = { 1,2,3,4,5 };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+1跟另外兩個不同,地址加了20,而另外兩個加了4;正如我們所想,arr確實代表著一個數組,但&arr取的是首元素的地址,整個數組是一個整體
使用指針
#include <stdio.h>
int main()
{int arr[5] = { 0 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);int* p = arr;for (i = 0; i < sz; i++){scanf("%d", p + i);}for (i = 0; i < sz; i++){printf("%d ", p[i]);//這里*(p+i)=p[i]}return 0;
數組元素的訪問在編譯器處理的時候轉換成?元素的地址+偏移量求出元素的地址,然后解引?來訪問。
深入理解一維數組
當我們寫函數的時候,如果想要改變數組的內容:?維數組傳參,形參的部分可以寫成數組的形式,也可以寫成指針的形式。
其實這個也是想當然的,因為數組可以用指針來表示,二者等同,那么取而代之肯定也是非常正確的,因為數組的本質就是指針
二級指針
二級指針的概念也很簡單,就是存放一級指針的地址的指針
int main()
{int i = 10;int* pi = &i;int** ppi = πreturn 0;
}
*ppi = pi;
**ppi = i;
同理,存放二級指針地址的就是三級指針
指針數組
指針數組就是存放指針的數組,里邊每個元素都是地址
int* arr1;//里邊的指針類型全部為int*
char* arr2;//里邊的指針類型全部為char*
二維數組與指針
#include <stdio.h>
int main()
{int arr1[5] = { 1,2,3,4,5 };int arr2[5] = { 2,3,4,5,6 };int arr3[5] = { 3,4,5,6,7 };int* parr[3] = { arr1, arr2, arr3 };//我們一般把p作為指針變量,后面加上arr表示是數組指針變量,有關于數組指針變量的知識我們下期再分享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 ][ j ]的形式,這其實就是二維數組的真正形態,在運行時二維數組也是要先變成指針的形式再進行運算的,所以說數組的本質是指針
這篇2.0就到這里了,感謝閱讀