首页 > 代码库 > 《你必须知道的495个C语言问题》笔记--数组和指针

《你必须知道的495个C语言问题》笔记--数组和指针

一.如何动态分配多维数组?

1.分配一个指针数组,然后把每个指针初始化为动态分配的行


代码如下:

	int **array = (int **)malloc(ROW * sizeof(int*));
        int i = 0;
        for(i=0; i<ROW; i++){
                array[i] = (int *)malloc(COL * sizeof(int));
        }

2.让数组的内容连续,但在后来重新分配行。


代码如下:

	int **array = (int**)malloc(ROW * sizeof(int *));
       	int i;
        for(i=1; i<ROW; i++){
                array[i] = array[0] + i * COL;
        }
上述两种方案都可以正常地使用数组下表array[i][j]来访问。


3.使用一个动态分配的一维数组来模拟二位数组,但是你必须手动计算数组下标。

int *array = (int *)malloc(sizeof(int) * ROW * COL);
但是必须手动计算下标,用array[i * COL + j]来访问第i行j列的元素。


所有这些技术都可以扩展到三维或更多维数组。这个是第一种技术的三维数组版本。

int ***a3d = (int ***)malloc(x * sizeof(int **));
        int i,j;
        for(i=0; i<x; i++){
                a3d[i] = (int **)malloc(y * sizeof(int *));
                for(j=0; j<y; j++){
                        a3d[i][j] = (int *)malloc(z * sizeof(int));
                }
        }


二.数组参数的传递

假设有下面二维数组的声明:

int array[ROW][COL];
int **array1; //每行分别进行内存的malloc,上面中第1种
int **array2; //连续进行内存的malloc,上面的第2种
int *array3; //使用一维数组模拟二维
int (*array4)[COL];
int  (*array5)[ROW][COL];

函数的声明如下:

void f1a(int a[][COL], int row, int col);
void f1b(int (*a)[COL], int row, int col);
void f2(int *aryp, int row, int col);

其中f1a和f1b接收传统二维数组,f2接收扁平二维数组


下面的调用可以如愿运行:

f1a(array, ROW, COL);
f1b(array, ROW, COL);
f1a(array4, ROW, COL);
f1b(array4, ROW, COL);

那为什么array1,array2和array3,array5不能被传入。

f1a和f1b要求列数位COL,但是array1,array2和array3没有指定列数,所以不符合。

f1a和f1b要求第一个参数是一个指向一维数组的指针,但是array5是一个指向二维数组的指针,所以不符合。


f2(&array[0][0], ROW, COL);
f2(&array2, ROW, COL);
f2(array3,ROW, COL);
f2(*array4, ROW, COL);
f2(**array5, ROW, COL);
传统的二维数组在内存结构上也是扁平的,而array1不是扁平的,所以只有array1不符合。