for循环次数太多的时间优化_超炫酷技巧!C语言代码优化的技巧

本文介绍了C语言代码优化的一些关键技巧,包括布尔、整型、浮点和指针变量与零值的比较,以及整型数、除法和取余数的运算优化。此外,还探讨了循环语句的优化,如循环展开、尽早退出循环和使用复合赋值语句。文章强调了避免在循环体内部进行条件判断、使用位运算替代四则运算以及利用数组下标和别名提高效率的重要性。最后,提出了函数设计的最佳实践,如参数完整、使用switch替换if...else...和避免将正常值与错误标志混合返回。
摘要由CSDN通过智能技术生成

一、变量与值得比较

1、布尔变量与零值的比较

不可将布尔变量直接与 TRUE、 FALSE或者 1、 0进行比较 。据布尔类型的语义,零值为“ 假”(记为 FALSE),任何非零值都是“ 真”(记为TRUE)。

TRUE的值究竟是什么并没有统一的标准。例如 Visual C++ 将 TRUE定义为 1, 而 Visual Basic则将 TRUE定义为-1 。

假设布尔变量名字为 flag,它与零值比较的标准 if语句如下:

if (flag) // 表示flag为真if (!flag) // 表示flag为假

其它的用法都属于不良风格,例如:

if (flag == TRUE)if (flag == 1 )if (flag == FALSE)if (flag == 0)

2、整形变量与零值的比较

应当将整型变量用“ ==” 或“ !=” 直接与 0比较 。假设整型变量的名字为 value,它与零值比较的标准 if语句如下:

if (value == 0)if (value != 0)

不可模仿布尔变量的风格而写成:

if (value) // 会让人误解 value是布尔变量if (!value)

3、浮点变量与零值的比较

不可将浮点变量用“ ==” 或“ !=” 与任何数字比较 。千万要留意, 无论是 float还是 double类型的变量, 都有精度限制。

所以一定要避免将浮点变量用“ ==” 或“ !=” 与数字比较,应该设法转化成“ >=” 或“ <=” 形式。假设浮点变量的名字为 x,应当 将:

if (x == 0.0) // 隐含错误的比

转化为:

if ((x>=-EPSINON) && (x<=EPSINON))

其中 EPSINON是允许的误差(即精度) 。

4、指针变量与零值的比较

应当将指针变量用“ ==” 或“ !=” 与 NULL比较 。指针变量的零值是“ 空”(记为 NULL)。

尽管 NULL 的值与 0相同,但是两者意义不同。假设指针变量的名字为 p,它与零值比较的标准 if语句如下:

if (p == NULL) // p与 NULL显式比较,强调 p是指针变量if (p != NULL)

不要写成:

if (p == 0) // 容易让人误解 p是整型变量if (p != 0)

或者:

if (p) // 容易让人误解p是布尔变量if (!p)

二、变量及基本运算

1、整型数

如果我们确定整数非负,就应该使用unsigned int而不是int。

有些处理器处理无符号unsigned 整形数的效率远远高于有符号signed整形数(这是一种很好的做法,也有利于代码具体类型的自解释)。

因此,在一个紧密循环中,声明一个int整形变量的最好方法是:

registerunsignedint variable_name;

记住,整形in的运算速度高浮点型float,并且可以被处理器直接完成运算,而不需要借助于FPU(浮点运算单元)或者浮点型运算库。

尽管这不保证编译器一定会使用到寄存器存储变量,也不能保证处理器处理能更高效处理unsigned整型,但这对于所有的编译器是通用的。

例如在一个计算包中,如果需要结果精确到小数点后两位,我们可以将其乘以100,然后尽可能晚的把它转换为浮点型数字。

2、除法和取余数

在标准处理器中,对于分子和分母,一个32位的除法需要使用20至140次循环操作。

除法函数消耗的时间包括一个常量时间加上每一位除法消耗的时间。

Time (numerator / denominator) = C0 + C1* log2 (numerator / denominator)     = C0 + C1 * (log2 (numerator) - log2 (denominator)).

对于ARM处理器,这个版本需要20+4.3N次循环。这是一个消耗很大的操作,应该尽可能的避免执行。

有时,可以通过乘法表达式来替代除法。例如,假如我们知道b是正数并且b*c是个整数,那么(a/b)>c可以改写为a>(c*b)。

如果确定操作数是无符号unsigned的,使用无符号unsigned除法更好一些,因为它比有符号signed除法效率高。

3、取模的一种替代方法

我们使用取余数操作符来提供算数取模。但有时可以结合使用if语句进行取模操作。考虑如下两个例子:

uint modulo_func1 (uint count){   return (++count % 60);}uint modulo_func2 (uint count){   if (++count >= 60)      count = 0;   return (count);}

优先使用if语句,而不是取余数运算符,因为if语句的执行速度更快。这里注意新版本函数只有在我们知道输入的count结余0至59时在能正确的工作。

4、使用数组下标

如果你想给一个变量设置一个代表某种意思的字符值,你可能会这样做:

switch ( queue ){case0 :   letter = 'W';   break;case1 :   letter = 'S';   break;case2 :   letter = 'U';   break;}

或者这样做:

if ( queue == 0 )  letter = 'W&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值