2017-07-25 65 views
-1

我试过寻找这个,但没有运气。我看了一下指针和使用他们,我知道,指针非类类型仅与同一指针类型兼容,就像有没有关于指针兼容类型的任何文档?

int* apointer = anotherintpointer; 

,但是这是不可能的(没有任何明确的转换)

int* apointer = aFLOATpointer; 

我的确看到了不允许这一点的观点,但并不完全。就像整数与浮点数兼容,比如int x = afloatvariable;,为什么指向int的指针不能和指向float的指针兼容?

我的主要问题是:有,我可以了解为什么这些指针只能使用相同指针类型,实际上指出,这是真实的地方兼容的任何地方,因为它仅仅是从一个假设我经验。如果您可以在标准中了解这方面的内容,请给我一个提示在哪里阅读,因为我在快速浏览时找不到它。所以如果有人能够给我提供一个链接或者什么的话,那真的不仅仅是真棒。

编辑:根据意见,我可以看到我使用这个词兼容的也许是有点过。我的意思兼容是一种允许被分配在内存中的另一个:)

+0

您需要详细了解C++中低级类型的基本属性。 'float'和'int'类型非常不同,你不能在没有转换的情况下交换它们。 – tadman

+0

Float和int在内存中的工作方式不同。所以,如果你的int指针指向一个float,并且试图像整数一样使用它。它会阻止浮动。指向int的浮点指针同样适用 – litelite

+0

'整数与浮点兼容'兼容的意思是什么?它们有一个_completely_不同的位表示形式,所以将float位解释为int不会给你任何有用的东西。 – tkausl

回答

1

integers are compatible with floating-points, so why should pointers to int not be compatible with pointers to float?

整数和浮点数有非常不同的表现。它们兼容的唯一原因是编译器提供了一些隐含的转换“魔术”。当你写

float f = someInt; 

编译器插入你的CPU指令someInt值转换为float表示。

编译器只能这样做,因为它在编译时知道someIntintffloat。如果你有一个指针float,写

float f = *pointerToFloat; 

但指针指向int,编译器会认为指针指向float,因为没有与pointerToFloat相关的任何其他类型。编译器必须相信你,无论指针是否指向float表示,所以它最终会将int重新解释为float,并带有完全意外的(和未定义的)结果。

If you can read about this in the standard, please give me a hint where to read

有自己相关的指针转换the standard两个部分 - 部分3.7.4.3.2,这解释了安全地衍生的指针可以是,除了别的以外,定义良好的指针转换的结果和4.10部分,它列出了三种与原始数据类型相关的指针转换。

+0

啊,现在这部分对我来说更有意义,但是“主要问题”(我知道你已经解释了一下,但仍然)。谢谢! –

+0

哦,我刚刚看到你实际上更新了你的答案。感谢您的更新,我真的可以使用这些信息。然而,如果某个地方有点直接说明指针不能指向另一种类型的对象,你看过这样的地方还是知道在哪里寻找它,因为我找不到这个地方呢?或者这只是严格的别名规则,定义或?非常感谢你的支持:) –

+0

@FacPam指针可以指向错误类型的对象,只是它们不再被定义好。从不明确定义的指针读取是未定义的行为。 – dasblinkenlight

3

Like, integers are compatible with floating-points, so why should pointers to int not be compatible with pointers to float?

整数是转换到浮点数(反之亦然),但如果你看一下实际的比特构成的RAM中的数据,他们有很大的不同。

例如,计算机可能代表了整数值1与这些32位:

10000000 00000000 00000000 00000000 

而“等效”浮点值1.0F通常与这些位表示:

00000000 00000000 10000000 00111111 

如果你设置一个整数指针指向一个浮点值(反之亦然),那么你会发现这些位会被严重误解,你不会得到你期望的结果。如果你不介意一点点滥用(注意,这段代码调用未定义的行为,仅用于教育目的;不要依赖这种行为在其他地方保持一致,而且不要这样做)在生产代码的东西):

#include <stdio.h> 

int main(int, char **) 
{ 
    int x = 1; 
    float y = 1; 

    float * py = reinterpret_cast<float *>(&x); // evil! 
    printf("y=%f\n", *py); 

    int * px = reinterpret_cast<int *>(&y); // evil! 
    printf("x=%i\n", *px); 

    return 0; 
} 

在我的机器,上面的代码打印出来的:

y=0.000000 
x=1065353216 

...这显然不是什么人会天真地期待。为避免这种无用的运行时行为,编译器会阻止你交叉转换指针类型(除非你绝对要求它,例如,通过使用reinterpret_cast <>,在这种情况下,你最好真的知道你在做什么:))

+0

啊,谢谢。但是有没有像标准定义的规则,或者它只是纯粹的逻辑(指向非类类型的指针只能指向相同的指针类型)? –

+1

我认为你正在寻找的规则可能是这样的:https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule –

+0

再次感谢,它看起来像它,但不完全但是,我已阅读,它说,char *可以指向任何类型,但每当我做一些像'char * acharp =&aninteger;',我得到的错误:“一个类型为”int * “不能用于初始化”char *“”类型的实体。你能说我做错了吗?或者你会建议我开始一个新的问题? –