在C语言中处理相同函数但使用不同运算符的有效方法
假设在C中,我有两个完全相同的方法,但1添加值,另一个减去值:在C语言中处理相同函数但使用不同运算符的有效方法,c,operators,C,Operators,假设在C中,我有两个完全相同的方法,但1添加值,另一个减去值: void decreaseValue(handle* myData, uint8_t amount) { /* Stuff going on */ myData->someAttribute -= amount; /* Stuff going on */ } void increaseValue(handle* myData, uint8_t amount) { /* Stuff going
void decreaseValue(handle* myData, uint8_t amount)
{
/* Stuff going on */
myData->someAttribute -= amount;
/* Stuff going on */
}
void increaseValue(handle* myData, uint8_t amount)
{
/* Stuff going on */
myData->someAttribute += amount;
/* Stuff going on */
}
除了运算符之外,这两个函数完全相同,这导致了相当多的重复代码行,这不是微不足道的
有没有一种安全、便携、不难看的方法来处理这个问题,或者我只能用ctrl+c ctrl+v
开关箱的可能性:
typedef enum
{
ADD,
SUBSTRACT
}operator;
void modifyValue(handle* myData, uint8_t amount, operator op)
{
/* Stuff going on */
switch(op){
case ADD:
myData->someAttribute += amount;
break;
case SUBSTRACT:
myData->someAttribute -= amount;
break;
/* Stuff going on */
}
它可以工作,但感觉没有任何好转。使用预处理器:
#define modifyValue(name, operator) \
void name##Value(handle* myData, uint8_t amount) \
{ \
/* Stuff going on */ \
myData->someAttribute operator= amount; \
/* Stuff going on */ \
}
modifyValue(increase, +)
modifyValue(decrease, -)
然后像这样使用它:
void decrease(handle* myData, uint8_t amount) { myData->someAttribute -= amount; }
void increase(handle* myData, uint8_t amount) { myData->someAttribute += amount; }
void decreaseValue(handle* myData, uint8_t amount)
{
doStuff(myData, amount, decrease);
}
void increaseValue(handle* myData, uint8_t amount)
{
doStuff(myData, amount, increase);
}
基本上,您使用的是C中相当于委托(或lambda)的对象。
doStuff
执行实际的重复操作。如何使用enum
typedef enum
{
SUBTRACT,
ADD,
...
} enumOperator;
void modifyValue(handle* myData, uint8_t amount, enumOperator operator)
{
switch(operator)
{
case SUBTRACT:
myData->someAttribute -= amount;
break;
case ADD:
myData->someAttribute += amount;
break;
case ...:
...;
break;
}
}
创建两个函数
void addAmount(handle* myData, uint8_t amount)
{
myData->someAttribute += amount;
}
void subtractAmount(handle* myData, uint8_t amount)
{
myData->someAttribute -= amount;
}
创建可以接受上述函数之一作为参数的genericFunction
void genericFunction(handle* myData, uint8_t amount,
void (*fun)(handle*, uint8_t))
{
/* Stuff going on */
/* Call the function */
fun(myData, amount);
/* Stuff going on */
}
使用addAmount
或subtractAmount
genericFunction(mData, amount, addAmount);
如果你的方法足够小,最好不要调用任何不必要的函数。使用if-else或switch。这个怎么样:
static inline void changeValue(handle* myData, int amount)
{
/* Stuff going on */
myData->someAttribute += amount;
/* Stuff going on */
}
void increaseValue(handle* myData, uint8_t amount)
{
changeValue(myData, (int)amount);
}
void decreaseValue(handle* myData, uint8_t amount)
{
changeValue(myData, -(int)amount);
}
switch-case
语句?这需要函数带一个额外的参数,因为减法和加负值是一样的,所以我会考虑用这种方法传递负值,你可以保留一个method@meda你应该把它写成一个答案,我认为你是对的。我可以将这两个函数合并到modify(handle*myData,int8\t amount)中,用户将传递负值,而不必模拟多态性或决定调用哪个函数。你让我意识到,我完全没有理由一开始就用两个不同的函数传递一个无符号值。我知道您的解决方案是如何定制的,因此我不必更改界面。我想我的问题是XY问题。@Asics:没问题:)。。。XY问题是什么?当你有问题X和部分解决方案Y时,你没有找到更好的方法来解决X,而是试图将Y重构成一个更优雅的解决方案,而它不能很好地解决核心问题。
static inline void changeValue(handle* myData, int amount)
{
/* Stuff going on */
myData->someAttribute += amount;
/* Stuff going on */
}
void increaseValue(handle* myData, uint8_t amount)
{
changeValue(myData, (int)amount);
}
void decreaseValue(handle* myData, uint8_t amount)
{
changeValue(myData, -(int)amount);
}