1

谁能解释我为什么在 init 函数中不需要 -> int ***zd ?这不是按值调用吗?当我想打印它时,初始化不应该保留吗?还是指针通过引用自动调用?我很想了解这到底是如何工作的,所以如果有人可以帮助我,我将不胜感激!

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


void initZD(int **zd, int width, int height){
    for(int i = 0; i < width; i++){
        for(int j = 0; j < height; j++){
            zd[i][j] = rand() % 10;
        }
    }
    return;
}
void printZD(int **zd, int breite, int hoehe){
for(int i = 0; i < breite; i++){
    for(int j = 0; j < hoehe; j++){
        printf("%d\t",zd[i][j]);
    }
    printf("\n");
}
}

int main(){

int **zd = NULL;
int width, heigth;

printf("Width: ");
scanf("%d", &width);
printf("Heigth: ");
scanf("%d", &heigth);

//zd = realloc(*zd, breite*sizeof(int));
//zd = calloc(breite, sizeof(int));
zd = malloc(width*sizeof(int));


for(int i = 0; i < width; i++){
//zd[i] = realloc(*zd, hoehe*sizeof(int));
//zd[i] = calloc(hoehe, sizeof(int));
zd[i] = malloc(heigth*sizeof(int));
}

initZD(zd, width, heigth);

printZD(zd, width, heigth);


free(zd);

for(int x = 0; x < width; x++){
    free(zd[x]);
}

return 0;
}
4

4 回答 4

1

initzD不需要的地址,zd因为它不会改变zd。它更改通过指向的zd事物(特别是由指向的指针指向的事物zd)。

要更改这些东西,它需要它们的地址,并且它有它们的地址,因为它们是由指向的指针zd指向的。(通常,指针只指向一定数量的第一个int,但下标运算符zd[i][j]进行指针运算以计算后续元素的地址。)

于 2020-12-29T13:53:56.850 回答
0

按值调用意味着将变量的副本传递给函数,而按引用调用意味着传递变量本身的地址。

这意味着被调用函数中的操作所做的更改将反映在调用函数中。C 中的数组通过引用传递(默认情况下),就像您将数组变量传递给函数一样,该函数实际上是指向数组第一个元素的指针。

当你写int **它时,它实际上意味着你指向一个指向一个元素的地址(因此是**)。因此,如果要访问数组的整数元素,则需要取消引用两次。对于这里的情况:

zd: 指向1st二维数组行的指针

zd + i: 指向ith二维数组行的指针

*(zd + i)/ zd[i]:取消引用 zd + i 以给出行的基本元素的地址ith

类似地zd[i][j]添加jith行的基础并取消引用它以给出行ithjth列元素的值。

这里的加法规则由指针算术控制,这意味着因为一个整数占用 4 个字节的数据,如果内存是按字节组织的,则一个指向整数的指针在递增 1 时将指向它之前指向的 4 个单位。

于 2020-12-29T14:01:59.713 回答
0

不需要将参数定义为,int ***zd因为您没有修改函数中指针zd的值main。您只是取消引用它以修改它指向的值。

已经zd未初始化,那么您将必须传递一个指向它的指针,以便该函数可以执行当前正在发生的内存分配main

于 2020-12-29T13:54:35.150 回答
0

您的函数initZD不会更改int **zd按值传递的指针。它甚至不会更改指向的指针数组zd的值,而只会更改这些指针指向的值。

int **zd = NULL;中的指针main被修改main只是因为你在那里分配了内存

zd = malloc(width*sizeof(int));

initZD如果要在函数内部分配内存,则必须将指针的地址传递给。

您的代码包含一个错误:在您使用循环中的其他内存之前main调用它。这是未定义的行为。free(zd)freefree(zd[x])

您需要通过引用传递指针的示例,即传递指针的地址:

void initZD(int ***zd, int width, int height){

    *zd = malloc(width*sizeof(int));

    for(int i = 0; i < width; i++){
        (*zd)[i] = malloc(heigth*sizeof(int));
    }
    for(int i = 0; i < width; i++){
        for(int j = 0; j < height; j++){
            (*zd)[i][j] = rand() % 10;
        }
    }
    return;
}

/* ... */

int main(){

    int **zd = NULL;
    int width, heigth;

    printf("Width: ");
    scanf("%d", &width);
    printf("Heigth: ");
    scanf("%d", &heigth);


    initZD(&zd, width, heigth);

    printZD(zd, width, heigth);

    for(int x = 0; x < width; x++){
        free(zd[x]);
    }

    /* NOTE you must not free this pointer before the loop above */
    free(zd);

    return 0;
}
于 2020-12-29T13:54:47.540 回答