指针与数组的结合
示例 1:指针访问数组元素
通过==指针访问数组元素=的例子:
#include <stdio.h>
int main() {
int arr[5] = {1,2,3,4,5};
//int *p1 = &arr;
int *p1 = (int *)&arr; // 需要强制类型转换
int *p2 = arr;
printf("*p1:%d\n", *(p1 + 1)); // 应该是访问第二个元素
printf("*p2:%d\n", *(p2 + 1)); // 应该是访问第二个元素
return 0;
}
p1
被初始化为数组的地址,但是由于没有进行强制类型转换,这里会有一个编译警告。通过(int *)&arr
进行强制类型转换可以解决这个问题。p2
被初始化为数组的第一个元素的地址。
示例 2:指针访问数组中的不同元素
通过指针访问数组中的不同元素:
#include <stdio.h>
int main() {
int arr[5] = {1,2,3,4,5};
int *p2 = &arr[2];
printf("*p2-1:%d\n", *(p2 - 1)); // 访问第二个元素
printf("*p2:%d\n", *p2); // 访问第三个元素
printf("*p2+1:%d\n", *(p2 + 1)); // 访问第四个元素
return 0;
}
p2
被初始化为指向数组的第三个元素。通过指针加减运算可以访问数组中的上一个和下一个元素。
示例 3:数组指针
数组指针: 专门用来指向一个数组的指针的例子:
#include <stdio.h>
int main() {
int arr[5] = {1,2,3,4,5};
int (*p)[5] = &arr;//定义一个 名为p 的指针,并且确定他指向的类型为int [5] ,一个拥有5个元素的整型数组
//注意 []的优先级大于*,所以会有括号将*p括起来
printf("arr:%p\n", &arr);
printf("%p---%d\n", p, (*p)[2]); // 访问第三个元素
printf("%p---%d\n", p + 1, (*(p + 1))[2]); // 已经越界访问
return 0;
}
p
是一个指向整型数组的指针,这个数组有 5 个元素。p+1
实际上会跳过整个数组,导致越界访问。–>实际上是加一个p的类型,由于p是一个整型数组[5],所以会越界。
示例 4:指针数组
指针数组:专门用来存放指针的数组,称为指针数组
#include <stdio.h>
int main() {
int a = 100;
int b = 250;
int c = 550;
int d = 256;
int e = 998;
int *p[5] = {&a, &b, &c, &d, &e}; // 定义一个名字为 p 的数组,数组中存放的是 int 型指针
for (size_t i = 0; i < 5; i++) {
printf("*p[%ld]:%d \n", i, *(p[i])); // 访问指针数组中的每个指针指向的值
}
return 0;
}
p
是一个指针数组,每个元素都是一个指向整型数据的指针。- 通过
*(p[i])
可以访问每个指针指向的值。
注意事项:
- 指针的类型决定了指针运算时的步长,
int *
类型的指针步长为 4 字节(在 32 位系统中),double *
类型的指针步长为 8 字节。 - 数组指针和指针数组是两个不同的概念。数组指针指向一个数组,指针数组是一个数组,数组的元素是指针。
- 指针运算时要确保不越界访问,否则会导致不可预测的行为甚至崩溃。