2013-04-15 63 views
5

參考線與評論:取消引用指向數組的指針?

  • 爲什麼在例如工作將括號打印陣列的所有內容?

該示例打印「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; 

回答

16

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輸出。

+0

很好的答案。我沒有意識到增加我會嘗試解引用另一個整個數組,但我知道運算符的優先級。我必須堅持數組作爲指針的思維。 – thelittlegumnut

2

Operator precedence

陣列選擇比解引用的優先級高,所以從編譯器點這真是:

*(p[i]) 
6

Operator precedence.沒有()操作[]將被稱爲第一,它的結果將是dereferenced。與() - 首先將dereference,然後致電運營商[]

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 
+0

輸出上面的代碼 –

+0

歡迎來到Stack Overflow,@ankitgupta。由於問題和答案被保存並作爲一種資源來幫助不僅個人提出問題,包含對代碼如何/爲何解決提問者問題的解釋很有用。您可以編輯您的答案以包含更多信息。您可能想要查看:https://stackoverflow.com/help/how-to-answer – Degan

+0

上面的代碼將幫助您瞭解編譯器內部處理數組的方式。 –