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 字节,请记住
所以从上面的“内存地址示例”中,你可以看到编译器为每个数组元素保留 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));
// 等等..
结果
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
这种处理数组的方式可能看起来有点过分。尤其是在上面的示例中,数组比较简单。但是,对于大型数组,使用指针来访问和操作数组可能效率更高。
使用指针访问 二维数组 也被认为更快、更容易。
由于字符串实际上是数组,你也可以使用指针来访问 字符串。
目前,了解它的工作原理非常重要。但是正如我们在上一章中所述;指针必须小心处理,因为有可能覆盖存储在内存中的其他数据。