参考带有注释的行:
该示例打印“one”,然后打印垃圾。
#include <iostream>
int main() {
const char* a[3] = { "one", "two", "three" };
const char*(*p)[3] = &a;
for(int i = 0; i < 3; i++) {
std::cout << *p[i] << std::endl; // this line
}
return 0;
}
改成这样后就可以工作了:
std::cout << (*p)[i] << std::endl;
p
是一个指向 3 个元素的数组的指针,如下所示:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ p
请注意,它指向整个数组,而不是其中的单个元素。
表达方式*p[i]
被视为*(p[i])
由于运算符优先级(相当于*(*(p + i))
)。这意味着您正在索引指向数组的指针。如果你这样做p[1]
,例如,您将指针移动到“下一个”数组并尝试取消引用它:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ p + 1
正如我们所看到的,那里什么也没有,你会得到未定义的行为。然而,当你这样做时(*p)[i]
(相当于*((*p) + i)
),您要确保首先发生取消引用。取消引用为我们提供了数组本身,然后可以通过数组到指针的转换将其隐式转换为指向数组第一个元素的指针。所以你得到的是:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ *p
在这种情况下,指针指向数组element而不是整个数组。例如,如果您随后建立索引,(*p)[1]
, 你会得到:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ (*p) + 1
这给你一个有效的const char*
然后可以通过以下方式输出cout
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)