了解了关于指针的基本内容后,针对于指针的高级内容,比如说指针数组和数组指针是经常容易混淆的两个概念,下面我就跟大家简单的介绍关于这两个概念的理解与记忆。
要想了解指针数组和数组指针这两个概念,那就得先来看一下指针和数组之间一些说不清的关系。
1. 指针与一维数组:直接上例子
举例:打印数组的内容:
Int a[4] = {1,2,3,4}, i;
Int *p = a;
For(I = 0; I < 4; i++)
{
Printf(“a[%d]=%d”, I, a[i]);
Printf(“a[%d]=%d”, I, *(p+i));//解释:p指针指向了数组a,数组是连续的地址,在前面的内容中学到,p+i是指向地址大的方向移动i个数据,p+I ==&a[i]
Printf(“a[%d]=%d”, I, p[i]);
Printf(“a[%d]=%d”, I, *(a+i));
}
举例:那打印数组的地址呢??
注意:从上面的例子可以看出:
数组的内容:a[i] == p[i] == *(p+i) == *(a+i)
数组的地址:&a[i] == &p[i] == p+I == a+i
在这里很多人可能会想指针与数组好像没有多大的区别,数组可以用指针来代替,但实际上两者之间存在一个本质的区别,那就是:数组名它是一个地址常量,指针是指针变量。
如: int a[3] = {1,2,3}, *p = a;
Printf(“%p\n”, p++);
Printf(“%p\n”, a++);//错:a++ a=a+1,a是地址常量,常量是不能被赋值的
Printf(“%p\n”, a+1);//对:a+1并没有进行赋值运算
2. 指针与二维数组:
对二维数组的理解:可以把二维数组看作由多个一维数组组成,如int a[2][3],可以理解成两个一维数组:a[0](是一个一维数组名,包含三个元素a[0][0]\a[0][1]\a[0][2])和a[1](包含三个元素:a[1][0]\a[1][1]\a[1][2])
思考:
1. 数组int a[2][3],如何表达第二行第二列元素的地址?
&a[1][1]、&a[1][0]+1、a[1]+1、*(a+1)+1
2. 数组int a[2][3],如何表达第二行第二列元素的元素?
a[1][1]、*(&a[1][0]+1)、*(a[1]+1)、*(*(a+1)+1)
到目前为止只是二维数组的一个相应操作,那把二维数组和指针牵扯上关系后会怎么样呢??接下来看我们的指针数组和数组指针。
注意:
数组的内容:a[i][j] == *(a[i]+j) == *(*(a+i)+j)
数组的地址:&a[i][j] == a[i]+j == *(a+i)+j
3. 指针数组:数组,指由若干个具有相同存储类型和数据类型的指针变量构成的集合,数组的元素是指针的数组。
形式:<存储类型> <数据类型> *<指针变量数组名>[<数组大小>];
int *p[3];
举例:
int a[2][3] = {{1,2,3},{4,5,6}};
int *p[2] = {a[0], a[1]}, i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
//printf("&a[%d][%d]=%p ", i, j, &a[i][j]);
//printf("&a[%d][%d]=%p ", i, j, a[i] +j);
//printf("&a[%d][%d]=%p ", i, j, *(a+i)+j);
//printf("&a[%d][%d]=%p ", i, j, &p[i][j]);
//printf("&a[%d][%d]=%p ", i, j, p[i]+j);
printf("&a[%d][%d]=%p ", i, j, *(p+i)+j);
}
}
putchar(10);
注意:
地址:&a[i][j] <==> a[i] + j <==> *(a+i) + j <==> *(p+i)+j <==> p[i] + j <==>&p[i][j]
内容:a[i][j] <==> *(a[i] + j) <==> *(*(a+i) + j) <==> *(*(p+i)+j) <==> *(p[i] + j) <==>p[i][j]
4. 数组指针:指针,指向数组的指针,指向特定位数数组的指针(指向一个有三个int 型元素数组的指针,指针加一,指针偏移12个字节)
形式:<存储类型> <数据类型> *<指针变量数组名>[<数组大小>];
int (*p)[3];
1) 指向一维的:
如:int a[4] int [4]a INT a
Int (*p)[4] int [4](*p) INT (*p)
所以等价关系为:p = &a
举例:
Int a[4] = {1,2,3,4};
Int (*p)[4], i;
P = &a;
For(I = 0; I < 4;i++)
{
Printf(“%d\n”, (*p)[i]);
Printf(“%d\n”, *((*p)+i));
Printf(“%p\n”, (*p)+i);
}
注意:
地址:(*p)+i
内容:*((*p)+i)、(*p)[i]
2) 指向二维的:
如:int a[3][4] int [4] a[3] INT [4] a[3]
Int (*p)[4] int [4] (*p) INT [4] (*p)
所以等价关系为:p = a
举例:
int a[3][4] = {11,22,33,44,55,66,77,88,99,100,110,120};
int (*p)[4] = a;
int i = 0,j = 0;
for(i = 0;i < 3;i++)
{
for(j = 0;j < 4;j++)
{
//printf("%d ",p[i][j]);
//printf("%d ",*(p[i] + j));
printf("%d ",*(*(p + i) + j));
}
putchar(10);
}
以上便是我对于指针数组和数组指针的理解,希望能够对读者有所帮助!