“*a”和“a[0]”有什么区别?

14

给定一个用户定义类型 A,以及一个指针 A* a*aa[0] 有什么区别?

(虽然 *(a+0)/a[0] 被定义为等价的,但对于 *a/a[0] 来说情况并非如此,在某些情况下微妙的差异可能导致编译错误。)


不,将“++”词法地附加到表达式中,并从“A”的可增量性中删除它并不算。 - Lightness Races in Orbit
1
“*a/a[0]”,在某些情况下微小的差异可能会导致编译错误 - 例如? - user529758
4
+1,我认为这是一个有趣的谜题。我曾经编写过一个类似于template<typename T, int N> T *begin(T(&x)[N]) { return &x[0]; }的begin函数,并没有注意到使用数组语法时对T产生了微妙的无用要求。 - Johannes Schaub - litb
3
@Non-StopTimeTravel,我建议你重新撰写你的问题,展示相关的场景和编译错误,并给出你显然知道的答案。否则,我同意“trolling”不是描述这种行为最糟糕的术语... - πάντα ῥεῖ
1
我们应该将*a视为表达式,还是只是一段文本?例如b * ab a[0] - Andy Prowl
@AndyProwl:作为一个表达式。所以,是的,不仅仅是词法上的。否则后缀++的例子就可以让你到达那里。 - Lightness Races in Orbit
1个回答

36

如果A是不完整的类型,则*a可用,但a[0]不能使用,在这个例子中

struct A;

void foo(A& r)
{
}

void bar(A* a)
{
    foo(*a);
    foo(a[0]);   // error: invalid use of incomplete type ‘struct A’
}

那是因为a[0]等同于*(a+0),但你不能对一个不完整类型的对象的指针加上任何值(包括零),因为指针算术需要已知大小。


4
sizeof(e) 需要求出 e 的类型必须是一个完整的类型,否则这种操作就没有意义。 - Yakov Galka
2
@Non-StopTimeTravel 你确实在恶意挑衅,即使有一个简洁的答案。 - user529758
9
如果你知道答案,自己回答你自己的问题。 - StilesCrisis
1
3.2/4 表示:如果将 sizeof 运算符(5.3.3)应用于类型为 T 的操作数,则必须完成类类型 T。 - Lightness Races in Orbit
1
@H2CO3: 相反,你声称解引用和绑定引用是彼此的反义词。我要说的是,标准甚至没有暗示这一点,它只是暗示只要你不使用它,你可以为一个未知类型的对象创建一个别名,如果你知道它在哪里。 - David Rodríguez - dribeas
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接