2017-02-27 69 views
-2

據我所知,這個數組[1]和數組+ 1實際上是兩種寫入相同內容的方式。不過,我最近一直在研究void指針和數組,並使這個程序來測試我對它的理解。陣列+ 1工作陣列[1]不起作用

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    void** data; 
    data = malloc(sizeof(int)*2); 
    *((int*)data) = 5; 
    *((int*)(data+1)) = 10; 
    printf("%d\n", *((int*)data)); 
    printf("%d\n", *((int*)(data+1))); 
    free(data); 
    return 0; 
} 

這是工作程序的版本,由於某種原因,但是這個版本不

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    void** data; 
    data = malloc(sizeof(int)*2); 
    *((int*)data[0]) = 5; 
    *((int*)data[1]) = 10; 
    printf("%d\n", *((int*)data)); 
    printf("%d\n", *((int*)data1])); 
    free(data); 
    return 0; 
} 

我不能完全讓編譯器錯誤,但程序簡單地停止運行,我已經在一臺使用gcc的win 10計算機上編譯,下面的標誌爲-pedantic-errors -Wall,就像我之前說過的,程序編譯但運行時我得到了經典的Program.exe has stopped working錯誤消息,至今我真的無法想到爲什麼其中一個原因會工作,其他人不會。

+7

否:'數組[1]'與'*(a + 1)'相同 - 「*」表示所有區別。 –

+2

在你的第二個例子中,你有:'printf(「%d \ n」,*((int *)data1]));' - 缺少'['。 –

+0

你爲什麼使用void指針? –

回答

-2

第一:請改變data類型int*或至少void*。 不要與void**混亂,除非你需要傳遞給函數一個指針。

second: change data[0/1] to &data[0/1]data[]是一個參數,而&data[]是他的指針。如果您仍然使用void*選擇*((int*)data+?)。如果yopu更改爲int*則使用data[?]

第三:爲什麼要在這個函數中使用指針?這不是一個需要指針的函數。我建議在這種情況下使用數組而不是指針。如果你已經知道你的參數的類型和大小,那麼你最好使用數組。更舒適。

+2

你能解釋爲什麼他必須做這些事嗎? –

+0

我做過.......... –

2

data+1無效C.您無法對void指針進行指針運算,因爲這沒有任何意義。

因此,你似乎在非標準垃圾模式下使用gcc(默認設置),它將void指針算術轉換爲字符算術並因此程序編譯,但是作爲非標準的C. data+1意味着+ 1字節,而不是+1 int

使用gcc作爲標準C編譯器代替-std=c11 -pedantic-errors。然後將代碼更改爲(int*)data+1

另外void**是沒有意義的,應該是void*。請注意,(int*)data[0]的意思是「做指針運算上void**類型,然後把結果給int*,這是一個運算符優先級的錯誤。[]比投()運營商更高的優先級。

只是折騰是整個代碼出來,使用這個:

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    void* data; 
    data = malloc(sizeof(int[2])); 
    ((int*)data)[0] = 5; 
    ((int*)data)[1] = 10; 
    printf("%d\n", *(int*)data); 
    printf("%d\n", *((int*)data+1)); 
    free(data); 
    return 0; 
} 
+1

'數據'不是void *,它是一個無效**,算術完美定義 – chqrlie

+0

啊好吧我雖然-pedantic-errors和-Wall就足夠了停止這一點。並感謝您讓我知道運營商優先級錯誤。然而,我一直在使用'void **'的原因是因爲我一直在研究動態數組是如何完成的,而且我多次看到人們說'void **'超過'void *'。我有點困惑,爲什麼人們會建議'void **'是否有利用它只是一個空指針? – zee

+0

@chqrlie好的,總結是原始代碼很奇怪,並沒有做OP的想法。 – Lundin

0

你的兩個例子都不正確。

void** data = malloc(sizeof(int)*2); 

被分配2個int整數,但如果data類型void**的。如果你希望仍然可以使用這個,這是不推薦的,你需要分配2個void*指針。那麼這將是:

void** data = malloc(sizeof(void*)*2); 

話雖如此,在這裏使用不需要void**。正如@ Lundin的文章所指出的那樣,您可以使用void*。如果您使用int *data代替,您的代碼將是最佳的,因爲在這裏使用void*指針沒有意義。如果你決定這樣做,你的代碼可以只是:

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
    int *data; 
    data = malloc(sizeof(int)*2); 
    data[0] = 5; 
    data[1] = 10; 
    printf("%d\n", data[0]); 
    printf("%d\n", data[1]); 
    free(data); 
    return 0; 
} 

哪個更直接,跳過void*指針在代碼帶來的併發症。

注意:您必須始終檢查退回malloc(),因爲它可以在失敗時返回NULL

+0

好的,謝謝,我以爲我應該使用sizeof的那個指針分配是要去指向。至於使用int * im只給這個代碼作爲例子,所以這不是實際使用它的方式,我主要試圖理解指針和通用指針以及數組和動態數組是如何工作的。 – zee