C 为什么指针类型转换到float不';不行?
大家好,我正在学习C语言,我正在尝试使用单个字符指针打印不同数据类型的值。我可以打印几乎所有的数据类型,但在打印浮点时有问题。有人能解释为什么这是一个问题吗?!如何用一个指针打印出精确的浮点值。很抱歉,如果是一个问题的话。我理解对齐问题。但我们确实需要一个解决方案 更新1-->很抱歉进行了愚蠢的类型转换。现在考虑更新代码。 更新2-->感谢大家的回答。就像我说的,我正在学习C语言,很抱歉语法错误。我不是CS出身,但再次感谢你们C 为什么指针类型转换到float不';不行?,c,C,大家好,我正在学习C语言,我正在尝试使用单个字符指针打印不同数据类型的值。我可以打印几乎所有的数据类型,但在打印浮点时有问题。有人能解释为什么这是一个问题吗?!如何用一个指针打印出精确的浮点值。很抱歉,如果是一个问题的话。我理解对齐问题。但我们确实需要一个解决方案 更新1-->很抱歉进行了愚蠢的类型转换。现在考虑更新代码。 更新2-->感谢大家的回答。就像我说的,我正在学习C语言,很抱歉语法错误。我不是CS出身,但再次感谢你们 #include <stdio.h> int
#include <stdio.h>
int main()
{
long int a = 10;
char ch = 'a';
float b = 16.89;
unsigned int c = 20;
short int d = 30;
char *p;
p = &a;
printf("Value of a: %d\n", *p);
p = &ch;
printf("Value of ch: %c\n", *p);
p = &b;
printf("Value of b(float): %f\n", *p);
printf("Value of b(decimal): %d\n", (int) *((float*)p));
p = &c;
printf("Value of c: %u\n", *p);
p = &d;
printf("Value of d: %i\n", *p);
return 0;
}
The output of the above program is :-
Value of a: 10
Value of ch: a
Value of b(float): 0.000000
Value of b(decimal): 16
Value of c: 20
Value of d: 30
#包括
int main()
{
长整数a=10;
char ch='a';
浮动b=16.89;
无符号整数c=20;
短整数d=30;
char*p;
p=&a;
printf(“a的值:%d\n”,*p);
p=&ch;
printf(“ch的值:%c\n”,*p);
p=&b;
printf(“b的值(浮动):%f\n”,*p);
printf(“b的值(十进制):%d\n”,(int)*((float*)p));
p=&c;
printf(“c的值:%u\n”,*p);
p=&d;
printf(“d的值:%i\n”,*p);
返回0;
}
上述程序的输出为:-
a值:10
ch:a的价值
b值(浮动):0.000000
b值(十进制):16
c值:20
d值:30
在此示例程序中执行的类型转换没有任何意义
F.e.p=(长整型*)&a代码>:a
的类型为long int
,这使得&a
的类型为long int*
&a
前面的类型强制转换为不可操作
p
的类型为char*
,这使得*p
的类型为char
。char
值存储在1个字节上。在程序中,对a
、c
和d
使用大于256
的值,您会发现它为它们打印了不正确的值
传递给printf()
的值必须与使用的格式说明符匹配,否则会得到意外结果。传递一个整数(*p
)并使用%f
格式化它不会神奇地进行任何类型转换,它只是强制printf()
以不正确的方式解释*p
的位序列,并产生意外的结果,因为这是您在这里进行的类型转换。
p = (float*)&b;
处于隐式强制转换中,不是必需的。&b
已经是float*
类型,不需要强制转换
实际上,您需要在printf
语句中进行强制转换。像这样
printf("Value of b(float): %f\n", *(float*)p);
在所有其他printf
语句中也需要类似的强制转换
你在这里所做的没有多大用处,如果你想打印一个int
,请使用int
指针,而不是char
指针。这种工作是偶然的p
是一个字符指针;所以*p
总是一个字符
- 您获取
a
的地址,将其转换为长整型*
。它已经是一个long int*
,因为您的地址是long int
——所以这实际上没有任何作用。然后把它塞进p
,这是一个char*
。它不能在char*
变量中保持long int*
;现在它是一个char*
。现在,很明显,你在一台使用体系结构的机器上,就像我们大多数人一样,所以最小的字节排在第一位:你的长int a
表示为[10,0,0,0]
,而*p
读取第一个字节。然后C的另一个特性开始发挥作用:所有小于int
的积分参数都作为int
传递;因此,字节10
被转换成int
并被推送到堆栈中(或通过较新体系结构的ABI中的整数寄存器),然后由printf
使用%d
格式正确读取,预期为int
- 对于
字符ch
,*p
不读取第一个字节,而是读取唯一的字节;其余的都一样。对于其他整数类型也是如此,在这里,您非常友好,从未超过255127[谢谢,Antti Haapala!](或者您会看到意外的结果)
- 然而,
float b
是另一回事。浮点在内存中的表示方式与整数截然不同;当*p
读取第一个字节时,它会得到一些与16.89
完全无关的东西-有点像是在通过万花筒看时试图猜一幅画。第一个字节被扩展为int并传递给函数。在较旧的体系结构中,它将被读取,就像它是浮点一样,但在多达四个(MS)或六个(UNIX)整数和浮点参数通过寄存器传递的情况下,它甚至不会被查看(因为它通过整数寄存器传递,但%f
将查看浮点寄存器)。请记住,这主要是因为您的指针以char*
结尾,因为您存储它的方式
- 在
decimal(b)
中,您可以做一些非常不同的事情:将指针投射到重要的位置。所以这里,p
的值在一段时间内变成一个float*
;然后取消对它的引用,并正确地得到16.89
;然后将其转换为int
,最后得到16
(使用%d
打印,因此一切正常)
tl;dr:C变量的类型是一成不变的。您所做的任何类型转换只在您不存储它们时才起作用-一旦您将它们放入变量中,类型就是变量的类型。如果在printf
期间的类型转换正确,它应该会起作用
printf("Value of b(float): %f\n", *(float *)p);
float
类型的表示方式与