C 宏函数,以避免函数调用期间样板文件的大小
我声明了一个具有以下签名的函数(简化了实现): 可以看出,函数调用看起来复杂、容易出错且难以读取 当涉及到使用3个参数时,情况会变得更糟:C 宏函数,以避免函数调用期间样板文件的大小,c,function,macros,type-safety,variadic,C,Function,Macros,Type Safety,Variadic,我声明了一个具有以下签名的函数(简化了实现): 可以看出,函数调用看起来复杂、容易出错且难以读取 当涉及到使用3个参数时,情况会变得更糟: int main(void){ struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}}; struct test_s a2[] = {{4, 6}}; struct test_s a3[] = {{2, 3}, {4, 5}}; foo((struct test_s *[]){a1, a2,
int main(void){
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
struct test_s a3[] = {{2, 3}, {4, 5}};
foo((struct test_s *[]){a1, a2, a3},
(size_t[]){sizeof a1 / sizeof(struct test_s), sizeof a2 / sizeof(struct test_s), sizeof a3 / sizeof(struct test_s)},
3);
}
因此,当涉及到数组时,最好将其实现为宏。实现它非常简单,如下所示:
int main(void){
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
foo((struct test_s *[]){a1, a2},
(size_t[]){sizeof a1 / sizeof(struct test_s), sizeof a2 / sizeof(struct test_s)},
2);
}
#define FOO_ARR_2(a1, a2) \
do{ \
foo((struct test_s *[]){a1, a2}, \
(size_t[]){sizeof a1 / sizeof(struct test_s), sizeof a2 / sizeof(struct test_s)}, \
2);\
} while(0)
我发现这样一个宏有两个问题:
FOO_ARR_3
,FOO_ARR_4
,等等struct test\u s[]
问题:是否有可能将其实现为一个变量宏函数,如
#define FOO_ARR(…)
?与其将复杂的初始化封装成一个复杂的(如果可能的话)变量宏,不如将该函数本身声明为变量宏
这可能是这样的:
#include <stdio.h>
#include <stdarg.h>
/* expects: number-of-arrays followed by
number-of-arrays tuples {arrays-size, pointer to array's 1st element} */
struct test_s{
int a, b;
};
void foo(size_t arr_len, ...)
{
va_list vl;
va_start(vl, arr_len);
for (size_t i = 0; i < arr_len; ++i)
{
size_t s = va_arg(vl, size_t);
struct test_s * p = va_arg(vl, struct test_s *);
for (size_t j = 0; j < s; ++j)
{
struct test_s ts = p[j];
printf("a = %d; b = %d\n", ts.a, ts.b);
}
}
va_end(vl);
}
struct test_s{
int a, b;
};
void foo(size_t, ...);
int main(void)
{
/* using two arrays: */
{
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
foo(2,
sizeof a1 / sizeof *a1, a1,
sizeof a2 / sizeof *a2, a2
);
}
/* using three arrays: */
{
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
struct test_s a3[] = {{2, 3}, {4, 5}};
foo(3,
sizeof a1 / sizeof *a1, a1,
sizeof a2 / sizeof *a2, a2,
sizeof a3 / sizeof *a3, a3
);
}
}
“我声明了一个具有以下签名的函数”您是使用此签名绑定到此函数,还是可以随意更改它?@alk是的,如果签名可以简化函数,则可以更改签名call@alk但是我还需要支持
malloc
ed指针。这就是它被宣布为那样的原因
struct test_s{
int a, b;
};
void foo(size_t, ...);
int main(void)
{
/* using two arrays: */
{
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
foo(2,
sizeof a1 / sizeof *a1, a1,
sizeof a2 / sizeof *a2, a2
);
}
/* using three arrays: */
{
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
struct test_s a3[] = {{2, 3}, {4, 5}};
foo(3,
sizeof a1 / sizeof *a1, a1,
sizeof a2 / sizeof *a2, a2,
sizeof a3 / sizeof *a3, a3
);
}
}