可變引數
使用場景:不確定傳入引數的個數,例如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,它除了有乙個...