指针的总结:指针与数组之间的联系

指针的总结

一级指针:可以和如下的内容建立联系

1.变量

int a = 10

int *p = &a;

2.一维数组

char a[10];

char *p = a;

3.二维数组

int a[3][2];

char *p =&a[0][0];

char *p = a[0];

二级指针:可以和如下的内容建立联系

1.一级指针

int a = 10;

char *p = &a;

char **q = &p;

2.指针数组

char *p[3];

char **q;

q = p;

指针数组:可以和如下的内容建立联系

1.二级指针

char *p[3];

char **q;

q = p;

2.二维数组

char a[3][2] = {1,2,3,4,5,6};

char *p[3];

//p = a 错误

p[0] = a[0];

p[1] = a[1];

p[2] = a[2];

就可以把指针数组当成二维数组来访问

数组指针:

1.二维数组

char a[3][2];

char (*p)[2];

p = a;

【1】一级指针和一维数组的关系[可以划等号]

char *p;
int *t;
char arr[10];
char trr[10];
复制代码

p = arr; p = &arr[0]; //p是指针变量而,arr是常量

t = trr; t = &trr[0];

p是指针变量而arr是常量 (?arr=p是错误的)

?如果指针类型相同,并且指针加1移动的大小也相同。
(arr+1和p+1移动的大小是相同的)
此时两者就可以划等号。

*&arr = arr;

**&arr = *arr;//一维数组取地址相当于二维数组,加两个*取到内容

☞如何获取指针类型:
printf("%d,arr");//由于arr和p都是地址,使用%d打印会报错
printf("%d,p"); //编译器报错就会显示类型
//这样打印出来提示的类型是char *

*arr     ===>arr[0]
*arr++   ===>错误 //常量
(*arr)++ ===>arr[0]++;
*p       ===>arr[0]
*p++     ===>arr[0] ,p++
(*p)++   ===>arr[0]++;
复制代码

?arr[i] <==> *(arr+i) <==> *(&arr[0]+i)<===>
p[i] <==> *(p+i) <==> *(&p[0]+i)

//指针+1,移动一个元素,地址+1,在内存上数组的连续的,所以划等号

【2】一级指针和二维数组的关系[不能划等号]

int a[3][2];
int *p;
复制代码
  • //p和a的指针类型不同
  • //p+1移动4字节,a+1移动8个字节
  • //所以两者不能够直接画等号
  • //p = a; 错误的赋值方法

//这样建立关系可以赋值
p = (int *)a;
p = &a[0][0];

p = a[0];

通过指针访问数组的成员

  • *p++; //p指向二维数组的首地址,取出p地址中的值,然后p地址自增1

  • *(p+i);//p指向二维数组的首地址,p+i,哪一个元素的地址,*取地址中的值

  • p[i]; ==》p+i; //p指向二维数组的首地址,一级指针和一维数组是等价的。

?!注意:p[i][j]是错误的//p[i]已经是值了,一级指针和一维数组是等价的

通过指针访问数组的成员的示例代码

#include <stdio.h>
#define ARRAY_SIZE(res) (sizeof(res)/sizeof(res[0][0]))
int main(int argc, const char *argv[])
{
    int i;
    int a[3][2] = {1,2,3,4,5,6};
    int *p;
	
    //p = a;
    //printf("%d\n",p);
    //printf("%d\n",a);
    //p = &a[0][0];
    printf("%d\n",a[0]);
    p = a[0];	
    for(i=0;i<ARRAY_SIZE(a);i++){
        printf("%d\t",*p++);
}
    puts("");
    puts("*********************************");
    p = &a[0][0];//注意这里,每次都重新赋值,因为指针的移动(p++)

for(i=0;i<ARRAY_SIZE(a);i++){
    printf("%d\t",*(p+i));
}
puts("");
puts("*********************************");

p = &a[0][0];
for(i=0;i<ARRAY_SIZE(a);i++){
    printf("%d\t",p[i]);
}
puts("");
puts("*********************************");

return 0;
}
复制代码

通过数组名来访问成员

  • a[i][j] //二维数组的正常访问形式
  • *(a[i]+j)//a[i]:代表的是行地址,行地址加1移动的是一个元素,
    //*从这个元素地址中取出值
  • ((a+i)+j)//a是二维数组的首地址,(a+i)代表的是第几行的地址
    //
    (a+i)+j :代表的是第i行,第j列的地址
    //((a+i)+j):从这个地址中取值
    //a是二维数组,前面取*相当于一维数组
  • (&a[0][0]+(i2)+j)//&a[0][0]第0个元素的地址,加1代表移动一个元素
    // 找到这个元素的地址之后,在前面加*代表从地址
    //中取值。这里的2是指数组定义时的列数

(*(a+i))[j]

?行[二维]----{*or[]}----》列[一维]----*or[]----》元素
	&与[]抵消
	*与[]等价
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享