编写高质量C代码一:数据

(1)注意数据类型及其范围

不同数据类型的表示方法和范围是不同的,整型如下图:

这里要注意符号数和无符号数是有区别的,符号的最高位要牺牲出来作为符号位,符号位为1表示负数,符号位为0表示正数。实质上,我们对内存中的数据进行解释,是按照他的数据类型进行解释的。举个例子,-3在内存中的补码(假设8位)表示为1000 0011,如果定义-3为无符号型,那么解释得到的数值就是131。所以,有时候会发生一些看似“奇怪”的事情。举两个例子:

char的表示范围是-127~127,这里定义char a=150,超过了其表示范围,编译器就会按照符号数进行处理,所以最后结果是负数。

(2)注意不同数据类型的转换

我们再来看例外一个例子:

按理说,最后的结果应该是i < sizeof(array)啊?

原来是这样,sizeof返回值是size_t类型,是一个无符号型。当有符号数和无符号数进行运算时,有符号数会转换成无符号数。这样,-1用无符号数表示的话就是一个非常大的正数。所以会出来“看似奇怪”的结果。

由此可见,有符号数和无符号数混合使用是危险的,所以在代码中要尽量少使用无符号型。

(3)防止无符号整数回绕

涉及无符号数的计算是永远不会发生溢出的,也就是说,如果数值超过了无符号数的最大上限,就会发生回绕。如果无符号数超过了最大值,就会返回0,然后从0开始增大;如果低于无符号数的下限,那么就会达到无符号数的上界,然后从上界开始减小。举个例子:

因此,在无符号数的运算中,要采取适当的方法防止回绕。例如做如下修改:

#include<stdio.h>
int main(){
    unsigned int a = 4294967295;
    unsigned int b = 2;
    unsigned int c = 4;
    if(UINT_MAX - a > b)
        printf("%u\n",a+b);
    if(UINT_MIN + c < b)
        printf("%u\n",b-c);
    return 0;
}

(4)防止符号整数溢出

当两个符号数运算溢出时,会导致“不确定的行为”,大多数编译器会忽略溢出,这样就会导致不确定或错误的值保存在变量中。溢出跟回绕类似,会使变量的值发生“意想不到”的变化,可以逃过边界检查,导致很多问题,比如缓冲区溢出。

(5)少使用浮点数

大多数平台下,浮点数都遵循IEEE754标准。浮点类型在不同平台下的实现差异很大,有的平台有浮点运算单元(FPU);有的处理器只能做整型运算,需要用整数运算实现模拟浮点运算(软浮点)。

5.1 避免浮点数进行精确计算,用分数精确表示浮点数,避免浮点数因舍入误差导致的不精确问题。

5.2 避免浮点数直接使用==进行判断,一般采用|V0 - V1 < MIN|的形式。

5.3 避免使用浮点数作为循环计数器。

5.4 尽量将浮点运算中的整数转换为浮点数。看个例子:

为什么第一个结果跟后面四个不一样呢?而且第一个结果明显精确度不高。因为x/9会首先执行,然后将结果35转换成浮点数赋给a。还有一点要注意,整数与浮点数运算,会将整数首先转化为浮点数。因此,为了避免这种信息缺失的情况,我们使用整数运算并把结果赋给一个浮点数时,要首先将一个整数转换成浮点数!

(6)数据类型转化时做范围检查

不同类型的数据进行转化,要先转化为级别最高的数据类型,然后再进行运算。例如int类型的数据和long类型的数据运算,int先要转化成long。还有一个要注意的是,所有的浮点操作都是双精度的,即使表达式中只有float类型,也要首先转化成double类型。

如果一个无符号类型转化成有符号类型,就有可能发生高位截断而数据丢失,主要是防止溢出。

(7)使用有严格定义的数据类型

首先看两个例子:

为什么会这样呢?因为ch与0xff比较时,首先将ch转换为int型,如果int是32位的,那么如果ch是有符号的,那么补为0xffff ffff;如果ch是无符号的,那么补为0x0000 00ff。

尽量使用严格形式定义的、可移植的数据类型,尽量不使用与具体硬件或软件关系密切的变量。

时间: 2024-10-31 23:55:00

编写高质量C代码一:数据的相关文章

[编写高质量iOS代码的52个有效方法](十)Grand Central Dispatch(GCD)

[编写高质量iOS代码的52个有效方法](十)Grand Central Dispatch(GCD) 参考书籍:<Effective Objective-C 2.0> [英] Matt Galloway 先睹为快 41.多用派发队列,少用同步锁 42.多用GCD,少用performSelector系列方法 43.掌握GCD及操作队列的使用时机 44.通过Dispatch Group机制,根据系统资源状况来执行任务 45.使用dispatch_once来执行只需要运行一次的线程安全代码 46.不

[编写高质量iOS代码的52个有效方法](十一)系统框架

[编写高质量iOS代码的52个有效方法](十一)系统框架 参考书籍:<Effective Objective-C 2.0> [英] Matt Galloway 先睹为快 47.熟悉系统框架 48.多用块枚举,少用for循环 49.对自定义其内存管理语义的容器使用无缝桥接 50.构建缓存时选用NSCache而非NSDictionary 51.精简initialize与load的实现代码 52.别忘了NSTimer会保留其目标对象 目录 编写高质量iOS代码的52个有效方法十一系统框架 先睹为快

JavaScript手札:《编写高质量JS代码的68个有效方法》(一)(1~5)

编写高质量JS代码的68个有效方法(一) *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table, pre { marg

编写高质量JS代码的68个有效方法(八)

[20141227]编写高质量JS代码的68个有效方法(八) *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table,

编写高质量JS代码的68个有效方法(七)

[20141220]编写高质量JS代码的68个有效方法(七) *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table,

编写高质量JavaScript代码的68个有效方法

简介: <Effective JavaScript:编写高质量JavaScript代码的68个有效方法>共分为7章,分别涵盖JavaScript的不同主题.第1章主要讲述最基本的主题,如版本.类型转换要点.运算符注意事项和分号局限等.第2章主要讲解变量作用域,介绍此方面的一些基本概念,以及一些最佳实践经验.第3章主要讲解函数的使用,深刻解析函数.方法和类,并教会读者在不同的环境下高效使用函数.第4章主要讲解原型和对象,分析JavaScript的继承机制以及原型和对象使用的最佳实践和原则.第5章

Effective Python之编写高质量Python代码的59个有效方法

                                                     这个周末断断续续的阅读完了<Effective Python之编写高质量Python代码的59个有效方法>,感觉还不错,具有很大的指导价值.下面将以最简单的方式记录这59条建议,并在大部分建议后面加上了说明和示例,文章篇幅大,请您提前备好瓜子和啤酒! 1. 用Pythonic方式思考 第一条:确认自己使用的Python版本 (1)有两个版本的python处于活跃状态,python2和pyt

[编写高质量iOS代码的52个有效方法](三)消息和运行期

[编写高质量iOS代码的52个有效方法](三)消息和运行期 参考书籍:<Effective Objective-C 2.0> [英] Matt Galloway 先睹为快 11.理解objc_msgSend的作用 12.理解消息转发机制 13.用"方法调配技术"调试"黑盒方法" 14.理解"类对象"的用意 目录 编写高质量iOS代码的52个有效方法三消息和运行期 先睹为快 目录 第11条理解objc_msgSend的作用 第12条理解

编写高质量Python代码的59个有效方法

作者Brett Slatkin是 Google公司高级软件工程师.他是Google消费者调查项目的工程主管及联合创始人,曾从事Google App Engine的Python基础架构工作,并利用Python来管理众多的Google服务器.Slatkin也是PubSubHubbub协议的联合创始人,还用Python为Google实现了针对该协议的系统.他拥有哥伦比亚大学计算机工程专业学士学位. 精彩书评 "Slatkin所写的这本书,其每个条目(item)都是一项独立的教程,并包含它自己的源代码.

编写高质量JS代码的68个有效方法(三)

[20141030]编写高质量JS代码的68个有效方法(三) *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table,