快排中一个宏的bug

来源:互联网 发布:网络好文学作品 编辑:程序博客网 时间:2024/05/22 05:35

今天写快速排序,碰到一个问题:使用了下面的宏:

[cpp] view plain copy
  1. #define SWAP(a,b) \  
  2.     int temp = a; \  
  3.     a = b; \  
  4.     b = temp  

咋看没有问题,但是在使用时a,不是一个值而是一个表达式

[cpp] view plain copy
  1. SWAP(v[++m], v[i]);  

这样在编译器预处理的时候会展开为

[cpp] view plain copy
  1. int temp = v[++m]; v[++m] = v[i]; v[i] = temp;  
m被加了两次,导致错误。

  对于宏的使用,如果不打算改变宏参数的值,可以在宏开始的地方,保存一边宏的值,避免重复计算,例如

[cpp] view plain copy
  1. #define MAX(a,b) \  
  2.     a > b? a: b  

如果传入的a,b时fa().fb(),那么至少有一个函数计算了两次,导致额外的计算。


完整的代码如下

[cpp] view plain copy
  1. #include <vector>  
  2. #include <iostream>  
  3. using std::vector;  
  4. using std::cout;  
  5. using std::endl;  
  6. #define SWAP(a,b) \  
  7.     int temp = a; \  
  8.     a = b; \  
  9.     b = temp  
  10. void sort(vector<int> & v, int beg, int end) {  
  11.     if (beg >= end) {  
  12.         return;  
  13.     }  
  14.     int flag = v[beg];  
  15.     int m = beg;  
  16.     for (int i = beg; i<=end; ++i) {  
  17.         if (v[i] < flag) {  
  18.             ++m;  
  19.             SWAP(v[m], v[i]);  
  20.         }  
  21.     }  
  22.     SWAP(v[m], v[beg]);  
  23.     sort(v, beg, m-1);  
  24.     sort(v, m+1, end);  
  25.   
  26.     return;  
  27. }  
  28.   
  29. void sort(vector<int> &v) {  
  30.     int size = v.size();  
  31.     sort(v, 0, size - 1);  
  32. }  
  33.   
  34. template<class T>  
  35. int container_print(const T &c) {  
  36.     typename T::const_iterator beg = c.begin();  
  37.     typename T::const_iterator end = c.end();  
  38.     for (;beg != end; ++beg) {  
  39.         cout << *beg << ",";  
  40.     }  
  41.     return 0;  
  42. }  
  43.   
  44. int main() {  
  45.     vector<int> v;  
  46.     v.push_back(10);  
  47.     v.push_back(20);  
  48.     v.push_back(-20);  
  49.     v.push_back(-30);  
  50.     v.push_back(-50);  
  51.     v.push_back(50);  
  52.     v.push_back(-10);  
  53.     v.push_back(-9);  
  54.     v.push_back(-8);  
  55.     v.push_back(-7);  
  56.     container_print(v);  
  57.     cout << endl;  
  58.   
  59.     sort(v);  
  60.     container_print(v);  
  61.     cout << endl;  
  62. }  
原创粉丝点击