小议 cout << i << " " << i++ << endl
2009-08-06 09:39
459 查看
前注: 本文除了最后半句话在讨论“i++”的问题外,通篇都不关i++或++i什么事。千万别望文生义。
王富涛 的一个话题,问:
Code:
int i = 0;
cout << i << " " << i++ << endl;
为什么在VC6里,DEBUG 版本输出 1,0 ,而Release版本输出0,0。
通常编译器,都是编译Release程序时,容易出错,因为错误的优化。不过VC的习惯是,通常RELEASE版运行的结果,更接近C++标准,私下里我们称它的优化,就是让程序更“标准化”。
这边不准备纠缠这个问题。倒是来看看,cout << i << " " << i++ << endl 是些什么东东?其它上面的代码相当于:
Code:
int i=0;
::operator << (cout.operator << (i), " ").operator << (i++).operator << (endl);
为什么这么复杂?是因为凑巧中间夹着输出了一个字符串,此时调用的是自由函数 ::operator(ostream&, char const *);
还是有些眼晕,那么我们再简化一下:
Code:
#define OUT operator<<
::OUT(cout.OUT(i), " ").OUT(i++).OUT(endl);
#undef OUT
为了描述方便,干脆为每个OUT编个号码:
Code:
::OUT_1(cout.OUT_2(i), " ").OUT_3(i++).OUT_4(endl);
其中,OUT_1 是一个全局自由函数,它带两个参数,一个是流,另一个是字符串,大致原型可以写成:
Code:
ostream& OUT_1(ostream& os, char const * pstr);
而 OUT_2 ~ OUT_4, 都是同一个函数,它们是某个类的成员函数。
cout 就是那个类的一个对象(换句话说:cout一个变量)。
endl 本是一个函数 endl()……但这里用的是它的地址,这是另一个话题了。
忽略与本问题无关的,最终代码结构类似:
Code:
foo_1( o.foo_2(i), " ").foo_3(i++).foo_4(endl);
foo_1() 函数运行之后,返回一个对象,假设为a。接着,调用a的成员函数foo_3,拆解代码为:
Code:
a = foo_1 (...);
a.foo_3 (i++);
//...
但要执行foo_1,则必须求出它的第一个入参的值,所以再拆解:
Code:
a_0 = o.foo_2(i);
a_1 = foo_1(a_0, " ");
a_2 = a_1.foo_3(i++);
a_3 = a_2.foo_4(endl);
补充一句,a_x 在本例中,其实都是同一个对象。
不管如何,在执行 a_0 = o.foo_2(i)时,关后面的 a_1.foo_3(i++)什么事呢?那时候 foo_3()的宿主a_1还没有产生呢,如果有编译器非在这时让i++影响了前面的o.foo_2(i)的执行,造成后者输出一个“1”来,那能说明什么呢?我想,只能说是它错了吧。
王富涛 的一个话题,问:
Code:
int i = 0;
cout << i << " " << i++ << endl;
为什么在VC6里,DEBUG 版本输出 1,0 ,而Release版本输出0,0。
通常编译器,都是编译Release程序时,容易出错,因为错误的优化。不过VC的习惯是,通常RELEASE版运行的结果,更接近C++标准,私下里我们称它的优化,就是让程序更“标准化”。
这边不准备纠缠这个问题。倒是来看看,cout << i << " " << i++ << endl 是些什么东东?其它上面的代码相当于:
Code:
int i=0;
::operator << (cout.operator << (i), " ").operator << (i++).operator << (endl);
为什么这么复杂?是因为凑巧中间夹着输出了一个字符串,此时调用的是自由函数 ::operator(ostream&, char const *);
还是有些眼晕,那么我们再简化一下:
Code:
#define OUT operator<<
::OUT(cout.OUT(i), " ").OUT(i++).OUT(endl);
#undef OUT
为了描述方便,干脆为每个OUT编个号码:
Code:
::OUT_1(cout.OUT_2(i), " ").OUT_3(i++).OUT_4(endl);
其中,OUT_1 是一个全局自由函数,它带两个参数,一个是流,另一个是字符串,大致原型可以写成:
Code:
ostream& OUT_1(ostream& os, char const * pstr);
而 OUT_2 ~ OUT_4, 都是同一个函数,它们是某个类的成员函数。
cout 就是那个类的一个对象(换句话说:cout一个变量)。
endl 本是一个函数 endl()……但这里用的是它的地址,这是另一个话题了。
忽略与本问题无关的,最终代码结构类似:
Code:
foo_1( o.foo_2(i), " ").foo_3(i++).foo_4(endl);
foo_1() 函数运行之后,返回一个对象,假设为a。接着,调用a的成员函数foo_3,拆解代码为:
Code:
a = foo_1 (...);
a.foo_3 (i++);
//...
但要执行foo_1,则必须求出它的第一个入参的值,所以再拆解:
Code:
a_0 = o.foo_2(i);
a_1 = foo_1(a_0, " ");
a_2 = a_1.foo_3(i++);
a_3 = a_2.foo_4(endl);
补充一句,a_x 在本例中,其实都是同一个对象。
不管如何,在执行 a_0 = o.foo_2(i)时,关后面的 a_1.foo_3(i++)什么事呢?那时候 foo_3()的宿主a_1还没有产生呢,如果有编译器非在这时让i++影响了前面的o.foo_2(i)的执行,造成后者输出一个“1”来,那能说明什么呢?我想,只能说是它错了吧。
相关文章推荐
- cout<<"a1="<<a<<endl; cout<<"a2="<<-0x80000000<<endl;
- [细节决定B度]之回首一瞥cout<<"Hello,world"<<endl;
- 详解让C++新手闹心的语句“cout<<"Hello!"<<endl;”
- cout<<endl;与cout<<"/n";的区别
- 为什么“cout << &c << endl;”这个语句有问题?
- copy(dist.begin(), dist.end(), ostream_iterator<int>(cout, " ")); cout << endl; 这句话是什么意思
- cout<<"hello csdn";
- cout<<endl;什么意思?
- C语言-cout<<"123"<<"45"<<endl;
- char *ptr=&character; cout<<ptr<<endl;为何乱码
- C++初始化,之不明白篇 cout<<x<<endl 与 cout<<"x = "<<cout<<x<<endl的输出的值会不一样
- 在 Python中使用 cout << 'Hello,world!' << endl
- cout < <true?1:"1" < <endl;
- [细节决定B度]之回首一瞥cout<<"Hello,world"<<endl;
- cout<<"Press any key to exit!\n"<<endl;
- hdoj1707(set)(s[day][time].insert(name))(cout<<" "<<*it)
- 关于cout<<1; cout<<endl;和cout<<1<<endl;的解析
- 短小的日志类 和用cout&lt;&lt;"A"&lt;&lt;B&lt;&lt;"/n"一样
- "cout<<char数组名/数组指针"跟"cout<<int数组/数组指针"的差别
- cout<<char数组名/数组指针"跟"cout<<int数组名/数组指针"的差别