Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 按引用调用和按值调用如何在多维指针数组上工作?_Arrays_C_Pointers_Pass By Reference_Call By Value - Fatal编程技术网

Arrays 按引用调用和按值调用如何在多维指针数组上工作?

Arrays 按引用调用和按值调用如何在多维指针数组上工作?,arrays,c,pointers,pass-by-reference,call-by-value,Arrays,C,Pointers,Pass By Reference,Call By Value,有人能解释一下为什么在init函数中不需要->int***zd吗?这不是按值调用吗?当我想打印它时,初始化不应该保留吗?或者指针是通过引用自动调用的? 我很想知道这到底是怎么回事,所以如果有人能帮助我,我将不胜感激 #include <stdio.h> #include <stdlib.h> void initZD(int **zd, int width, int height){ for(int i = 0; i < width; i++){

有人能解释一下为什么在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;
}
#包括
#包括
无效初始zd(整数**zd,整数宽度,整数高度){
对于(int i=0;i
initzD
不需要
zd
的地址,因为它不改变
zd
。它更改通过
zd
指向的内容(特别是
zd
指向的指针指向的内容)


要改变这些东西,它需要它们的地址,它有它们的地址,因为它们被
zd
指向的指针指向。(通常,指针只指向一些
int
中的第一个,但
zd[i][j]
中的下标运算符执行指针运算以计算以下元素的地址。)该参数不需要定义为
int***zd
,因为您没有在
主函数中修改指针
zd
的值。您只是取消引用它来修改它所指向的值


如果
zd
未初始化,则必须传递指向它的指针,以便该函数可以执行当前在
main

中发生的内存分配。您的函数
initZD
不会更改通过值传递的指针
int**zd
。它甚至不更改
zd
指向的指针数组的值,而只更改这些指针指向的值

指针
int**zd=NULLmain
中的code>在
main
中被修改,这仅仅是因为您使用

zd = malloc(width*sizeof(int));
如果要在函数中分配内存,必须将指针的地址传递到
initZD

您的代码包含一个错误:在
main
中调用
free(zd)
,然后使用它
释放
循环中另一个内存的
free(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;
}
void initZD(int***zd,int宽度,int高度){
*zd=malloc(宽度*sizeof(int));
对于(int i=0;i
按值调用表示将变量的副本传递给函数,而按引用调用表示传递变量本身的地址

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

当您编写
int**
时,实际上意味着您指向的是指向元素的地址(因此是
**
)。因此,如果要访问数组的整数元素,则需要取消引用两次。就本案而言:

zd
:它是指向2D数组的
1st
行的指针

zd+i
:它是指向2D数组第i行的指针

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

类似地,
zd[i][j]
j
添加到
ith
行的底部,并对其取消引用,以给出
ith
行和
jth
列处元素的值


这里的加法规则由指针算法控制,这意味着由于一个整数占用4个字节的数据,并且如果内存是字节组织的,那么当递增1时,指向整数的指针将比之前指向的指针提前4个单位。

int**zd
不是多维数组。它是指向一个一维数组的指针,指向单个一维数组的指针。谢谢你的回答,这实际上是有意义的!我仍然认为我没有百分之百地理解它,但这让我对它有了更好的了解,因为这确实是一个非常好的问题和答案,它解释了指向指针的指针和真正的多维数组(以及如何动态分配它们):我真的理解了,谢谢!