2013-04-06 81 views
1

說我在c中有一個叫array_push的函數。從函數更新指向c數組的指針

void array_push(int *array_pointer, int array_length, int val) { 
    int i; 
    int *temp_array = malloc(sizeof(int) * (array_length + 1)); 

    for (i = 0; i < array_length; i++) { 
     temp_array[i] = *array_pointer; 
     array_pointer++; 
    } 

    temp_array[array_length] = val; 
    *array_pointer = temp_array; 
} 

如何更新指針*array_pointer,使其指向temp_array和我的程序可以使用新的陣列的其他部分?讓我做這樣的事情

int t[2] = {0,2}; 
array_push(t, 2); 
/* t should now contain {0,2,3} */ 
+1

你不能這樣做。 't'不是一個指針,它是一個數組,你不能改變數組的大小。 – Barmar 2013-04-06 06:13:42

+0

@Barmar - 你絕對正確。我沒有注意到OP的問題部分首先... – paulsm4 2013-04-06 06:50:35

回答

2

您需要打開array_pointer成指針到指針:

void array_push(int **array_pointer, int array_length, int val) { 

(注意額外的星號)。

此外,您需要更改呼叫站點,以便t是一個指針,而不是數組(您不能將數組指向其他位置)。最後,爲了讓調用者知道數組的新大小,array_length也需要通過指針傳遞。

因此,你的代碼的整體結構可以是這樣的:

void array_push(int **array_pointer, int *array_length, int val) { 
    int *temp_array = malloc(sizeof(int) * (*array_length + 1)); 
    memcpy(temp_array, *array_pointer, sizeof(int) * *array_length); 
    temp_array[(*array_length)++] = val; 
    free(*array_pointer); 
    *array_pointer = temp_array; 
} 

int main() { 
    int n = ...; 
    int* t = malloc(sizeof(int) * n); 
    /* ... */ 
    array_push(&t, &n, 2); 
    /* ... */ 
    free(t); 
} 

注意我是如何在堆中分配t,並釋放*array_pointerarray_push()。考慮到這一點,許多array_push()的邏輯可以通過使用realloc()被簡化:

void array_push(int **array_pointer, int *array_length, int val) { 
    *array_pointer = realloc(*array_pointer, sizeof(int) * (*array_length + 1)); 
    (*array_pointer)[(*array_length)++] = val; 
} 
+0

你重新創造了'realloc()'。 – Barmar 2013-04-06 06:15:30

+0

@Barmar:我知道。我正在朝着它的方向努力(答案仍在工作中)。 – NPE 2013-04-06 06:16:05

0

問題1:

如果你想在函數中創建或修改* int數組,然後你需要一個 「指針的指針」 通:

// WRONG: 
void array_push(int *array_pointer, int array_length, int val) { 
... 
    int *temp_array = malloc(sizeof(int) * (array_length + 1)); 
... 
    *array_pointer = temp_array; 

相反:

// BETTER: 
void array_push(int **array_pointer, int array_length, int val) { 
... 
    int *temp_array = malloc(sizeof(int) * (array_length + 1)); 
... 
    *array_pointer = temp_array; 

或者:

// BETTER YET: 
int * array_push(int array_length, int val) { 
... 
    int *temp_array = malloc(sizeof(int) * (array_length + 1)); 
... 
return temp_array; 

問題2:

如果要聲明一個靜態數組這樣int t[2] = {0,2};,那麼你就不能隨意改變它的大小。這裏的「數組指針VS」一個很好的說明:

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1069897882&id=1073086407

的第一件事情學習C和C++ 是指針和數組是等價的,當一個新的學生學習。這不可能是進一步從 真相......

1

這裏有兩個問題:你似乎感到困惑傳遞的價值,但更顯著的問題是,你似乎感到困惑指針。 int *array_pointer array_pointer指向一個int,而不是一個數組。它可能是指向數組中的第一個int。在不相關的說明中,「指向int數組的指針」如下所示:int (*array_pointer)[array_length]

回到頂端:int *array_pointer array_pointer指向int。在*array_pointer = temp_array;中,表達式*array_pointer爲您提供指向的對象,它可以存儲int。儘管如此,temp_array並不是int的值。

由於傳遞值的語義,我可以看到你正試圖解決由於array_pointer所做的更改對調用方不可見的問題。因此,您需要更改array_pointer,以便指向調用方提供的int *,以便您修改調用方的int *或使用返回類型返回新指針。事實證明,這兩個選項都可以解決您的兩個問題。