[英]I don't understand how my compiler got this output
请注意,我使用的是 Turbo C++ 编译器,因为我们应该只为我们的学校教学大纲学习 Turbo C++。 这就是为什么在这种情况下从右到左评估cout
语句的原因。
程序
#include <iostream.h>
#include <string.h>
void func(char *s, char t[]) {
strcpy(t, "Have fun");
s = "Be\0Cool";
cout << s[0] << ++s << s++ << --s << strupr(s+2) << ++s << s++ << s;
}
int main() {
char x[] = "Hello World!!!", y[] = "Hello World";
func(x, y);
cout << x << y;
return 0;
}
Output
CCOOLeeOOLBeBeBeHello World!!!玩得开心
我觉得 output 应该是:
C酷eeOOLBeBeBeHello World!!!玩得开心
因为在cout
语句的++s
部分(第二个位置),指针位于字符串s
索引3处,所以应该只打印 'Cool'。 相反,正在打印“酷”。 为什么会这样?
使用 Visual Studio 2019 进行测试
出于比较目的,在 Visual Studio 2019 (DEBUG) 中,如果我们进行必要的更改来编译代码,则程序会崩溃,因为我们尝试修改常量字符串 ( "Be\0Cool"
)。
如果我们进行额外的更改以避免崩溃(通过使用本地数组),output 是:
CCoOLeCoOLOLCoOLBeCoOLHello World!!!玩得开心
如果我们拆分cout << s[]…;
对cout
的多次调用(每个<<
之前一个),那么 output 将是:
BeeeCOOLCOOLHello World!!!玩得开心
或者如果我们在每个 output 之后添加一行,我们得到:
B
e
e
e
COOL
COOL
Hello World!!!
Have fun
试图了解 Turbo C++ 的 output
如果我们然后将每个对 cout 的调用反转为从最后一个开始(即cout << s<< endl;
)并以第一个结束( cout << s[0] << endl
),那么我们得到:
Be
Be
OOL
e
e
COOL
C
Hello World!!!
Have fun
如果我们手动编写它,从倒数第三行开始,然后是最后两行,没有空格,我们得到:
CCOOLeeOOLBeBeBeHello World!!!玩得开心
这正是您作为 output 得到的。
因此,Turbo C++ 似乎从右到左评估每个表达式。
关于编译(和运行)所需更改的说明
<iostream.h>
不可用,因此我必须改用<iostream>
。#define _CRT_SECURE_NO_WARNINGS
必须添加在顶部,因为某些函数不安全(默认情况下不会编译)。using namespace std;
以避免对代码进行更多更改。s = (char *)"Be\0Cool";
所以该行编译。
char data[] = "Be\0Cool"; s = data;
char data[] = "Be\0Cool"; s = data;
CCoOLeCoOLOLCoOLBeCoOLHello World!!!Have fun
未定义的行为
有些事情没有由标准定义,因此不需要以某种方式工作。 好吧,正如预期的那样,如果不支持只读 memory,它就像读写 memory 一样工作。
对于评估顺序,常见的可能性是:
此外,由于变量被多次修改,因此在评估期间和之后没有定义 s 的值。 容易记住的规则是避免在一个表达式中多次修改同一个变量。
关于 strupr
function 将字符串修改为终止 null 字符。 在您的情况下,它将在调用时将任何值s
每个字母转换为大写。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.