C语言可变参数函数取参方法

On February 26, 2012, in C语言, 语言学习, by sponge

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

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

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

C语言之所以可以支持可变参数函数,一个重要的原因是C调用规范中规定C语言函数调用时,参数是从右向左压入栈的;这样一个函数实现的时候,就无需关心调用他的函数会传递几个参数过来,而只要关心自己用到几个;以printf为例:

printf("%d%s\n",i,s);

printf函数在定义的时候,不知道函数调用的时候会传递几个参数。在实现上,printf函数只需关心第一个参数,即字符串“%d%s\n”,当读到%d的时候,printf知道自己需要第二个参数,这时只需要去栈上寻找即可;当读到%s时,再去栈上网上寻找一个参数即可。简单说,printf不关心栈上到底压了多少参数,只关心自己需要多少。

那么对于一个定义为可变参数的函数,函数定义的时候并没有定义形参原型,怎么使用参数呢?

Tagged with:
 

很久以前,我接触的最初几本C语言书中,我记得有类似这么一句话“C语言是一种弱类型的语言,类型之间可以进行隐式的转换;而C++是强类型的语言,需要进行强制类型转换”。我忘了是哪本书,但这句话我一直记得。因为实际写代码中一直也没有触碰隐式的转换(我一般都会强制转换),所以也没有深究过这个问题。然而最近的一段代码却给我带来了一些困惑。
copyright@ www.spongeliu.com
先抛开我遇到的问题不说,简单回顾下C语言的隐式类型转换,如下一段代码:

#include <stdio.h>
double sum(double x, double y); //声明一个函数
 
int main()
{
    int x=10;
    int y=10;
 
    double z=sum(x,y);
    printf("%lf\n",z);
    return 0
}

没问题,我们得到的结果是20.000000。