c中的指针如何在这里工作?

时间:2010-11-02 02:58:22

标签: c pointers

#include <stdio.h>

int my_array[] = {1,23,17,4,-5,100};
int *ptr;

int main(void)
{
    int i;
    ptr = &my_array[0];     /* point our pointer to the first
                                      element of the array */
    printf("\n\n");
    for (i = 0; i < 6; i++)
    {
      printf("my_array[%d] = %d   ",i,my_array[i]);   /*<-- A */
      printf("ptr + %d = %d\n",i, *(ptr + i));        /*<-- B */
      printf("ptr + %d = %d\n",i, *ptr++);
      printf("ptr + %d = %d\n",i, *(++ptr));
    }
    return 0;
}
ptr ++应该打印ptr值而不是增量,而++ ptr在ptr中执行第一次增量而不是打印ptr的值..但是当我编译代码时它会给我相同的结果,什么是void指针。有什么用呢。

5 个答案:

答案 0 :(得分:2)

这些行:

printf("ptr + %d = %d\n",i, *ptr++);
printf("ptr + %d = %d\n",i, *(++ptr));

修改指针值。因此,在每次迭代中,您将在当前位置i之外添加2个偏移量。当你的for循环到达第6次迭代时,你将尝试从数组的末尾打印内存位置到6(迭代)* 2(偏移)* 4(int size)=超出48个字节。

答案 1 :(得分:2)

表达式*ptr++被解析为*(ptr++),并按如下方式进行评估:

  1. 检索ptr
  2. 的当前值
  3. 取消引用此指针值以获取整数值
  4. 在下一个序列点之前的某个时刻,将 1 sizeof *ptr添加到ptr
  5. 大致等同于写作

    x = *ptr;
    ptr = ptr + sizeof *ptr;
    

    除了更新ptr的副作用可能在下一个序列点之前的任何时间发生(从不假设以特定顺序应用副作用); IOW,序列可能是

    tmp = ptr;
    ptr = ptr + sizeof *ptr;
    x = *tmp;
    

    在这种情况下,序列点位于printf函数调用的末尾。

    表达式*(++ptr)被解析为书面形式,并按如下方式计算:

    1. 检索ptr + sizeof *ptr
    2. 的当前值
    3. 将此指针值推迟以获取整数值
    4. 在下一个序列点之前的某个时刻,将 1 sizeof *ptr添加到ptr
    5. 大致等同于写

      tmp = ptr + sizeof *ptr;
      x = *tmp;
      ptr = ptr + sizeof *ptr;
      

      同样,更新ptr的值的副作用可能发生在下一个序列点之前的任何点; IOW,序列可能是

      tmp = ptr + sizeof *ptr;
      ptr = ptr + sizeof *ptr;
      x = *tmp;
      

      这是程序启动时的假设存储器映射(假设32位地址和16位整数):

      Item        Address            0x00  0x01  0x02  0x03
      ----        --------           ----  ----  ----  ----
      my_array    0x08000000         0x00  0x01  0x00  0x17
                  0x08000004         0x00  0x11  0x00  0x04
                  0x08000008         0xff  0xfb  0x00  0x64
      ptr         0x0800000C         0x00  0x00  0x00  0x00
      i           0x10008000         0x??  0x??  0x??  0x??
      

      0x??表示随机字节值。由于ptr在文件范围内声明,因此它具有静态范围并隐式初始化为NULL。由于i被声明为auto,因此它未初始化并包含随机垃圾。

      执行语句ptr = &my_array[0]后,ptr的值为0x08000000

      执行

      行时
      printf("ptr + %d = %d", i, *ptr++);
      

      表达式*ptr++取消引用地址0x08000000的内存,其中包含值1,因此输出为

      ptr + 0 = 1
      

      ++运算符的副作用会将ptr的值更新为0x08000002

      执行

      行时
      printf("ptr + %d = %d, i, *(++ptr));
      

      由于表达式*(++ptr)的计算结果为0x08000004,因此表达式0x08000002会对 ++ptr 而非ptr + sizeof *ptr的记忆产生差异。所以这一行的输出是

      ptr + 0 = 17
      

      并且++运算符的副作用会将ptr的值更新为0x08000004

      当你循环时,你的输出看起来像

      my_array[0] = 1     /* ptr = 0x08000000 */
      ptr + 0 = 1
      ptr + 0 = 1         /* ptr = 0x08000002 after */
      ptr + 0 = 17        /* ptr = 0x08000004 after */
      my_array[1] = 23
      ptr + 1 = 4         
      ptr + 1 = 4         /* ptr = 0x08000006 after */
      ptr + 1 = -5        /* ptr = 0x08000008 after */
      

答案 2 :(得分:1)

经过几次循环之后,你将开始引用超出数组末尾的内存;除此之外,你的程序看起来很有意义。

答案 3 :(得分:0)

你可能只看输出的最后一部分,因为当我编译它时,它会显示数组的每个值,然后在你完成代码的整个部分之后显示0。

至于无效指针:

它们也称为通用指针,因为您可以将它们分配给任何数据类型。

答案 4 :(得分:0)

首先像Ignacio指出的那样,这都是C代码。不是c ++。 C ++是C的超集。

1)我想指出你的for循环不安全。因为您在每次迭代中将循环内部的指针递增两次。因此,您将在第4次迭代时结束在分配的数组之外。

2)任何C问题请参考优秀的c faq和c ++ faq。这是您问题的相关答案。 http://c-faq.com/ptrs/unopprec2.html。    它与运算符优先级有关。 * ptr ++相当于*(ptr ++)。

第一次迭代的输出应该是 1 1 1 17

void指针是通用指针。你不能对它做算术。它只是用于传递位置,粗略地说。另外,重要的是你不能对它进行算术运算。因为,你不知道它指向的是什么。