标题:有点不懂,高手帮个忙
只看楼主
forever74
Rank: 12Rank: 12Rank: 12
来 自:CC
等 级:贵宾
威 望:49
帖 子:1636
专家分:3940
注 册:2007-12-27
得分:0 
double是64位长度,8字节
int是32位长度,4字节
p=(int*)&y;的意思是把变量y所占据的8字节的首地址转换成合适的类型然后赋值给p
*p=20;这是说把p的目标,也就是y的8字节里面的低端4个字节(本来全是0)按照整数方式赋值为20(针对以Intel为代表的小头CPU)

需要指出的是这个20的二进制10100所放的位置是y的小数点后面很远的位置,所以从表面上看不出来。
如果要看一下实际效果,可以在*p=20;前后各输出一次y,但是不要默认格式,要保留18位小数那种。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2010-08-07 18:51
不归鹄
Rank: 9Rank: 9Rank: 9
来 自:冥王星
等 级:蜘蛛侠
威 望:4
帖 子:491
专家分:1380
注 册:2009-12-20
得分:0 
以下是引用lishizelibin在2010-8-7 12:58:40的发言:

上次看到一个发的贴,还应该是double和int在内存中的位数和表达形式不同(转int,只取了double中8个字节的四个)
我将*p=2000000;在监视器发现y值不等于1.0000000000000而是1.0000000004441,最后打印为1
正如lishizelibin所说。之所以是这样是因为数据在内存中的存放是从高地址向低地址的,而变量的地址则指向低地址。
例如:
假如变量 y 的值是 0x124a5623(十六进制),&y 的值(也就是 y 的地址)是 0x0020,那么它的值在内存中的存放就如下(一个地址只能存放八位二进制,也就是两位十六进制)

所以 0x0023 存放 0x12, 0x0022 存放 0x4A ...最后的位数存放在最低的地址,而变量的地址也就是低地址(0x0020)。所以当p=(int *)&y,*p=20时,p 指向的是 0x0020 ,所以只改变了 y 的尾数,对于浮点数来说,后面的字节是表示小数点后的数字的,1.0000000 和 1.0000020 没什么大的差异。所以几乎没什么改动

2010-08-07 19:05
苗伊
该用户已被删除
得分:0 
回复 9楼 安普留香
提示: 作者被禁止或删除 内容自动屏蔽
2010-08-08 14:59
不归鹄
Rank: 9Rank: 9Rank: 9
来 自:冥王星
等 级:蜘蛛侠
威 望:4
帖 子:491
专家分:1380
注 册:2009-12-20
得分:0 
看来我又失败了又一次没有表达清楚,我也懒得说了,不过我还是要说!


他的指针 P 是这样赋值的

 p=(int *)&y

所以 p 存放的地址当然是 y 的地址,只不过 p 指向的内容是整形而已,所以地址是相同的。关键在于对这一内存地址进行赋值时,假如

 y=20.000000

的话,20 这个整数是存放在高地址的,后面的内存空间都存放 .000000 去了。当你

 *p=20

时,其实是改动 内存中

.000000

的数据,也就是低地址。

20.000000

 和

20.000020

当然没什么大的区别。再重申一遍,变量的地址是指变量占据的内存空间中的低地址。因为不是每个变量都只有8位,一个字节而已。你不可能用变量占据的所有内存空间的地址作为变量的地址,因为这就有不确定性了。所以规定变量占据的内存空间中的低地址是变量的地址。

访问变量的时候不但要知道地址,而且要知道类型,要不就不知道该读取到哪结束了。

所以字符串才以'\0'作为结束符,因为字符串长度是不确定的。要不你来个

char str[3]={'a','b','c'},

然后以 %s 的格式输出,保证出来的不止 abc ,除非运气特别号,遇到存放字符数组后的内存的第一个空间存放的是 ‘\0’。

2010-08-08 19:35
不归鹄
Rank: 9Rank: 9Rank: 9
来 自:冥王星
等 级:蜘蛛侠
威 望:4
帖 子:491
专家分:1380
注 册:2009-12-20
得分:0 
还是用代码来说吧
程序代码:
#include<stdio.h>

int main()
{
    float  y=20;
    unsigned int *p=(int *)&y;/* *p 未赋值,只是让 p 等于 y d 地址而已*/
   
    printf("%9.6f\n%d\n\n",y,*p);
   
    *p=200;/*对 *p 赋值*/
   
    printf("%9.6f\n%d\n\n",y,*p);
   
    system("pause");
    return 0;
}
运行结果

至于为什么不是20.000200,这与浮点型数据用几位来表示小数有关,也和数据在内存中是以补码形式存放有关。

要是觉得这不好,那我们换成无符号长整形和无符号整形来试就知道了


程序代码:
#include<stdio.h>

int main()
{
    unsigned long  y=0x10000005;
    unsigned int *p=(int *)&y;/* *p 未赋值,只是让 p 等于 y d 地址而已*/
   
    printf("%lx\n%x\n\n",y,*p);
   
    *p=0x20;/*对 *p 赋值*/
   
    printf("%lx\n%x\n\n",y,*p);
   
    system("pause");
    return 0;
}
运行结果

看看后面的 05 是不是被改成了 20?

[ 本帖最后由 不归鹄 于 2010-8-8 20:05 编辑 ]

2010-08-08 20:03
Kid_X
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:216
专家分:515
注 册:2007-10-8
得分:0 
楼上几位都回答得不错。
其实这种问题学了汇编之后就很容易理解了。所以我强烈建议,如果要想真正把C语言学好,有时间还是学一下汇编。这样会对你理解很多基础性问题有很大帮助。
2010-08-08 20:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-315035-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.132624 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved