简体   繁体   English

如果我为 int 指针分配一个浮点变量地址会发生什么,反之亦然?

[英]What happens if I assign to an int pointer a float variable address and vice-versa?

I was wondering what would happen if I gave an int pointer a float variable address and vice-versa, so I tried it but couldn't exactly understand what's happening so if anyone can explain I would be grateful.我想知道如果我给一个int指针一个float变量地址会发生什么,反之亦然,所以我尝试了它,但无法完全理解发生了什么,所以如果有人能解释我会很感激。

int n = 5;
float f = 1.21;
float *pf = &n;
int *pn = &f;

printf("%p  %p\n", pn, pf);
printf("%p  %p\n", &f, &n);
printf("%d   %f \n", *pn, *pf);
printf("%f   %d \n", n, f);
printf("%d  %f \n", n, f);

Output:输出:

0xffffcba8  0xffffcbac
0xffffcba8  0xffffcbac
1067114824   0.000000
0.000000   0
5  1.210000

There is a number of instances of undefined behavior in your code:您的代码中有许多未定义行为的实例:

  • int n = 5; : OK : 好的
  • float f = 1.21; : OK : 好的
  • float *pf = &n; initializes a pointer with the value of a pointer to a different type.用指向不同类型的指针的值初始化一个指针。 The C Standard makes no guarantees as to what this does nor as to what happens when you dereference this pointer. C 标准不保证这会做什么,也不保证当你取消引用这个指针时会发生什么。 With -Wall -W , you would definitely get a warning for this, which you could silence with a cast: float *pf = (float *)&n;使用-Wall -W ,您肯定会收到警告,您可以通过-Wall -W使其静音: float *pf = (float *)&n; , yet the result is the same, dereferencing the pointer has undefined behavior. ,但结果是相同的,取消引用指针具有未定义的行为。
  • int *pn = &f; same as above.和上面一样。
  • printf("%p %p\\n", pn, pf); -> you should cast the pointers as (void *) because %p expects a void * as an argument. -> 你应该将指针转换为(void *)因为%p需要一个void *作为参数。 On some rare systems (old Cray systems IIRC), pointers to int , float and void may have different representations, causing this call to printf to behave in unexpected ways.在一些罕见的系统(旧的 Cray 系统 IIRC)上,指向intfloatvoid指针可能有不同的表示,导致对printf调用以意想不到的方式运行。 Use this instead:改用这个:

     printf("%p %p\\n", (void *)pn, (void *)pf);
  • printf("%p %p\\n", &f, &n); -> same problem. -> 同样的问题。 Use this instead:改用这个:

     printf("%p %p\\n", (void *)&f, (void *)&n);

    The output is correct and the same for both expressions because your system is regular, but the C Standard does not guarantee it.两个表达式的输出是正确的并且相同,因为您的系统是常规的,但 C 标准不保证它。

  • printf("%d %f \\n", *pn, *pf); this one is correct but dereferencing the pointer has undefined behavior.这是正确的,但取消引用指针具有未定义的行为。
  • printf("%f %d \\n", n, f); passing value of types different from the expected types has undefined behavior.传递与预期类型不同的类型值具有未定义的行为。 The output you get is incorrect.你得到的输出是不正确的。
  • printf("%d %f \\n", n, f); this one is correct and the output is 5 1.210000 as expected.这个是正确的,输出是5 1.210000正如预期的那样。

Chqrlie´s answer is way better than mine. Chqrlie的回答比我的好得多。 Please re-accept his answer.请重新接受他的回答。


You should not abuse pointers and objects - Even not for curiosity reasons.你不应该滥用指针和对象——即使不是出于好奇的原因。 The results of the 1., 2. and the 5. printf command are correct, but the results of the 3. and 4. printf command are products of Undefined Behavior, thus noone can explain them. 1., 2., 5. printf命令的结果是正确的,而3., 4. printf命令的结果是Undefined Behavior的产物,没有人可以解释。

For more information about Undefined Behavior: Undefined, unspecified and implementation-defined behavior有关未定义行为的更多信息: 未定义、未指定和实现定义的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM