对于数组,与指针变量总有千丝万缕的关系。
int arr[3][4] = {
1,2,3,4,
5,6,7,8,
9,10,11,12};
int base; // 以下三个地址值相同,但类型不同,尺寸不一
printf("%p\n",&arr); // 0012FF18
printf("%p\n",arr); // 0012FF18
printf("%p\n",arr[0]); // 0012FF18
printf("%p\n",&arr[0][0]); // 0012FF18
//取值需要不同级别的解引用
printf("%d\n",**arr); // 1
printf("%d\n",*arr[0]); // 1
printf("%d\n",arr[0][0]); // 1
printf("%p\n",base=(int)&arr[0][0]); // 0012FF18
// +1的偏移值是其类型尺寸的偏移
printf("%d\n",(int)(&arr+1)-base); // 48 sizeof(int)*4*3
printf("%d\n",(int)(arr+1)-base); // 16 sizeof(int)*4
printf("%d\n",(int)(arr[0]+1)-base); // 4 sizeof(int)
printf("%d\n",(int)(&arr[0][0])-base);// 0
一级指针,可以用一维数组名赋值。
而对于多维数组,与多级指针就不存在等价关系了。
对于n维数组,可以直接用一级指针去处理,因为n维数组在内存中也是线性存储的。
另外,n维数组,可以理解为其元素是n-1数组,这样,n维数组就可以用n-1维数组指针来表示。也可以用指针数组(其指针指向一个n-1维数组)来表示。所以从这个意义上说,这是一种降维的处理方式,对于符号“*”与“[]”,不是很严格地可以理解为有一定的等价性:
#include <iostream>
using namespace std;
int main()
{
int arr[3][4] = {
1,2,3,4,
5,6,7,8,
9,10,11,12};
int i,j;
cout<< "1 二维数组下标遍历"<<endl;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++) // 以下四种写法等价
// cout<<arr[i][j]<<"\t";
cout<<*(arr[i]+j)<<"\t";
// cout<<*(*(arr+i)+j)<<"\t";
// cout<<(*(arr+i))[j]<<"\t";
cout<<endl;
}
cout<<"2 二维数组看作线性一维来遍历"<<endl;
for(i=0;i<3*4;i++)
{
cout<<*(*arr+i)<<"\t";
if((i+1)%4==0)
cout<<endl;
}
cout<< "3 数组指针遍历二维数组"<<endl;
int (*ap)[4] = arr; // 行指针ap,指向arr每行的首地址
for(i=0;i<3;i++)
{
for(j=0;j<4;j++) // 以下四种写法等价
cout<<ap[i][j]<<"\t";
//cout<<*(ap[i]+j)<<"\t";
//cout<<*(*(ap+i)+j)<<"\t";
//cout<<(*(ap+i))[j]<<"\t";
cout<<endl;
}
cout<< "4 指针数组遍历二维数组"<<endl;
int* pa[3];
for(i=0;i<3;i++)
pa[i]=arr[i]; // 指针数组的元素是每行的首地址
for(i=0;i<3;i++)
{
for(j=0;j<4;j++) // 以下二种写法等价
cout<<pa[i][j]<<"\t";
cout<<endl;
}
cout<< "5 一级指针遍历二维数组"<<endl;
int* p; // 以下四种写法等价
p = (int*)arr;
p = &arr[0][0];
p = arr[0];
p = *arr;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++) // 以下二种写法等价
cout<<*(p+i*3+j)<<"\t";
//cout<<(p+i*3)[j]<<"\t";
cout<<endl;
}
for(i=0;i<3*4;i++)
{
//cout<<p[i]<<"\t";
cout<<*(p+i)<<"\t";
if((i+1)%4==0)
cout<<endl;
}
while(1);
return 0;
}
数组指针也可以指向一维数组,但写法细节略有区别:
int a[4] = {11,22,33,44};
cout<<&a[0]<<endl; // 一维数组首地址
cout<<a+1<<endl; // +1是偏移一个元素
cout<<&a+1<<endl; // +1是偏移整个数组的长度
int (*p1)[4] = &a;
cout<<(*p1)[2]<<endl; // 33
三维数组的遍历:
#include <iostream>
using namespace std;
int main()
{
int arr[2][3][4] = {0};
int* p = (int*)arr;
int i,j,k;
for(i = 0; i<2*3*4; i++)
*p++ = i+1;
p= arr[0][0]; // p = &arr[0][0][0];
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
for(k=0;k<4;k++) // 以下5种方式等价
//cout<< arr[i][j][k] <<" ";
//cout<< *(arr[i][j]+k) <<" ";
//cout<< *(*(arr[i]+j)+k) <<" ";
//cout<< *(*(*(arr+i)+j)+k) <<" ";
cout<< *(p+i*3*4+j*4+k) <<" ";
cout<<endl;
}
cout<<endl;
}
int (*ap)[3][4] = arr; // 如果将三维数组理解为层、行、列,则ap为层指针,指向每层的首地址
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
for(k=0;k<4;k++) // 以下两种方式等价
//cout<< ap[i][j][k] <<" ";
cout<< *(*(*(ap+i)+j)+k) <<" ";
cout<<endl;
}
cout<<endl;
}
while(1);
return 0;
}
/*
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
21 22 23 24
*/
-End-
上一篇
下一篇