万贤
作家
作家
  • 铜币1枚
  • 威望24点
  • 贡献值1点
阅读:1394回复:15

问一个关于宏的问题~

楼主#
更多 发布于:2006-01-26 23:13
[color=#ff0000]#define BAND(x) (((x) > 5 && (x) <10) ? (x) : 0)[/color]

int main() {
   ofstream out("macro.out");
   assure(out, "macro.out");
   for(int i=4; i<11; i++){
      int a =i;
      out <<"a=" << a << endl <<'\t';
      out << "BAND(++a)=" << BAND(++a) <<endl;
      out <<"\t a = " << a << endl;
   }
}



输出结果:

a = 4
   BAND(++a)=0
     a = 5
[color=#ff0000]a = 5
   BAND(++a)=8
     a = 8
a = 6
   BAND(++a)=9
     a = 9
a = 7
   BAND(++a)=10
     a = 10[/color]
a = 8
   BAND(++a)=0
     a = 10
a = 9
   BAND(++a)=0
     a = 11
a = 10
   BAND(++a)=0
     a = 12


--------------------------------------------------------------

输入的结果并不是期望得到的

a等于4时,仅测试了条件表达式的第一部分,表达式只求职一次,所以红调用的副作用是a等于5,这是相同的情况下从普通函数调用所期望得到的.
但当数字在值域范围内时,两个表达式都测试,产生两次自增操作.产生这个结果是由于再次对参数操作.一旦数字出了范围,两个条件仍然测试,所以也产生两次自增操作

---------------------------------------------------------------

两个自增操作是如何实现的??有点不明白,望大人们指点 [ 2006-01-26 23:15:55 万贤 修改 ]
★fly★
著名写手
著名写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
1C#
发布于:2006-01-26 23:35
Re:问一个关于宏的问题~
越来越发现,你比瞧克里特还瞧克里特,比suchas还suchas...
[fly][color=#ff0012]开始混日子。。。[/color][/fly] [img]http://id.91cool.net/sign/?name=印苑家园[/img]
suchasplus
作家
作家
  • 铜币16枚
  • 威望11点
  • 贡献值1点
2C#
发布于:2006-01-26 23:47
Re:问一个关于宏的问题~
没装C++编译器...   算的和楼上的答案不一样    看的郁闷  

帮顶  等kmwang来解释~

ps:  万贤用的哪个C++编译器?
The history of these days will be written in blood... By crushing the armies of our enemy, by seizing the weapons they thought to turn against us, we were fighting for our very existence!
suchasplus
作家
作家
  • 铜币16枚
  • 威望11点
  • 贡献值1点
3C#
发布于:2006-01-26 23:47
Re:问一个关于宏的问题~
越来越发现,你比瞧克里特还瞧克里特,比suchas还suchas...


我在算的时候,你跑出来灌水~
The history of these days will be written in blood... By crushing the armies of our enemy, by seizing the weapons they thought to turn against us, we were fighting for our very existence!
万贤
作家
作家
  • 铜币1枚
  • 威望24点
  • 贡献值1点
4C#
发布于:2006-01-27 13:15
Re:问一个关于宏的问题~
不是啊,你看我后面有一段文字说明,我主要是不太明白他说的"两次自增操作"是只哪两个?为什么还要让x+1再+1
★fly★
著名写手
著名写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
5C#
发布于:2006-01-27 14:22
Re:问一个关于宏的问题~
我在算的时候,你跑出来灌水~

看来你的专精度也挺高的~
[fly][color=#ff0012]开始混日子。。。[/color][/fly] [img]http://id.91cool.net/sign/?name=印苑家园[/img]
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
6C#
发布于:2006-01-27 16:16
Re:问一个关于宏的问题~
哥,你也别研究这么玄的问题了,好好拿本C的手册看看都比到处求人强.

产生两次自增操作=>明显是三次嘛,要不咋10和7呢.
王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
7C#
发布于:2006-01-27 16:17
Re:问一个关于宏的问题~
主席再伟大,也解决不了江青同志的例假问题嘛!这种问题还是自己解决吧.
王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
万贤
作家
作家
  • 铜币1枚
  • 威望24点
  • 贡献值1点
8C#
发布于:2006-01-27 20:03
Re:问一个关于宏的问题~
当a等于4时,仅测试了条件表达式的第一部分,表达式只求职一次,所以红调用的副作用是a等于5,这是相同的情况下从普通函数调用所期望得到的.
但当数字在值域范围内时,两个表达式都测试,产生两次自增操作.产生这个结果是由于再次对参数操作.一旦数字出了范围,两个条件仍然测试,所以也产生两次自增操作


mumu大人可能没明白我的意思,也许可能我没有明白mumu大人的意思吧~

上面那段文字说明是来自<thinking in c++>里第九章内联函数,关于预处理器的讨论,给出了一段代码,并加以的文字说明,书上说了,这段代码的缺陷是并不能使我们得到期望的结果,指的是x在(5~10)这个范围内.因为产生了"两次自增操作",所以想请问一下这个问题~~谢谢~
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
9C#
发布于:2006-01-27 20:43
Re:问一个关于宏的问题~
是我没看懂:)

你用g++ -M还是-S看一下代码就知道了.
王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
10C#
发布于:2006-01-27 20:53
Re:问一个关于宏的问题~
BTW: T..I..C..这书成色似乎不怎么好也.作者也越来越不长进了~~当然是比较Kent Beck & Matrin Fowler这类真正的大师而言.

王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
suchasplus
作家
作家
  • 铜币16枚
  • 威望11点
  • 贡献值1点
11C#
发布于:2006-01-27 23:38
Re:问一个关于宏的问题~
--------------------Configuration: def - Win32 Debug--------------------
Compiling...
wanxian.cpp
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(4) : error C2065: 'ofstream' : undeclared identifier
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(4) : error C2146: syntax error : missing ';' before identifier 'out'
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(4) : error C2065: 'out' : undeclared identifier
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(5) : error C2065: 'assure' : undeclared identifier
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(8) : error C2297: '<<' : illegal, right operand has type 'char [3]'
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(8) : error C2065: 'endl' : undeclared identifier
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(9) : error C2297: '<<' : illegal, right operand has type 'char [11]'
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(10) : error C2297: '<<' : illegal, right operand has type 'char [7]'
e:\program files\microsoft visual studio\myprojects\def\wanxian.cpp(12) : warning C4508: 'main' : function should return a value; 'void' return type assumed
Error executing cl.exe.

def.exe - 8 error(s), 1 warning(s)
[ 2006-01-27 23:38:29 suchasplus 修改 ]
The history of these days will be written in blood... By crushing the armies of our enemy, by seizing the weapons they thought to turn against us, we were fighting for our very existence!
万贤
作家
作家
  • 铜币1枚
  • 威望24点
  • 贡献值1点
12C#
发布于:2006-01-29 13:20
Re:问一个关于宏的问题~
春节快乐~~
KxjIron
普通会员
普通会员
  • 铜币0枚
  • 威望0点
  • 贡献值1点
13C#
发布于:2006-02-03 14:34
Re:问一个关于宏的问题~
大家春节好
这段代码没有什么,输出结果应该是正确的
正如 mumu 所说翻翻手册, 自己思考是最重要的
首先要搞清楚 前置++ operator, 与 后置++ operator 的概念
然后是 && || 运算时及3目表达式会忽略掉不必要的 exp 处理
exp1 && exp2 很明显如果 exp1 == false 会忽略掉 exp2 运算
那么 || 运算与 exp1 ? exp2 : exp3 什么会被省略掉?

a = 5
BAND(++a)
>>>>>>> 展开
(((++a) > 5 && (++a) < 10) ? (++a) : 0
exp1 = (++a) > 5
exp2 = (++a) < 10
exp3 = (++a)
这里3个表达式都会被执行
exp1 == true ===> a = 6
exp2 == true ===> a = 7
(exp1 && exp2) == true
exp3 ===> a = 8

两次自增操作应该是指
((x) > 5 && (x) <10) 表达式, ++a 被宏展开后
((++a) > 5 && (++a) <10) 很明显只要 a > 5, ++a 操作会进行 2 次
事实上如果 exp3 也被执行到 ++a 操作会进行 3 次, 这就是宏的副作用
怎么避免又不失效率呢?用 inline 函数
注意:MACRO 和 #include 作用一样只是起到 copy/parse 的作用

I like running
KxjIron
普通会员
普通会员
  • 铜币0枚
  • 威望0点
  • 贡献值1点
14C#
发布于:2006-02-03 14:51
Re:问一个关于宏的问题~
我上学的时候也买了<Thinking in c++>, 看了2页就丢到书箱里, 再没有看过.
当时觉得晦涩难懂, 看得很伤自尊.不知道是作者没有文采还是译者喝醉了翻的
让我心有余悸的就2本, 还有一本是 <<The C++ Programming Language>>, 买的英文版特别版,
被我丢弃在书箱至今, 那叫一个看不懂.
现在想想, <Thinking in c++> 应该是面向有大量 c 实践想转 c++ 的人.
实践得多了看目录就知道内容大概要写什么了
I like running
万贤
作家
作家
  • 铜币1枚
  • 威望24点
  • 贡献值1点
15C#
发布于:2006-02-09 22:05
Re:问一个关于宏的问题~
谢谢铁板大哥指点,明白了

最近过节瞎忙,真是心有余而力不足啊~~
游客

返回顶部