C 向指针添加数字 #包括 int main() { 浮点数a=10; 浮动*p=&a; printf(“%u\n”,p); p=p+3; printf(“%u”,p); }

C 向指针添加数字 #包括 int main() { 浮点数a=10; 浮动*p=&a; printf(“%u\n”,p); p=p+3; printf(“%u”,p); },c,pointers,pointer-arithmetic,C,Pointers,Pointer Arithmetic,执行这个程序后,我得到了2个内存地址作为输出,后者的值比前者大12 #include<stdio.h> int main() { float a=10; float* p=&a; printf("%u\n",p); p=p+3; printf("%u",p); } #包括 int main() { 浮点数a=10; 浮动*p=&a; printf(“%u\n”,p); p=p+3.5; printf(“%u”,p);

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

#include<stdio.h>
int main()
{  
     float a=10;
     float* p=&a;
    printf("%u\n",p);
     p=p+3;
     printf("%u",p);
}
#包括
int main()
{  
浮点数a=10;
浮动*p=&a;
printf(“%u\n”,p);
p=p+3.5;
printf(“%u”,p);
}
我尝试将3更改为3.5,但得到的输出是两个地址的值相等。我预计在这两种情况下,该值都至少会增加12。
原因可能是什么?

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

  • 将整数添加到指针
  • 从指针中减去整数
  • 从一个指针减去另一个指针(它们应该指向同一个数组)
标准规定:

C11:6.5.6加法运算符: 2对于加法,两个操作数都应具有算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应具有整数类型。(增加等于增加1。)

3对于减法,以下其中一项应适用:

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


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

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

  • 将整数添加到指针
  • 从指针中减去整数
  • 从一个指针减去另一个指针(它们应该指向同一个数组)
标准规定:

C11:6.5.6加法运算符: 2对于加法,两个操作数都应具有算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应具有整数类型。(增加等于增加1。)

3对于减法,以下其中一项应适用:

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


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

,指针算法就是这样工作的。它设计用于阵列

#include<stdio.h>
int main()
{  
     float a=10;
     float* p=&a;
    printf("%u\n",p);
     p=p+3.5;
     printf("%u",p);
}
将整数添加到指针时,它会将许多元素进一步指向数组中。如果数组元素的大小为N字节,则将x添加到指针会将x*N添加到地址

在您的机器上,似乎
sizeof(float)
是4:您看到x*N=12,x=3,所以N=4

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


使用
%u
打印指针值也是一个错误。实际上,它可能会工作、打印垃圾或崩溃,这取决于编译器以及指针的大小是否与
unsigned int
相同。任何编译器都会警告您
printf(“%u”,p)
不正确;如果您没有,请确保启用其有用的警告(例如,如果您正在使用gcc,请启用gcc-O-Wall)。它设计用于阵列

#include<stdio.h>
int main()
{  
     float a=10;
     float* p=&a;
    printf("%u\n",p);
     p=p+3.5;
     printf("%u",p);
}
将整数添加到指针时,它会将许多元素进一步指向数组中。如果数组元素的大小为N字节,则将x添加到指针会将x*N添加到地址

在您的机器上,似乎
sizeof(float)
是4:您看到x*N=12,x=3,所以N=4

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

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

该程序包含多个错误和糟糕的编程实践
#包括
int main()
{  
float a=10;//init使用浮点值进行浮点运算,因此使用“10.0f”
浮动*p=&a;
printf(“%u\n”,p);//用“%p”而不是“%u”打印地址
p=p+3;//现在“p”指向某个未知区域
printf(“%u”,p);//用“%p”而不是“%u”打印地址
}
幸好代码没有在“p”之后“反引用”p
已修改,因为这将是未定义的行为
可能导致seg故障事件
该程序包含多个错误和糟糕的编程实践
#包括
int main()
{
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