[英]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.