gpt4 book ai didi

c - 为什么要投指针?

转载 作者:太空宇宙 更新时间:2023-11-04 01:03:55 25 4
gpt4 key购买 nike

我有一个关于 C 指针和转换的基本问题。
我不明白为什么要投指点?

我刚刚尝试了这段代码,每个选项都得到了相同的输出:

#include <stdio.h>

int main(void)
{
int x = 3;
int *y = &x;
double *s;

option 1: s = (double*)y;
option 1: printf("%p, %d\n", (int*)s, *((int*)s));
option 2: s = y;
option 2: printf("%p, %d", s, *s);

return 0;
}

我的问题是为什么我必须这样做:s = (double*)y?
直观地说,所有变量的地址都是相同的。区别应该是从这个地址读取多少字节。此外,关于打印 - 如果我使用 %d,它将自 Action 为 int

为什么我需要将其转换为 int*
我错了吗?

最佳答案

您的问题中存在很多混淆。 intdouble 是不同的东西:它们使用不同的位模式表示内存中的数字,在大多数情况下甚至是不同的字节数。当您隐式或显式要求时,编译器会生成在这些表示之间进行转换的代码:

int x = 3;
double d;

d = x; // implicit conversion from integer representation to double
d = (double)x; // explicit conversion generates the same code

这是一个更微妙的例子:

d = x / 2;      // equivalent to d = (double)(x / 2);

会将 1 的双重表示存储到 d 中。而这:

d = (double)x / 2;  // equivalent to d = (double)x / 2.0;

会将 1.5 的双重表示存储到 d 中。

转换指针是完全不同的事情。这不是转换,而只是一种强制。您是在告诉编译器相信您知道自己在做什么。它不会更改它们指向的地址,也不会影响该地址内存中的字节。 C 不允许您将指向 int 的指针存储为指向 double 的指针,因为这很可能是一个错误:当您使用错误的类型取消引用指针时,内存内容被错误地解释,可能会产生不同的值甚至导致崩溃。

您可以通过显式转换为 (double*) 来覆盖编译器的拒绝,但您是在自找麻烦。

当您稍后取消引用s时,您可能会访问无效内存并且读取的值肯定没有意义。

进一步的混淆涉及 printf 函数:格式字符串中的格式说明符是程序员关于他作为额外参数传递的实际值类型的 promise 。

printf("%p,%d",s,*s)

这里你传递了一个double(没有有意义的值)并且你告诉printf你传递了一个int。多个未定义行为的公然案例。任何事情都可能发生,包括 printf 产生与其他选项相似的输出,从而导致完全困惑。在 64 位 Intel 系统上,将 double 和整数传递给 printf 的方式不同且相当复杂。

要避免在 printf 中出现这种错误,请使用 -Wall 进行编译。 gcc 和 clang 会提示格式说明符和传递给 printf 的实际值之间的类型不匹配。

正如其他人评论的那样,您不应该在 C 中使用指针转换。即使是典型的情况 int *p = (int *)malloc(100 * sizeof(int)) 也不需要转换在 C 中。

关于c - 为什么要投指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28657641/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com