今天同事解決了乙個問題,頗有啟發,拿出來共賞之。
char str = "******";
printf(str);
如果這樣寫,會編譯不過:
printf("str = %s\n");
因為引數不夠。
可是你有沒有考慮過下面這種情況?
char str = "im a good man %s\n";
printf(str);
這段程式碼是可以編過並執行的,但是。。。它似乎又有點問題。
很容易看出printf在解析字串時會發現有個%s,於是它會試圖用後面乙個引數替換%s,可是哪兒來的後面的引數呢?
printf函式當但不知道,它以為有,所以就按「慣例」行事,在x86上它會到堆疊裡找,本來我們只壓入了str乙個引數,cpu會往上找,它認為str下面的那個就是這個引數,於是毫不猶豫的拿去用。。。可是那可能是別的什麼東西,比如壓在棧裡的ip、ebp什麼的,這樣就出錯了。如果它取的這個值是個不可訪問的記憶體,程式就完蛋。在ppc上cpu會使用r4暫存器,情況也是相同的,誰知道r4裡面是什麼東西!
大多情況下沒有程式設計師會這樣寫,但一旦我們的printf裡帶的是變數的時候就要多考慮考慮了。比如我們要輸出使用者輸入的字串或一段密文,那麼這裡面的東西可能是不可控的,可能就會有類似%s、%d之類的東西。 需要做限定或轉義。
現在回想起來以前在hw數通的時候為什麼不讓直接用printf,是有考慮的。
乙個printf引發的問題
牛客網上的乙個題目 intmain 看起來挺簡單的,牽扯的東西比較多。這是我的思路 printf函式執行的時候,會先把這三個數字壓入棧裡,然後再執行列印。壓入棧的時候按照資料本身的長度來,首先把c和b壓入,並且每乙個都是8個位元組 printf自動轉化為double 然後再壓入a是4個位元組。然後再...
自己實現乙個printf函式
在arm嵌入式開發環境中,串列埠一般使用arm pl011的uart實現,uart的實現原理就是實現了乙個8bits寬度,32深度的fifo,不停的往螢幕輸出乙個byte,乙個byte。這個就是硬體的實現,那麼軟體是怎麼實現列印 高階程式語言中定義的char,short,int,long,float...
乙個 inline 函式引發的葫蘆案
乙個同事在檢查另外乙個同事的 時,突然發現乙個 inline 函式在不同的 cpp 檔案裡面都有定義,而且,在另外乙個cpp裡面也引用了這個inline函式。示意 如下 a.h inline extern void foo a.cpp include include a.h inline void ...