我正在学习C编程,我可以在线浏览本教程,这说明您应该尽可能多地使用[]运算符而不是指针算术。
您可以使用指针算法(但通常不使用指针算法)
考虑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++;
}使用指针算法会在软件中引起问题的情况是什么?它是不好的实践,还是它缺乏经验的工程师可以不注意?
发布于 2020-01-11 08:09:55
不建议这样做:
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++;
}因为没有任何理由您有两个指向同一位置的不同指针,2)您不检查malloc()的结果--已知它偶尔返回NULL,3)代码不容易阅读,4)很容易在后面很难发现一个愚蠢的错误。
总之,我建议用这个代替:
int array[50] = { 0 }; // make sure it's zero-initialized
int* p_array = array; // if you must =)发布于 2020-01-20 00:30:42
既然在这一点上似乎完全混淆了:
在过去,我们有16位CPU的Think8088,268等,你必须加载你的段寄存器(16位寄存器)和你的地址寄存器的地址。如果访问数组,则可以将数组基加载到段寄存器中,地址寄存器将是索引。这些平台的C编译器确实存在,但是指针算法涉及检查地址是否溢出,如果有必要的话,对段寄存器进行碰撞,在硬件中根本不可能实现平面寻址指针。
快速前进到80386,现在我们有一个完整的32位空间。硬件指针是可能的索引+基寻址引起了一个时钟周期的损失。段也是32位,所以即使您运行32位模式,也可以使用段加载数组,从而避免了这一损失。368也增加了2段寄存器的数量。(不知道为什么英特尔认为这是个好主意)仍然有很多16位代码。
现在,段寄存器在64位模式下被禁用,Base+Index寻址是免费的。
在硬件上,是否有一个平面指针可以优于数组寻址的平台?嗯,是的。摩托罗拉68000发布于1979年,有一个扁平的32位地址空间,没有段和基本+索引寻址模式导致8时钟周期的惩罚超过立即寻址。因此,如果你正在编程一个80年代早期的太阳站,Apple等,这可能是相关的。
总之。如果您想要数组,请使用数组。如果您想要指针,请使用指针。不要尝试和聪明你的编译器。将数组转换为指针的复杂代码不太可能带来任何好处,而且速度可能更慢。
发布于 2020-01-11 08:08:22
在您的示例中,如果没有编译器优化,指针算法可能会更高效,因为在每一个循环迭代中,只增加指针比计算新的偏移量要容易。但是,大多数现代CPU的优化方式是,使用偏移量访问内存不会造成(重大的)性能损失。
即使您碰巧是在指针算法更快的平台上编程,那么很可能,如果您激活编译器优化(大多数编译器上的“-O3”),编译器将使用任何最快的方法。
因此,是否使用指针算法主要是个人偏好的问题。
使用数组索引而不是指针算法的代码通常更容易理解,并且不容易出错。
不使用指针算法的另一个优点是,指针混叠可能不是什么问题(因为您使用的指针较少)。这样,编译器在优化代码(使代码更快)方面可能有更多的自由。
https://stackoverflow.com/questions/59692578
复制相似问题