指针的总结
一级指针:可以和如下的内容建立联系
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[]----》元素
&与[]抵消
*与[]等价
复制代码