最近看了一些关于C/C++语言中数组的资料,发现以前的理解确有不妥。所谓数组并不是简单的元素阵列,而是一种数据类型或数据结构。数组名也并不是简单的常量指针,是一个数组类型的变量,其值为数组中第一个元素的地址。
**int**a[2][2][3]={{{10,6,3},{5,4,15}},{{3,5,33},{23,12,7}}};
**typeof**(a) b = {0};//说明a是一种不同于普通指针的数据类型,见sizeof输出 **printf**("sizeof(a): %d/n",**sizeof**(a)); // 48 = 12 * sizeof(int) **printf**("sizeof(b): %d/n",**sizeof**(b)); // 48 = 12 * sizeof(int) |
数组和指针的对应关系:
**int***p1 = a; // error
**int****p2 = a; // error **int*****p3 = a; // error **int**(*p4)[2][3] = a; // OK **printf**("sizeof(p4): %d/n",**sizeof**(p4)); // 4,指针大小 **printf**("0x%p/n", a);// 0x0022FF30,数组首地址 **printf**("0x%p/n", &a);// 0x0022FF30,数组首地址,和指针变量有区别 **printf**("0x%p/n", p4);// 0x0022FF30,数组首地址 **printf**("0x%p/n", &p4);// 0x0022FEFC, p4自身的地址 **printf**("0x%p/n", *p4);// 0x0022FF30,数组首地址 **printf**("0x%p/n", **p4);// 0x0022FF30,数组首地址 **printf**("0x%p/n", ***p4); // 0x0000000A, a[0][0][0]的值 |
数组类型和指针类型的对应关系可总结为:
ElemType a[M][N][O]…[X][Y][Z] ↔ ElemType (*pa)[N][O]…[X][Y][Z] |
多维数组的使用必须遵循这个等价关系才能做到类型安全。
多维数组的动态分配:
**int***p5 =**new****int**[10]; // OK
**int***p6 =**new****int**[8][10]; // error **int****p7 =**new****int**[8][10]; // error **int**(*p8) [10] =**new****int**[8][10]; // OK,如果语言支持“**int**[10] (*p8)”则更好理解 |
数组的不同访问方法(这里不讨论常用的用“[]”访问元素的方法):
**int**i,j,k;
**for**(i=0;i<2;i++) **for**(j=0; j<2; j++) **for**(k=0; k<3; k++) **printf**("%d ", *(*(*(a+i)+j)+k)); **printf**("/n");
**for**(i=0;i<2;i++) **for**(j=0; j<2; j++) **for**(k=0; k<3; k++) **printf**("%d ", *(**a + i*2*3 + j*3 + k)); **printf**("/n");
**for**(i=0; i<2; i++) **for**(j=0; j<6; j++) **printf**("%d ", *(**(a+i)+j)); **printf**("/n");
**for**(i=0; i<2; i++) **for**(j=0; j<6; j++) **printf**("%d ", *(**a + i*2*3 + j)); **printf**("/n");
**for**(i=0; i<12; i++) **printf**("%d ", *(**a+i)); **printf**("/n"); |
对于一个二维数组int array[m][n]而言以下4中表达方法是等价的。
array[i][j]
*(array[i]+j) (*(array+i))[j] *(*(array+i)+j) |
数组名作为函数的参数:
// array退化为int *array,array是一个指针
// C/C++把数组传递改写为指针传递的主要原因有: // 1)数组在内存中是连续字节存放的,编译器可以通过地址计算来引用数组中的元素 // 2)出于性能考虑,如果把整个数组的元素全部传递进去,不仅需要大量时间来拷贝数组,拷贝操作还会占用 //大量的栈空间 //从后面的输出可以看出array和array+1相差4,即sizeof(int) **void****func1**(**int**array[],**int**size) { **printf**("sizeof(array): %d, 0x%p, 0x%p/n",**sizeof**(array), array, array+1); }
**void****func2**(**int***array,**int**size) { **printf**("sizeof(array): %d, 0x%p, 0x%p/n",**sizeof**(array), array, array+1); }
// array退化为int (*array)[10],array是一个指针 //向函数传递多维数组时不需要说明第一维的大小而必须说明其他所有维的大小,主要原因有: // 1)数组在内存中按照“行优先”规则存储,所以需要列数来确定一行有多少个元素 // 2)编译器在计算元素的地址时不需要数组第一维的长度,但是需要其他维的长度信息 // 3) C/C++不对数组进行越界访问检查,因此对编译器来说不需要知道第一维的长度 //从后面的输出可以看出array和array+1相差40 //这说明array并不是一个普通的指针,它指向的数据类型大小为40,即10*sizeof(int) **void****func3**(**int**array[][10],**int**line) { **printf**("sizeof(array): %d, 0x%p, 0x%p/n",**sizeof**(array), array, array+1); }
**void****func4**(**int**(*array)[10],**int**line) { **printf**("sizeof(array): %d, 0x%p, 0x%p/n",**sizeof**(array), array, array+1); }
**int**array1[10]; **int**array2[8][10]; func1(array1, 10); // sizeof(array): 4, 0x0022FEB0, 0x0022FEB4 func2(array1, 10); // sizeof(array): 4, 0x0022FEB0, 0x0022FEB4 func3(array2,8); // sizeof(array): 4, 0x0022FD70, 0x0022FD98 func4(array2,8); // sizeof(array): 4, 0x0022FD70, 0x0022FD98 |
原文链接: https://www.cnblogs.com/zhtwe/archive/2010/08/30/2159004.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/14480
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!