cprimerplus中講解printf函式的一些性質時講

時間 2021-12-23 04:02:13

1樓:匿名使用者

你思考的真的很深入,將來對於程式設計來講,不可限量。

為了徹底瞭解printf的機制,建議讀下printf的實現**,無論是windows下面的還是linux下面的,懂一個就可以。原理一樣。但全部的**非常複雜,我也沒有時間全部每行都讀一下,只在這裡說下他的原理,你可以讀**時候進一步加深理解,先讀c,有必要再看下相應彙編的底層操作。

你說的問題和函式呼叫時候棧的操作息息相關,所以先說下棧。

比如函式a,呼叫printf(char *fmt,...)

void a(int a, double b, char c)

int w;

printf("%d %f %c\n",a,b,c);

};這時,printf做為引數個數不定,型別不定的子函式,是用_cdecl方法呼叫,棧類似下面

wfmtab

c返回地址

由於printf並不知道自己被傳了幾個引數,也不知道每個引數是啥型別的,它通過下面幾個巨集來識別:

va_start :作用,找到第一個可變引數的地址,設為ap,則ap=&fmt+sizeof(fmt),可找到a的地址,相信你能理解

va_arg, 每呼叫一次,它會往前移動指向一下個引數,這需要知道步長,因為每個引數型別可能不能,步長也不同

有個while 語句在迴圈解析fmt裡的字串,處理%後面的格式字元,發現第一個為%d,就取a為整形值,4個位元組,va_arg步長為4, 讀到第二%後面是f,則取8個位元組的值當浮點數處理,步長為8...直到字串結束

計算步長的時候,還要考慮位元組對齊的影響,已經有非常高效成熟的演算法,與本題無關,可以自己瞭解。

這樣,由於printf不知道自己會被傳多少個引數,也不知道型別,它只會根據fmt中%號的多少,一步步往下走,去棧裡取引數,在%多於引數個數的情況下,就會出現你說的情況,

比如你在fmt格式字串裡寫了4個%號,但只傳了,a,b,c三個引數

printf("%d %f %c,%c\n",a,b,c),當printf解析到第三個格式%c的時候,指標已經指向了棧裡最後一個引數c,這時候,由於字串沒結束,它還會解析後面的格式 ,也就是","後面的%c, 這時候如果堆疊夠長,並且裡面還遺留以前程式留下的資料,那就會被printf取出一個位元組來顯示,可能是亂碼或者別的資料,但如果最後一個格式是%s, 但堆疊碰巧剩下那部分裡沒有'\0',且很快超過堆疊合法空間,很容易讓程式去讀不該讀的地址,引起空難。

從上面原理可以看出,在格式符號多於實際引數個數的時候,會有問題,但在格式符號少於實際引數的時候,起碼程式不會列印意外結果或者崩潰。因為沒有越界。如果你想利用這點乾點什麼有技巧的事,到是安全的。

隨機數:

所以,也是基於上面原理,你用這種方式產生隨機數是沒有道理的,程式並不是隨機產生一個值列印出來,只是把記憶體裡殘餘資料列印出來而矣,況且還可能崩潰。這些殘餘資料不是隨機數,甚至是可以預料的。如果你不動它,每次打出來結果都一樣,並不「隨機」,甚至牛人結合作業系統相關演算法和程式邏輯,想推測出相關位置的值不是不可能。

連偽隨機數都算不上。

所以也不能實現你的設想:在某一特定位置取變數中的隨機值而後面的佔位說明符仍然取指定值,只可能最後面多餘的變更可能是個殘值。前面的值是按順序取的,別想跳過去,取後面的殘值。

這類函式不止printf,即存的目前和它都比較像,但如果你看明白printf原理和**,自己寫幾個引數不固定,型別不固定的函式那是很easy了,而且是合法的可以用到你或者別人程式裡的,現在的編譯器都支援的。就目前現存的來講,有scanf, sscanf,fscanf, printf,  vsprintf, sprintf, 相對應寬字元處理函式wprintf, 對應執行緒安全處理函式等等,很類似,只是場合不同。

2樓:匿名使用者

應該只有這個,其它函式取地址時,沒有匹配的項時,直接在編譯時是報錯的,printf裡面是警告。

一些隨筆性質的文集,推薦一些隨筆性質的文集

看看餘秋雨的 中國之旅 彩色插圖本 從遺址看,這個被稱為上京龍泉府的渤海國首都由外城 內城 宮城三重環套組成,外城周長30餘里。全城由一條貫通南北的寬闊大道分成東西兩區,又用10餘條主要街道分隔成許多方塊區域,完全是唐朝首府長安的格局和氣派。文化苦旅 依仗著淵博的文學和史學功底,豐厚的文化感悟力和藝...

對數函式與指數函式的一些重點內容

janifer瑤 重點就是指數函式 定義域,影象,值域,單調性,以及它的求導公式對數函式 定義域,影象,值域,對數的公式,單調性 看它的底數,真數 等,它的求導 想學好指數與對數的話這些非常重要,還有就是,最好的一條辦法,看書,把數學書這塊的內容,定義 很重要 習題 最好做有答案的,自己做一遍,再去...

初三物理 電學一些性質的意義沒懂

電流也就是導體中自由電子的定向移動產生的 如果要弄得很清楚的話,就結合化學來吧,導體如金屬,它原子的最外層電子是不是很容易脫落原子核的束縛,當一根導體在電場的作用下,最外層電子就會容易脫離原子核的束縛而定向移動,從而形成了所謂的電流,一個物體的導電能力就看它裡面的能脫離原子核的束縛而移動的電子 既自...