C/C++数组指针和指针数组
數組指針和指針數組的區別
指針數組:首先它是一個數組,每一個元素都是一個指針。
數組指針:首先它是一個指針,它指向一個數組。它是"指向數組的指針"的簡稱。
運算符的優先級關系:()?>?[]?> *
?
數組指針(也稱行指針)
例如:int (*p)[n];
根據優先級,先看( )內,p是一個指針,后面的[ ]又說明了p是一個指向數組的指針,由于前面的int,所以p是一個指向 int 類型數組的一個指針。
將二維數組賦給指針:
int a[3][4]; int (*p)[4]; //該語句是定義一個數組指針,指向含4個元素的一維數組。 p=a;??????? //將該二維數組的首地址賦給p p++;?????? //該語句執行過后,也就是p=p+1;p跨過行a[0][]指向了行a[1][]所以數組指針也稱指向一維數組的指針,亦稱行指針。
?
指針數組
例如:?int *p[n];
根據優先級,p先與[ ]結合,所以p是一個數組,再結合 *,表明數組里面的元素是指針,再加上int,說明p數組中的元素是int類型的指針。
將二維數組賦給指針數組:
int *p[3]; int a[3][4]; p++;? //該語句表示p數組指向下一個數組元素。for(i=0;i<3;i++)p[i]=a[i] 這里int *p[3] 表示一個一維數組內存放著三個指針變量,分別是p[0]、p[1]、p[2]所以要分別賦值。在二維數組里面
a,&a,a[0],&a[0],&a[0][0]五個值是一樣的,都指向二維數組的首地址(起始位置)。區別在于這五種表達方式的類型是不同的,以int a[2][3]舉例:
a是二維數組名,是常量,存放著二維數組的首地址,類型為二維數組,sizeof(a)=24。
&a 二維數組a的(首)地址,本身是一個指針,sizeof(&a)=4,指針類型都為4。
a[0]指向二維數組中的第一行數組a[0][],類型是一維數組sizeof(a[0])=12。
&a[0]代表a[0]的地址,與一維數組名a[0]值相同,但本身是指針類型sizeof(&a[0])=4。
&a[0][0]表示二維數組中第一個元素的地址,指針類型sizeof(&a[0][0])=4。
?
A和&A之間的區別
分析如下代碼:
int main() {char a[5]={'A','B','C','D'};char (*p3)[5] = &a;char (*p4)[5] = a;return 0; }上面對p3 和p4 的使用,哪個正確呢?p3+1 的值會是什么?p4+1 的值又會是什么?毫無疑問,p3 和p4 都是數組指針,指向的是整個數組。&a 是整個數組的首地址,a是數組首元素的首地址,其值相同但意義不同。在C/C++里,賦值符號“=”號兩邊的數據類型必須是相同的,如果不同需要顯示或隱式的類型轉換。p3 這個定義的“=”號兩邊的數據類型完全一致,而p4 這個定義的“=”號兩邊的數據類型就不一致了。左邊的類型是指向整個數組的指針,右邊的數據類型是指向單個字符的指針。在Visual C++6.0 上給出如下警告:
warning C4047: 'initializing' : 'char (*)[5]' differs in levels of indirection from 'char *'。這里給出了警告,可是由于&a 和a 的值一樣,而變量作為右值時編譯器只是取變量的值,所以運行并沒有什么問題。雖然能運行,但不能這么用。
現在清楚了p3 和p4 都是指向整個數組的,那p3+1和p4+1的值就很好理解了。測試代碼如下:
結論:根據指針類型及所指對象,表示指針大小,每次加1,表示增加指針類型大小的字節。
?
另一個實例
#include <iostream> #include <cstdio> using namespace std;int main() {int a[4]={1,2,3,4};int *ptr1=(int *)(&a+1); //指向a數組后面的內存單元,&a+1表示向后移16個存儲單元int *ptr2=(int *)(a+1); //表示a的存儲單元的地址增加一個字節printf("%d,%d",ptr1[-1],*ptr2); //ptr1[-1]其實指向的是a數組的最后一個單元return 0; }其內存布局如下圖:
參考:https://www.cnblogs.com/mq0036/p/3382732.html
總結
以上是生活随笔為你收集整理的C/C++数组指针和指针数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++函数指针
- 下一篇: C++ 深复制与浅复制 RVO问题