user-0 提问: 二维数组和动态分配二维数组的区别问题

回复:
user: user-1
content: 引用 6 楼 bear234 的回复:[quote=引用 5 楼 u010165006 的回复:] [quote=引用 3 楼 bear234 的回复:] 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针 我是觉得像：int (*p)[5]这样的指针很不灵活，因为一个维数已经固定了。[/quote]   如果你觉得c++不灵活，那这个世界上就没灵活的语言了....... c/c++是给予程序员自由度最高的编程语言 这里之所以必须固定下来这个5，是因为你本身就是要让这个指针指向一个维度在编译期就已经固定下来的二维数组 如果你觉得这样不够灵活，那么你就是在说：我们应该允许 m = 3; n = 2; int arr[m][n]; 而这是不允许的  如果你想要灵活，请用malloc或者new  不管多少维度的数组，都由你给定的变量决定其每个维度的长度----就像你贴出来的代码那样[/quote]  告诉我为什么是不允许的？？？？ m = 3; n = 2; int arr[m][n]

user: user-2
content: int **a=new int *[M]; a[0] = new int[N*M]; for(int i=1;i<M;i++)a[i] =a[0]+i*N;

user: user-2
content: nt **a=new int *[sizeof(int *)*M]; a[0] = new int[sizeo(int)*N*M]; for(int i=1;i<M;i++)a[i] =a[0]+i*N;式子写错了，抱歉

user: user-2
content: 引用 14 楼 u010165006 的回复:[quote=引用 12 楼 lm_whales 的回复:] 二级指针，完全模拟并兼容二维数组，可以如下  int **a=new int *[sizeof(int *)*M]; a[0] = new int[sizeo(int)*N]; for(int i=1;i<M;i++)a[i] =a[0]+i; 这样，得到的数组，可以和 静态数组保持一定程度的一致。 a[i]除了a[0]都没有空间吗（非法空间）？a[i] =a[0]+i;是什么意思？偏移i？ 就算可以和 静态数组保持一定程度的一致，也不可能可以像一维数组一样连续分布。[/quote]就是连续分布

user: user-0
content: 引用 12 楼 lm_whales 的回复:二级指针，完全模拟并兼容二维数组，可以如下  int **a=new int *[sizeof(int *)*M]; a[0] = new int[sizeo(int)*N]; for(int i=1;i<M;i++)a[i] =a[0]+i; 这样，得到的数组，可以和 静态数组保持一定程度的一致。 a[i]除了a[0]都没有空间吗（非法空间）？a[i] =a[0]+i;是什么意思？偏移i？ 就算可以和 静态数组保持一定程度的一致，也不可能可以像一维数组一样连续分布。

user: user-3
content: 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

user: user-2
content: 二级指针，完全模拟并兼容二维数组，可以如下  int **a=new int *[sizeof(int *)*M]; a[0] = new int[sizeo(int)*N]; for(int i=1;i<M;i++)a[i] =a[0]+i; 这样，得到的数组，可以和 静态数组保持一定程度的一致。

user: user-4
content: 引用 9 楼 qq_24935843 的回复:[quote=引用 3 楼 bear234 的回复:] 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针  请问“二维数组则只能转换成一个指向指针数组的指针”这句话怎么理解?[/quote]  我觉得3楼的意思是二维数组可以转换成一个指向数组的指针， 即数组指针，如定义 int (*p)[n]; 其实，由于静态二维数组元素的地址是连续的，完全可以把二维数组转换成一级指针，然后通过地址偏移访问

user: user-0
content: 引用 9 楼 qq_24935843 的回复:[quote=引用 3 楼 bear234 的回复:] 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针  请问“二维数组则只能转换成一个指向指针数组的指针”这句话怎么理解?[/quote] 帮你顶

user: user-5
content: 引用 3 楼 bear234 的回复:因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针  请问“二维数组则只能转换成一个指向指针数组的指针”这句话怎么理解?

user: user-6
content: 引用 7 楼 u010165006 的回复:[quote=引用 6 楼 bear234 的回复:] [quote=引用 5 楼 u010165006 的回复:] [quote=引用 3 楼 bear234 的回复:] 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针 我是觉得像：int (*p)[5]这样的指针很不灵活，因为一个维数已经固定了。[/quote]   如果你觉得c++不灵活，那这个世界上就没灵活的语言了....... c/c++是给予程序员自由度最高的编程语言 这里之所以必须固定下来这个5，是因为你本身就是要让这个指针指向一个维度在编译期就已经固定下来的二维数组 如果你觉得这样不够灵活，那么你就是在说：我们应该允许 m = 3; n = 2; int arr[m][n]; 而这是不允许的  如果你想要灵活，请用malloc或者new  不管多少维度的数组，都由你给定的变量决定其每个维度的长度----就像你贴出来的代码那样[/quote] 我说像：int (*p)[5]这样的指针不灵活，意思是说假如需要一个函数显示不固定维数的二维数组，形参要怎么写呢？类似： void  displayArray(???p, int rows, int cols) 因为行数、列数都不固定，所以参数p的类型就不好定。 不过看到书上一个方法，就是把二维数组当做一维数组来处理，这样形参p的类型例如int *p，实参&array[0][0]，这样array[i][j]==p[i*cols+j] 也许是最好的方法了。[/quote]   是的，传递首元素地址和各个维度即可  编译器永远必须知道每个元数据的大小  而数组是符合数据类型，所以可以不知道它的长度（传递参数的时候，只要告诉编译器这个数组从哪儿开始就可以了，至于数组的长度，你甚至可以定义一个全局const变量来告诉相关函数---当然这种方法不好），但是数组的每个元素都是元数据，所以编译器必须知道它的大小   如果数组的元素本身就是数组的话，那么毫无疑问，你必须告诉编译器它的大小

user: user-0
content: 引用 6 楼 bear234 的回复:[quote=引用 5 楼 u010165006 的回复:] [quote=引用 3 楼 bear234 的回复:] 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针 我是觉得像：int (*p)[5]这样的指针很不灵活，因为一个维数已经固定了。[/quote]   如果你觉得c++不灵活，那这个世界上就没灵活的语言了....... c/c++是给予程序员自由度最高的编程语言 这里之所以必须固定下来这个5，是因为你本身就是要让这个指针指向一个维度在编译期就已经固定下来的二维数组 如果你觉得这样不够灵活，那么你就是在说：我们应该允许 m = 3; n = 2; int arr[m][n]; 而这是不允许的  如果你想要灵活，请用malloc或者new  不管多少维度的数组，都由你给定的变量决定其每个维度的长度----就像你贴出来的代码那样[/quote] 我说像：int (*p)[5]这样的指针不灵活，意思是说假如需要一个函数显示不固定维数的二维数组，形参要怎么写呢？类似： void  displayArray(???p, int rows, int cols) 因为行数、列数都不固定，所以参数p的类型就不好定。 不过看到书上一个方法，就是把二维数组当做一维数组来处理，这样形参p的类型例如int *p，实参&array[0][0]，这样array[i][j]==p[i*cols+j] 也许是最好的方法了。

user: user-6
content: 引用 5 楼 u010165006 的回复:[quote=引用 3 楼 bear234 的回复:] 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针 我是觉得像：int (*p)[5]这样的指针很不灵活，因为一个维数已经固定了。[/quote]   如果你觉得c++不灵活，那这个世界上就没灵活的语言了....... c/c++是给予程序员自由度最高的编程语言 这里之所以必须固定下来这个5，是因为你本身就是要让这个指针指向一个维度在编译期就已经固定下来的二维数组 如果你觉得这样不够灵活，那么你就是在说：我们应该允许 m = 3; n = 2; int arr[m][n]; 而这是不允许的  如果你想要灵活，请用malloc或者new  不管多少维度的数组，都由你给定的变量决定其每个维度的长度----就像你贴出来的代码那样

user: user-0
content: 引用 3 楼 bear234 的回复:因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针 我是觉得像：int (*p)[5]这样的指针很不灵活，因为一个维数已经固定了。

user: user-3
content: 3楼才是真相。 看真相的方法： VC调试时按Alt+6,打开内存窗口看数组对应的实际内存。

user: user-6
content: 因为动态二维数组真的是指针的指针  而普通的二维数组并不是指针的指针  事实上，数组在转换成指针时会丢失长度信息  所以一维数组可以直接转换成指针 而二维数组则只能转换成一个指向指针数组的指针

user: user-7
content: 问题1：动态分配的二维数组matrix是int **类型，为什么它能够用matrix[i][j]来存取？ 首先，不管是二维数组还是三维数组，我们都可以把它看成一维的线性表，matrix[i][j]共有8*2*5个字节类存空间（好像是这样）所以能够用matrix[i][j]来存取。 问题2：为什么不能声明：int  **p=arr，然后用p[i][j]来存取arr[i][j]数据？1和2看起来很相似。 arr是数组地址，这样可以吗？

user: user-8
content: 对于matrix[i][j]来说，matrix[i]=(int*)malloc(cols*sizeof(int*)), 所以matrix[i]的类型可以看成是一个int数组，就好像int arr[cols], 这样的话，matrix[i][j]就相当于访问arr[j]了  对于int  **p=arr，这时候p已经丢了二维数组的类型信息，所以p[i][j]的用法编译器理解不了，计算不出准确的地址