如何解决引用调用和值调用如何作用于多维指针数组?
谁能解释一下为什么我不需要 -> int ***zd 在 init 函数中?这不是按值调用吗,当我想打印它时不应该保留初始化吗?还是指针自动通过引用调用? 我很想了解这究竟是如何工作的,所以如果有人能帮助我,我将不胜感激!
#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,heigth);
free(zd);
for(int x = 0; x < width; x++){
free(zd[x]);
}
return 0;
}
解决方法
initzD
不需要 zd
的地址,因为它不会改变 zd
。它改变了通过 zd
指向的事物(特别是由 zd
指向的指针所指向的事物)。
要改变这些东西,它需要它们的地址,它有它们的地址,因为它们是由 zd
指向的指针指向的。 (一般情况下,指针只指向一些int
中的第一个,但zd[i][j]
中的下标运算符进行指针运算以计算后续元素的地址。)
参数不需要定义为 int ***zd
,因为您没有修改 zd
函数中指针 main
的值。您只是取消引用它以修改它指向的值。
如果 zd
未初始化,那么您必须向它传递一个指针,以便该函数可以执行当前在 main
中发生的内存分配。
您的函数 initZD
不会更改按值传递的指针 int **zd
。它甚至不会改变 zd
指向的指针数组的值,而是只改变那些指针指向的值。
int **zd = NULL;
中的指针 main
在 main
中被修改只是因为您在那里分配了内存
zd = malloc(width*sizeof(int));
如果要在函数内部分配内存,则必须将指针的地址传递给 initZD
。
您的代码包含一个错误:在 main
中,您先调用 free(zd)
,然后再使用它free
循环中的 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,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;
}
,
按值调用意味着将变量的副本传递给函数,而通过引用调用意味着传递变量本身的地址。
这意味着被调用函数中的操作所做的更改将反映在调用函数中。 C 中的数组是通过引用传递的(默认情况下),就像您将数组变量传递给函数一样,该函数实际上是指向数组第一个元素的指针。
当你写 int **
时,它实际上意味着你指向一个指向元素的地址(因此是 **
)。因此,如果要访问数组的整数元素,则需要取消引用两次。对于这里的情况:
zd
:它是指向二维数组1st
行的指针
zd + i
:它是指向二维数组的ith
行的指针
*(zd + i)/ zd[i]
:取消引用 zd + i 以给出 ith
行的基本元素的地址。
类似地,zd[i][j]
将 j
添加到 ith
行的底部并取消引用它以给出 ith
行和 jth
列的元素的值.
这里的加法规则由指针算术控制,这意味着由于整数占用 4 个字节的数据,如果内存是字节组织的,则指向整数的指针在增加 1 时将指向它之前指向的指针前 4 个单位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。