指针增量运算符错误

时间:2010-11-01 14:36:27

标签: c operator-precedence

好的,所以这个让我很困惑。 我正在研究硬件问题,并发现了一些对我来说非常奇怪的东西。 这是功能和有问题的电话

int find_oldest_frame(int **a, int size)
{
   int min = clock();
   int **ptr;
   int *ptr2;
   int frame = 0;
   int i;
   // get address of pointer so we can modify it
   ptr = a;
   // store off original pointer location.
   ptr2 = *a;

   for (i=0; i<size; i++)
   {

      // Who is the oldest time
      if (**ptr < min)
      {
         min = **ptr;
         frame = i;
      }
      printf("Current_Pointer %d\n", *ptr);
      *ptr++; // For some reason ++ doesn't work.

   }
   // now store the oldest frame with the current system time, so it's no longer the oldest.
   *ptr = ptr2;
   *ptr += frame;
   **ptr = clock();
   *ptr = ptr2;
   // Return the array index so that we can change the right page!
   return frame;

}

所以长话短说,我得到一个弹出窗口(在窗口中),表示存在问题并且必须关闭。

当我尝试更换时     * PTR ++; 同     * PTR + = 1;

程序运行。 这让我感兴趣所以我在gcc中使用-S 使用* ptr ++版本,我得到了这条指令:

addl    $4, -20(%ebp)

* p + = 1我得

movl    -20(%ebp), %eax
movl    (%eax), %eax
leal    4(%eax), %edx
movl    -20(%ebp), %eax
movl    %edx, (%eax)

对我而言,这看起来像是一个非常相似的操作,所以假设我正确地阅读了这个,

案例1

增加-20(%ebp)乘以4(假设$ 4表示)

案例2

我们将ebp中的内容存储到eax,

(不确定()做什么),但又做了吗?

然后将eax偏移量的地址从4加载到edx,

现在再次将ebp复制回eax,

现在将edx复制到eax,

我的意思是看起来他们正在做同样的事情,但出于某种原因* ptr ++!= * ptr + = 1

为什么呢?我看到的是什么?

编辑:感谢现在每个人都觉得特别,我无法相信我没有意识到这一点!

4 个答案:

答案 0 :(得分:6)

这实际上是operator precedence的问题。在取消引用指针之前,后缀增量运算符应用,这意味着您递增指针的值(它指向的内存),然后尝试取消引用它。这是调用未定义的行为,因为它指向单个int

在后一种情况下,{<1}}在取消引用后应用,因此您获得存储在指针内存中的值,然后添加到它。如果要使用后缀增量,则需要确保首先取消引用,您可以使用以下命令来执行:

+=

而不是你现在拥有的。

答案 1 :(得分:2)

*ptr++; // For some reason ++ doesn't work.

应该是

 (*ptr)++;

运算符优先级在此处起作用 - *ptr++以这种方式工作:*(ptr++) - 与

相同
 while( ( *t++ = *s++ ) != 0 );

复制以null结尾的字符串。

答案 2 :(得分:2)

运算符优先级不相同。它们分别相当于:

*(ptr++);

(*ptr) += 1;

你可以*(ptr)++;增加指向值并保持指针本身不受影响。

答案 3 :(得分:1)

++运算符的precedence高于*,其优先级高于+=++绑定到ptr,而+=绑定到(*ptr)