webdancer's Blog
max宏引起的杯具
程序执行的时间与估计的渐近时间出现了很大的出入,程序的结构如下:
float maxsubarr3(int l,int u){ ......//省略 return max(lmax+rmax,max(maxsubarr3(l,m),maxsubarr3(m+1,u))); }
问题在max定义上,我用宏定义了max,如下:
#define max(a,b) ((a)>(b)?(a):(b))
忽视了宏替换的一个缺陷:作为参数的表达式重复计算了两次。而且本身参数是递归定义函数,时间的开销就会增长巨大,导致了在数量级到达5的时候,程序就无法运行了。
明确了问题所在,那就可以更正了。解决的方法:
1.将宏定义改为函数定义。
float max(float a,float b){ return a>b?a:b; }
2.更正宏定义的方式。
#define max(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; })
使用函数定义后,bug就没了。
参考:
重新拾起C(1)-关键字
前记: 以前自学的C语言,但是很肤浅!决定,再认真地学一遍。认真的看看C语言,学习的书是陈正冲老师的《C语言深度解析》。套用一句话,永远给我记住一点:结果对,并不代表程序真正没有问题。
c 的关键字:
auto | break | case | char | const | continue | default | do |
double | else | enum | extern | float | for | goto | if |
int | long | register | return | short | signed | sizeof | static |
struct | switch | typedef | union | unsigned | void | volatile | while |
2)register:寄存器变量修饰,其变量必须是单一的值,且不能用&,取得地址。
3)static:静态修饰符,只能被本文件引用,其他文件不可用。
4)short:短整型。
3)int:整型。
4)long:长整型。
5)float:单精度浮点数。
6)double:双精度浮点数。
7)char:字符类型。
8)enum:枚举类型。(应该是基本类型吧!)
enum ColorT {red, orange, yellow, green, blue, indigo, violet}; ... ColorT c1 = indigo; if( c1 == indigo ) { cout << "c1 is indigo" << endl; }
8)struct:结构体。
struct Date { int day; int month; int year; } today;
9)union:共用体。
union Data { int i; char c; };
10)void:函数,返回值为空。指针,可以指向任何类型数据。
11)sizeof:计算参数大小。
12)signed:有符号。
13)unsigned:无符号。
14)if :条件。
15)else:其他,条件语句。
16)switch:条件分支语句。
17)case:条件分支语句。
18)do :循环语句。
19) while :循环语句。
20)for:循环语句。
21)break:跳出循环体。
22)continue:结束本次循环,进入下次循环。
23)goto:跳转语句,应该禁用,破坏结构化。当然,还是自己的习惯!
24)return:返回值。
25)const:常量,在c与c++有区别。
26)volatile:可变的,编译器不会自作主张优化其声明的变量。
27)extern :可以置于变量或者函数前,以标示变量或者函数的定义在别的文件
28)typedef:分一个新名字,与原来的一样用。
typedef unsigned int* pui_t; // data1 and data2 have the same type pui_t data1; unsigned int* data2;