打印

long的问题

[复制链接]
2544|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chen3bing|  楼主 | 2010-11-5 20:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我写了个小程序,C51,伟福编译器。

#include<reg51.h>
void main(void)
{unsigned long addr=5;
addr = 7*4096;  //(1)
  ;
  ;
  
addr = 10*4096;(2)
while(1);
}
单步执行时,发现
执行完第一步(1)后,addr=0;
执行完第二步(2)后,addr=0FFFFA000H.
我搞不懂,请高手指教。谢谢!

相关帖子

沙发
chen3bing|  楼主 | 2010-11-5 20:33 | 只看该作者
高手支招啊!

使用特权

评论回复
板凳
chen3bing|  楼主 | 2010-11-5 20:46 | 只看该作者
怎么没人理?

使用特权

评论回复
地板
chen3bing|  楼主 | 2010-11-6 08:29 | 只看该作者
没人知道吗?

使用特权

评论回复
5
ayb_ice| | 2010-11-6 08:41 | 只看该作者
可能编译器认为没有语句意义,实际被优化了
将addr改为全局变量,OK

使用特权

评论回复
6
jack821119| | 2010-11-12 09:37 | 只看该作者
addr = 7*4096;  //(1)
改为addr = 7;
addr = addr *4096;
应该就可以了

使用特权

评论回复
7
chen3bing|  楼主 | 2010-11-12 13:32 | 只看该作者
果然如楼上所言,只是不知道为什么。

使用特权

评论回复
8
liang7143| | 2010-11-12 14:13 | 只看该作者
果然如楼上所言,只是不知道为什么。
chen3bing 发表于 2010-11-12 13:32



原因如5楼所言,6楼只是“骗”过了编译器~~

使用特权

评论回复
9
komad| | 2010-11-12 20:20 | 只看该作者
可能编译器认为没有语句意义,实际被优化了
将addr改为全局变量,OK
ayb_ice 发表于 2010-11-6 08:41


请教下,什么改为全局的就OK呢?

使用特权

评论回复
10
komad| | 2010-11-12 20:21 | 只看该作者
为什么改为全局的就OK了,这种情况改为全局变量时,是否要再上volatile关键字?

使用特权

评论回复
11
STM32W| | 2010-11-13 07:59 | 只看该作者
本帖最后由 STM32W 于 2010-11-13 08:12 编辑

原因很简单:
A=B
B的值不会因为A得类型而改变。

A=B*C

是先计算B*C的结果,再赋值给A
B*C的结果不会因为A得类型而改变。

回到正题:
addr = 10*4096;(2)
先不管addr是什么类型,先计算10*4096的值,10*4096运算的结果本身与addr是什么类型无关。
首先要搞清楚,10,4960是什么类型。

根据C语言标准,字面值10进制常数,如果在int范围,则类型是int.
10*4960
相当于((int)10)*((int)4096)=-24576

addr = 10*4096;
相当于addr = -24576
结果:addr的值为0xFFFFA000



再举个例子:
float f;
f=1/10;

f 结果是0.0,而不是0.1。
因为是先计算1/10,再赋值给f,
而不是先转换成浮点,再计算。
1/10本身的运算结果与f的类型无关。

改为addr=addr*7为什么结果会对呢?
先看表达式addr*7,
addr的类型是long,7的类型是int.
按照C语言运算规则,long与int运算,int自动提升至long。
addr*7相当于
((long)addr)*((long)7)
结果是对的,没有溢出。

谨记:

形如
A=表达式
是先计算表达式的值,再把值赋值给A。
表达式运算的结果是按照表达式自己的运算规则运算,
不要想当然,表达式会用A的类型进行计算。





使用特权

评论回复
12
xlsbz| | 2010-11-13 12:38 | 只看该作者
不想被优化掉 就用关键字 VoliatE  啊

你的第一句应该没有编译进去吧  界面上应该能看出来的吧

使用特权

评论回复
13
老鱼探戈| | 2010-11-13 13:00 | 只看该作者
你定义的局部变量
看看局部变量和全局变量的区别

使用特权

评论回复
14
niulei| | 2015-4-1 14:51 | 只看该作者
很受用,long类型=int类型*int类型,会导致溢出
必须:long类型=(long)int类型*(long)int类型;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

439

主题

2540

帖子

2

粉丝