#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。 可能是什么原因?
答案 0 :(得分:3)
C中只允许使用三种类型的指针算法:
标准说:
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