不管你是怎么想的,用宏容易犯错误!

来源:互联网 发布:淘宝上推荐一款望远镜 编辑:程序博客网 时间:2024/04/29 19:30

问题74:Gross Error(什么意思?)
下面的程序在编译的时候说第16行有语法错误。哪么第16行错在哪了呢?
1 /************************************************
  2  * gross -- Print out a table of 1 to 10 gross. *
  3  ************************************************/
  4 // A Gross is a dozen - dozen
  5 #define GROSS (12 ** 2)
  6
  7 #include <iostream>
  8
  9 int main()
 10 {
 11     int i;      // Index into the table
 12
 13     for (i = 1; i <= 10; ++i)
 14     {
 15         std::cout << i << " gross is " <<
 16             (GROSS * i) << '/n';
 17     }
 18
 19     return (0);
 20 }
//////////////////////////////////////////////////////////////
//提示:
单纯看第16行,是没有问题的,之所以这么问是为了“迷糊”大家的。
//////////////////////////////////////////////////////////////
//我的答案:
我就是那个被迷糊的,我还真以为C++中会有这种东西,虽然在很多语言里会有(比如Fortron)我学的第二门计算机语言。远古没有任何印象了。
//////////////////////////////////////////////////////////////
//标准答案:
在c++中就没有**运算符(至少对于整数而言)。所以(12**2)不是有效的初始化值。语句的问题是在于错误被隐藏在宏里面,编译器直到分析到16行才会发现这个问题。这就是为什么说16行有语法错误。
//////////////////////////////////////////////////////////////
//翻译者的话:
//宏不是好东西,对于c++来说,不少书已经说过这个问题了,(Effective C++)等等。这个例子虽然牵强,但的确是宏的毛病!
//////////////////////////////////////////////////////////////
//貌似编程真理:
存在两种方式去写没有错误的代码。但是只有第三种是有效的。

 

问题75:快速退出
ABORT宏用来显示错误信息然后退出。当程序出现问题时候,用这个宏显示信息然后退出。
当有错误时下面的程序的确显示错误然后退出。但是我们没错误时候它也退出。事实上它总是退出。
这是为什么呢?
1 /************************************************
  2  * Test the square_root function.               *
  3  ************************************************/
  4 #include <iostream>
  5 #include <math.h>
  6
  7 /************************************************
  8  * ABORT -- print an error message and abort.   *
  9  ************************************************/
 10 #define ABORT(msg) /
 11     std::cerr << msg << std::endl;exit(8);
 12 /************************************************
 13  * square_root -- Find the square root of the   *
 14  *      value.                                  *
 15  *                                              *
 16  * Returns:                                     *
 17  *      The square root.                        *
 18  ************************************************/
 19 static int square_root(
 20     const int value
 22 ) {
 23     if (value < 0)
 24         ABORT("Illegal square root");
 25
 26     return (int(sqrt(float(value))));
 27 }
 28
 29 int main() {
 30     int square; // A number that's square
 31     int root;   // The square root of the number
 32
 33     square = 5 * 5;
 34     root = square_root(square);
 35
 36     std::cout << "Answer is: " << root << '/n';
 37     return (0);
 38 }
//////////////////////////////////////////////////////////////
//提示:
看看用编译器将预编译替换宏的代码就知道了。
//////////////////////////////////////////////////////////////
//我的答案:
说实话我对宏一点不感冒,除了头文件保护之外。所以关于宏的东东我总是很抵触,这个题我当时没好好看。大家看答案就知道,挺简单的。
//////////////////////////////////////////////////////////////
//标准答案:
ABORT宏展开后是两条语句。展开后如下:
 if (value < 0)
   std::cerr << "Illegal root" << std::endl;exit (8);
让我们正确的运用格式美化再看看:
if (value < 0)
  std::cerr << "Illegal root" << std::endl;
exit (8);
这就是为啥程序总是退出的原因了。
//////////////////////////////////////////////////////////////
//翻译者的话:
实在想要效率用inline实现一个就是了。没有必要和宏走得那么近^_^。

//还想翻译下面几个问题,发现都是跟宏有关的。就感觉没什么精神了。不要用它,除了特别的情况(我能想到的就是条件编译和头文件保护)

问题78的小故事挺有意思,大家是不是也遇上过呢?
我在公司网络系统上安装了Adventure游戏(我想这个游戏应该是个文字游戏,在Emacs上就有,虽然我没有玩过,貌似复杂的冒险世界。翻译者的话)在我非工作时间呢,我会花上不少时间在那上面。一天早上,我的头头叫我去他的办公室。
“听说你在系统上安装了冒险这款游戏?”他问。
“我只在我下班时间...”我回答。
“哦,我不是在指责你,”他安慰我说。“恰恰相反,我还要夸你呢。自从这个项目开始,我们每天都要从Bill(市场部的负责人)接到反馈意见。每天他来,都要运行我们的程序,然后坚持叫我们改进。但这几周以来,他把大部分时间都用在冒险游戏上了,没有时间叫我们修改程序了。我太感谢你让他不像苍蝇样骚扰我了。”

//翻译者的话:人家说打工者只发挥10%的能力就能在公司混下去。看了这个故事后,我觉得的确如此。越到高层越是如此。

 

 

原创粉丝点击