一、指针数组
1.指针数组就是数组元素是指针类型的数组.
可以看出,这些地址都是连续的,因为是int型数组,所以每个地址相差4个字节。
2.指针也可以进行加减运算,但指针的加减不是数值上的加减,它表示加或减该指针指向的数据类型的字节数,比如:
3.二维指针数组
#include<stdio.h>
#include<windows.h>
int main()
{
int *p[3][3];
int a[3][3]={1,2,3,4,5,6,7,8,9};
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
p[i][j]=&a[i][j];
printf("p[%d][%d]=%d ",i,j,p[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
可以看出,二维数组的内存分配也是连续的。
#include<stdio.h>
#include<windows.h>
int main()
{
int *p;
int a[3][3]={1,4,6,78,3,2,78,5,0};
int i,j;
p=&a[0][0];//取二维数组的首地址
for(i=0;i<9;i++)
{
printf("*(p+%d):%d",i,*(p+i));//由于地址是连续的,每次指针加1,偏移一个数组成员的大小
printf("\n");
}
system("pause");
return 0;
}
二、数组指针:一个直指向数组的指针。
int (*p)[3]=NULL;//表示一个指向有三个元素的int型数组的指针
#include<stdio.h>
#include<windows.h>
int main()
{
int a[3][3]={1,3,5,7,9,11,13,15,17};
int (*p)[3];//定义数组指针
int i,j;
p=a;//把a的首地址赋给p
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("%d ",*(*(p+i)+j));//p+i是每行的行地址,*(p+i)是每行的首元素的地址,*(p+i)+j是每行第几列的地址,也就是每个元素的地址
}
printf("\n");
}
system("pause");
return 0;
}
为了更好的理解有如下代码:
#include<stdio.h>
#include<windows.h>
int main()
{
int i,j;
int a[3][3]={1,3,5,7,9,12,15,13,11};
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("%d ",&a[i][j]);
}
printf("\n");
}
printf("a:%d a+1:%d a+2:%d\n",a,a+1,a+2);//每行的首地址
printf("*a:%d *(a+1):%d *(a+2):%d\n",*a,*(a+1),*(a+2));//每行首元素的地址
printf("*a+1:%d *(a+1)+1:%d\n",*a+1,*(a+1)+1);//行地址加1和元素地址加1不同
printf("**a:%d *(*(a+1)):%d *(*a+1):%d\n",**a,*(*(a+1)+1),*(*a+1));//输出元素的值,通过两次解引用
system("pause");
return 0;
}
对于以上可以总结出,对于二维数组名可以理解为指向指针的指针,计算机在处理二维数组时是以一维数组为基本单位来处理,可以理解为计算机不能直接看到数组的某个元素,它只知道这个二维数组有几个一维数组组成,即上面的数组名a表示第一行的行地址,所以行地址和某行数组元素的首地址虽然数值上相同但意义完全不同。
而对于数组指针,比如(*p)[3],它是一个指针,指向一个一维数组,所以赋值时就用该赋行地址比如:
int a[3][3];
int (*p)[3];
p=a;//a表示行地址,所以可以这样赋值
p=&a//错误的赋值,&a表示数组整体的地址,与一维数组指针不兼容就会报错
int a[3];
int (*p)[3];
p=&a;//&a表示一维数组整体的地址可以赋给一维数组指针
p=a;//赋值错误,此时a表示首元素的地址,与一维数组指针兼容,会报错
以上就是我对数组指针和指针数组的一些看法。