Lazarus中文社区

 找回密码
 立即注册(注册审核可向QQ群索取)

QQ登录

只需一步,快速开始

Lazarus IDE and 组件 下载地址版权申明
查看: 2051|回复: 1

[Lazarus实战宝典] 不引人注目的运算符优先级问题

[复制链接]

该用户从未签到

发表于 2013-7-15 15:16:14 | 显示全部楼层 |阅读模式
本帖最后由 逍遥派掌门人 于 2013-7-15 15:23 编辑

Lazarus 程序片段:
  1. var   a1,a2,a3:byte;
  2. begin
  3.    a1:=$31;
  4.    a2:=(a1 shr 4 ) and $0F * 10 + a1 and $0F;
  5.    a3:=a1 shr 4 and $0F * 10 + a1 and $0F;
  6.    showmessage(inttostr(a2)+'---'+inttostr(a3));
复制代码
结果显示 a2=31, a3=31 ,均为预期的结果,正确。

然而,将上面的代码直接翻译为C语言的代码时,问题出来了:
  1.          unsigned char a1,a2,a3;

  2.           a1=0x31;
  3.           a2=(a1 >>4 ) & 0x0F *10 + a1 & 0x0F;
  4.           a3=a1 >> 4 & 0x0F *10 + a1 &0x0F;   
复制代码
得到的结果: a2=3 ,a3=3 ,很显然,不是所期望得到的结果。

为什么会这样呢? 答案是:运算符的优先级。
在Pascal语言里面: 运算符 * , shr ,and 的优先级是相同的,遵循从左到右的优先规则, 运算符 + 的优先级则相对最低;
在C语言里:运算符 * 优先级最高,接着是运算符 +,再接着是 运算符>>,最低是运算符 &。
由于上述的差别,导致了无法得到正确的结果。

正确的C语言代码为:
  1.   unsigned char   a1,a2;
  2.    
  3.    a1=0x31;   
  4.    a2=((a2 >>4 ) & 0x0F) * 10 +  (a2 & 0x0F);
复制代码
用C语言例优先级最高的圆括号来强制实现Pascal语言的优先级顺序,从而得到期望的值: a2=31 。

不同的语言,运算符的优先级可能会有不同,在转换代码的时候要特别注意,以免得不到正确的结果。
回复

使用道具 举报

  • TA的每日心情

    2021-8-18 08:54
  • 签到天数: 1421 天

    [LV.10]以坛为家III

    发表于 2013-7-16 06:11:46 | 显示全部楼层
    受教了,不过我一般都用括号的。
    回复 支持 反对

    使用道具 举报

    *滑块验证:

    本版积分规则

    QQ|手机版|小黑屋|Lazarus中国|Lazarus中文社区 ( 鄂ICP备16006501号-1 )

    GMT+8, 2025-5-2 23:54 , Processed in 0.026810 second(s), 10 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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