参考评论这一行:
该示例打印“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;
答案 0 :(得分:20)
p
是一个指向3个元素数组的指针,如下所示:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ p
请注意,它指向整个数组,而不是指向它的单个元素。
由于运算符优先级(相当于*p[i]
),表达式*(p[i])
被视为*(*(p + i))
。这意味着您正在索引指向数组的指针。例如,如果你执行p[1]
,则将指针移到“下一个”数组并尝试取消引用它:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ p + 1
正如我们所看到的,那里什么都没有,你会得到未定义的行为。但是,当您执行(*p)[i]
(相当于*((*p) + i)
)时,您确定首先发生取消引用。取消引用为我们提供了数组本身,然后可以通过数组到指针的转换将其隐式转换为指向数组第一个元素的指针。所以你得到的是:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ *p
在这种情况下,指针指向数组元素而不是整个数组。然后,如果您编入索引,例如(*p)[1]
,您将获得:
┌─────┬─────┬─────┐
│ │ │ │
└─────┴─────┴─────┘
^
└─ (*p) + 1
这会为您提供有效的const char*
,然后可以cout
输出。
答案 1 :(得分:6)
Operator precedence.首先调用()
运算符[]
,其结果为dereferenced
。使用()
- 首先是dereference
,然后拨打运营商[]
。
答案 2 :(得分:2)
答案 3 :(得分:1)
#include <iostream>
using namespace std;
int main() {
int arr[5] = {1,2,3,4,5};
int *p=arr;
int intgerSize=sizeof(int);
for(int k=0;k<5;k++)
{
cout<<"arr ["<<k<<"] "<<*(p+(k*sizeof(int)/intgerSize));
cout<<" "<<(p+(k*sizeof(int)/intgerSize));
cout<<" "<<p+k<<"\n";
}`enter code here`
return 0;
}
OUTPUT:-
arr [0] 1 0x7ffd180f5800 0x7ffd180f5800
arr [1] 2 0x7ffd180f5804 0x7ffd180f5804
arr [2] 3 0x7ffd180f5808 0x7ffd180f5808
arr [3] 4 0x7ffd180f580c 0x7ffd180f580c
arr [4] 5 0x7ffd180f5810 0x7ffd180f5810