看到刘汝佳提到的一个KISS(Keep It Simple and Stupid)原则很受启发,程序的目的是为了解决问题,应该用尽量简洁的方式,不是为了写程序而写程序,不是展示技巧
比如:交换两个数的顺序输出。
可以用中间变量,也可以直接用相加的和来分别减
a = a + b;
b = a - b;
a = a - b;
甚至是:
a ^= b;
b ^= a;
a ^= b;
最直接的莫过于
scanf("%d%d",&a,&b);
printf("%d %d\n", b, a);
再比如:对三个整数排序
虽然可以用各种方法排序再输出,但我们最终只关心输出结果,甚至根本不需要排就能殊途同归
x = a; if(b < x) x = b;if(c < x) x = c;
z = b; if (a > y) y = a;if(c > y) y = c;
y = a + b + c - x - z;
printf("%d %d %d\n",x,y,z);
--------分割线------
杂记:
1、程序运行时间测量:
clock_t clock(void) 函数(time.h)返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元,该函数返回值是硬件滴答数,要换算成秒,需要除以CLOCKS_PER_SEC。返回值clock_t是长整型。
可直接在程序结尾处插入
printf("Elapsed time: %f secs\n",(double)clock()/CLOCKS_PER_SEC);
也可选定某一程序片段测量:
clock_t start, end;
start = clock();
..
fun()
..
end = clock();
printf("Elapsed time: %f secs\n",(double)(end - start)/CLOCKS_PER_SEC);
为避免输入数据时间影响测试结果,通常用管道命令辅助测试,e.g:echo 100 | test
unix下可以使用精度更高的
int gettimeofday(structtimeval*tv, struct timezone *tz);(sys/time.h)
其中第二个时区参数通常可置为 NULL;
第一个参数timeval的定义为:
struct timeval{
long int tv_sec; // 秒数
long int tv_usec; // 微秒数
}
它获得的时间精确到微秒(1e-6 s)量级。在一段代码前后分别使用gettimeofday可以计算代码执行时间:
structtimevaltv_begin, tv_end;
gettimeofday(&tv_begin, NULL);//有些编译器第二个参数需置0
foo();
gettimeofday(&tv_end, NULL);
printf("Elapsed time: %ld us\n" ,1000000 * (tv_end.tv_sec - tv_begin.tv_sec) + tv_end.tv_usec - tv_begin.tv_usec);
浮点运算可能会出现误差,尤其是在进行比较时,需特别注意。
比如验证完全平方数:
m = sqrt(n);
if (floor(m + 0.5) == m)
printf("%d",n);
适当调整floor()的取值区间以降低误差
浮点数的陷阱
double i;
for(i = 0; i != 10; i += 0.1)
printf("%.11f\n", i)
该程序的运行结果是: 无限循环.
调用gdb输出中间结果来观察,发现 i 自加0.1后,并不是我们预想的等于0.1
而是等于 0.10000000000000001.
再往下执行几次,i 的值分别是0.20000000000000001.
0.30000000000000004.
0.40000000000000002.
因此,在定义循环变量时,尽量采用int型及整数的加减.因为循环的本质意义就是通过各种条件来控制语句重复运行次数.而这个次数本身就是整数.要实现小数的功能尽量
通过循环中的语句来实现.
其次,在判断语句 i != 10 也有问题,常用可以fabs(A-B) < epsilon 来减少误差,更加精确点可以参考http://zhangzhibiao02005.blog.163.com/blog/static/3736782020118244733682/
3、gcc编译选项
可以用-O1 -O2 -O3对代码进行速度优化。一般情况下,直接编译出的程序比用-O1编译出的慢,后者比用-O2慢。尽管理论上-O3编译出的程序更快,但由于某些优化可能会误解程序员的本意,不推进经常使用。另外,如果程序中有不确定的因素(如未初始化的变量),运行结果可能会与编译选项有关。当然如果是一个规范的程序,运行结果不会和优化方式有关。
4、注意中间变量溢出