一段很有意思的代碼,你能說出為什麼結果是這樣嗎?
由於字數限制,問題在這裡:一段很有意思的C++代碼,你能說出它為什麼是這樣么? - 知乎專欄
見仁見智地說說吧。
一坨*的代碼,其中遺留了大量C語言時代的糟粕寫法,和錯誤
挨個講
- string對象傳值
C++的string對象,不是char*,拷貝的行為是深拷貝,對於過長的字元串,是會消耗一定性能的,應該儘可能使用const string來傳遞
- 使用了new和裸指針,而且還沒delete
鑒於這是一段示例代碼,我就不說太多了
- 注釋中的代碼有強行把string對象轉為char*使用的痕迹
再說一遍,string對象不是char*,強轉是會出問題的,而且也觸發了C++的UB
- 使用了危險的C式轉型
不去明確轉換操作而去使用C式轉型,各種潛在錯誤都從這裡來,針對這段代碼:
使用C式轉型從字元串字面量構造string對象
使用C式轉型將c_str()返回的const char*轉換為char*
- 保存了c_str()的返回值而沒有考慮string對象的生命周期
void append(int index, string arg)
{
printf("[append]arg.data()=0x%08p.
", arg.data());
m_args[index] = (char *)arg.c_str();
// m_args[index] = (char *)arg;
}
c_str函數的返回值的生命周期是和string對象的生命周期綁死的,所以上面這個函數結束之後arg析構,c_str的返回值就失效了,再用就是UB。這個函數還把他保存了起來,而且用的是char*不是const char*,觸發了兩條UB
- printf輸出指針用錯了格式字元串
64位環境下指針長度是64bit,你把他當成unsigned int輸出,等著炸吧
總結:這段代碼並沒有任何意思,只暴露了編寫者C++基礎很弱
第一,這一點都不有趣。這段代碼問題實在太多了。
第二,地址一樣有什麼奇怪的。運行到rm-&>append(1, (string)"l2");的時候,前面一行的string已經被析構了。這是個C++基本常識。
第三,什麼叫「導致了賦值的問題」。你用了pass-by-value,編譯器按照你的吩咐做事情的。
想看內容還得跳轉,跳轉了居然還不使用代碼格式寫的代碼,然後居然還沒有縮進,然後這個代碼哪裡有意思了??還「見仁見智」地說說。。。題主你是故意使用激將法的吧。。
為了怕有無聊的人說我沒答題,那麼我答題如下:我不能,回答完畢。因為前面 append 參數中的 string 對象已經析構掉了,但還用著它的.data(),當然會出問題。
另外,使用 printf 輸出指針應該使用 %p 而不是 %x。
零分,下一個
就這垃圾代碼,看了一眼頭引用就關了,然後忍住沒吐又回去看了,寫了個(string)"xxx",這次是真的關了。
智力障礙tag好評。其實這個問題從一個側面證明Linus當初黑C++是有道理的,C++的確是「糟糕程序員的垃圾語言」
此題目的代碼就是最好的詮釋!如果寫這個的人做項目,不敢想,必然是一場災難。
這技炫的,我根本看不懂…
但是看最後一段說的,我彷彿又看到了計算機二級的題:
a = 1;b = 1;
c = a+++++b;c = ?不能,下一題
你是騙熱度的吧?這種東西是個程序員都不會這麼寫,除了計算機等級考試命題題庫的那幾個老頭子喜歡這麼玩來炫技。語法玩的好有毛用。
一段令人窒息的代碼
硬是把面向對象寫成面向過程
慢慢更新……
少用指針,少用c寫c++
1.第一次見main函數結尾寫 return 1的
2.class裡面全是public,直接寫結構不是更方便嗎,還有把m_args直接公開了真的好?
3.c++裡面用printf,有好好的std::cout不用
4.構造函數直接賦值m_args會更好,m_args用string會更好,或者用容器
值傳遞,後面的append,前面的就析構了。。然後想幹嘛,完全不知道想表達什麼。。。
這就是不好好聽課,瞎裝,看吧,車禍了吧,主要我不知道他想幹嘛。。而且也不有趣,這不就是瞎?寫出來的嗎。看到char就知道這是是一段垃圾
你確定這是c++而不是c?
這是當年看了什麼書才能寫出這樣的代碼的...
垃圾。
鑒定完畢。
我看到同時混用C和C++頭文件就直接關掉了stdio.hiostreamstringstring.h人才啊,好歹也要用cstdio和cstring吧
1,頭文件很奇怪
2,違反資源使用原則,管殺不管埋
3,使用printf沒注意32和64位區別
4,直接使用指針是很危險的,特別是跳出函數,string就析構了。如果只是列印沒關係,千萬別干別的。
5,地址一樣是個意外吧,未定義行為,不能假設編譯器會這麼搞。
6,因為append一樣,所以setargs一樣。
總體來說,考的基礎知識很簡單,代碼寫的太爛了。
C++析構函數在什麼情況下會被系統調用雖然我寫Java的...但是這個問題我也是知道答案的
好大一坨翔
函數是值傳遞而不是引用傳遞,當string對象拷貝給函數的形參,實參就被析構了,而且,拷貝string對象是非常不明智的做法,總之,這代碼很爛
推薦閱讀:
※既然c++的非virtual的函數可以重定義,virtual函數相比非virtual的有什麼優勢?
※用MFC做的貪吃蛇遊戲,求大神。?
※C++ primer 第四版這段關於vector的程序是否有未定義的行為?
※c/c++中簡單加法出現奇怪的錯誤?
※如何使用C++11實現跨平台的定時器timer?
TAG:CC |