Arrays 按引用调用和按值调用如何在多维指针数组上工作?
有人能解释一下为什么在init函数中不需要->int***zd吗?这不是按值调用吗?当我想打印它时,初始化不应该保留吗?或者指针是通过引用自动调用的? 我很想知道这到底是怎么回事,所以如果有人能帮助我,我将不胜感激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++){
#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;iinitzD
不需要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
不是多维数组。它是指向一个一维数组的指针,指向单个一维数组的指针。谢谢你的回答,这实际上是有意义的!我仍然认为我没有百分之百地理解它,但这让我对它有了更好的了解,因为这确实是一个非常好的问题和答案,它解释了指向指针的指针和真正的多维数组(以及如何动态分配它们):我真的理解了,谢谢!