向指针添加数字

时间:2015-03-01 14:46:04

标签: c pointers pointer-arithmetic

#include<stdio.h>
int main()
{  
     float a=10;
     float* p=&a;
    printf("%u\n",p);
     p=p+3;
     printf("%u",p);
}

在执行这个程序后,我得到了2个内存地址作为输出,thelatter的值比前者大12。

#include<stdio.h>
int main()
{  
     float a=10;
     float* p=&a;
    printf("%u\n",p);
     p=p+3.5;
     printf("%u",p);
}

我尝试将3更改为3.5,但我得到的输出具有相同的两个地址值。我预计在任何一种情况下,该值都至少增加12。 可能是什么原因?

3 个答案:

答案 0 :(得分:3)

C中只允许使用三种类型的指针算法:

  • 向指针添加整数。
  • 从指针中减去一个整数。
  • 从另一个指针中减去一个指针(它们应指向同一个数组)。

标准说:

C11:6.5.6加法运算符:

  

2另外,两个操作数都应具有算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应为整数类型。 (递增相当于添加1.)

     

3对于减法,以下之一应保持:

     

- 两个操作数都有算术类型;
   - 两个操作数都是兼容完整对象类型的限定或非限定版本的指针;或
   - 左操作数是指向完整对象类型的指针,右操作数是整数类型

任何其他算术运算都无效,并将调用未定义的行为。请注意,打印地址的正确说明符为%p

答案 1 :(得分:3)

这就是指针算法的工作原理。它旨在用于阵列。

float array[4];
float *q;
q = array; /* Now q points to the first element of the array: q == &array[0] */
printf("%p\n", q);
q += 3; /* Now q points to the fourth element of the array: q == &array[3] */
printf("%p\n", q);

向指针添加整数时,它会将许多元素指向数组。如果数组元素的大小是N个字节,那么将x添加到指针会将x * N添加到地址。

在您的计算机上,似乎sizeof(float)为4:您看到x * N = 12,x = 3,因此N = 4.

请注意,您的代码中存在多个错误。在您的程序中,p=p+3具有未定义的行为,因为p指向单个float(其内存布局与1 float的数组相同)。将指针指向对象边界之外是错误的。在典型的PC编译器上,您只需默默地获取无效指针;一个罕见的少数实现会在计算后立即检测到无效指针,并以错误中止程序。

使用%u打印指针值也是一个错误。在实践中,它可能会工作,打印垃圾或崩溃,具体取决于您的编译器以及指针是否与unsigned int具有相同的大小。任何中途体面的编译器都会警告你printf("%u", p)是不正确的;如果您没有,请确保启用其有用的警告(例如gcc -O -Wall如果您正在使用GCC)。

答案 2 :(得分:0)

the program contains several errors and poor programing practices

#include<stdio.h>
int main()
{  
    float a=10; // init floats with float values, so use '10.0f'
    float* p=&a;
    printf("%u\n",p); // print addresses with '%p' not '%u'
    p=p+3;        // now 'p' is pointed to some unknown area
    printf("%u",p); // print addresses with '%p' not '%u'
}

good thing the code did not 'de-reference' 'p' after 'p'
was modified, because that would have been undefined behaviour
possibly leading to a seg fault event