关于指针类型强制转换

帅气好男人_Jack 2013-07-02 09:33:19
下面两段程序:
void main()
{
int k=1;
int *f = &k;
*(float *)(f) = 2;
printf("%f ",*f);
}
将int型转换为float型输出结果一直都是0,不论怎么改,网上查资料,解释是:强制转换float*型使变量存储空间由两个字节变为4个字节,还有float型的存储方式不一样,故取的时候不一样,(我也在想,int的数据强制转换为float型是不是把他在内存存的01编码从新更改了一编,而不是int和char型转换简单的增加一个字节或减少一个字节)故最后输出结果不一样。

但是,我稍微改一下就不同,感觉把上面的都否定了,如下代码:
int k=1;
int *f = &k;
*(float *)(f) = 2;
printf("%f %d",*f,k);
这次,把第三行代码随便改,输出结果更着变,这又作何解释呢?
...全文
250 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-07-03
  • 打赏
  • 举报
回复
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
水平不流 2013-07-03
  • 打赏
  • 举报
回复
引用 6 楼 startservice 的回复:
[quote=引用 2 楼 adlay 的回复:] 你还是 16 位系统吗? int 是 2 个字节?? 以下我所说的是基于 32 位系统, int 是 4 个字节的: 普通的 int 转 float: int x = 10; float y = x; 是通过 浮点寄存器 来转换的. 转换后的是一个新创建的值, 不会更改 x 的内存编码, 也没有增加减少字节一说. 而普通的 float 转 int, float x = 2.0f; int y =x; 是需要调用函数来进行转换的, 效率非常低, 当然, 它返回的也是一个新的值. 不会影响 x 原本的值.

void main()
{
int k=1;
int *f = &k;
*(float *)(f) = 2;
printf("%f ",*f);
}
这个程序一直输出 0, 问题并不在转换上, 而是在输出上. printf("%f" 是要从参数里读 8 个字节, float 类型传参数的时候会转换成 double 来传 8 个字节. 但是你传的是 int 还是只有 4 个字节, 所以导致没能输出. 你像 printf 传 8 个字节作为 "%f" 就可以看到结果位 2 了:

void main()
{
	int k=1;
	int *f = &k;
	*(float *)(f) = 2;
	printf("%f ", 0, *f);
}

有了上面的东西, 下面的就好解释了, 你多加了个参数, %f 就可以输出了.
顶[/quote] 分析的很透彻.
www_adintr_com 2013-07-02
  • 打赏
  • 举报
回复
你还是 16 位系统吗? int 是 2 个字节?? 以下我所说的是基于 32 位系统, int 是 4 个字节的: 普通的 int 转 float: int x = 10; float y = x; 是通过 浮点寄存器 来转换的. 转换后的是一个新创建的值, 不会更改 x 的内存编码, 也没有增加减少字节一说. 而普通的 float 转 int, float x = 2.0f; int y =x; 是需要调用函数来进行转换的, 效率非常低, 当然, 它返回的也是一个新的值. 不会影响 x 原本的值.

void main()
{
int k=1;
int *f = &k;
*(float *)(f) = 2;
printf("%f ",*f);
}
这个程序一直输出 0, 问题并不在转换上, 而是在输出上. printf("%f" 是要从参数里读 8 个字节, float 类型传参数的时候会转换成 double 来传 8 个字节. 但是你传的是 int 还是只有 4 个字节, 所以导致没能输出. 你像 printf 传 8 个字节作为 "%f" 就可以看到结果位 2 了:

void main()
{
	int k=1;
	int *f = &k;
	*(float *)(f) = 2;
	printf("%f ", 0, *f);
}

有了上面的东西, 下面的就好解释了, 你多加了个参数, %f 就可以输出了.
waitaheadsss 2013-07-02
  • 打赏
  • 举报
回复
栈溢出了,第一次后面是return,第二次是k
startservice 2013-07-02
  • 打赏
  • 举报
回复
引用 2 楼 adlay 的回复:
你还是 16 位系统吗? int 是 2 个字节?? 以下我所说的是基于 32 位系统, int 是 4 个字节的: 普通的 int 转 float: int x = 10; float y = x; 是通过 浮点寄存器 来转换的. 转换后的是一个新创建的值, 不会更改 x 的内存编码, 也没有增加减少字节一说. 而普通的 float 转 int, float x = 2.0f; int y =x; 是需要调用函数来进行转换的, 效率非常低, 当然, 它返回的也是一个新的值. 不会影响 x 原本的值.

void main()
{
int k=1;
int *f = &k;
*(float *)(f) = 2;
printf("%f ",*f);
}
这个程序一直输出 0, 问题并不在转换上, 而是在输出上. printf("%f" 是要从参数里读 8 个字节, float 类型传参数的时候会转换成 double 来传 8 个字节. 但是你传的是 int 还是只有 4 个字节, 所以导致没能输出. 你像 printf 传 8 个字节作为 "%f" 就可以看到结果位 2 了:

void main()
{
	int k=1;
	int *f = &k;
	*(float *)(f) = 2;
	printf("%f ", 0, *f);
}

有了上面的东西, 下面的就好解释了, 你多加了个参数, %f 就可以输出了.
AnYidan 2013-07-02
  • 打赏
  • 举报
回复
站在不同的角度看同一个物体(二进制)
nadleeh 2013-07-02
  • 打赏
  • 举报
回复
引用 楼主 jackzhouyu 的回复:
下面两段程序: void main() { int k=1; int *f = &k; *(float *)(f) = 2; printf("%f ",*f); } 将int型转换为float型输出结果一直都是0,不论怎么改,网上查资料,解释是:强制转换float*型使变量存储空间由两个字节变为4个字节,还有float型的存储方式不一样,故取的时候不一样,(我也在想,int的数据强制转换为float型是不是把他在内存存的01编码从新更改了一编,而不是int和char型转换简单的增加一个字节或减少一个字节)故最后输出结果不一样。 但是,我稍微改一下就不同,感觉把上面的都否定了,如下代码: int k=1; int *f = &k; *(float *)(f) = 2; printf("%f %d",*f,k); 这次,把第三行代码随便改,输出结果更着变,这又作何解释呢?
变量k的起始地址和f指向的地址是一样的, k占4B,*f取4B,也就说2者都是同一段内存,你%x分别打印就知道什么问题了
赵4老师 2013-07-02
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧