指針和數組
編譯器在編譯的時候會將數組名轉化爲對應類型的指針
數組注意點
不能直接用一個數組初始化另一個數組,也不能用一個數組給另一個數組賦值
void arrayassigntest()
{
int a[10]={0};
int b[10]=a;
}
此時提示數組可以用大括號的方式初始化,第四行用指針初始化數組,所以報錯
void arrayassigntest()
{
int a[10]={0};
int b[10]={0};
a=b;
}
如果用一個數組給另一個數組初始化,會提示數組賦值無效
上述兩種情況的原因都是在於使用數組名的時候,會將數組名轉爲指針
使用指針遍歷數組
void traversearraybyp()
{
int a[7]={1,2,3,4,5,6,7};
int *s=a;
int *e=&a[7];
for (int *p=s;p!=e;++p) {
cout<<*p<<endl;
}
/*for (int i=0;i<sizeof(a)/sizeof(a[0]);++i) {
cout<<a[i]<<endl;
}*/
}
int *e=&a[7]指向了尾後元素之後的地址,類似於尾後迭代器
當指針指向數組的某個元素時,用指針和下標訪問數組時,下標可以爲負數
void negativeindex()
{
int a[7]={1,2,3,4,5,6,7};
int *p=&a[4];
cout<<p[-2]<<endl;
}
複雜數組聲明的理解
數組本身是對象,所以存在數組的指針和數組的引用,而指針也是對象,所以存在指針的數組,但是引用不是對象,所以不在引用的數組
int *p[10]={nullptr};//指針的數組,每個數組的內容都是一個int指針
//int &r[10]; 錯誤,不存在引用的數組
因爲數組的指針是對象,所以還存在數組的指針的引用和數組的指針的指針
int a[10]={0};
int *p[10]={nullptr};
int (*ap)[10]=&a;//ap指針指向一個長度爲10的int數組
int (&ar)[10]=a;//ar是數組a的引用
int *(*app)[10]=&p;//app是指針數組的指針
int *(&apr)[10]=p;//apr是指針數組的引用
注意,這裏int (*ap)[10]=&a不能寫成int (*ap)[10]=a,因爲a是int數組,編譯時被解讀爲指針,而不是數組的指針
同理,int *(*app)[10]=&p也不能寫成int *(*app)[10]=p,因爲p是指針數組,編譯時被解讀爲指針的指針
關於ap ar app的識別方法如下
int (*ap)[10],先看括號裏面的ap,我們知道這是一個變量,看到前面的*,判斷這是個指針,之後 看到[10],斷定該指針指向一個數組,最後看到int,知道指向的數組元素類型是int
int (&ar)[10],先看括號裏面的ar,我們知道這是一個變量,看到前面的&,判斷這是個引用,之後 看到[10],斷定該引用綁定一個數組,最後看到int,知道綁定的數組元素類型是int
int *(*app)[10],先看括號裏面的app,我們知道這是一個變量,看到前面的*,判斷這是個指針,之後 看到[10],斷定該指針指向一個數組,最後看到int *,知道指向的數組元素類型是int指針
int *(&apr)[10],先看括號裏面的apr,我們知道這是一個變量,看到前面的&,判斷這是個引用,之後 看到[10],斷定該引用綁定一個數組,最後看到int *,知道綁定的數組元素類型是int指針
總的來說,數組的指針和引用,以及數組指針的指針的讀法是括號內,然後兩邊
使用數組指針二維數組
void twodimarray()
{
int a[3][4]={1,2,3,4,5};
for (int (*ap)[4]=&a[0];ap<&a[0]+3;++ap) {分別取行地址
for (int *p=ap[0];p<ap[0]+4;++p) {分別遍歷每行
cout<<*p<<endl;
}
}
}
參考:
《C++ Primer》
歡迎大家評論交流,作者水平有限,如有錯誤,歡迎指出