1

假设我有一个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} */ 
4

3 回答 3

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;
}
于 2013-04-06T06:10:55.077 回答
1

这里有两个问题:您似乎对按值传递感到困惑,但更重要的问题是您似乎对指针感到困惑。int *array_pointerarray_pointer 指向一个int,而不是一个数组。它可能指向int数组中的第一个。在不相关的注释中,“指向 int 数组的指针”看起来像:int (*array_pointer)[array_length]

回到正题:int *array_pointerarray_pointer 指向一个int. 在*array_pointer = temp_array;中,表达式*array_pointer为您提供指向的对象,该对象可以存储int. temp_array不过,这不是一个int值。

我可以看到您正在尝试解决array_pointer由于按值传递的语义而导致的更改对调用者不可见的问题。因此,您需要更改array_pointer它以使其指向int *调用者提供的 ,以便您修改调用者的int *,或使用返回类型来返回新指针。事实证明,这两个选项都可以解决您的两个问题。

于 2013-04-06T06:23:30.387 回答
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};,那么你不能随意改变它的大小。这是“数组与指针”的一个很好的描述:

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

新学生在学习 C 和 C++ 时学到的第一件事就是指针和数组是等价的。这与事实相去甚远……

于 2013-04-06T06:11:13.517 回答