设为首页 加入收藏

TOP

C语言可变长参数函数与默认参数提升
2014-11-24 07:43:27 来源: 作者: 【 】 浏览:2
Tags:语言 可变 参数函数 默认 参数 提升

1、概述


C标准中有一个默认参数提升(default argument promotions)规则。
默认参数提升有时会给我们带来疑惑。本文结合C语言的可变长参数函数来说明默认参数提升存在的陷阱。


2、默认参数提升的定义


标准中的定义如下:


If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. -- C11 6.5.2.2 Function calls (6)


意思大概是:如果一个函数的形参类型未知, 例如使用了Old Style C风格的函数声明,或者函数的参数列表中有 ...,那么调用函数时要对相应的实参做Integer Pormotion,此外,相应的实参如果是float型的也要被提升为double类型,这条规则称为Default Argument Promotion


3、可变长参数函数


熟悉C的人都知道,C语言支持可变参长数函数(Variable Argument Functions),即参数的个数可以是不定个,在函数定义的时候用(...)表示,比如我们常用的printf()\execl函数等;printf函数的原型如下:


int printf(const char *format, ...);


注意,采用这种形式定义的可变参数函数,至少需要一个普通的形参,比如上面代码中的*format,后面的省略号是函数原型的一部分。


C语言定义了一系列宏来完成可变参数函数参数的读取和使用:宏va_startva_argva_end;在ANSI C标准下,这些宏定义在stdarg.h中。三个宏的原型如下:


void va_start(va_list ap, last);// 取第一个可变参数(如上述printf中的i)的指针给ap,
// last是函数声明中的最后一个固定参数(比如printf函数原型中的*fromat);
type va_arg(va_list ap, type); // 返回当前ap指向的可变参数的值,然后ap指向下一个可变参数;
// type表示当前可变参数的类型(支持的类型位int和double);
void va_end(va_list ap); // 将ap置为NULL


当一个函数被定义为可变参数函数时,其函数体内首先要定义一个va_list的结构体类型,这里沿用原型中的名字,ap。va_start使ap指向第一个可选参数。va_arg返回参数列中的当前参数并使ap指向参数列表中的下一个参数。va_end把ap指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va_start开始,并以va_end结尾。


下面是一个具体的示例(摘自wikipedia):


#include

double average(int count, ...)
{
va_list ap;
int j;
double tot = 0;
va_start(ap, count); //使va_list指向起始的参数
for(j=0; j tot+=va_arg(ap, double);//检索参数,必须按需要指定类型
va_end(ap); //释放va_list
return tot/count;
}


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android中ListView的用法 下一篇Linux动态链接库导出函数

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)
·[ Linux运维学习 ] (2025-12-26 02:52:27)
·HTTPS 详解一:附带 (2025-12-26 02:20:37)
·TCP/IP协议到底在讲 (2025-12-26 02:20:34)