8

参考带有注释的行:

  • 为什么在示例中添加括号可以打印数组的所有内容?

该示例打印“一”,然后打印垃圾。

#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;
4

4 回答 4

22

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.

于 2013-04-15T11:03:23.630 回答
6

运算符优先级。如果没有()运算符[],将首先调用它的结果dereferenced。使用()- 首先将是dereference然后调用操作员[]

于 2013-04-15T11:00:15.810 回答
3

运算符优先级

数组选择的优先级高于取消引用,因此从编译器的角度来看,它实际上是:

*(p[i])
于 2013-04-15T11:00:15.353 回答
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
于 2017-09-12T17:42:08.190 回答