2013-12-08 94 views
6

C++ 11代碼:C&C++:數組的指針和地址有什麼區別?

int a[3]; 
auto b = a;  // b is of type int* 
auto c = &a;  // c is of type int(*)[1] 

的C代碼:

int a[3]; 
int *b = a; 
int (*c)[3] = &a; 

b的和c的值是相同的。

bc有什麼區別?他們爲什麼不是同一類型?

更新:我改變了數組大小爲1〜3

+0

'auto'不能很好的使用指針,這種類型通常是不可信的。 – user2485710

+1

@ user2485710你能詳細說明一下嗎?任何參考/引用? – Domi

+0

'auto'在指針下工作得很好,不知道你有什麼想法。 –

回答

7

sizeof經營者應不同的表現,爲一體,特別是如果你改變a申報到不同數量的整數,如int a[7]

int main() 
{ 
    int a[7]; 

    auto b = a; 
    auto c = &a; 

    std::cout << sizeof(*b) << std::endl; // outputs sizeof(int) 
    std::cout << sizeof(*c) << std::endl; // outputs sizeof(int[7]) 

    return 0; 
} 

對於我來說,這個打印:

4 
28 

這是因爲兩個指針是非常不同的類型。一個是指向整數的指針,另一個是指向7個整數數組的指針。

第二個確實有指針數組類型。如果你取消引用它,當然,在大多數情況下它將會是decay to a pointer,但它實際上並不是指向int的指針。第一個是指向int的指針,因爲衰減發生在賦值處。

其它地方它會顯示是,如果你真的有指針到數組類型的兩個變量,並試圖分配一個到另一個:

int main() 
{ 
    int a[7]; 
    int b[9]; 

    auto aa = &a; 
    auto bb = &b; 

    aa = bb; 

    return 0; 
} 

這贏得了我的錯誤消息:

xx.cpp: In function ‘int main()’: 
xx.cpp:14:8: error: cannot convert ‘int (*)[9]’ to ‘int (*)[7]’ in assignment 
    aa = bb; 

該實施例,然而,工,因爲訪問bb允許其衰減到指針到INT:

int main() 
{ 
    int a; 
    int b[9]; 

    auto aa = &a; 
    auto bb = &b; 

    aa = *bb; 

    return 0; 
} 

請注意,衰減不會發生在任務的左側。這不起作用:

int main() 
{ 
    int a[7]; 
    int b[9]; 

    auto aa = &a; 
    auto bb = &b; 

    *aa = *bb; 

    return 0; 
} 

它賺你:

xx2.cpp: In function ‘int main()’: 
xx2.cpp:14:9: error: incompatible types in assignment of ‘int [9]’ to ‘int [7]’ 
    *aa = *bb; 
+0

'sizeof'也會丟棄'const'部分爲你的第二''cout'''變量。這就是爲什麼他們會產生相同的輸出。 – user2485710

+0

@ user2485710:什麼導致相同的輸出?我的兩條'cout'線輸出兩個不同的數字。 'const'根本不會出現在圖片中。我無法將您的評論與我的帖子中的任何內容對齊。 –

+0

很棒的回答。突出一大堆我以前沒有想過的概念!我可能應該更頻繁地使用數組類型來支持指針類型! – Domi

6

在C++中的任何對象的身份由其類型及其地址確定。

在你的例子中,有兩個不同的對象具有相同的地址:數組本身和數組的第一個元素。第一種是int[1],第二種是int。如果一個對象是另一個對象的子對象,那麼兩個不同的對象可以具有相同的地址,就像數組元素,類成員和類基類子對象一樣。

如果你寫你的例子會比較清楚:

int a[5]; 
int (*ptr_to_array)[5] = &a; 
int * ptr_to_array_element = &a[0]; 

但你已經採取的,對於陣列的ID表達a衰變到一個指向數組的第一個元素的事實優勢,所以a有在您的上下文中與&a[0]的值相同。

+0

謝謝!我在你的代碼中添加了一個稍微修改過的版本。 – Domi

1

考慮這個例子:

#include<stdio.h> 

int main() 
{ 
    int myArray[10][10][10][10]; //A 4 Dimentional array; 

    //THESE WILL ALL PRINT THE SAME VALUE 
    printf("%d, %d, %d, %d, %d\n", 
      myArray, 
      myArray[0], 
      myArray[0][0], 
      myArray[0][0][0], 
      &myArray[0][0][0][0] 
     ); 

    //NOW SEE WHAT VALUES YOU GET AFTER ADDING 1 TO EACH OF THESE POINTERS 
    printf("%d, %d, %d, %d, %d\n", 
      myArray+1, 
      myArray[0]+1, 
      myArray[0][0]+1, 
      myArray[0][0][0]+1, 
      &myArray[0][0][0][0]+1 
     ); 
} 

你會發現,在第一種情況下打印所有5個值都相等。因爲他們指向相同的初始位置。

但是當你將它們加1時,你會發現不同的指針現在跳到(指向)不同的位置。這是因爲myArray[0][0][0] + 1將跳過40個字節的10個整數值,而myArray[0][0] + 1將跳過100個整數值,即400個字節。同樣myArray[0] + 1跳轉1000個整數值或4000個字節。

所以這個值取決於你指的的的水平。

但現在,如果我用指針來指代所有的人:

#include<stdio.h> 

int main() 
{ 
    int myArray[10][10][10][10]; //A 4 Dimentional array; 

      int * ptr1 = myArray[10][10][10]; 
      int ** ptr2 = myArray[10][10]; 
      int *** ptr3 = myArray[10]; 
      int **** ptr4 = myArray; 

    //THESE WILL ALL PRINT THE SAME VALUE 
    printf("%u, %u, %u, %u\n", ptr1, ptr2, ptr3, ptr4); 

    //THESE ALSO PRINT SAME VALUES!! 
    printf("%d, %d, %d, %d\n",ptr1+1,ptr2+1,ptr3+1,ptr4+1); 
} 

所以你看,不同層次的指針變量的不規矩數組變量的方式做。