当前位置: 首页 > news >正文

《编写高质量代码:改善c程序代码的125个建议》——建议14-4:尽量避免在同一个数据上执行位操作与算术运算...

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第2章,建议14-4,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议14-4:尽量避免在同一个数据上执行位操作与算术运算

虽然位操作在很大程度上可以提高程序的执行效率,但在同一个变量上执行位操作和算术运算会模糊程序员的意图,削弱代码的可移植性与可读性,还会导致安全审核员或代码维护人员难以确定应该执行什么检查以消除安全缺陷,保证数据的完整性。示例代码如下:

unsigned int x=10;
x+=(x<<3)-5;

虽然上面的代码是一条合法的优化语句,但是它的确严重地破坏了程序的可读性。因此,建议采用下面的方式来书写代码:

unsigned int x=10;
x=x*9-5;

或许这时候有读者会问,这样写代码不就降低了程序的执行效率吗?
其实不然,有些优化编译器会比我们做得更好。以整数乘法为例,如果目标系统有乘法指令,硬件的乘法比自己用移位操作实现的乘法要快得多;如果目标系统没有乘法指令,编译器会自动用移位等操作来优化乘法,示例代码如下:

unsigned int x=8; 
unsigned int y=x*4;
unsigned int z=x/2;

上面的代码在Microsoft Visual Studio 2010集成开发环境VC++的Debug模式下将生成如下汇编代码:

unsigned int x=8; 
00DB139E  mov         dword ptr [x],8  
    unsigned int y=x*4;
00DB13A5  mov         eax,dword ptr [x]  
00DB13A8  shl         eax,2  
00DB13AB  mov         dword ptr [y],eax  
    unsigned int z=x/2;
00DB13AE  mov         eax,dword ptr [x]  
00DB13B1  shr         eax,1  
00DB13B3  mov         dword ptr [z],eax

从上面的汇编代码可以看出,编译器会自动在汇编代码中用移位操作来优化乘除法运算。因此,完全没有必要用手工进行这种优化,编译器会自动完成。我们应该把精力放在改进程序的算法上,一个好的算法可以使程序运行效率大大提高。当然,如果除数为2的幂,那么在进行除法运算时可以适当地采用移位算法来实现乘除法。
除此之外,采用移位操作还需要注意不要超过该数据类型的精度范围(数据范围),示例代码如下:

#include <stdio.h>
int main (void)
{
    int x=-2147483647;
    x=x<<1;
    printf("%d \n",x);
    return 0;
}

在上面的代码中就要注意精度问题,在32位系统中,int类型占4个字节,精度范围为“-2147483647~2147483647”。其中,数据“-2147483647”的原码为“11111111111111111111111111111111”,补码为“10000000000000000000000000000001”。现在将“10000000000000000000000000000001”左移1位,最高位的1没有了,最低位左移一位,得到的结果为2。

相关文章:

  • 《51单片机应用开发范例大全(第3版)》——1.4 【实例19】P1口控制直流电动机实例...
  • 《微信公众平台开发:从零基础到ThinkPHP5高性能框架实践》——2.3 本章小结...
  • 《Adobe Photoshop CS6中文版经典教程(彩色版)》—第1课1.1节开始在Adobe Photoshop中工作...
  • MySQL 大数据量快速插入方法和语句优化
  • 《C++入门经典(第5版•修订版)》——6.8 作业
  • 《Adobe Premiere Pro CC经典教程(彩色版)》——1.4 Premiere Pro界面概述
  • 《树莓派开发实战(第2版)》——2.4 为树莓派配置网络名称
  • 《实施Cisco统一通信管理器(CIPT2)》一1.5 可用性方面面临的挑战
  • 《跨境电商 —— 阿里巴巴速卖通实操全攻略》一一2.4 淘代销
  • 《社会智能与综合集成系统》—第1章1.1节认知科学的发展
  • 《像计算机科学家一样思考Python》——3.13 使用from导入模块
  • 《MySQL DBA修炼之道》——1.2MySQL 的基础架构和版本
  • 定制并发类(七)实现ThreadFactory接口生成自定义的线程给Fork/Join框架
  • 《Python游戏编程快速上手》——2.2 计算表达式
  • 《Adobe Flash CS4中文版经典教程》——1.9 预览影片
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • Angular4 模板式表单用法以及验证
  • Objective-C 中关联引用的概念
  • PhantomJS 安装
  • Python实现BT种子转化为磁力链接【实战】
  • react-native 安卓真机环境搭建
  • 今年的LC3大会没了?
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 试着探索高并发下的系统架构面貌
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • HanLP分词命名实体提取详解
  • MyCAT水平分库
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 仓管云——企业云erp功能有哪些?
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • #define 用法
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (附源码)springboot教学评价 毕业设计 641310
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .net framework profiles /.net framework 配置
  • .net Stream篇(六)
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net反编译的九款神器
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • @angular/cli项目构建--http(2)
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • []FET-430SIM508 研究日志 11.3.31
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • [2023-年度总结]凡是过往,皆为序章
  • [Angular] 笔记 18:Angular Router
  • [AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步
  • [BZOJ2850]巧克力王国
  • [C/C++随笔] char与unsigned char区别
  • [C语言]一维数组二维数组的大小