指针算术伪装&(数组[0])

时间:2013-01-08 00:05:49

标签: c++ c pointers pointer-arithmetic

今天我浏览了一些源代码(这是一个解释软件框架使用的示例文件)并发现了很多这样的代码:

int* array = new int[10]; // or malloc, who cares. Please, no language wars. This is applicable to both languages
for ( int* ptr = &(array[0]); ptr <= &(array[9]); ptr++ )
{
   ...
}

所以基本上,他们已经完成了“获取位于地址array + x的对象的地址”。

通常我会说,这很简单,因为写array + 0array + 9直接做同样的事。我甚至总是会将这样的代码重写为size_t for循环,但这是一种风格问题。

但是过度使用这个让我思考:我是否遗漏了一些明显或者隐藏在语言黑暗角落里的东西?

对于任何想要查看原始源代码的人,以及所有令人讨厌的gotomalloc s,当然还有这个指针的东西,请随意look at it online。< / p>

5 个答案:

答案 0 :(得分:5)

是的,第一个没有充分的理由。这是完全相同的事情:

int *ptr = array;

我同意第二,也可以写一下:

ptr < (array + 10)

当然你也可以从0到9进行for循环,并将temp指针设置为指向数组的开头。

for(int i = 0, *ptr = array; i < 10; ++i, ++ptr)
    /* ... */

当然,假设ptr未在循环体内被修改。

答案 1 :(得分:2)

你没有遗漏任何东西,他们的确意味着同样的事情。

然而,为了试图对此有所了解,我应该说我还会不时地写出这样的表达,以增加清晰度。

我个人倾向于考虑面向对象编程,这意味着我更喜欢引用“数组n元素的地址”,而不是“n偏离数组的起始地址“。虽然这两件事在C语言中是等价的,但当我编写代码时,我会记住前者 - 所以我表达了这一点。

也许这也是写这篇文章的人的推理。

答案 2 :(得分:1)

编辑:部分不正确。阅读评论。


&(array[0])的问题在于它扩展为&(*(array + 0)),涉及取消引用。现在,每个编译器显然都会将其优化为与array + 0相同的内容,但就语言而言,取消引用可能会导致array + 0不会出现的UB。

答案 3 :(得分:1)

我认为他们这样写的原因是

&(array[0])

&(array[9])

看起来很相似。另一种方法是写它

array + 0

array + 9

分别。正如您已经提到的,它们基本上是这样做的(至少大多数编译器都将它视为相同的,我希望)。

您可以不同地解释两种不同类型的表达式:第一种可以被解读为“元素0/9的地址”。第二个可以读作“元素偏移为0/9的数组指针”。第一个听起来更高级别,第二个听起来更低级别。但是,大多数人倾向于使用第二种形式。

现在array + 0当然与array相同,你可以写array。我认为这里的重点是循环的开始和结束看起来彼此“相似”。个人品味问题。

答案 4 :(得分:1)

根据经典数学:

Array[n]

指的是数组中的 nth 元素。

要“取 nth 元素的地址,应用&address of运算符:

  &Array[n]  

要清除任何假设的歧义,请添加括号:

  &(Array[n])  

对于读者,从左到右阅读,这个表达具有以下含义:
    返回位置'n'

的元素地址

保险可能已经发展成为对旧故障编译器的保护。

有些人认为它比以下更具可读性:

  Array + n  

抱歉,我上学了,而且更喜欢使用'&amp;'版本,paren或没有。我会浪费我的时间使代码更容易阅读,而不是担心哪个版本需要更长的编译时间或哪个版本更有效。

明确评论的代码部分具有更高的投资回报率,而不是针对效率进行微优化的代码部分,或者使用对非语言律师不熟悉的语言部分。