在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