A. b[i][j] 这是最基本的访问二维数组元素的方式。在内存中,二维数组b被存储为一系列连续的内存块。因此,b[i][j]实际上是*(b[i] + j),即先访问第i行的起始地址,然后偏移j个元素。这种写法是最直观和常见的。
B. *(b[i]+j) 这是通过指针算术来访问二维数组b的第i行第j列元素的方式。首先,b[i]得到第i行的起始地址,然后加上j,相当于偏移了j个元素,最后用 * 解引用得到了元素的值。
C. *(*b+i)+j 这个表达式是无效的。首先,*b是第一行的起始地址,然后加上i,这样得到的地址是第i行的起始地址。然后再解引用,得到第i行的第一个元素,接着再加上j,这是一个错误的写法。
D. (*(b+i))[j] 这是另一种通过指针算术来访问二维数组b的第i行第j列元素的方式。首先,b+i得到了第i行的起始地址,然后用 * 解引用得到第i行的数组,最后再用 [j] 访问第j列的元素的值。
#include<iostream> using namespace std; int main(){ int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; // 目标:访问arr[1][2] = 6。// ps: arr[2][1] = 8 // \ 0 1 2 // 0 1 2 3 // 1 4 5 6 // 2 7 8 9 int i = 1,j = 2; // *****B项***** cout<<*(arr[i]+j)<<endl;// arr[i]是第i+1行一维数组的首地址,加j就是列向后移动j个单位 // *****C项*****逐层分析 // 内层 cout<<arr<<endl;// 二维数组首地址(验证:加一代表向下移动一行) // cout<<arr + 1<<endl; cout<<*arr<<endl;// 二维数组第零行的首地址(验证:加一代表向左移动一个元素) // cout<<*arr + 1<<endl; cout<<&arr[0][0]<<endl;// 结果相同都是arr[0][0]的地址 // cout<<**arr<<endl; // 思考:这行输出个啥 // 此时外层分析就easy了,就是arr第零行下标为i的元素在数值上加j后输出,验证:可把arr[1][0]赋值为40,输出结果不变 // arr[1][0] = 40; cout<<*(*arr+i)+j<<endl; // *****D项***** cout<<(*(arr+i))[j]<<endl;// 由C项的分析(18行)知(*(arr+i))等价于arr[i] // cout<<*((*(arr+i))+j)<<endl;// 输出结果相同 } // 思考答案:**arr输出首元素:1 // 总结:二维数组*与[]符号累计出现两次就是数值,一次及以下(arr)就是地址,在此基础上理解+i的意义即可
6 0x61fdf0 0x61fdf0 0x61fdf0 4 6 这是运行结果。 感兴趣的可以把代码粘走试试,再自己组合一下*,[]对二维数组操作一下,还是挺助于理解的,毕竟编译器不会骗人
A.通过下标的方式取到第i行第j行的元素,正确
B.b[i]表示第i行,
b[i]+j表示第i行第j列,
*(b[i]+j)表示取值;正确
C.因为二维数组名b表示行地址,即第一行的行地址;
*b表示把行降级为列,则*b+i表示第一行第i个元素的地址,也就是b[0][i];
*(*b+1)表示取b[0][i]的值,也就是第一行第i个元素的值;
所以*(*b+i)+j是取了b[0][i]的值之后加j;错误
D.b+i,代表的是第i行的行首地址;
*(b+i)即把行地址降为列地址;
(*(b+i))[j]即以下标的方式取第i行中的第j个元素的值;正确