我正在学习 C 编程,我在网上看到了本教程,其中指出您应该始终尽可能多地使用 [] 运算符而不是指针算法。
https://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html#dynamic
you can use pointer arithmetic (but in general don't)
考虑下面的 C 代码
int *p_array;
p_array = (int *)malloc(sizeof(int)*50);
for(i=0; i < 50; i++) {
p_array[i] = 0;
}
使用如下代码 的指针算术有什么区别? (以及为什么不推荐) ?
int *p_array;
p_array = (int *)malloc(sizeof(int)*50); // allocate 50 ints
int *dptr = p_array;
for(i=0; i < 50; i++) {
*dptr = 0;
dptr++;
}
在哪些情况下使用指针算法会导致软件出现问题?这是不好的做法还是缺乏经验的工程师可能不注意?
最佳答案
由于对此似乎完全困惑:
在过去,我们有 16 位 CPU 认为 8088、268 等。
要制定地址,您必须加载段寄存器(16 位寄存器)和地址寄存器。如果访问数组,则可以将数组基址加载到段寄存器中,地址寄存器将作为索引。
这些平台的 C 编译器确实存在,但指针算法涉及检查地址是否溢出并在必要时碰撞段寄存器(低效)平面寻址指针在硬件中根本不可能。
快进到 80386 现在我们有一个完整的 32 位空间。硬件指针是可能的 索引 + 基址寻址会导致 1 个时钟周期的损失。不过,这些段也是 32 位的,因此即使您正在运行 32 位模式,也可以使用段加载数组,避免这种损失。 368 还将段寄存器的数量增加了 2。(不知道为什么 Intel 认为这是个好主意)尽管周围仍然有很多 16 位代码
现在,段寄存器在 64 位模式下被禁用,Base+Index 寻址是免费的。
是否有任何平台在硬件中平面指针的性能优于数组寻址?嗯,是。 1979 年发布的摩托罗拉 68000 具有平坦的 32 位地址空间,没有段,并且基址 + 索引寻址模式比立即寻址会导致 8 个时钟周期的损失。因此,如果您正在编写 80 年代早期的 Sun 站、Apple Lisa 等程序,这可能是相关的。
简而言之。如果需要数组,请使用数组。如果你想要一个指针,使用一个指针。不要尝试聪明的编译器。将数组转换为指针的复杂代码极不可能提供任何好处,并且可能会更慢。
关于c - 为什么不建议在 C 中使用指针进行数组访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59692578/