下面是ChatGPT的回答,太专业了,比网上查的资料都好很多可能。
是的,可以在子函数中动态申请一个指向二维数组的内存,然后将其传递给调用函数使用。在C语言中,可以通过以下方式实现:
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
int **allocate_2d_array(int rows, int cols) {
int i;
int **array = (int **)malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++) {
array[i] = (int *)malloc(cols * sizeof(int));
}
return array;
}
void free_2d_array(int **array, int rows) {
int i;
for (i = 0; i < rows; i++) {
free(array[i]);
}
free(array);
}
int main() {
int rows = 3;
int cols = 4;
int **my_array = allocate_2d_array(rows, cols);
// 使用动态分配的二维数组
my_array[0][0] = 1;
my_array[0][1] = 2;
// 释放内存
free_2d_array(my_array, rows);
return 0;
}
真的是太专业了!之前还以为不行,只能以一维数组的形式返回呢。
简单解释下:
即先定义一个指向一维数组(可以当成行数组)的指针,即每个指针指向的是行数组,然后——关键的来了——
这个行数组中每个元素,是指针!且,每个指针,又是动态申请一维数组(可当成列数组,即数组维数等于需要申请的二维数组的列数),所以定义类型是int**,即指向指向int型变的指针的指针,其访问各个内存需要按照先寻址行地址的首元素地址,再根据这个首元素地址寻址列地址,相当于得到二维数组的某行某列的地址,和指向二维数组的指针完全一样用,比如指针是int**p,则二维数组第i行第j列的地址是:
*(p+i)+j
或者类似文中主函数调用赋值时写法,写成:p[i][j]
看下面代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
int** allocate_2d_array(int rows, int cols) {
int i;
int** array = (int**)malloc(rows * sizeof(int*));
for (i = 0; i < rows; i++) {
array[i] = (int*)malloc(cols * sizeof(int));
}
printf("array = %x\n", array);
printf("array + 1 = %x\n", array + 1);
**array = 2;
*(*array+1) = 3;
return array;
}
void free_2d_array(int** array, int rows) {
int i;
for (i = 0; i < rows; i++) {
free(array[i]);
}
free(array);
}
int main() {
int rows = 3;
int cols = 4;
int** my_array = allocate_2d_array(rows, cols);
// 使用动态分配的二维数组
my_array[0][0] = 1;
my_array[0][1] = 2;
// 释放内存
free_2d_array(my_array, rows);
return 0;
}
调试打印:
说明一个4元素的指针数组占8个字节?每个指针两个字节了?
——正解:还是得看ChatGPT啊:
是指针的下一个,即int**移动一个单位,其实就是一个指针的字节数,所以是8......