理解可变参数的原理

理解可变参数的原理

今天在学习中,发现了函数的参数还可以是三个点的,让我有点奇怪。所以就去在网上查了一下,这个知识点称为“可变参数”。以下就是我对于可变参数的理解:

知识储备:

首先我们先了解一个知识点:在《STL源码剖析》这本书中,空间配置器那一章节中二级空间配置,需要每此申请空间个数为8的整数倍。以下就是其实现的方式。

下来,我们来看可变参数是如何实现的?

首先,我们来看一端代码:

#include

//#include

typedef char* va_list;

#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define va_end(ap) ( ap = (va_list)0 )

int Avg(int n, ...) //可变参数的理解

{

int i;

int sum = 0;

va_list v1;

va_start(v1, n); //(v1 = (va_list)&n + _INTSIZEOF(n))

for (i = 0; i < n; i++)

{

//(*(int *)((v1 += _INTSIZEOF(int)) - _INTSIZEOF(int)))

sum += va_arg(v1, int);

}

va_end(v1); //v1 = (va_list)0;

return sum / n;

}

int main()

{

int avg = 0;

avg = Avg(3, 10, 20, 30);

printf("%d", avg);

return 0;

}

实现原理:

实现说明:

( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

此步骤含义同上面的知识储备

(v1 = (va_list)&n + _INTSIZEOF(n))

此步骤含义是将创建好的指针v1指向可变参数列表的第一个数据。

(*(int *)((v1 += _INTSIZEOF(int)) - _INTSIZEOF(int)))

此步骤含义是将创建好的指针向后移动,再减去sizeof(char)*4的偏移量,通过强转(int*)来取得参数的第一个值,循环移动,直至取至最后一个参数。

v1 = (va_list)0;

此步骤含义是将创建的指针v1赋值NULL(0);

黄金推荐

吴莫愁发文怒怼女歌手,网友纷纷说:张碧晨很装
365体育管网登录网站

吴莫愁发文怒怼女歌手,网友纷纷说:张碧晨很装

🕒 11-20 💰 2266
这届世界杯为啥冷门这么多啊?
365体育管网登录网站

这届世界杯为啥冷门这么多啊?

🕒 09-21 💰 1172
“慎交友,教益友”主题班会 5
365体育管网登录网站

“慎交友,教益友”主题班会 5

🕒 01-27 💰 5084