搜索
bottom↓
回复: 15

C语言强制类型转换的疑惑

[复制链接]

出0入0汤圆

发表于 2013-2-2 10:52:25 | 显示全部楼层 |阅读模式
谁能告诉我cmd =(unsigned char)-1 ;  cmd的值为多大? cmd的定义类型为unsigned char
也请求高人,讲解一些与强制类型转换的知识。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-2-2 10:58:51 | 显示全部楼层
cmd=0xFF   

出0入0汤圆

发表于 2013-2-2 11:03:21 | 显示全部楼层
2L正解,显然是0xff

出0入0汤圆

 楼主| 发表于 2013-2-2 11:22:01 | 显示全部楼层
cqfeiyuxmj 发表于 2013-2-2 10:58
cmd=0xFF

有个问题啊;
float f= 5.75;
那么(int)f 是多少呢?
强制类型转化的规则是什么?
顺便再问一下:
(unsigned char) -2 多少呢?

出0入0汤圆

发表于 2013-2-2 11:27:29 | 显示全部楼层
feixiang1990 发表于 2013-2-2 11:22
有个问题啊;
float f= 5.75;
那么(int)f 是多少呢?

(int)f = 5;
(unsigned char)(-2) = 0xfe

出10入0汤圆

发表于 2013-2-2 11:28:00 | 显示全部楼层
本帖最后由 yoz 于 2013-2-2 11:53 编辑

(编辑原因:补回我错误的思路,提出疑问,也消除话没说清楚引起的误会)
5.75就是101.11,也就是1.0111*2^10,对应应该是0 10000001 0111 0000 0000 0000 0000 000,对应的int应该是1085800448
(但是读出却是0,于是我做了实验)
/********************/
#include <stdio.h>

int main(void)
{
    float a = 5.75;
    int b;
    b = (int)a;
    printf("%d\n" , b);
    printf("%d\n" , a);//我故意试验两种方法的,在工作中不可能做这么2的事
    return 0;
}
/********************/
才明白
(int)5.75==5

float a=5.75;
printf("%d\n",a);
会输出0
我之前对c理解的还是不到位
现在还是有疑惑,为什么用%d会输出0而不是1085800448?难道是大小端?我还不明白

出0入0汤圆

发表于 2013-2-2 11:41:02 | 显示全部楼层
yoz 发表于 2013-2-2 11:28
刚才说错了,(int)5.75==0

float a=5.75;


float a=5.75;
printf("%d\n", (int)a);

肯定结果是5


你输出0是因为没加强制类型转换

效果等同于  *(int*)&a, 而不是(int)a

出0入0汤圆

发表于 2013-2-2 11:42:28 | 显示全部楼层
yoz 发表于 2013-2-2 11:28
刚才说错了,(int)5.75==0

float a=5.75;

%d怎么能和float连用?
你这种写法在我公司会被罚款

出10入0汤圆

发表于 2013-2-2 11:43:43 | 显示全部楼层
本帖最后由 yoz 于 2013-2-2 11:53 编辑
snoopyzz 发表于 2013-2-2 11:41
float a=5.75;
printf("%d\n", (int)a);


是的,(int)5.75==5,而直接printf就是0,谢谢提醒,不然我就不会发现自己错了,实践出真知。

出10入0汤圆

发表于 2013-2-2 11:44:24 | 显示全部楼层
本帖最后由 yoz 于 2013-2-2 11:46 编辑
asdf1776 发表于 2013-2-2 11:42
%d怎么能和float连用?
你这种写法在我公司会被罚款


只是故意看看这种不匹配的后果
(补充)
我本来以为按照ieee754存储的float也是32位,能否在printf中用%d来强制把这四个字节当作int来输出,结果好像并不如我所愿。

出0入0汤圆

 楼主| 发表于 2013-2-2 11:53:08 | 显示全部楼层
谢谢 大家 虽然还是有点小疑惑,不过还是很感谢大家,看来只能回家看课本了

出10入0汤圆

发表于 2013-2-2 11:55:17 | 显示全部楼层
我也是,还需要多学习,谢谢各位指点。

出0入0汤圆

发表于 2013-2-2 13:51:19 | 显示全部楼层
feixiang1990 发表于 2013-2-2 11:53
谢谢 大家 虽然还是有点小疑惑,不过还是很感谢大家,看来只能回家看课本了 ...

先理论分析。然后机器验证一下。

出10入0汤圆

发表于 2013-2-3 10:22:09 | 显示全部楼层
本帖最后由 yoz 于 2013-2-3 10:29 编辑

我又做了一个实验,看来float转换为int也因机器而已,在windows的vc6上,以下程序测试结果是
5.000000
#include <stdio.h>

func(void)
{
        return 5.75;
}

int main(void)
{
    float f;
        f = func();
        printf("%f\n" , f);
    return 0;
}
但是在sparc机上,按照C与指针的说法是这样的

说明了这个问题意义不大

(补充总结)
用%d输出float的方法去做“强制类型转换”是无意义的
用(int)转换float则是做小数截断
用(float)转换int则是加小数点

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入93汤圆

发表于 2013-2-3 11:39:06 | 显示全部楼层
yoz 发表于 2013-2-3 10:22
我又做了一个实验,看来float转换为int也因机器而已,在windows的vc6上,以下程序测试结果是
5.000000
#inc ...

int和float/double之间的转换是会调用转换函数的,因为类型不兼容。
char、short、int、long、long long/int64以及它们的unsigned版本转换是不需要调用转换函数的,因为类型是兼容的。
同样,C++专门有转换函数的概念,只不过并不以函数的形式表现,而是以操作符重载的形式体现。

至于你6楼所说的%d会输出0而不是1085800448是因为变量存储的地址不一致所引起的,而不是大小端。float会使用FPU,很遗憾,%d不访问FPU,它所访问的寄存器根本就不是float所使用的寄存器,所以输出一个无法确定的值。孟子曰:以若所为(float所在的FPU寄存器),求若所欲(%d所用的CPU寄存器),犹缘木而求鱼也。

出10入0汤圆

发表于 2013-2-3 11:45:45 | 显示全部楼层
takashiki 发表于 2013-2-3 11:39
int和float/double之间的转换是会调用转换函数的,因为类型不兼容。
char、short、int、long、long long/ ...

谢谢你的指教,暴露出了我对计算机组成原理缺乏了解,我接下来会继续看一些相关的资料,学一点汇编。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 18:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表