模擬實現 」printf「 函式

2021-08-20 14:38:18 字數 2123 閱讀 3881

在c語言學習中,通過將函式實現為可變引數

形式,使得函式可以接受任意多個引數。

當了解可變引數之後很容易實現printf函式。

能完成下面函式的呼叫。 

print("s ccc d.\n","hello",'b','i','t',100);

函式原型:

print(char *format, ...)

#include #include //使用可變引數列表

#include #include #include int print(const char *format, ...) // 保護指標防止被意外修改

break;case 'c': putchar(va_arg(arg, char));break;case 'd':tmp = va_arg(arg, int);char tmp2[5];int i = 0;_itoa(tmp, tmp2, 10); // 整型轉換為字串 10是指進製while (tmp2[i])break;case '\n':putchar('\n');break;case '\0': putchar('\0');break;default: putchar(' '); break;}format++;}return 0;va_end(arg);}int main()

執行結果:

上述**有些不常見的語句,在這裡進一步解釋:

1.va_list arg;

va_list轉到其定義:

typedef char *  va_list;
由定義可以看出這裡的va_list 其實就是宣告定義的 char *。

這句也就相當於定義 字元型指標arg (

即char * arg)。

2.

va_start(arg, format);
va_start轉到定義:

#define va_start _crt_va_start
這裡 巨集定義 va_start  就相當於 _crt_va_start

而_crt_va_start 

依然不明白,所以再轉到定義:

#define _crt_va_start(ap,v)  ( ap = (va_list)_addressof(v) + _intsizeof(v) )
這裡ap --> arg , v --> format .

_addressof 轉到定義:

#define _addressof(v)   ( &(v) )
_intsizeof  轉到定義:

#define _intsizeof(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
獲取型別占用的空間長度,最小占用長度為int的整數倍。這裡format 是 char型指標所以是 4 位元組。

va_start(arg, format) --> arg = ((char *) &format +4)

將format位址取出強制轉化為 char * 型別,再加 4 位元組(即就是未知引數列表第乙個引數位址),再賦給 arg。

3.

va_arg(arg, char*)
va_arg轉到定義:

#define va_arg _crt_va_arg
檢視_crt_va_arg定義:

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )
結合之前的理解

va_arg(arg, char*) --> (*(char **) ( (arg += 4) - 4) )

arg 指向當前位置的位址強制轉化為字元型指標,在解引用轉化為當前字元。

4.va_end   訪問完最後乙個引數,呼叫其結束。

模擬實現printf函式

如果要想解決這個問題 就要 知道乙個知識點 可變引數列表 可變引數列表是通過巨集來實現的,這些巨集定義於stdarg.h標頭檔案中,它是標準庫的一部分。這個標頭檔案宣告 個型別va list 和三個巨集va start va arg和va end。轉到定義處 檢視一下這幾個巨集和型別 typedef...

模擬實現printf 函式

在構建printf 函式之前,需要簡單分析printf 在幫助文件中可以看到,printf 的格式為printf char format,也就是說printf 是乙個可變引數的函式 此外,還需要了解這些引數是如何在記憶體中儲存的。從這個棧楨結構圖中可以看到print 函式的引數的存放方式,print...

模擬實現printf函式

printf函式我們平時用的最多,當然用的時候並沒有想太多庫裡面是如何實現這個函式的,下面我們來看看 首先我們來分析一下,printf需要具備的功能 1,輸出字串 2,輸出字元 3,輸出整型 4 當然還有其他的型別,這裡主要實現前三種 下面我們先寫出主函式 主函式如下 由於printf函式輸出的型別...