getchar 宣告為 int getchar(void) 而非 char,原因在於需區分正常字元與 EOF(通常為 -1)。若回傳 char,EOF 可能超出 char 範圍(-128~127),導致 if (c == EOF) 永遠失敗。這是函式設計者誤導使用者的經典案例,責任不在使用者。
正常值用輸出參數取得,錯誤標誌用 return 回傳。將 getchar 改為:
BOOL GetChar(char* c);
雖 getchar 靈活(可 putchar(getchar())),但用錯時靈活性無補於事。
strcpy 原型:
char* strcpy(char* strDest, const char* strSrc);
將來源複製至輸出參數 strDest,同時回傳 strDest,獲得靈活性:
int length = strlen(strcpy(str, "Hello World"));
class String {
String& operator=(const String& other);
char* m_data;
};
String& String::operator=(const String& other) {
if (this == &other) return *this;
delete[] m_data;
m_data = new char[strlen(other.m_data) + 1];
strcpy(m_data, other.m_data);
return *this; // 回傳參考,無複製開銷
}
若改傳值,a = b 產生 1 次複製,a = b = c 產生 2 次,效率大幅下降。
String operator+(const String& s1, const String& s2) {
String temp;
delete[] temp.m_data;
temp.m_data = new char[strlen(s1.m_data) + strlen(s2.m_data) + 1];
strcpy(temp.m_data, s1.m_data);
strcat(temp.m_data, s2.m_data);
return temp; // 傳值:回傳區域物件 temp 的副本
}
若改回傳參考 String&,則回傳指向區域物件 temp 的參考。temp 函式結束時銷毀,導致懸空參考:
c = a + b; // a+b 不回傳期望值,c 什麼也得不到,埋下隱患
鐵律:回傳區域物件**必須傳值**;回傳既存物件(如 *this)宜傳參考。