先看下面的代码:
int max(int n,
)
{
int *p, ret, i;
p = &n + 1;
ret = *p;
for(i = 0; i < n; i++)
{
if(ret < *(p+i)) ret = *(p+i);
}
return ret;
}

{
int *p, ret, i;
p = &n + 1;
ret = *p;
for(i = 0; i < n; i++)
{
if(ret < *(p+i)) ret = *(p+i);
}
return ret;
}
我们可以这样使用这个函数:
max(2, 1, -1) , 结果是 1.
max(4, 1, 2, -1, -2) , 结果是 2.
C 语言里面支持变参数的传递方法,可变参数的地址从最后一个地址的下一个位置开始。这个特性十分有用。
PHP函数的原始C代码实现,用了一个宏PHP_FUNCTION,就用到了类似的原理。
C语言里面的经典函数 printf 也用到了这个可变参数的特点。只是,它更加的进一步,可以传递不同参数类型的参数。
下面再来看一个例子:
void param_demo(char *fmt,
)
{
int param_count, i;
char *pi;
param_count = (int)strlen(fmt);
pi = (char *)&fmt + sizeof(char *);
for (i=0; i < param_count; i++)
{
switch(fmt[i])
{
case 'i':
printf("int : %d \n", *((int *)pi));
pi = pi + sizeof (int);
break;
case 's':
printf("string : %s \n", *((char **)pi));
pi = pi + sizeof (char *);
break;
case 'c':
printf("char : %c \n", *pi);
pi = pi + sizeof (int);
break;
case 'd':
printf("double : %lf \n", *((double *)pi));
pi = pi + sizeof (double);
break;
default:
break;
}
}
}

{
int param_count, i;
char *pi;
param_count = (int)strlen(fmt);
pi = (char *)&fmt + sizeof(char *);
for (i=0; i < param_count; i++)
{
switch(fmt[i])
{
case 'i':
printf("int : %d \n", *((int *)pi));
pi = pi + sizeof (int);
break;
case 's':
printf("string : %s \n", *((char **)pi));
pi = pi + sizeof (char *);
break;
case 'c':
printf("char : %c \n", *pi);
pi = pi + sizeof (int);
break;
case 'd':
printf("double : %lf \n", *((double *)pi));
pi = pi + sizeof (double);
break;
default:
break;
}
}
}
这个函数可以这样调用:
param_demo("idsc", 2, 2.01, "hello, world", 'c');
然后将会输出:
int : 2
double : 2.010000
string : hello, world
char : c
大多数对指针比较了解的人应该能够明白上面的代码。只是有一点要注意,char 类型 原则上只占用一个字节,但是,实际上,
CPU有一个对齐问题,一般来说,函数的参数最小也要满足一个 "字",一个字的大小,在大多数平台下就是 int 的大小。
比如 在 i386 机器上,一个字的大小是 4个字节。char 类型占用 1个 字节,剩余 3个字节空闲,然后再接下去存储。
仔细读读上面的例子,相信你也能写可变参数的函数了。