Maz*_*azi 5 c c++ pointer-arithmetic multidimensional-array implicit-conversion
常规静态分配数组如下所示,可以使用以下公式进行访问:
const int N = 3;
const int M = 3;
int a1[N][M] = { {0,1,2}, {3,4,5}, {6,7,8} };
int x = a1[1][2]; // x = 5
int y = *(a1+2+N*1); // y = 5, this is what [] operator is doing in the background
Run Code Online (Sandbox Code Playgroud)
数组是连续的内存区域。在动态数组分配的情况下看起来有所不同,而是有指向数组的指针数组:
int** a2 = new int*[N];
for (int i = 0; i < N; i++)
a2[i] = new int[M];
//Assignment of values as in previous example
int x = a2[1][2];
int y = *(*(a2+1))+2); // This is what [] operator is doing in the background, it needs to dereference pointers twice
Run Code Online (Sandbox Code Playgroud)
我们可以看到,在典型的连续数组和动态分配数组的情况下,[]运算符所做的操作是完全不同的。我的问题现在如下:
对于这个数组的声明
int a1[N][M] = { {0,1,2}, {3,4,5}, {6,7,8} };
Run Code Online (Sandbox Code Playgroud)
这些记录
int x = a1[1][2];
int y = *(a1+2+N*1);
Run Code Online (Sandbox Code Playgroud)
不等价。
第二个是不正确的。该表达式*(a1+2+N*1)的类型隐式转换为用作初始值设定int[3]项的类型的对象。int *所以整型变量y是由指针初始化的。
运算符 a1[1] 的计算方式类似于*( a1 + 1 )。结果是 类型的一维数组int[3]。
因此,应用第二个下标运算符,您将得到*( *( a1 + 1 ) + 2 )。
使用二维数组和动态分配数组时的表达式之间的区别在于,该表达式中二维数组的指示符(a1 + 1) 隐式转换为指向其类型的第一个元素的指针int ( * )[3],而指向动态分配数组的指针指针数组仍然具有相同的类型int **。
在第一种情况下,取消引用表达式,*(a1 + 1 )您将获得类型的左值int[3],该类型的左值又在表达式中使用,*( a1 + 1) + 2并再次隐式转换为类型的指针int *。
在第二种情况下,表达式*(a1 + 1)生成 类型的对象int *。
在这两种情况下都使用了指针算术。不同之处在于,当您在下标运算符中使用数组时,它们会隐式转换为指向其第一个元素的指针。
当您动态分配数组时,您已经处理了指向其第一个元素的指针。
例如,代替这些分配
int** a2 = new int*[N];
for (int i = 0; i < N; i++)
a2[i] = new int[M];
Run Code Online (Sandbox Code Playgroud)
你可以写
int ( *a2 )[M] = new int[N][M];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
196 次 |
| 最近记录: |