在OK6410的UART 中看到這個 3個點 有點不知道什麼意思。。於是通過網路搜尋了些。。總結總結。。如下
void UART_Printf(const char *fmt,...){ va_list ap; char string[256];int i; va_start(ap, fmt); vsprintf(string, fmt, ap); for (i = 0; string[i]; i++)UART_Putc(string[i]); va_end(ap);}
我們在stdio.h中可以看到printf()函數的原型:
int printf(char * format,...)
事實上,我們如果要寫這樣的函數也可以類似的寫,那麼在定義函數時用上這個符號“...”,它叫預留位置,喊它“三個點”也可以,只要你願意!那麼我可以這樣定義我的函數:
fun(int a,...)
{ }
基礎知識:
1、va_list
2、va_arg()
3、va_start()
在學習這3個小東東之前,我們先回憶一下,C語言是怎麼操作檔案時,是怎麼樣處理記憶體中的資料的呢?學習檔案操作時,我們提到了“流”的概念,我們用指標指向資料所在的記憶體位址,再一個一個的操作。
學習指標時,我們知道有函數指標這個東東,不是指標函數而是函數打針哦!(呵呵,我的同學如果還記得就當複習一下,不要嫌我囉嗦^_^)。我們記得程式在執行時,會將函數儲存到記憶體中去。現在深入的講一點點,儲存函數時,參數傳遞的過程是怎樣實現的呢?所謂的形式參數(局部變數)實質上又是什麼呢?把這些問題連起來想想,想通了,你的思維勢如破竹!
在調用函數時,程式同樣會把實參傳入,在函數儲存區儲存起來,如果有很多參數,將一起儲存起來。
這時候就要用到va_list了,這是個類型定義,我們可以把它理解成一個指標,它指向第一個參數的地址。
如果,我們這樣定義: va_list pp;
則pp就是這樣一種變數,它是指向所有參數中的第一個參數的。它不同於一般的指標變數,它是個複合變數,什麼是複合變數啊?結構體類型的嘛,呵呵。如果a是第一個參數,能不能寫成 pp=a呢?
假設我定義了char d[]="ruixin",e[]="gelin";我要把e的值賦給d,能不能寫成d=e呢?得用strcpy(),是吧!呵呵,一樣的道理,這兒我們也用一個函數來實現,它就是va_start();
如果這樣寫:va_start(pp,a);
那麼pp就指向第一個參數a了,並且可得到a的類型int。
這時候如果有下一個參數,就需要使pp指向下一個參數,並且得到它的類型。同樣需要使用函數來實現,這個函數是:va_arg()
可以這樣寫:va_arg(pp,類型),這樣pp就指向一個參數,並且可以得到那個參數的類型了。
注意!類型非常重要,學過指標的都應該清楚,指標的類型如果弄錯的話,位置正確,取出來的數可能也是亂七八糟的。
下面我們看一個簡單的例子:
#include <stdio.h>
#include<stdarg.h>
void fun(int a,...)
{
va_list pp;
int n=1;//使用n計量參數個數
va_start(pp,a);
do
{
printf("第%d個參數=%d\n",n++,s);
a=va_arg(pp,int);//使pp指向下一個參數,將下一個參數的值賦給變數a
}
while (a!=0);//直到參數為0時停止迴圈
}
main()
{
fun(20,40,60,80,0);
}
注意!
一定要有上面兩個檔案包含命令,因為程式中用到的那3個小東東都在那個檔案裡。其實真正意義上應該說那是函數,實質上那不過是兩個宏,呵呵。
轉載:http://hi.baidu.com/wjun520/item/c9e688f5905514cd531c263c