1. 使用指针访问数组
指针的加减运算可以用来在内存中移动指针的地址。加上一个整数 `n`,实际上就是移动了 `n` 个步长字节。步长是由指针指向的数据类型决定的。
例如,假设有一个 `int` 类型的指针 `p`:
int *p = (int *)100;
那么,执行 `p + 1` 后,指针地址会向后移动 `sizeof(int)` 字节(通常是4字节),即地址变为104。同样,执行 `p - 1` 后,指针地址会向前移动4字节,变为96。
这种加减运算对于访问在内存中连续排布的数据(比如数组)非常方便。
2. 使用第一个元素获取数组首地址
我们已经学会了使用下标访问数组元素:
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
printf("%d\n", arr[0]);
printf("%d\n", arr[1]);
printf("%d\n", arr[2]);
printf("%d\n", arr[3]);
printf("%d\n", arr[4]);
return 0;
}
既然数组元素在内存中是连续排布的,第一个元素的地址就是整个数组的首地址。我们可以用取地址运算符 `&` 来获取第一个元素的地址:
int *p = &arr[0]; // 从第一个元素获取数组首地址
然后使用指针进行操作:
```
p; // 指向第一个元素
p + 1; // 指向第二个元素
p + 2; // 指向第三个元素
p + 3; // 指向第四个元素
p + 4; // 指向第五个元素
```
通过取值运算符 `*`,可以访问或修改目标数据对象:
```
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
int *p = &arr[0];
printf("%d\n", *p); // 第一个元素
printf("%d\n", *(p + 1)); // 第二个元素
printf("%d\n", *(p + 2)); // 第三个元素
printf("%d\n", *(p + 3)); // 第四个元素
printf("%d\n", *(p + 4)); // 第五个元素
return 0;
}
```
注意,表达式 `p + 1` 必须先用括号包裹起来,然后再用取值运算符 `*`。这是因为 `*` 的优先级高于加法运算符:
```
*(p + 1) // 正确
*p + 1 // 错误,这会对指针解引用的值再加1
```
3. 使用数组名获取数组首地址
我们还可以通过数组名直接获取数组的首地址:
```
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
printf("arr = %u\n", arr);
printf("&arr[0] = %u\n", &arr[0]);
return 0;
}
```
`arr` 和 `&arr[0]` 都表示数组的首地址,那么我们可以直接将 `arr` 赋值给指针:
```
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
int *p = arr;
printf("%d\n", *p); // 第一个元素
printf("%d\n", *(p + 1)); // 第二个元素
printf("%d\n", *(p + 2)); // 第三个元素
printf("%d\n", *(p + 3)); // 第四个元素
printf("%d\n", *(p + 4)); // 第五个元素
return 0;
}
```
虽然这些操作成功了,但这并不意味着数组名是一个指针。我们通过 `sizeof` 可以验证这一点:
```
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
int *p = arr;
printf("sizeof arr = %d\n", sizeof(arr)); // 输出20
printf("sizeof p = %d\n", sizeof(p)); // 输出4(假设是32位系统)
printf("sizeof arr + 1 = %d\n", sizeof(arr + 1)); //输出4
return 0;
}
```
数组名 `arr` 在代码中使用时,会被转换为指向数组第一个元素的指针。但在以下两种情况下不会:
1. 对数组名使用 `sizeof` 操作。
2. 对数组名使用 `&` 操作。
4. 使用指针访问数组等价于下标访问
通过下面的例子,我们可以看到使用指针访问数组和使用下标访问数组是等价的:
```
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
printf("%d\n", arr[0]); // 第一个元素
printf("%d\n", arr[1]); // 第二个元素
printf("%d\n", arr[2]); // 第三个元素
printf("%d\n", arr[3]); // 第四个元素
printf("%d\n", arr[4]); // 第五个元素
printf("%d\n", *arr); // 第一个元素
printf("%d\n", *(arr + 1)); // 第二个元素
printf("%d\n", *(arr + 2)); // 第三个元素
printf("%d\n", *(arr + 3)); // 第四个元素
printf("%d\n", *(arr + 4)); // 第五个元素
return 0;
}
```
`arr[k]` 实际上会被编译器解读为 `*(arr + k)`。我们通过一个小测试来验证这个规则:
```
#include <stdio.h>
int main() {
int arr[5] = {111, 222, 333, 444, 555};
printf("arr[2] = %d\n", arr[2]);
printf("2[arr] = %d\n", 2[arr]);
printf("*(arr + 2) = %d\n", *(arr + 2));
return 0;
}
```
运行结果验证了 `arr[2]` 和 `2[arr]` 是等价的,都是访问数组的第三个元素。
总结起来,我们学会了两种访问数组的方法:
1. `数组名[下标]`
2. `*(数组名 + 偏移量)`
这两种方式在功能上是完全等价的。
标签:arr,数组,int,元素,应用,printf,指针 From: https://blog.csdn.net/fang_xuan_xiang/article/details/141190700