2017-01-04 321 views
3

如何解釋以下代碼行?指向C中數組的指針

int (*arrayABC)[10]; 

在我的教科書中,它說我們有一個指向指向整數數組的第0個元素的指針。

但是,我不太明白這一點。

我的解釋:我們有一些變量,它的值是某個地址。這個地址就是UNNAMED整型數組的第0個元素的地址。基本上我們有一個指向第0個元素的指針。

爲什麼然後要有一個指針指向一個指針?

+0

誠然,它不會已經足以回答你的問題,但是當你有一個C聲明麻煩, [Cdecl](http://cdecl.org/)總是一個很好的起點。無論如何,它是什麼教科書? –

+0

請注意,有一個指向指針的指針有時是好的和有用的。然而,正如答案所解釋的那樣,這不是你的例子。 –

+0

@FabioTurati鏈接可以定製。示例[arrayABC作爲指向int數組10的指針](http://cdecl.org/?q=int+%28*arrayABC%29%5B10%5D%3B) – chux

回答

9

這是一個指向數組的指針。它不是指向指針的指針。數組和指針是不同的。一個數組有一個地址,但是一個數組不是地址。數組是一系列連續的元素。

這個指針指向整個數組而不僅僅是第一個元素,就像float *指向整個float而不僅僅是第一個字節一樣。

如果您有例如:

int foo[10]; 
int (*arrayABC)[10] = &foo; 

則表達式(*arrayABC)foo是相同的。例如。 foo[3](*arrayABC)[3]相同。

+0

所以基本上這個表達式和int arrayABC [10]是一樣的,除了我們可以做類似於arrayABC++的東西嗎? –

+0

@KevinWu不,它不是那麼多。 int x [10];'和'int(* x)[10];之間的區別與'float y;'和'float * y之間的區別相同' –

+0

如果我解除引用,那麼會發生什麼? (Do * arrayABC) –

2

如果你有一個類型T然後一個指向對象的指針聲明如下

T obj; 

T *ptr = &obj; 

現在我們的目標是T的類型,定義方式如下

typedef int T[10]; 

因此上面的代碼

T obj; 

T *ptr = &obj; 

可以使用typedef definiti像

int obj[10]; 

int (*ptr)[10] = &obj; 

在這兩種情況下,當T是一些抽象類型,並且當Tint[10]一個別名,PTR是指向的對象。在最後一種情況下,ptr是指向int類型的10元素數組的指針。這是ptr指向的對象具有數組類型。陣列和poiters是不同的類型。

嘗試使用以下簡單示範程序

#include <stdio.h> 

int main(void) 
{ 
    typedef int T[10]; 

    T a; 

    T *pa = &a; 

    printf("%zu\n", sizeof(*pa)); 

    int b[10]; 

    int (*pb)[10] = &b; 

    printf("%zu\n", sizeof(*pb)); 
}  

它的輸出是

40 
40 

正如可以看到這兩個值都等於10個元件的整數數組的大小。所以指針指向數組。

如果你寫

int *arrayABC[10]; 

你會得到int *類型的10個指針的數組。

如果你寫

int (*arrayABC)[10]; 

你會得到一個指向10個整數數組。

1

在我的教科書中,它說我們有一個指向指向整數數組的第0個元素的指針。

你的教科書是...措辭嚴厲,讓我們把它留在那。這是一個指向int的10元素數組的指針。

我可以種類看看書是從哪裏來的。鑑於聲明

int (*a)[10]; 

表達*a將具有類型int [10](的int 10元件陣列)。但是,除非該表達式是sizeof或一元運算符&的操作數,否則它將從int [10]類型轉換(「衰減」)到int *,並且表達式的值將是該數組的第一個元素的地址:

Expression  Type  "Decays" to  Value 
----------  ----  -----------  ----- 
     *a  int [10] int *    Address of first element of the array; 
               equivalent to `&(*a)[0]`. 

因此,如果我打電話等

foo(*a); 

函數什麼實際接收的功能將是一個指向指向的陣列(其類型的第一個元素將是int *,不int **)。

因此,實際上,是的,a經常捲起來表現爲指向指向數組的第一個元素的指針;然而,它的類型而不是「指向指向int的指針」,並鍵入問題。鑑於:

int (*a)[10]; 
int **b; 

,那麼你會得到不同的行爲以下:

sizeof *a vs. sizeof *b 
a + i vs b + i (also applies to a++ vs b++)