c - 带有数组指针的for循环,将值设置为指针

标签 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 (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/

相关文章:

php - 修复未加引号的 PHP 数组键

Mysql 嵌套并声明为数组

c++ - 找到相对于任意原点的两点之间的顺时针角度

c - 删除和替换文件后哈希函数返回不同的结果

c++ - 在 C 中比较相同的浮点值

Ruby 创建数组形式的 git 日志?

c - 打印有很多限制的字符串

C:使用指向 uint8_t[] 的指针时遇到一些问题

c - 这可能吗? [指向字符数组 C 的指针]

c - 使用 'char' 类型输入的无限循环