参考评论这一行:
该示例打印“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],则将指针移动到“next”数组并尝试取消引用它:
┌─────┬─────┬─────┐ │ │ │ │ └─────┴─────┴─────┘ ^ └─ p + 1
我们可以看到,那里什么都没有,你会得到未定义的行为.但是,当您执行(* p)[i](相当于*((* p)i))时,您确保首先发生取消引用.取消引用为我们提供了数组本身,然后可以通过数组到指针的转换将其隐式转换为指向数组第一个元素的指针.所以你得到的是:
┌─────┬─────┬─────┐ │ │ │ │ └─────┴─────┴─────┘ ^ └─ *p
在这种情况下,指针指向数组元素而不是整个数组.如果你然后索引,例如,(* p)[1],你会得到:
┌─────┬─────┬─────┐ │ │ │ │ └─────┴─────┴─────┘ ^ └─ (*p) + 1
这给你一个有效的const char *然后可以由cout输出.