VA__ARGS
#define A( ...) __VA__ARGS__
, 这样是没有效果的, 这样的结果, 就是变成了一个__VA__ARGS__
的一行字符串
__VA__ARGS__
它的作用是: 将 (宏定义中的 各个参数), 对应到 (你的函数 的 各个参数)
#define DEBUG_( ...) __Debug( __VA_ARGS__, __LINE__)
其中, ...
不可以为空, 否则就是: __Debug( , __LINE__)
可变长参数
C语言有一种特殊函数参数,void func(...)
,他表示有很多类型变量
func()、func(true)、func('a', 123)、func( ST() )
这些调用方式,都是正式的。
且,变长参数 必须写在参数列表的最后一项 void func(bool a, int b, ...)
比如printf
函数,就需要用到这个技术。
且,...
只能用作:函数参数,他不能用来传参!!
void func1(...){ }
void func2(int a, ...){ func1(...); }
这是错的!!!
即...
只能用来接收数据,他不可以再用来发送数据(这一点,与c++的可变长模板参数不同
)
但问题是,我们如何遍历...
这个参数呢?
函数参数内存
void func(bool a, short b, int c){}
函数参数是存放在栈区,且从右往左 依次入栈
栈: 栈底在内存的高地址[x],从[x, x-1, …, 0]是栈
所以,bool a
在低地址。
{
bool a; // [x + 4 + 2] 高地址
short b; // [x + 4]
int c; // [x]
}
因为是依次入栈,所以,函数参数是在连续的内存地址
即,你得到&a
的地址,然后+=k
走高地址,就可以取到&b, &c
的地址
函数参数提升
void func(bool a, short b, int c){}
我们已知abc
的内存是连续的。
如果不是在函数参数里,连续的bool a, short b, int c
,则他们的内存,确实是: [1字节a][2字节b][4字节c]
但,在函数参数func(bool a, short b, int c)
时,会有函数参数提升
虽然,你type(a), type(&a)
都还是bool类型的量。
但其实: a地址是x, b地址是x+8, c地址是x+16
,这就是参数提升,即基本数据类型 在函数参数里,其实是提升到8字节!!
[1字节a, 7字节null] [2字节b, 6字节null] [4字节c, 4字节null]
void f(bool a, short b, int c){