打印

关于宏定义和乘法运算的可靠用法

[复制链接]
5909|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
触觉的爱|  楼主 | 2011-3-4 16:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#define add   0x32     
#define max  0xFF78   
#define min   0xEB8C  

这样用有问题吗?编译是通过

与下面这样声明有区别吗?
uchar add=0x32;  
uint max=0xFF78;
uint min=0xEB8C;


实际程序中,add / min / max 这三个都是固定不变的常量。用宏定义方式,编译的代码量要小三分一左右,不过测试中,会出错。 直接声明常量的方式虽然代码量偏大,不过测试中稳定,没出现错误。 程序中其它部分部分代码都不变,只是改变这三个来测试

另外,
void  count(unsigned int m)  
   {
    count=1000;       //
      count=count*m;   //
    while(count>0);  //
    }


void  count(unsigned int m)  
   {
    count=0;       //
      count=1000*m;   //
    while(count>0);  //
    }
这两种乘法计算差别大吗,测试中只有 count=count*m 这样用才是没问题。其中count在循环等待中通过中断来改变

另外不用函数,直接在程序中给中count的值也是会出错

过年期间才学会看简单的程序,现学的单片机,C也不熟悉。有没熟悉的网友说明一下其中的区别,谢谢

相关帖子

沙发
触觉的爱|  楼主 | 2011-3-4 16:44 | 只看该作者
补充一下,add  用来实现加法运算 。 min 和 max 用作比较, 这个不会有影响吧:loveliness:

使用特权

评论回复
板凳
nevsayno| | 2011-3-4 16:47 | 只看该作者
没怎么看明白LZ想要表达啥 猜应该是这么两个问题没有注意
1 前台与后台访问共享资源的竞争问题
2 相乘后数据溢出的问题

使用特权

评论回复
地板
ayb_ice| | 2011-3-4 16:49 | 只看该作者
一个是宏定义,一个是变量定义,区别大了,宏只是替换而已
用在一起是有问题的,不能同名。

使用特权

评论回复
5
highgear| | 2011-3-4 22:30 | 只看该作者
常量宏替换会让常量嵌入在代码了,作为立即数直接载入。作为变量则需要通过定位存取。
add, max, min这类名称及其容易冲突。

void  count(unsigned int m)  
   {
    count=0;       //
      count=1000*m;   //
    while(count>0);  //
    }
count 名称冲突了,而且很混乱。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
触觉的爱 + 1
6
linqing171| | 2011-3-4 23:16 | 只看该作者
第二个count没有被用到,被优化掉了.

使用特权

评论回复
7
触觉的爱|  楼主 | 2011-3-5 10:21 | 只看该作者
难道偶说得不够清楚吗?

4楼   偶只是说宏定义和直接变量定义替换来测试,不是说一起用。一起用同样的名称,编译应该不能过吧。在好多相关的书上都说用宏定义比较好,像用宏来定义一个常量代表圆周率参与运算 的例子说得特别多,所以偶才比较困惑 。可能就如 5楼 所说的那样,变量是定位存取,估计是有保护的。  

另外 5楼 所说的count 名称冲突 , 是函数在发帖时写错了,函数count还有后缀的,要不然编译也会有提示的。 测试时是用 count=0;count=1000*m;  和count=1000;count=count*m  这两种写法来替换的。编译后下载到板上测试,count=0;count=1000*m;只能正确循环计算三次左右;
而count=1000;count=count*m  这种用法却怎么折腾都是正确。 所以才比较困惑

使用特权

评论回复
8
new1988| | 2011-3-5 10:35 | 只看该作者
第一种宏,当你用这宏的时候,例如A = add*min*max。编译器会直接把add*min*max算出结果来,然后送给A。这个结果电脑已经给你算好了。
第二种是变量的用法,虽然在用之前已经赋值了,但是这个编译器是不会自己把给过算出来的,他会编译成对应的代码,交给单片机去运算。只要你定义了一个变量,不管你在程序中有没有改变它的值,编译器都不会自己去算,而是编译成相应的代码交给单片机去计算。
所以这两种方法的代码量差别很大。至于两种计算的差别,没看见具体的代码,不好判断。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
触觉的爱 + 1
9
xwj| | 2011-3-5 10:50 | 只看该作者
1、错漏百出的程序,LZ先去吧程序写正确再说;
2、完全不搭边的来了哥哥问题,干嘛要放在一起问?
3、注意count的类型,不要溢出;
4、任何数乘以0都等于0 ,所以下面“count=1000*m;”或被优化掉,甚至“while(count>0); ”也会被优化掉。
void  count(unsigned int m)  
   {
    count=0;       //
      count=1000*m;   //
    while(count>0);  //
    }

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
触觉的爱 + 1
10
触觉的爱|  楼主 | 2012-4-8 21:16 | 只看该作者
回头来看看当初第一个帖子

  其实问题在于 计算中类型转换方面。 在计算中加入强制类型转换的语句,就没问题了

估计是编译器对于常量的计算,会自动进行类型转换,而对于宏定义和变量的计算,并不会做这方面的处理。所以才会导致只有定义成常量,才不会出错。而定义成变量、宏定义的 计算,就会间中出错。

感谢上面的几位参与

使用特权

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

本版积分规则

个人签名:降额设计是提升产品可靠性的最有效手段之一

2

主题

909

帖子

6

粉丝