float指针和int指针地址有什么区别?

Roh*_*t O 9 c pointers

我试着运行这段代码,

int *p;
float q;
q = 6.6;
p = &q;
Run Code Online (Sandbox Code Playgroud)

虽然它会是一个警告,但我认为&q并且p大小相同,所以p可以有一个地址q.但是当我打印&q并且p我得到不同的输出.这是我的输出

*p =  6.600000 
 q = 0.000000, p = 0x40d33333, &q = 0x7fffe2fa3c8c 
Run Code Online (Sandbox Code Playgroud)

我错过了什么?和p&q是相同的当两个指针和变量类型是一样的.

我的完整代码是

#include<stdio.h>
void main()
{   
    int *p;
    float q;
    q = 6.6;
    p = &q;
    printf("*p =  %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
}
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 9

您需要更严肃地对待编译器警告.

C不要求编译器拒绝无效程序,它只需要"诊断"来规则违规.诊断可以是致命错误消息或警告.

不幸的是,编译器通常会为不兼容的指针类型的分配发出警告.

void main()
Run Code Online (Sandbox Code Playgroud)

这是错的; 它应该是int main(void).你的编译器可能会让你逃脱它,它可能不会导致任何明显的问题,但没有必要正确编写它.(这不是简单,但是这已经足够接近.)

int *p;
float q;
q = 6.6;
Run Code Online (Sandbox Code Playgroud)

没关系.

p = &q;
Run Code Online (Sandbox Code Playgroud)

p属于int*; &q是类型的float*.将一个分配给另一个(没有强制转换)是违反约束的.看待它的最简单方法是它完全是非法的.

如果你真的想做这个任务,你可以使用一个演员:

p = (int*)&q; /* legal, but ugly */
Run Code Online (Sandbox Code Playgroud)

但这样做的理由很少. p是指向int; 应该指出的int,除非你有一个对象非常充分的理由,使其指向别的东西.在某些情况下,转换本身可能具有未定义的行为.

printf("*p =  %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
Run Code Online (Sandbox Code Playgroud)

%f格式要求double的参数(float参数提升为double在这方面如此float将是确定的).但是*p类型int.printf使用错误类型的参数调用会导致程序的行为未定义.

%p需要一个类型的参数void*,而不仅仅是任何指针类型.如果要打印指针值,则应将其强制转换为void*:

printf("&q = %p\n", (void*)&q);
Run Code Online (Sandbox Code Playgroud)

它可能在没有强制转换的情况下工作,但同样,行为是不确定的.

如果在编译程序时收到任何警告,请不要打扰它.首先修复警告.

至于标题中的问题,类型指针int*float*不同类型的指针.一个int*应指向的int对象; a float*应该指向一个float对象.您的编译器可能会让您混合它们,但这样做的结果是实现定义或未定义.C语言,特别是许多C编译器,可以让你逃避许多没有多大意义的事情.

它们是不同类型的原因是(试图)防止或至少检测其使用中的错误.如果声明一个类型的对象,则int*表示您打算将其指向一个int对象(如果它不是空指针).在float对象中存储对象的地址int*几乎肯定是一个错误.强制类型安全允许尽早检测到此类错误(当您的编译器打印警告时,而不是在重要客户端的演示期间程序崩溃时).

它可能(但不能保证)int*并且float*具有相同的大小并具有相同的内部表示.但含义一个的int*对象不是"包含虚拟地址32(或64)位的集合",但"的东西,指向一个int对象".

  • 因为你把书扔给他,所以读"*p"会违反严格的别名,所以无论你对这个值做什么,它本身就是UB. (5认同)
  • `p =(int*)&q;`并不总是合法的.C 2011(n1570)6.3.2.3 7表示如果结果未正确对齐,则行为未定义.它将在典型的当前平台上,因此如果您相应地计划目标,这是可以的,但如果您计划标准C或想要理解C规范的语义则不行. (3认同)

tep*_*pic 8

你得到了未定义的行为,因为你传递了错误的类型printf.当你告诉它期望一个浮动时,它实际上期望一个double- 但你传递了一个int.

因此,它会输出错误的信息,因为printf完全依赖于格式字符串来访问传递它的参数.