是否可以为C预处理器定义一个宏,它将数组作为参数并扩展为<type of array elements>_string
?例如,如果整数数组中的x
,则使用参数x
调用的宏应扩展为int_string
。
我试过
#define TypePaste(array) typeof(array[0])##_string
但它会扩展为)_string
。
即使对##
操作数使用多级间接,宏也不能正确扩展。
答案 0 :(得分:6)
那是不可能的。在转换阶段(预处理阶段),其中宏被扩展并且标记被连接,编译器(此时,预处理器)还没有类型的概念因此不可能生成类型。
答案 1 :(得分:3)
您要解决的问题并不是很清楚,但请注意:
宏应扩展为现有函数的名称。我想为每个现有类型定义一个函数
<type>_string
,然后根据给定数组的类型使用宏来选择正确的函数。
然后您可以使用C11 _Generic
关键字:
#include <stdio.h>
void int_string (size_t size, int array[size])
{
printf("I am %s, do stuff here.\n", __func__);
}
void float_string (size_t size, float array[size])
{
printf("I am %s, do stuff here.\n", __func__);
}
#define TypePaste(array) \
_Generic( array, \
int: int_string, \
float: float_string ) \
(sizeof(array)/sizeof(*array), array) // function parameters
int main()
{
int i_arr[5];
float f_arr[3];
TypePaste(i_arr);
TypePaste(f_arr);
}
输出:
I am int_string, do stuff here.
I am float_string, do stuff here.
注意:这假定传递的参数是本地/文件范围分配的数组。如果传递指针,则没有类型安全,程序将失败。
答案 2 :(得分:0)
C11的_Generic
类型选择是“正确”的方式来做你想要的。还有其他依赖于平台的解决方案,很难。
如果你正在使用gcc - 你没有这么说,但是你已经使用了gcc的扩展名typeof
- 你可以使用gcc的statement expresions和nested functions创建一个比较函数qsort
当场:
double a[5] = {8.4, 8.1, 9.3, 12.2, 5.2};
qsort(a, 5, sizeof(*a), ({
int cmp(const void *p, const void *q) {
const typeof(a[0]) *pp = p;
const typeof(a[0]) *qq = q;
return (*pp < *qq) ? -1 : (*pp > *qq);
}
cmp;
}));
这会创建一个函数并返回其地址。 (复合表达式的最后一个语句是它的值。局部变量的范围是语句表达式,但是不会在堆栈上创建嵌套函数,因此可以安全地返回指向该函数的指针。)
对于基本类型,您希望根据比较运算符<
和>
进行排序,您可以将其转换为宏:
#define COMPARE(ARRAY)({ \
int cmp(const void *p, const void *q) { \
const typeof(ARRAY[0]) *pp = p; \
const typeof(ARRAY[0]) *qq = q; \
return (*pp < *qq) ? -1 : (*pp > *qq); \
} \
cmp; \
})
qsort(a, 5, sizeof(*a), COMPARE(a));
甚至:
#define SORT(ARRAY, N) \
qsort(ARRAY, N, sizeof(*ARRAY), COMPARE(ARRAY))
SORT(a, 5);
那不是标准C,所以如果你需要平台之间的兼容性,这是不可能的。