【问题标题】:Array Assignments in C Using Pointer ArithmeticC中使用指针算术的数组赋值
【发布时间】:2013-03-18 01:43:50
【问题描述】:

当我使用指针算法访问特定元素时,如何更改数组中的值?

#include <stdio.h>

int main() {
  int a[3] = {1, 1, 1}, b[3] = {2, 2, 2};

  a++ = b++; // How can I get this to work so a[1] = b[1]?

  return 0;
}

【问题讨论】:

  • 您也许可以摆脱*(a+1) = *(b+1),因为这样可以进行算术运算,而无需像a++ 那样尝试更新变量本身。问题是您为什么要这样做:indexed 表单,正如您已经展示的 a[1] = b[1] 是等效的并且更易于阅读。

标签: c arrays pointers pointer-arithmetic


【解决方案1】:

数组不是指针。重复此操作三遍; 数组不是指针

你不能增加一个数组,它不是一个可赋值的值(即你不能改变它)。您当然可以对其进行索引以获取值:

a[1] = b[1];

其次,当您打算分配给数组的一个元素时,您当前的代码正在尝试递增然后为 数组本身分配一个新值。数组在需要时会降级为指针,所以这也可以:

int *a_ptr = a;
int *b_ptr = b;
*++a_ptr = *++b_ptr;
// or, better...
a_ptr[1] = b_ptr[1];

这就是你想要做的。我更喜欢版本 1,而且通常也使用带指针的索引,因为它通常更易于阅读。

【讨论】:

  • *++a_ptr = *++b_ptr; 代表a[1] = b[1];
  • 重复三遍……这很有趣。
  • “这就是你的本意。” -- 不,OP 打算做a[1]++a[1] = b[1]
  • @JimBalter:我怀疑你对第一个是正确的,第二个是我给出的例子......我的指针示例做了完全相同的事情,但也增加了指针。跨度>
  • a) 我说的是“或”。如果我的析取分支之一为真,则该陈述为真。值得怀疑的是 OP 的含义,以及许多在这里回答的人的教学技能。 b)不,您的第二个示例影响a[0],而不是a[1],并且具有相同的效果并不相同。 OP 的评论说 a[1] 应该与 b[1] 相同......与指针运算无关;这是人们根据自己的知识和经验做出的假设,而不是 OP 的假设。
【解决方案2】:

我怎样才能让它工作,所以 a[1] = b[1]?

简单:

a[1]++;

如果您只是想将 a[1] (1) 增加到 b[1] 恰好是 (2),或者

a[1] = b[1];

如果您希望 a[1] 具有与 b[1] 相同的值,无论该值是什么。

当我使用指针算法访问特定元素时?

在您的示例中,您没有访问任何元素,也没有进行指针运算,因为 ab 是数组,而不是指针。你的问题的表述很难解释,既是因为这个,也是因为

a++ = b++;

1) 完全没有意义 2) 即使ab 指针也不合法,因为左边必须是左值,但a++ 不是 3 ) 与您希望 a[1]b[1] 相同的愿望没有明显相关。可能你想要的是:

int* ap = a; // get pointer to first element of a
int* bp = b; // get pointer to first element of b

// point ap to second element of a and
// point bp to second element of b and
// copy the value at *bp to *ap
*++ap = *++bp;

这确实会将a[1] 设置为b[1]

【讨论】:

  • 我应该指出,虽然您的第一个选项有效,但它在语义上是不正确的。如果a[1] 必须始终假定b[1] 的值,那么a[1]++ 具有完全不同的含义,无论它是否在给定示例中实现相同的结果。这两个例子都与指针运算无关。
  • “它在语义上是不正确的”——正如我所说,“取决于你的意图到底是什么”。 OP 并没有说a[1] 必须始终假定b[1] 的值,所以没有办法知道什么在语义上是正确的。 “这两个例子都与指针算术无关”——为什么这里的人会认为这个问题与指针算术有关?请记住,OP 是一个完整的 C 新手,并且可能不打算通过 a++ 进行指针运算(这当然不进行指针运算,因为 a 不是指针)。
  • P.S.我是 X3J11 的前成员和 35 年的 C 程序员,我不是新手,不需要居高临下地谈论什么具有完全不同的含义或与指针运算无关。
  • 当他们使用术语“指针算术”时,你肯定要相信他们的话。即使是使用该术语的新手也意味着他们所说的。还有语义……好吧,我们可以整天扯头发。我试图提出建设性的意见。要么接受,要么离开它。 =)
  • @SeKa 没有办法让人们在阅读某些内容时进行思考,坦率地说,我不相信我的澄清会有所不同......如果有人不理解 1+1 = x = 2 仅当 x = 2 而不是当 x 具有其他值时,无论多么详细,他们都无法理解这个或任何其他 SO 答案。
【解决方案3】:

在这种情况下,您的数组实际上并不是指针。当它们作为指针访问时,它们会被编译器转换,但我不相信你可以做类似a++的事情。

如果你想用算术来做这件事,你需要实际的指针:

int *ap = a, *bp = b;

*ap++ = *bp++;

这就像a[0] = b[0]; 然后将每个指针移动到其关联数组中的下一个元素。

但是你的问题是你想设置a[1] = b[1]。好吧,你可以这样做:

*++ap = *++bp;

或者你可以只使用数组索引,让你在做什么更明显。

【讨论】:

  • "当它们作为指针访问时,它们会被编译器转换" -- 不,当传递给具有指针参数的函数时,它们会被语言规范“转换” ...也就是说,数组的第一个元素的地址被传递给函数而不是整个数组,因为数组不是 C 中的第一类对象(它们不能是因为它们的长度没有被存储) . “我不相信你可以做类似 a++ 的事情”——事实上,因为 ++ 不是函数调用。
  • “当传递给具有指针参数的函数时”——实际上我应该说“当分配给指针时”——传递给指针参数是一个实例。
  • @JimBalter:它们实际上在除&amp; 运算符和sizeof(以及支持它的地方的typeof)之外的任何上下文中都转换为指针,而不仅仅是在传递时
  • @newacct 对……我似乎一直在遗漏一些东西。此外,我对上面的评论进行了更正:“我不相信你可以做类似 a++ 的事情”——事实上,因为 a 被转换为 &amp;a[0],这不是左值。
  • 鉴于这一切,我说它们“在作为指针访问时被编译器转换”实际上是错误的吗?对我来说,这意味着编译器理解您正在尝试使用数组,就好像它是一个指针(根据语言规范),并且它会进行适当的转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
  • 2021-05-13
  • 2021-05-12
  • 2020-09-07
  • 1970-01-01
  • 2016-05-03
  • 2018-10-20
相关资源
最近更新 更多