我不明白为什么下面的代码更改了数组b
:
int a[] = { 3, 6, 9 };
int b[] = { 2, 4, 6, 8, 10 };
int **c;
int **d[2];
c = (int **)malloc (b[1] * sizeof(int *));
*c = &a[1];
c[1] = c[0] + 1;
*d = c;
c = c + 2;
*c = b;
c[1] = &c[0][3];
*(d + 1) = c;
d[0][3][1] = d[1][0][0];
d[1][0][2] = d[0][1][0];
我已经运行了这段代码,并找到了数组a
和数组b
的值,但是我无法理解这些值的来源。
数组a
保持不变,而b
变为2, 4, 9, 8, 2
。这是怎么发生的?
c = (int**)malloc(b[1] * sizeof(int*)); //int **c[4] ???
c
是一个双指针数组*c = &a[1]
,这意味着c[0]
的地址为数组a的第二个索引。我没有办法解释这一点。
答案 0 :(得分:4)
该代码包含实际语句,因此它必须是函数主体的一部分,因此此处的所有声明均具有自动存储功能。它是高度复杂的,具有故意设计的双重间接...让我们一次对其进行分析:
int a[] = { 3, 6, 9 };
-a
是一个由3个整数组成的数组,这些整数初始化为一些显式值。
int b[] = { 2, 4, 6, 8, 10 };
-同样,b
是一个由3个整数组成的数组,这些数组以一些显式值初始化。
int **c;
-c
是指向int
的指针的未初始化指针,可以使它指向指向int
的指针数组。
int **d[2];
-d
是一个未初始化的数组,其中包含2个指向int
的指针,每个指针可以指向一个指向{{ 1}}。
int
-c = (int **)malloc(b[1] * sizeof(int *));
设置为指向未初始化的内存块,其大小为c
指向4
的指针。简而言之,int
现在指向c
指向4
的指针的未初始化数组。
int
-由*c = &a[1];
指向的元素(又名c
)被设置为指向A[0]
的第二个元素(又名{{1 }},其值为a
)。 a[1]
的值为6
。
A[0]
-由&a[1]
指向的数组中的第二个元素(也称为c[1] = c[0] + 1;
)被设置为指向{{ 1}},因此它指向c
的第三个元素(又名A[1]
,值为c[0]
)。 a
&a [2]`的值。
a[2]
-9
的第一个元素被设置为指针A[1] is
的值,它是*d = c;
的地址。 d
的值为c
。
A[0]
-指针d[0]
递增&A[0]
,现在指向由{{1}分配的数组c = c + 2;
的第三个元素},c
。
2
-由A
指向的元素malloc()
(本身就是一个指针)被设置为指向A[2]
的第一个元素,*c = b;
。 c
的值为A[2]
。
b
-之后的元素,由b[0]
分配的数组的第4个元素A [3]指向所指向的数组的第4个元素A[2]
指向的元素。 &b[0]
等效于c[1] = &c[0][3];
或malloc
或简称为c
。该元素是&c[0][3]
,其值为c[0] + 3
。 &(*c)[3]
&b [3]`的值。
*c + 3
-等效于b[3]
,它将8
的第二个元素设置为指针A[3] is
的值,该指针是指针的地址。分配给*(d + 1) = c;
,d[1] = c;
的数组的第三个元素,该元素指向d
。 c
的值为malloc()
。
A[2]
-让我们重写以下术语:
b[0]
=>(&A [0])[3] [1] => d[1]
=> &A[2]
=> d[0][3][1] = d[1][0][0];
=> {{ 1}}
d[0][3][1]
=> A[3][1]
=> (&b[3])[1]
=> *((b + 3) + 1)
=> b[4]
=> d[1][0][0]
(&A[2])[0][0]
。
因此(*&A[2])[0]
。
A[2][0]
-我们重写一下:
(&b[0])[0]
=> b[0]
=> 2
=> b[4] = 2;
=> d[1][0][2] = d[0][1][0];
=> d[1][0][2]
=> (&A[2])[0][2]
。(*&A[2])[2]
=> A[2][2]
,即(&b[0])[2]
=> (b + 0)[2]
=> b[2]
=> d[0][1][0]
,其值为{{ 1}}。(&A[0])[1][0]
结果,数组A[1][0]
现在具有元素(&a[2])[0]
。
您可以运行该程序:
*&a[2]