指针与数组的连接
int main()
{
int a[5] = {1,2,3,4,5};
int *p1,*p2,*p3;
// 因为 a 本身就代表了数组的地址,所以此处,& 必须省略
p1 = a;
p2 = &a[0];
p3 = &a[3];
printf("%p,%p,%p\n",p1,p2,p3); //000000000062FDF0,000000000062FDF0,000000000062FDFC
}
- p 的地址就是数组 a 的地址,就是 a[0]的地址
int main()
{
int a[5] = {1,2,3,4,5};
int *p;
p = a;
printf("%d,%d,%d\n",p,a,&a[0]); //6487552,6487552,6487552
return 0;
}
指针的算术运算
int main()
{
int a[10],*p;
// 用指针指向数组第一项的地址
p = &a[0];
*p = 5;
p[1] = 6;
printf("%d\n",a[0]); //5
printf("%d\n",a[1]); //6
}
指针的算术运算包括
- 指针加上整数
- 指针减去整数
- 两个指针相减
// 指针加
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p,*q;
p = &a[0];
// 将 p 后移三位的地址赋给 q
q = p+3;
// p 后移六位
// 注意加不能超过数组的长度,否则出现不可预知的值
p += 6;
printf("p指向的值:%d,q指向的值:%d\n",*p,*q);
return 0;
}
// 指针减
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p,*q;
p = &a[10];
q = p-3;
p -= 6;
printf("p指向的值:%d,q指向的值:%d\n",*p,*q);
return 0;
}
// 输出
p指向的值:5,q指向的值:8
// 指针相减,表示指针间的距离,也是数组元素中的个数
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p,*q;
p = &a[10];
q = &a[0];
printf("p-q:%d\n",p-q);
return 0;
}
// 输出
p-q:10
note
- 只有指针指向同一数组时才有意义
指针用于数组处理
#include <stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p;
for(p = &a[0];p<&a[10];p++)
{
printf("%d ",*p);
}
return 0;
}
// 输出
1 2 3 4 5 6 7 8 9 10
* 和 ++ 运算符结合
#include <stdio.h>
int main()
{
int a[10]={0};
int *p;
int i=0;
for(p = &a[0];p<&a[10];)
{
// 相当于 *(p++) ,也就是先对 p 移动位置,在取 p 值做加法运算
*p++ = i;
i++;
}
for(p = &a[0];p<&a[10];p++)
{
printf("%d ",*p);
}
return 0;
}
// 输出
0 1 2 3 4 5 6 7 8 9
用数组名作为指针
- 数组名作为指向数组的第一个元素的指针
如,a+i = &a[i],*(a+1) = a[i]
#include <stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p;
printf("a的值:%d\n",*a);
printf("a的地址:%d",a);
return 0;
}
// 输出
a的值:1
a的地址:6684144
// 用指针作为数组名
#include <stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p;
p = a;
printf("a的值:%d\n",*p);
printf("a的地址:%d",p);
return 0;
}
// 输出
a的值:1
a的地址:6684144
指针和多维数组
// 方式一:嵌套循环
int main(){
int row,col;
int a[5][5] = {
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25},
};
for(row=0;row<5;row++){
for(col=0;col<5;col++){
a[row][col]=0;
}
};
printf("%d\n",a[0][0]); // 可以看到值已经被修改成 0 了
}
// 方式二:模拟成一维数组
int row,col;
int a[5][5] = {
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25},
};
// 二维数组在用指针指向的时候,不能写成 int *p = a 的形式
// 只有一维的时候才可以这样
int *p = &a[0][0];
for(;p<&a[4][4];p++){
*p=0;
}
printf("%d\n",a[0][0]); // 可以看到值已经被修改成 0 了
【注】二维数组在用指针指向的时候,不能写成 int *p = a 的形式。只有一维的时候才可以这样
处理多维数组的行
想要让指针定位到某一样,我们可以这样写
p=&a[i][0]
或者p=a[i]
int row,col;
int a[5][5] = {
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25},
};
printf("%d",a[1][0]) ;
int (*p)[5] = a;
printf("%d,%d\n",p[0][0],**a);
指针数组和数组指针
指针数组,首先是一个数组,数组的元素都是指针,
int *p1[10]
,因为 [] 优先级高,则说明是先 p1[10],再 *- 数组指针,首先是一个指针,一个指针指向数组,
int (*p1)[10]
,因为()优先级高,所以是先指针,再数组
- 关于 a 和 &a
&a 是整个数组的首地址,a 是数组首元素的首地址,值相同但意义不同,但是 = 两边需要数据类型必须一致,所以不要误用