我是 C 的新手,必须使用现在有点令人困惑的指针。
我的任务是重写一段代码:
const int length = 3;
int a[3] = { 2, 1, 3 };
int* p = a;
for (int i = length - 1; i > 0; i--)
a[i - 1] += a[i];
因此它不再使用数组的“[]”,而是使用指针。
我的第一次尝试:
const int length = 3;
int a[3] = { 2, 1, 3 };
int* p = a;
for (int i = length - 1; i > 0; i--) {
*(p - 1) += *p;
p--;
}
所以我知道这个不起作用,但我不知道如何正确使用指针。什么时候使用 *
什么时候不用?这到底是什么意思? *
是指针后面的值,而 p 本身是地址吗?如何递减/递增指向下一个地址的指针?
提前致谢
最佳答案
错误
指针p
已经指向数组的第一个元素,自减操作(--p
)后,p
开始指向一个位置未分配(在数组外)——导致未定义的行为。
基本方法
首先你需要明白数组表达式 a[i]
等价于 *(a + i)
也等价于 *(p + i)
如果 p
是指向数组第一个元素的指针。此外,a[i - 1]
也可以写成 *(a + i - 1)
等价于表达式 *(p + i - 1)
。
在 p
的声明中:
int* p = a;
数组名称衰减到数组中第一个元素的地址(与 &a[0]
相同)。
现在,以下是反向循环 - 从数组中的最后一个位置向后迭代。
for (int i = length - 1; i > 0; i--)
a[i - 1] += a[i];
也可以写成:
for (int i = length - 1; i > 0; i--)
*(a + i - 1) += *(a + i);
所以可以写成
for (int i = length - 1; i > 0; i--)
*(p + i - 1) += *(p + i);
代码中的更正
这只是以 p
指向第一个元素的指针的形式简单翻译您的代码。
让我们采用一种新方法并了解循环的实际作用:
for (int i = length - 1; i > 0; i--)
a[i - 1] += a[i];
运算 a[i - 1] += a[i];
等同于 a[i - 1] = a[i - 1] + a[i];
。这意味着 — 在循环中,在每次迭代中,第 i
位置的值被添加到 i - 1
,其中 i
的值是 2 >= 我 > 1
。见:
for (int i = 3 - 1; i > 0; i--)
// ^^ == 2
a[i - 1] = a[i - 1] + a[i];
所以,如果数组的初始值为:a[3] = { 2, 1, 3 };
那么每次迭代都是:
// 0 1 2
{ 2, 1, 3 };
i = 2
a[2 - 1] = a[2 - 1] + a[2];
a[1] = a[1] + a[2]
{ 2, 4, 3 };
i = 1
a[1 - 1] = a[1 - 1] + a[1];
a[0] = a[0] + a[1]
{ 6, 4, 3 };
在上面的循环中,您迭代回来并将当前 i
索引值添加到先前的索引中。请注意,因为在每次迭代中,您都在 i - 1
处访问一个元素,因此循环必须在 i == 1
处中断,或者我们可以说在 i > 0
.
让我们按照您希望的方式重写正确的代码:
const int length = 3;
int a[3] = { 2, 1, 3 };
int* p = a + length - 1; // now `p` points to `&a[2]`
for (int i = length - 1; i > 0; i--)
*(p - 1) += *p;
--p;
更好的方法
现在,这仍然是相当冗长的代码,我们可以改进它如下:
int a[3] = { 2, 1, 3 };
for (int* p = &a[2]; p != a; --p)
*(p - 1) += *p;
更好的代码
int a[] = { 2, 1, 3 };
int length = sizeof(a) / sizeof(*a);
for (int* p = a + length - 1 ; p != a; --p)
*(p - 1) += *p;
试试吧!
关于c - 带有数组指针的for循环,将值设置为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30017997/