1

cで呼び出される関数があるとarray_pushします。

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

ここには 2 つの問題があります。値渡しについて混乱しているように見えますが、より重大な問題は、ポインターについて混乱しているように見えることです。int *array_pointerarray_pointerintは、配列ではなく を指します。int配列の最初を指している可能性があります。関係のないメモとして、「int 配列へのポインター」は次のようになりますint (*array_pointer)[array_length]

要点に戻る: int *array_pointerarray_pointer はint. では*array_pointer = temp_array;、エクスプレッション*array_pointerは を格納できるオブジェクトを示しますinttemp_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++ を勉強しているときに新しい学生が最初に学ぶことの 1 つは、ポインターと配列が同等であるということです。これは真実から遠く離れることはできませんでした...

于 2013-04-06T06:11:13.517 に答える