C 语言 - 指针与数组
指针和数组
您还可以使用指针来访问数组。
请思考以下整数数组:
实例
int myNumbers[4] = {25, 50, 75, 100};
在数组章节中,你学习了如何使用 for 循环遍历数组元素:
实例
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++) {
printf("%d\n", myNumbers[i]);
}
结果:
25 50 75 100
现在,我们不打印每个数组元素的值,而是打印每个数组元素的内存地址:
实例
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++) {
printf("%p\n", &myNumbers[i]);
}
结果:
0x7ffe70f9d8f0 0x7ffe70f9d8f4 0x7ffe70f9d8f8 0x7ffe70f9d8fc
请注意,每个元素的内存地址的最后一部分是不同的,增加了 4。
这是因为 int 类型的大小通常为 4 个字节,请记住:
实例
// 创建一个 int 变量
int myInt;
// 获取 int 的内存大小
printf("%lu", sizeof(myInt));
结果:
4
因此,从上面的“内存地址示例”中,你可以看到编译器为每个数组元素保留了 4 字节的内存,这意味着整个数组占用了 16 字节(4 * 4)的内存存储:
实例
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 数组的大小
printf("%lu", sizeof(myNumbers));
结果:
16
指针与数组有何关系
那么,指针和数组之间有什么关系呢?在 C 语言中,数组的名称实际上是指向数组第一个元素的指针。
困惑了吗?让我们更好地理解一下,并再次使用上面的“内存地址示例”。
第一个元素的内存地址与数组的名称相同:
实例
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 数组的内存地址
printf("%p\n", myNumbers);
// 获取第一个数组元素的内存地址
printf("%p\n", &myNumbers[0]);
结果:
0x7ffe70f9d8f0 0x7ffe70f9d8f0
这基本上意味着我们可以通过指针来处理数组!
如何操作?由于 myNumbers 是指向 myNumbers 中第一个元素的指针,你可以使用 * 运算符来访问它:
实例
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 中第一个元素的值
printf("%d", *myNumbers);
结果:
25
要访问 myNumbers 中的其余元素,您可以递增指针/数组(+1、+2 等):
实例
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 中第二个元素的值
printf("%d\n", *(myNumbers + 1));
// 获取 myNumbers 中第三个元素的值
printf("%d", *(myNumbers + 2));
// and so on..
结果:
50 75
或者遍历它:
实例
int myNumbers[4] = {25, 50, 75, 100};
int *ptr = myNumbers;
int i;
for (i = 0; i < 4; i++) {
printf("%d\n", *(ptr + i));
}
结果:
25 50 75 100
还可以使用指针更改数组元素的值:
实例
int myNumbers[4] = {25, 50, 75, 100};
// 将第一个元素的值更改为 13
*myNumbers = 13;
// 将第二个元素的值更改为 17
*(myNumbers +1) = 17;
// 获取第一个元素的值
printf("%d\n", *myNumbers);
// 获取第二个元素的值
printf("%d\n", *(myNumbers + 1));
结果:
13 17