user-0 提问: [C]动态数组

回复:
user: user-1
content: 具体说哪里看不明白，这是一个二维数组的初始化过程

user: user-2
content: 你想 引用 9 楼 ALNG 的回复:int array[5][4]; 怎样把它传递给调用函数以便调用函数还能用[][] 完全可以是 void foo(int parr[][4]) { parr[4][3] = 99; } foo(array);  不一定得用一维数组模拟

user: user-3
content: 引用 10 楼 lin5161678 的回复:你想 [quote=引用 9 楼 ALNG 的回复:] int array[5][4]; 怎样把它传递给调用函数以便调用函数还能用[][] 完全可以是 void foo(int parr[][4]) { parr[4][3] = 99; } foo(array);  不一定得用一维数组模拟[/quote]  试了，确实可以。谢谢！

user: user-2
content: 引用 3 楼 ALNG 的回复:我觉得恰恰相反，这个才叫二维数组。C那个使用一维数组模拟的二维或多维数组，是通过编译器特殊处理糊弄过去的，效率高，但有语法上的漏洞。  int array[5][4];  array是个什么东东？ 假定我在local作用域，比如main函数体中声明/定义它，怎样把它传递给调用函数以便调用函数还能用[][]来存取其中的元素？ 不考虑C中不存在的模板方式，也不许取巧把它放在一个结构体中。没有办法。这时它就得现出一维数组的原形，要把它cast成int *p, 再用类似p[i*4+j]的语法来访问具体的元素。你没用过 数组指针?

user: user-4
content: //在堆中开辟一个6个元素的一维int数组 #include <stdio.h> #include <malloc.h> int *p; int i; int main() {     p=(int *)malloc(6*sizeof(int));     if (NULL==p) return 1;     for (i=0;i<6;i++) {         p[i]=i;     }     for (i=0;i<6;i++) {         printf(" %2d",p[i]);     }     free(p);     return 0; } //  0  1  2  3  4  5  //在堆中开辟一个4×5的二维int数组 #include <stdio.h> #include <malloc.h> int **p; int i,j; void main() {     p=(int **)malloc(4*sizeof(int *));     if (NULL==p) return;     for (i=0;i<4;i++) {         p[i]=(int *)malloc(5*sizeof(int));         if (NULL==p[i]) return;     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             p[i][j]=i*5+j;         }     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             printf(" %2d",p[i][j]);         }         printf("\n");     }     for (i=0;i<4;i++) {         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19  //在堆中开辟一个3×4×5的3维int数组 #include <stdio.h> #include <malloc.h> int ***p; int i,j,k; void main() {     p=(int ***)malloc(3*sizeof(int **));     if (NULL==p) return;     for (i=0;i<3;i++) {         p[i]=(int **)malloc(4*sizeof(int *));         if (NULL==p[i]) return;         for (j=0;j<4;j++) {             p[i][j]=(int *)malloc(5*sizeof(int));             if (NULL==p[i][j]) return;         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 p[i][j][k]=i*20+j*5+k;             }         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 printf(" %2d",p[i][j][k]);             }             printf("\n");         }         printf("---------------\n");     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             free(p[i][j]);         }         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //--------------- // 20 21 22 23 24 // 25 26 27 28 29 // 30 31 32 33 34 // 35 36 37 38 39 //--------------- // 40 41 42 43 44 // 45 46 47 48 49 // 50 51 52 53 54 // 55 56 57 58 59 //---------------

user: user-3
content: 引用 8 楼 lin5161678 的回复:[quote=引用 3 楼 ALNG 的回复:] 我觉得恰恰相反，这个才叫二维数组。C那个使用一维数组模拟的二维或多维数组，是通过编译器特殊处理糊弄过去的，效率高，但有语法上的漏洞。  int array[5][4];  array是个什么东东？ 假定我在local作用域，比如main函数体中声明/定义它，怎样把它传递给调用函数以便调用函数还能用[][]来存取其中的元素？ 不考虑C中不存在的模板方式，也不许取巧把它放在一个结构体中。没有办法。这时它就得现出一维数组的原形，要把它cast成int *p, 再用类似p[i*4+j]的语法来访问具体的元素。你没用过 数组指针?[/quote]  什么意思，要免费教我吗？洗耳恭听。

user: user-3
content: 第一个*是unary, 只有一个操作数的，这里表示指针，比如我们声明一个指针 int *a; 那么sizeof(int*)和sizeof(a)都会返回同样的结果，在32位编译器上出来是4， 64位编译器出来是8，就是一个整型指针占用的字节数。  第二个*是乘法，这里是整数的乘法  如果sizeof(int*)是4，那么sizeof(int*)*length就是4*length.  因为要分配足够容纳length个int*的空间，所以需要的字节数是length*sizeof(int*)或sizeof(int*)*length.

user: user-5
content: 前面一个是指针，后面一个表示乘法。

user: user-0
content: 引用 3 楼 ALNG 的回复:我觉得恰恰相反，这个才叫二维数组。C那个使用一维数组模拟的二维或多维数组，是通过编译器特殊处理糊弄过去的，效率高，但有语法上的漏洞。  int array[5][4];  array是个什么东东？ 假定我在local作用域，比如main函数体中声明/定义它，怎样把它传递给调用函数以便调用函数还能用[][]来存取其中的元素？ 不考虑C中不存在的模板方式，也不许取巧把它放在一个结构体中。没有办法。这时它就得现出一维数组的原形，要把它cast成int *p, 再用类似p[i*4+j]的语法来访问具体的元素。再问一下，定义size的部分还是没看懂：(sizeof(int*)*length)，没分清两个*的用法，谢谢了

user: user-3
content: 我觉得恰恰相反，这个才叫二维数组。C那个使用一维数组模拟的二维或多维数组，是通过编译器特殊处理糊弄过去的，效率高，但有语法上的漏洞。  int array[5][4];  array是个什么东东？ 假定我在local作用域，比如main函数体中声明/定义它，怎样把它传递给调用函数以便调用函数还能用[][]来存取其中的元素？ 不考虑C中不存在的模板方式，也不许取巧把它放在一个结构体中。没有办法。这时它就得现出一维数组的原形，要把它cast成int *p, 再用类似p[i*4+j]的语法来访问具体的元素。

user: user-5
content: 严格来说，这个不叫二维数组，而是数组的数组。 二维数组的特点是每行每列元素相等。并且连续在内存中存放。本质上说，二维数组是一维数组下标分成两部分作乘法的语法糖。  所谓“动态”，在这里主要体现在malloc上，它的作用就是为指针分配内存。分配的大小由sizeof得到的单个元素的大小和元素个数的乘积决定。 malloc得到的内存记得要用free释放，否则会造成泄露。

user: user-3
content: 它是建立一个lengthxlength的二维整型数组，在实用中这并不是一个好方式（成本高), 但用来理解指针和数组还是有一定的意义的。  好了，把length放一个比较小的值，实际比划一下就更容易明白了。大过年的，让我们来二一把吧，就放2.  先看看我们怎么用它。如果对Arr做一次indirection, 比如 *Arr, Arr[0], Arr[1], 我们得到什么呢。答对了，从类型去掉一个*号，成了 int *。什么意思Arr应该是长度为2（length)的整型指针数组。理所当然，如果要从堆中动态分配，应该 Arr=(int **)malloc(sizeof(int*)*length/*2*/); 现在，Arr[0]和Arr[1]放的是什么。整型指针，不过是垃圾指针，指向随机地址，不能拿来用的。怎么办，一个一个来。 Arr[0]应该指向一个长度为2的整型数组，所以 Arr[0]=（int*)malloc(sizeof(int)*length/*2*/); 同样的 Arr[1]=（int*)malloc(sizeof(int)*length/*2*/);  那如果length很大的时候，上面的写法不是要累死人吗？简单，用循环，看以看到，就是Arr的下标变了，其他不变 for(int i=0; i<length; ++i)     Arr[i]=(int*)malloc(sizeof(int)*length);  这就是你看到的。