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

建议4-1:整数转换为新类型时必须做范围检查

关于整数类型数据的转换原则,在C99的6.3.1.3节中做了非常重要的阐述,其表达的主要意思如下:
当我们将一个整数类型的数据转换成除_Bool类型之外的另一个整数类型时,如果这个值可以被新的整数类型所表示,那么它就不会被修改,可以正确转换;如果所转换的新类型是无符号的,那么这个值就会反复加上或减去这个新类型可以表示的最大值加1,直到这个值位于这种新类型的范围之内;如果所转换的新类型是有符号的,并且这个值无法用新类型表示,那么它的结果是由编译器定义的。
因此,为了保证整型数据转换时不会发生丢失或错误解释数据的情况,我们必须做一定的范围检查,以保证要转换的数据的值在新类型的取值范围之内。而在头文件limits.h中就定义了相关整型数据的取值范围,例如,在VC++ 2010中定义的limits.h部分代码如下所示:

#define CHAR_BIT      8             /* number of bits in a char */
#define SCHAR_MIN   (-128)          /* minimum signed char value */
#define SCHAR_MAX     127          /* maximum signed char value */
#define UCHAR_MAX     0xff         /* maximum unsigned char value */
#ifndef _CHAR_UNSIGNED
#define CHAR_MIN    SCHAR_MIN        /* mimimum char value */
#define CHAR_MAX    SCHAR_MAX        /* maximum char value */
#else
#define CHAR_MIN      0
#define CHAR_MAX    UCHAR_MAX
#endif  /* _CHAR_UNSIGNED */
#define MB_LEN_MAX   5             /* max. # bytes in multibyte char */
#define SHRT_MIN    (-32768)        /* minimum (signed) short value */
#define SHRT_MAX      32767        /* maximum (signed) short value */
#define USHRT_MAX     0xffff        /* maximum unsigned short value */
#define INT_MIN (-2147483647 - 1)    /* minimum (signed) int value */
#define INT_MAX     2147483647        /* maximum (signed) int value */
#define UINT_MAX    0xffffffff        /* maximum unsigned int value */
#define LONG_MIN (-2147483647L - 1)    /*minimum(signed) long value */
#define LONG_MAX    2147483647L        /* maximum (signed) long value */
#define ULONG_MAX   0xffffffffUL        /* maximum unsigned long value */
#define LLONG_MAX   9223372036854775807i64    /* maximum signed     long long int value */
#define LLONG_MIN  (-9223372036854775807i64 - 1) /* minimum signed long long int value */
#define ULLONG_MAX  0xffffffffffffffffui64    /* maximum unsignedlong long int value */#define _I8_MIN    (-127i8 - 1)        /* minimum signed 8 bit value */
#define _I8_MAX    127i8             /* maximum signed 8 bit value */
#define _UI8_MAX   0xffui8            /* maximum unsigned 8 bit value */
#define _I16_MIN  (-32767i16 - 1)    /* minimum signed 16 bit value */
#define _I16_MAX   32767i16         /* maximum signed 16 bit value */
#define _UI16_MAX  0xffffui16         /* maximum unsigned 16 bit value */
#define _I32_MIN  (-2147483647i32 - 1)    /* minimum signed 32 bit value */
#define _I32_MAX   2147483647i32        /* maximum signed 32 bit value */
#define _UI32_MAX  0xffffffffui32    /*maximum unsigned 32 bit value*/
/* minimum signed 64 bit value */
#define _I64_MIN    (-9223372036854775807i64 - 1)
/* maximum signed 64 bit value */
#define _I64_MAX      9223372036854775807i64
/* maximum unsigned 64 bit value */
#define _UI64_MAX     0xffffffffffffffffui64
#if     _INTEGRAL_MAX_BITS >= 128
/* minimum signed 128 bit value */
#define _I128_MIN
(-170141183460469231731687303715884105727i128 - 1)
/* maximum signed 128 bit value */
#define _I128_MAX
170141183460469231731687303715884105727i128
/* maximum unsigned 128 bit value */
#define _UI128_MAX    0xffffffffffffffffffffffffffffffffui128
#endif

举个例子,从一种无符号类型转换为一种有符号类型时,就可能发生数据的高位被截断而导致数据丢失,或者符号位丢失,所以在转换之前要对取值范围进行验证。下面的示例代码演示了如何从unsigned int类型转换为signed char类型:

unsigned int ui1=12345;
signed char sc1;
if(ui1>SCHAR_MAX)
{
}
else
{sc1=(signed)ui1;
}

同样,如果将有符号类型转换为无符号类型,也必须进行取值范围的验证,示例代码如下所示:

signed int si1=-12345;
unsigned int ui1= 0;
if(si1<0||si1>UINT_MAX)
{
}
else
{ui1=(unsigned int)si1;
}

在数据类型由“高级向低级”转换的时候,同样必须进行取值范围验证,示例代码如下所示:

long long int lli1=LLONG_MAX;
int i1= 0;
if(lli1<INT_MIN||lli1>INT_MAX)
{
}
else
{i1=(int)lli1;
}

《编写高质量代码:改善c程序代码的125个建议》——建议4-1:整数转换为新类型时必须做范围检查...相关推荐

  1. 《编写高质量代码:改善c程序代码的125个建议》——建议4-2:浮点数转换为新类型时必须做范围检查...

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

  2. 读《编写高质量iOS与OS X代码的52个有效方法》

    又看了一遍<编写高质量iOS与OS X代码的52个有效方法>这本书,做一个简单的总结,其中runtime和GCD那些的不是太详细,要想很详细估计写的东西比篇文字都多,但恰巧又是iOS的重点 ...

  3. 如何编写高质量和可维护的代码

     如何编写高质量和可维护的代码 我们怎么做才能既不需要写很多注释,又能保证代码易于理解呢? 其中一个主要的方法就是让代码自文档化.其优势在于,既不用写注释,又能使得代码易于维护. 下面就是三种使得 ...

  4. [读书笔记]读《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法》(一)...

    第一条:了解Objective-C 语言的起源 Objective-C为C语言添加了面向对象特性,是其超集.Objective-C使用动态绑定的消息结构,也就是说,在运行时才会检查对象类型.接收一条消 ...

  5. 《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》笔记

    2019独角兽企业重金招聘Python工程师标准>>> 这本书很早有了解过,评价都不错,但最近才终于把这本书看完,整本书介绍了很多个提高Objective-C的方法,都是平时用得很多 ...

  6. 【Python】使用31条规则编写高质量且美丽的Python代码

    Raymond Hettinger在pycon US 2013 视频,幻灯片上的讲话. 代码示例和直接引用都来自Raymond的演讲.我在这里复制它们是为了我自己的启发和希望别人会发现它们像我一样方便 ...

  7. Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法笔记-协议与分类...

    23.通过委托与数据源协议进行对象间通信 如果要在委托对象上调用可选方法,那么必须提前使用类型信息查询方法判断这个委托对象能否响应相关选择子. if ( [_delegate respondsToSe ...

  8. 编写高质量代码改善C#程序的157个建议——建议148:不重复代码

    建议148:不重复代码 如果发现重复的代码,则意味着我们需要整顿一下,在继续前进. 重复的代码让我们的软件行为不一致.举例来说,如果存在两处相同的加密代码.结果在某一天,我们发现加密代码有个小Bug, ...

  9. 编写高质量代码改善C#程序的157个建议——建议86:Parallel中的异常处理

    建议86:Parallel中的异常处理 建议85阐述了如何处理Task中的异常.由于Task的Start方法是异步启动的,所以我们需要额外的技术来完成异常处理.Parallel相对来说就要简单很多,因 ...

最新文章

  1. centos6.5安装zabbix3.4
  2. 树莓派文件服务器nas,树莓派搭建NAS服务器
  3. Uva1103 古代象形符号
  4. Linux-HA 高可用开源方案 Keepalived VS Heartbeat 对比
  5. 指定结构体字节对齐方式
  6. WordPress Restful API registration to Kyma WordPress API注册到Kyma的实现原理
  7. MVC之前的那点事儿系列(4):Http Pipeline详细分析(上)
  8. LeetCode 第 201 场周赛(304/5614,前5.42%)
  9. python报错对象没有属性_属性错误:函数对象在python中没有属性
  10. Oracle实现数据不存在则插入,数据存在则更新(insert or update)
  11. EMNLPICLR 多模态学习前沿分享
  12. 菜鸟学Linux 第079篇笔记 mysql备份lvm
  13. veevalidate的使用3.X版本
  14. 频域自适应 matlab,FDAF 频域自适应滤波器( )演示程序 Matlab; LMS算法 266万源代码下载- www.pudn.com...
  15. 倍福TwinCAT 3 气缸动作程序编写
  16. 用印审批移动办公用户手册
  17. python太极代码_旋转的太极图动画源代码
  18. php生成其他网页截图,php实现网页截图
  19. (附源码)mysql+ssm学生选课系统 毕业设计 170920
  20. marquee参数详解

热门文章

  1. 未来之路—写在大二结束之前
  2. Android性能优化 - 内存优化
  3. 自定义控件:视差特效
  4. W10中给文件夹添加备注或者注释
  5. 开关电源反馈环路设计matlab,开关电源控制环路设计(初级篇).pdf
  6. python全局解释锁_Python GIL 全局解释性锁介绍
  7. php编程输出心形图案_利用php输出不同的心形图案,php心形图案_PHP教程
  8. 主成分分析法_“主成分分析法”——线上讨论会等你加入
  9. 图标适配大小_主题真的是大吃一鲸适配全EMUI
  10. Linux怎么创建date文件,Linux下手工创建oracle database