有人能解释我为什么不需要->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("%dt",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;
}
initzD
不需要zd
的地址,因为它不会更改zd
。它改变了通过zd
指向的东西(特别是zd
指向的指针指向的东西(。
要改变这些东西,它需要它们的地址,它有它们的地址是因为zd
指向的指针指向它们。(通常,指针只指向某些数量的int
中的第一个,但zd[i][j]
中的下标运算符进行指针运算来计算以下元素的地址。(
参数不需要定义为int ***zd
,因为您没有在main
函数中修改指针zd
的值。你只是取消引用它来修改它指向的值。
如果zd
未初始化,那么您必须向它传递一个指针,以便该函数可以执行main
中当前发生的内存分配。
按值调用意味着将变量的副本传递给函数,而 引用调用这意味着被调用函数中的操作所做的更改将反映在调用函数中。C中的数组是通过引用传递的(默认情况下(,就像将数组变量传递给函数一样,函数实际上是指向数组第一个元素的指针。 当你写 类似地, 这里的加法规则由指针算术控制,这意味着由于一个整数占据了4个字节的数据,并且如果内存是字节组织的,那么当整数增加1时,指向该整数的指针将比它之前指向的指针提前4个单位。int **
时,它实际上意味着你指向的是一个指向元素的地址(因此是**
(。因此,如果您想访问数组的整数元素,则需要取消引用两次。对于这里的情况:zd
:指向2D阵列的1st
行的指针zd + i
:指向2D阵列的ith
行的指针*(zd + i)/ zd[i]
:取消引用zd+i以给出ith
行的基元素的地址。zd[i][j]
将j
添加到ith
行的基,并对其解引用以给出ith
行和jth
列处的元素的值。
函数initZD
不会更改按值传递的指针int **zd
。它甚至不更改zd
所指向的指针数组的值,而只更改这些指针所指向的值。
main
中的指针int **zd = NULL;
在main
中被修改,只是因为您使用在那里分配内存
zd = malloc(width*sizeof(int));
如果要在函数内部分配内存,则必须将指针的地址传递给initZD
。
您的代码包含一个错误:在main
中,您先调用free(zd)
,然后再将其用于循环中具有free(zd[x])
的另一个内存free
。这是未定义的行为。
需要通过引用传递指针的示例,即传递指针的地址:
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;
}