C 对于带有数组指针的循环,设置指针的值

C 对于带有数组指针的循环,设置指针的值,c,arrays,pointers,C,Arrays,Pointers,我对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 (i

我对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
开始指向未分配的位置(数组外部)-导致未定义的行为

基本方法 首先,您需要了解en数组表达式
a[i]
相当于
*(a+i)
,如果
p
是指向数组第一个元素的指针,则它也相当于
*(p+i)
。此外,
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
th位置的值被添加到
i-1
,其中
i
的值为
2>=i>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;
更好的代码
试试看

顺便说一句,在你的代码
a[i-1]+=a[i]中,
+=
在哪里看起来不像
*(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;