比较器作为函数参数
Comparator as function parameter
C89 中是否有可能将运算符作为函数参数传递?我的意思是通过示例 <
、==
、>=
等。类似于 Java 中的自定义比较器,但仅通过特定符号通过。也许有特殊类型的预处理器宏的解决方案(我尝试使用从处理器宏中获取的“#”)?
我知道函数指针,但我想要一些不同的东西。
示例:
void fun(int a, int b, comperator)
{
if(a comperator b)
........
}
不,你不能,只是像字符串一样传递它并在函数中进行测试
您可以使用宏。但请记住——宏不是函数;它是函数。它有不同的(丑陋的)语法、一些特定的问题、一些优点等。
假设你有一个函数:
int fun(int x, int y)
{
if (x < y)
return 1;
else if (x < 2 * y)
return 2;
else if (x < 2 * y)
return 3;
else
return 4;
}
要使用不同的比较器,首先将其转换为宏:
#define FUN(x, y) \
x < y ? 1 : \
x < 2 * y ? 2 : \
x < 3 * y ? 3 : \
4
这种转换非常丑陋(通常会比我的例子更丑陋),而且并非总是可行,但现在你可以添加一个比较器:
#define FUN(x, y, c) \
x c y ? 1 : \
x c 2 * y ? 2 : \
x c 3 * y ? 3 : \
4
用法:
printf("%d\n", FUN(3, 5, <));
(注意:在宏中,您应该在变量周围添加括号,例如 here;为清楚起见,我省略了它们)。
最简单的方法是使用代表比较器的枚举,但通过一些操作,您可以为 fun() 编写宏包装器,调用 funLT()、funGT... 或将比较器枚举为 LT、GT、 .. 用于开关盒。
如果 fun(...)
相当大,您可能希望在函数内的适当位置使用枚举和开关盒。
enum{LT,GT,EQ,NE,LE,GE};
#define fun(a,b,OP) fun_(a,b,
(0 OP 1) \
? (1 OP 0) \
? NE \
: (0 OP 0) \
? LE \
: LT \
: (0 OP 0) \
? (1 OP 0) \
? GE \
: EQ \
: GT \
)
fun(int a, int b, int op){
//code
switch(op){
case GE: //etc...
}
//more code
}
如果函数很小,您可能更愿意为每个运算符设置单独的函数
#define fun(a,b,OP) \
(0 OP 1) \
? (1 OP 0) \
? funNE((a),(b)) \
: (0 OP 0) \
? funLE((a),(b)) \
: funLT((a),(b)) \
: (0 OP 0) \
? (1 OP 0) \
? funGE((a),(b)) \
: funEQ((a),(b)) \
: funGT((a),(b))
C89 中是否有可能将运算符作为函数参数传递?我的意思是通过示例 <
、==
、>=
等。类似于 Java 中的自定义比较器,但仅通过特定符号通过。也许有特殊类型的预处理器宏的解决方案(我尝试使用从处理器宏中获取的“#”)?
我知道函数指针,但我想要一些不同的东西。
示例:
void fun(int a, int b, comperator)
{
if(a comperator b)
........
}
不,你不能,只是像字符串一样传递它并在函数中进行测试
您可以使用宏。但请记住——宏不是函数;它是函数。它有不同的(丑陋的)语法、一些特定的问题、一些优点等。
假设你有一个函数:
int fun(int x, int y)
{
if (x < y)
return 1;
else if (x < 2 * y)
return 2;
else if (x < 2 * y)
return 3;
else
return 4;
}
要使用不同的比较器,首先将其转换为宏:
#define FUN(x, y) \
x < y ? 1 : \
x < 2 * y ? 2 : \
x < 3 * y ? 3 : \
4
这种转换非常丑陋(通常会比我的例子更丑陋),而且并非总是可行,但现在你可以添加一个比较器:
#define FUN(x, y, c) \
x c y ? 1 : \
x c 2 * y ? 2 : \
x c 3 * y ? 3 : \
4
用法:
printf("%d\n", FUN(3, 5, <));
(注意:在宏中,您应该在变量周围添加括号,例如 here;为清楚起见,我省略了它们)。
最简单的方法是使用代表比较器的枚举,但通过一些操作,您可以为 fun() 编写宏包装器,调用 funLT()、funGT... 或将比较器枚举为 LT、GT、 .. 用于开关盒。
如果 fun(...)
相当大,您可能希望在函数内的适当位置使用枚举和开关盒。
enum{LT,GT,EQ,NE,LE,GE};
#define fun(a,b,OP) fun_(a,b,
(0 OP 1) \
? (1 OP 0) \
? NE \
: (0 OP 0) \
? LE \
: LT \
: (0 OP 0) \
? (1 OP 0) \
? GE \
: EQ \
: GT \
)
fun(int a, int b, int op){
//code
switch(op){
case GE: //etc...
}
//more code
}
如果函数很小,您可能更愿意为每个运算符设置单独的函数
#define fun(a,b,OP) \
(0 OP 1) \
? (1 OP 0) \
? funNE((a),(b)) \
: (0 OP 0) \
? funLE((a),(b)) \
: funLT((a),(b)) \
: (0 OP 0) \
? (1 OP 0) \
? funGE((a),(b)) \
: funEQ((a),(b)) \
: funGT((a),(b))