學習printf函式

2021-05-28 07:37:32 字數 1834 閱讀 2137

今天想學習printf函式,有幾個疑問?1、如何實現可變引數。2、如何將記憶體的東西輸入螢幕。3、是將各種格式的引數都轉化為字串輸入,還是以各種格式輸出。4、如果引數有表示式,比如printf((i%9)?"%4d";"%4d\n"); 該怎麼處理。5、如何自己寫乙個printf函式。其實還有很多相關的函式如:sprintf、vsprintf、vsnprintf等,這些函式都有是什麼關係,怎樣使用?盡量了解一下吧。

通過查詢linux2.6.31.13核心**,在vsprint.c檔案看到sprintf的原型:

1250 int sprintf(char * buf, const char *fmt, ...)

1251

可以看到實現可變引數的是 va_list、va_start、va_end這幾個巨集。而vsprintf才是真正實現功能的函式。

1、先了解可變引數是怎麼實現的。由於形參是以堆疊的資料結構存放,也就是說在記憶體中是連續存放的。這樣就可以通過位址找到該引數的內容。先看看另一段**吧,在acenv.h

288 #define  _aupbnd                (sizeof (acpi_native_int) - 1)

289 #define _adnbnd (sizeof (acpi_native_int) - 1)

290

291 /*

292 * variable argument list macro definitions

293 */

294 #define _bnd(x, bnd) (((sizeof (x)) + (bnd)) & (~(bnd)))

295 #define va_arg(ap, t) (*(t *)(((ap) += (_bnd (t, _aupbnd))) - (_bnd (t,_adnbnd))))

296 #define va_end(ap) (void) 0

297 #define va_start(ap, a) (void) ((ap) = (((char *) &(a)) + (_bnd (a,_aupbnd))))

acpi_native_int 被定義為s32,在32位機上就佔4個位元組。所以sizeof(acpi_native_int )-1=3。即bnd=0x00000003。而~bnd=0xfffffffc。所以_bnd是用來對齊記憶體的。為什麼要這樣做?在網上找到了解釋:因為在intel80×86機器上,每個變數的位址都要是sizeof(int)的倍數,這樣能提公升cpu執行的效率。也就是說,所有引數的首位址都要是4的倍數,就算你是char型的,那浪費3個byte也要安排你佔第四個坑。

好,我們現在來分析#define va_start(ap, a)         (void) ((ap) = (((char *) &(a)) + (_bnd (a,_aupbnd))))  這個巨集。

((char *) &(a))是取得指向函式第乙個引數的指標的位址,注意是堆疊中指標的位址,在該堆疊中存放著指向每個引數的指標。加上(_bnd (a,_aupbnd)),就是取得下乙個引數的位址。所以va_start(ap,a)執行完後,ap就指向第乙個可變引數,是可變引數而不是固定引數。

現在來分析va_arg(ap,t),先看看((ap) += (_bnd (t, _aupbnd))),把ap後移乙個變數的長度,也就是指向下乙個引數。所以va_arg(ap, t)的功能是返回當前引數的值,然後ap指向下一引數。

這樣va_start、va_arg就分析完了,第一點疑問也解開了。暫時先寫到這裡吧vsnprintf函式也看不懂,還要查很多資料。

Printf函式與Scanf函式學習

剛上大一時,主要學習了c 現在開始學c語言。下面來講講c語言輸出與輸入函式。一.printf的使用格式為 printf control string,item1,item2,control string 控制字串,它用來描述專案如何列印字串 item1和item2是要列印的專案,可以為常量,可以為變...

printf函式詳解

printf 格式轉換的一般形式如下 flags width prec type 以括號括起來的引數為選擇性引數,而 與type則是必要的。底下先介紹type的幾種形式 d 整數的引數會被轉成一有符號的十進位制數字 u 整數的引數會被轉成一無符號的十進位制數字 o 整數的引數會被轉成一無符號的八進位...

printf函式實現

要實現printf函式需要考慮如下三點 1.如何告訴printf傳入引數的個數 引數個數不確定。2.printf如何訪問到這些引數。3.函式呼叫完成後,系統如何釋放在堆疊的引數。printf函式的定義 原型 int cdecl printf const char format,注 cdecl是c c...