Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中处理相同函数但使用不同运算符的有效方法_C_Operators - Fatal编程技术网

在C语言中处理相同函数但使用不同运算符的有效方法

在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

假设在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 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);
}