2015-05-14 155 views
2
typedef struct node { 
    int value; 
    struct node* next; 
}node; 

int* to_array (node* ll, int size) { 
    int i = 0; 
    int* arr = malloc(size*sizeof(int)); 
    while (ll) { 
      arr[i] = ll->value; 
      ll = ll->next; 
      i++; 
    } 

return arr; 
} 

有人可以請解釋爲什麼結構鏈表到一個數組

int* arr = malloc(size); 

會給我們一個數組?我認爲當我們有指針時,我們不能像arr[i] = 5那樣單獨改變它。

回答

5

你實際上是一個非常好的問題。誠然,一個已經被問及在SO上多次回答的問題。但是,一個很好的問題。

從C/C++ FAQ:

http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr

數組不是指針,但它們密切相關(見問題 6.3),並同樣可以使用(參見問題4.1,6.8, 6.10和6.14)。

  1. 當聲明的陣列(例如int a[5]),你已經被分配用於5 「INT」 元素存儲。您可以訪問每個元素,如a[i]

  2. 當您聲明指針(例如int *b)時,您尚未分配ANY存儲。

  3. 你可以聲明和初始化在同一時間的指針:當你宣佈從堆疊陣列a,你分配的空間

    int *b = NULL; /* Initialize to 0 */ 
    ... OR ... 
    int *b = malloc (5 * sizeof (int)); /* Allocate storage for 5 "int" elements */ 
    
  4. 。分配不能改變。

    當您聲明b時,您分配了SAME空間量,但是您是從堆中分配的。此外,您可以隨時將b更改爲指向其他任何內容。你也可以用realloc()你的內存來改變你的存儲大小。

  5. 就像您可以使用索引語法a[i]一樣,您可以使用完全相同的語法b[i]

此鏈接可能有助於解釋:http://www.geeksforgeeks.org/g-fact-5/

PS: 當你 「有一個指針」,你最肯定CAN 「更改個別像arr[i] = 5什麼的」。

+0

謝謝。我很感謝你的詳細解釋!我現在明白了。 – wiwen

+0

我的榮幸。謝謝*你* :) – FoggyDay

2

int *arr = malloc(size * sizeof(int));不會給出數組,它會給你一個足夠容納size整數的內存塊。

arr[i] = ll->value;語句使用指針算法:表達arr + 5手段取整數的存儲器地址指向arr並從那裏移動5個位置。現在,因爲編譯器知道它正在使用指針,並且假設32位的數據爲int,所以它會知道要在arr的值上加上20(= 5 * 4字節)來查找第6個元素。

接下來,C語言具有語法糖,其中表達式arr[5]等於*(arr + 5)

這也是爲什麼C中的數組從0開始編號,以及爲什麼C數組的名稱也可以用作指向數組的第一個元素的指針。

1

在此語句

int* arr = malloc(size*sizeof(int)); 

函數malloc分配存儲的程度,即能夠存儲int類型的size對象並返回指針到這個程度(或在程度的第一時隙,其中的一個目的類型int可以被容納)爲具有類型void *,其被隱式轉換爲類型int *,因爲在聲明標識符arr的左側具有類型int *

按照C標準(6.5.2.1數組下標)

2 ...下標操作符[]的定義是,E1 [E2]是 相同(*((E1) +(E2)))。由於 適用於二元運算符的轉換規則,如果E1是數組對象 (等價地,指向數組對象的初始元素的指針) 並且E2是整數,則E1 [E2]指定E2- E1 的th元素(從零開始計數)。

因此,該表達

arr[i] 

評價像

*(arr + i) 

其中在子表達式

arr + i 

有使用指針運算,它是此表達指向我分配中的第 - 個元素記憶的程度。

如果有一個數組聲明例如像

int array[size]; 

然後在此表達

array[i] 

陣列名稱被隱式轉換爲指針到它的第一個元素。你可以把它想象像

int *p = array; 
*(p + i) 

因此,如果你有以下聲明

int array[size]; 
int *p; 

那麼下面的語句是等價的

array[1] = 10; 

p = array; 

*(p + 1) = 10; 

監守操作array + i是可交換的,那麼你可以互換寫

array[i] 

i[array] 

例如,在你的函數,你可以寫

i[arr] = ll->value; 

雖然它只會混淆讀者。:)

初學者總是懷疑當看到這樣的代碼

int a[10]; 

0[a] = 5; 
+0

謝謝!我現在明白了! – wiwen