【发布时间】:2018-12-24 16:35:39
【问题描述】:
在书中,"Understanding and Using C Pointers" by Richard Reese 在第 85 页上写着,
int vector[5] = {1, 2, 3, 4, 5};
vector[i]生成的代码与*(vector+i)生成的代码不同。符号vector[i]生成从位置向量开始的机器代码,移动i从该位置定位,并使用其内容。符号*(vector+i)生成从位置vector开始的机器代码,添加i到地址,然后使用该地址的内容。虽然结果相同,但生成的机器代码不同。这种差异对大多数程序员来说很少有重要意义。
您可以看到excerpt here。这段话是什么意思?在什么情况下,任何编译器都会为这两者生成不同的代码?从基地“移动”和“添加”到基地有区别吗?我无法让它在 GCC 上工作——生成不同的机器代码。
【问题讨论】:
-
我能想到的情况是使用内存检查工具和代码检查工具,因为它们确实试图考虑代码的预期含义。
-
"生成的机器码不同。"对于大多数当代编译器来说可能是错误的。
-
对我来说,“将 i 添加到地址”意味着移动 i 个字节。但实际发生的是它增加了 i * sizeof(&vector[0]) 字节。正如其他人指出的那样,C 标准将 a[i] 声明为 *(a + i),所以这段话简直令人困惑。
-
@KonradRudolph 我有很多关于书籍和已发表博客的指针的问题,如果你想毁掉你的一周,我认为这些都是勘误表。 stackoverflow.com/q/51227140/124486 更多内容也在筹备中。
-
如果下标是常量表达式(如
a[5]),编译器会生成不同的代码,因为它可以在编译时计算偏移量,但我看不出a[i]和@如何在翻译时不知道i的值的情况下,987654334@ 的处理方式将有所不同。
标签: c arrays pointers pointer-arithmetic errata