规范化的C++编程方法备忘录 C/C++算数运算:
已经知道的,不说了...大家都知道的,可以问问,查查资料。这里又放些附加建议:
1.基本算数运算:
既然计算机里没有真正的整数,那么计算机里也没有真正的算数运算。
取值范围:
设a和b是两个占一样位宽的无符号整数,这种整数可取到最大值MAX:
如果f1为一元运算,f2为二元运算,则先将计算机中的整数和运算扩展到 {0}UZ+ 域
有
f1(a) = fz1(az) % MAXz,
f2(a, b) = fz2(az, bz) % MAXz.
其中MAXz=R(MAX) + 1.
这些东西计算机系的应该知道的啦。即“有溢出可能的运算”或有穷域的取值问题
还有隐式转换、强制类型转换等。因为可查,略过。
书写代码时很多书里建议......(这里主要谈括号的问题)。对于默认顺序,个人认为有些建议没有必要:
已知的先乘除,后加减;先算数,后逻辑。初中、高中的东西。很多建议将算数加括号,多此一举。自己该补课去。但如果代码很长那就是另外一回事了。还有,位运算一定要加括号。因为它们不是基本代数运算。
加、乘、与、或运算也不满足交换率(尤其是对其他线程数据的读写运算)。
如果某一小块代码区域集中了大量的代数运算,而上面这类问题对结果有很大影响,建议用类将整数包装一下(但不要太复杂,影响性能),以便能正确地处理进位截断问题。
如果表达式中有超过一处使用同一变量,该变量是同时被多个线程存储的,要用本地临时变量拷贝取代表达式里所有的那个变量,以避免计算出莫名其妙的值。记住不要依赖编译器优化机制的隐含修改。
2.比较运算:
- 比较符号的左右两边数据类型必须相同。如果不同,代码照常编译通过。但是数据类型一定是相等的,只是通过了隐式转换,这种转换有时会让你晕倒...
正确的代码
引用:
WORD a, b, c
...
if((WORD)(a+b) >= c) // Never thought that '(WORD)()' be unnecessary.
...
- 比较必须完整,不
相关文档:
googletest C/C++ 测试框架非常好用,介绍及下载请看 http://code.google.com/p/googletest/
//============================================================================
// 使用 googletest 测试框架
//============================================================================
// Returns n! ......
/*
思路:递归算法
从开始往后递增地写数字,当前从now值开始,存储的位置从cur开始,
则显然加上,now..n,都是新的组合数,对于每一个,{ 输出之,然后递归,处理 _c(n, cur+1, a, i+1) }
*/
/* 输出1,2,3,..,n的组合数 */
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
void ......
/*
注意不断右移判断最低位是1有多少个的算法是错误的,
因为根据GNU C/C++的实现来看,负数是带符号填充进行右移的,所以如果是负数,该算法会死循环。
变通办法:Java可以用>>>逻辑右移位操作符,C/C++可以强制转换成无符号整数再处理
下面的程序是正解。其中num &= (num - 1) 会消除num的最小位置的"1" ......
#include <stdio.h>
#define bits(p, d) { \
int _tmp=p->d, _bits=0; \
for (p->d=1; p->d; p->d<<=1) \
_bits++; \
p->d=_tmp; \
printf("%s->%s has %d bits", #p, #d, _bits); \
}
typedef struct _s{
int a:4;
} S;
int main()
{
S tmp, ......
花费了十天时间,为公司开发了一套简单的网络版的信息管理系统,功能主要有客户信息管理,员工信息管理,常用信息管理(各种信函打印、常用网址/常用电话等),公司简单的财务管理等。把一些点点滴滴的技巧在此记录下来,以备查用。
1.数据绑定。 DataReader 读取数据,用DataTable.Load(IDataReader)方法将数据加载到 DataTable ......