c語言可變引數原理以及printf函式的自實現

2021-08-16 18:18:55 字數 1638 閱讀 1485

可變引數

使用場景:不確定傳入引數的個數,例如printf,scanf,

原理:由於函式引數是存放在棧中的,而且是從左到右依次入棧(引數的位址從左到右依次增大),從右到左依次初始化,所以,函式的引數位置是確定的,一旦我們知道了某乙個引數的位址我們就可以獲得所有引數的位址。

知道了原理就可以自己來實現乙個可變引數了。

首先取得first的位址。

void test(int first, ...) 

int main()

通過結果可以發現,發現first引數是在棧底,向上尋找4個位元組就是第二個引數的位址。同樣這就是為什麼形參初始化的時候是從左到右,也就是從上到下依次初始化的。

通過以上就可以取得引數列表中所有的值了。

但是在取char 和short型別的引數時,就不能用整型指標,應該用char*指標和short*指標。

明白了以上原理之後,就可以自己實現乙個printf函式了。

**如下:

#include //實現printf()函式,可以格式化%c, %d||%i, %o, %x, %s

void my_printf(char* format, ...)

else if (*(format + 1) == 'd' || *(format + 1) == 'i')

;//取得這個整數

int i = *args;

//使用itoa將整數轉換成字元

itoa(i, buffer, 10);

char *pstr = buffer;

while (*pstr) putc(*pstr++, stdout);

args += 1;

}else if (*(format + 1) == 'o')

;//取得這個整數

int i = *args;

//使用itoa將整數轉換成字元

itoa(i, buffer, 8);

char *pstr = buffer;

while (*pstr) putc(*pstr++, stdout);

args += 1;

}else if (*(format + 1) == 'x')

;//取得這個整數

int i = *args;

//使用itoa將整數轉換成字元

itoa(i, buffer, 16);

char *pstr = buffer;

while (*pstr) putc(*pstr++, stdout);

args += 1;

}else if (*(format + 1) == 's')

else

format += 2;

} else

}}int main()

程式的輸出結果為:

用C 可變引數模板實現類似C語言的printf

在以前,c 要實現可變引數的函式,得用c語言的va list那一套東西,直到c 11的可變引數模板誕生,正好最近在寫乙個日誌模組,是時候了解一下可變引數模板了。下面這個簡單的log函式,只使用 進行佔位,並沒有區分型別,有點像c 的 include include include templatev...

c 語言可變引數

1 當無法列出傳遞函式的所有實參的型別和數目時,可用省略號指定參數列 void foo void foo parm list,2 函式引數的傳遞原理 函式引數是以資料結構 棧的形式訪問,從右至左入棧.eg include void fun int a,int main output 12 343 獲...

c語言可變引數

ifdef debug print info x printk x,else print info x endif 一 什麼是可變引數 我們在c語言程式設計中有時會遇到一些引數個數可變的函式,例如printf 函式,其函式原型為 int printf const char format,它除了有乙個...