__attribute__((format(printf, 1, 2)));的作用

随心所欲myprintf---可变参数列表的实现

 (2010-10-13 15:14:06)

转载

标签: 

可变参数列表

 

it

分类: 编程

大家可能习惯了printf家族的习惯,但是有的时候,我们可能有新的需求,C语言所带的printf家族的函数不再满足我们的需求。但强大的C语言,由stdarg.h提供了强大的字符合成和解析功能。下面,我以一个例子来给大家介绍可变参数列表的解析。

#include <stdarg.h>
#include <unistd.h>
#include <stdio.h>
#define ATTR __attribute__
static char sprint_buf[1024];
static int myprintf(char *fmt, ...) ATTR((format(printf,1,2)));
int myprintf(char *fmt, ...)
{
    va_list args;
    int n;
    va_start(args, fmt);
    n = vsprintf(sprint_buf, fmt, args);
    va_end(args);
    write(1, sprint_buf, n);
    return n;
}
int
main()
{
    char a[10] = "Misoralv";
    char b[10] = "Klose";
    int a1 = 14;
    int n = myprintf("%s %s, his WorldCup goals reach %d.", a,b,a1);
    printf("n=%d\n",n);
    return 0;
}
简单介绍:
1. __attribute__ 为编译器提供了错误检查的功能,(format(printf,1,2)) 1= format 的位置, 2为parameters 的位置,这个后缀要加在函数声明之后。

cat test.c
1 extern void eprintf(const char *format, ...) 
2 __attribute__((format(printf, 1, 2)));
3 
4 void foo() 
5 { 
6 eprintf("s=%s\n", 5); 
7 
8 eprintf("n=%d,%d,%d\n", 1, 2); 
9 } 
$ cc -Wall -c test.c test.c: 
In function `foo': 
test.c:6: warning: format argument is not a pointer (arg 2) 
test.c:8: warning: too few arguments for format
使得编译器多了一层检查,这就是__attribute__的目的。

2.va_list 用来存储可变参数表
va_start(va_list a, fmt),va_list获取fmt之后的参数列表的值, va_start的具体实现是一个宏,它的具体内容为:
#define va_start(v,l)    __builtin_va_start(v,l)
// GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and will not be documented here because they may change from time to time; we do not recommend general use of these functions
同理可以理解va_end(va_list a)标识参数列表结束。

在我的函数中还有没有使用到的 va_arg,它的含义是取va_list中下一个的值。接口如下:
type va_arg ( va_list ap, type ) 
type: int / double/ long /...
例子:最大值 
int FindMax ( int amount, ...) 
{ 
int i,val,greater; 
va_list vl; va_start(vl,amount); 
greater=va_arg(vl,int); 
for (i=1;i<amount;i++) { 
val=va_arg(vl,int); 
greater=(greater>val)?greater:val; 
} 
va_end(vl); 
return greater; 
}
在我们的函数最为重要的是
int vsprintf (char * str, const char * format, va_list arg );

format是类似"%s %s, his WorldCup goals reach %d."的输出格式。
str是按照输出格式将arg输出的字符串
返回值为int,表述输出了多少个字符。


Klose
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值