变参函数的参数

变参函数的参数

在c语言中,存在诸如 printf scanf 函数等可以传入参数不固定个数的函数,其实现原理为变参函数。

变参函数的基本写法示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

void funArg(int nTag, ...) {
va_list argPointer; //定义变参指针
va_start(argPointer, nTag); //获取第二个参数的首地址
int nCount = 0;
while (true) {
//返回指针指向的数据,并将指针后移一个int步长
char argData = va_arg(argPointer, int);
if (argData == 0)break;
printf("第 %d 个参数是: %d\n", nCount++, argData);
}
va_end(argPointer); //关闭变参指针
}

int main() {
funArg(1, 2, 3, 4, 5, 0);
system("pause");
return 0;
}

这是c提供的变参函数标准写法,但是由于指针后移导致一般情况下无法获取到第一个参数。

运行结果如下:
普通表参函数

所以派生出了A1pass大佬的新奇想法。

自己动手尝试一个变参函数

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

void funArg(int nTag, ...) {
void* argPointer; //定义自己的变参指针
argPointer = (void*)&nTag; //获取参数的首地址
int nCount = 0;
while (true) {
//nCount当成计数器,并且可以获取到第一个参数的值
char argData = *((char*)(((int)argPointer)+sizeof(int)*nCount));
if (argData == 0)break;
printf("第 %d 个参数是: %d\n", nCount++, argData);
}
va_end(argPointer); //关闭变参指针
}

int main() {
funArg(1, 2, 3, 4, 5, 0);
system("pause");
return 0;
}

在demo中,由于argData的指默认是指针指向第一个参数的位置,所以可以获取到所有的参数。

运行结果如下:
自己定义的变参函数指针结果

同样,同理与数组传参,由于没有办法获取长度,所以必须需要一个定界符(本案例中是0)。

printf函数就是用第一个参数中的%个数来确定参数的总共个数