1. 程式人生 > >一道程式設計題讓老程式設計師鄒起了眉頭,這樣的題你會怎麼解?

一道程式設計題讓老程式設計師鄒起了眉頭,這樣的題你會怎麼解?

程式設計師來說,程式的魅力在於它的變化無窮,對於一門計算機語言來說,他的基礎語法是固定有限的,可是程式設計的花樣卻是千變萬化,無法窮舉,可以用它做出無數個不同領域,不同業務,形形色色的產品,正因為這麼靈活,關於程式設計的題目,也是自然很多,想必面試過的程式設計師都見過各種各樣的面試題,有簡單的,有“造火箭”的,有非常挑戰大腦思考力的等等,近期,一名程式設計師網友就被一道程式設計題難住了,他把這樣的題目分享給了大家。

根據這名程式設計師的分享,可以看出應該是c++程式設計題,不過重在考察程式設計師的思路,是考察程式設計師的思考能力,題目內容如下圖,具體的操作要求是在pass函式中進行一番操作,然後使得第二個列印語句輸出 456,這個題目看上去很一般,不過與往常我們的情況不一樣的地方是pass函式並不可以傳參,傳引用什麼的,第二個方法如何改變x值呢?針對這樣的情況,讓我們看看有沒有程式設計師網友可以給出讓人眼睛一亮的方案吧!

網友一:pass函式裡面print 456,然後exit。 保證螢幕第二個列印的是456

上世是朵花:這麼做輸出的結果與想要的結果是一樣的,不過請注意審題,題目中的要求是:“使得第二個列印語句輸出 456”,你這算是阻止了第二個語句的列印,重新偽造了一個列印語句。

網友二:64位系統gcc 測試通過。不同編譯器和系統會有所不同。int tmp; *(&tmp+8) = 456;

上世是朵花:雖然沒驗證這段程式碼,但是已經看出這名網友的思路是通過記憶體定址的方式改變x的值,這是一個思路。

網友三:在C中調函式會建立一個棧幀,棧幀範圍是2指標(rbp,rsp)確定,棧擴張是從地址高到低,在pass中定義

變數x1,地址減去一定值訪問main中的x。這個值跟編譯時優化程度有關。g++ -O2優化,會省掉建立棧幀的指令和記憶體分配,x的地址即x1減int寬度。可以在pass中加兩行:int x1;*reinterpret_cast<int*>(reinterpret_cast<uint64_ptr>(&x1)-sizeof(int)) = 456;使用g++ -O2 -std=cpp11編譯

上世是朵花:這名網友說出了實現的思路,核心思想與網友二差不多,但是考慮到的更細緻一點。

網友四:從上面的回答可以看出你們這些程式設計師c語言基礎之差。

上世是朵花:評論題目就行,評論人就不友好了。

 

網易員工:第二個列印語句不一定是主函式裡面的第二個printf吧

上世是朵花:這不就是“網友一”的思路麼?

網友六:這是腦筋急轉彎吧。

上世是朵花:這名網友是這麼認為的,看你怎麼看了。

騰訊員工:如果是單解這道題,就從pass裡的臨時變數地址往上遍歷,發現了123的值,就姑且認為就是那個x了,然後改成456。不過這類題很古董了,現在寫業務程式碼的同學大把都不知道。

上世是朵花:有道理,除了遍歷定址的方式好像還真想不到其他更好的辦法。

網友八:用堆疊溢位來做的我一律不通過。這叫ub,ub的東西你也能告訴我這是正確的?

上世是朵花:這名網友diss了一部分網友,不過更期待的是你能給出高明的辦法。

從上面網友的評論中可以看出兩種思路,一種是通過“障眼法”的方式達到與預期結果一致,這個思路也是很值得讚的,不過仔細審題的話,有點不符合題目中的要求,第二種思路是通過記憶體定址的方式找到x的指標位置,然後給其賦值456,這種做法是符合了題目中的要求,不過在我們實際做專案中,這樣的方法我們都不會去用的,因為在實際專案中,變數之多,使用指標是很危險的一個行為了,最後很可能會出現一些很奇怪的問題,還不好找原因,這也是為什麼好多高階計算機語言中廢除了c++中指標這個特性的原因,頂多是會用一用引用,指標就完全廢棄了,當然,這只是一道面試題,只要符合要求就行,也不需要考慮的太多,那麼接下來,我丟擲一個問題,面試官出這樣的問題又是想考察程式設計師的什麼呢?請說出你的看法來,下方評論區歡迎你!

最後,如果有想一起學習web前端,HTML5及JavaScript的可以來一下我的前端群733581373,好友都會在裡面交流,分享一些學習的方法和需要注意的小細節,每天也會準時的講一些前端的炫酷特效,及前端直播課程學習

 

如果想看到更加系統的文章和學習方法經驗可以關注的微訊號:‘web前端技術圈’或者‘webxh6’關注後回覆‘2018’可以領取一套完整的學習視訊