今天我浏览了一些源代码(这是一个解释软件框架使用的示例文件)并发现了很多这样的代码:
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 + 0
或array + 9
直接做同样的事。我甚至总是会将这样的代码重写为size_t for循环,但这是一种风格问题。
但是过度使用这个让我思考:我是否遗漏了一些明显或者隐藏在语言黑暗角落里的东西?
对于任何想要查看原始源代码的人,以及所有令人讨厌的goto
,malloc
s,当然还有这个指针的东西,请随意look at it online。< / p>
答案 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或没有。我会浪费我的时间使代码更容易阅读,而不是担心哪个版本需要更长的编译时间或哪个版本更有效。
明确评论的代码部分具有更高的投资回报率,而不是针对效率进行微优化的代码部分,或者使用对非语言律师不熟悉的语言部分。