C 将两个功能合二为一

C 将两个功能合二为一,c,function,C,Function,我有两个函数,分别实现编码和解码: void delta_encode (char *buffer, const unsigned int length) { char delta = 0; char original; unsigned int i; for (i = 0; i < length; ++i) { original = buffer[i]; buffer[i] -= delta; delta = original; } } void delta_d

我有两个函数,分别实现编码和解码:

void
delta_encode (char *buffer, const unsigned int length)
{
 char delta = 0;
 char original;
 unsigned int i;
 for (i = 0; i < length; ++i)
 {
  original = buffer[i];
  buffer[i] -= delta;
  delta = original;
 }
}

void
delta_decode (char *buffer, const unsigned int length)
{
 char delta = 0;
 unsigned int i;
 for (i = 0; i < length; ++i)
 {
  buffer[i] += delta;
  delta = buffer[i];
 }
}
void
增量编码(字符*缓冲区,常量无符号整数长度)
{
字符增量=0;
原稿;
无符号整数i;
对于(i=0;i

我不喜欢的是,除了+=对-=部分,它们非常相似。是否有一种方法将它们合并为一个函数,该函数将询问用户是否要编码或解码,并分别选择-=或+=版本。如果有,它的代码会是什么样子?如果有几种方法可以做到这一点,那么哪一种是最好的?

我同意所有人说这样做是不好的。它会降低程序的效率,使代码更笨重(从而降低可读性)。如果在实现设计时遇到这样的障碍,您可能需要重新思考您的设计以及为什么会存在这样的需求

尽管如此,你还是可以这样做:

typedef enum
{
    ENCODE,
    DECODE
} CONTEXT;

void
delta_operation (char *buffer, const unsigned int length, CONTEXT context)
{
    if(context == ENCODE)
    {
        char delta = 0;
        char original;
        unsigned int i;
        for (i = 0; i < length; ++i)
        {
            original = buffer[i];
            buffer[i] -= delta;
            delta = original;
        }
    }
    else if(context == DECODE)
    {
        char delta = 0;
        unsigned int i;
        for (i = 0; i < length; ++i)
        {
            buffer[i] += delta;
            delta = buffer[i];
        }
    }
}
encode_decode( buffer, length, encode );
encode_decode( buffer, length, decode );

我同意每一个说这样做不好的人。它会降低程序的效率,使代码更笨重(从而降低可读性)。如果在实现设计时遇到这样的障碍,您可能需要重新思考您的设计以及为什么会存在这样的需求

尽管如此,你还是可以这样做:

typedef enum
{
    ENCODE,
    DECODE
} CONTEXT;

void
delta_operation (char *buffer, const unsigned int length, CONTEXT context)
{
    if(context == ENCODE)
    {
        char delta = 0;
        char original;
        unsigned int i;
        for (i = 0; i < length; ++i)
        {
            original = buffer[i];
            buffer[i] -= delta;
            delta = original;
        }
    }
    else if(context == DECODE)
    {
        char delta = 0;
        unsigned int i;
        for (i = 0; i < length; ++i)
        {
            buffer[i] += delta;
            delta = buffer[i];
        }
    }
}
encode_decode( buffer, length, encode );
encode_decode( buffer, length, decode );

我个人同意@paddy。您不应该为了减少代码行而使代码不可读

通常,如果要在+=和-=之间切换,可以使用(+/-1)乘法器。对于+=您应该使用乘数=1,然后您将得到:

buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] + delta
buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] - delta
对于-=您可以使用乘数=-1,然后您将得到:

buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] + delta
buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] - delta
特别是对于您的代码,它可能看起来像这样(您可以使用boolean而不是int,并在函数中对值进行asign):


使用EOOPTION而不是硬编码的-1/+1值和int参数

我个人同意@paddy。您不应该为了减少代码行而使代码不可读

通常,如果要在+=和-=之间切换,可以使用(+/-1)乘法器。对于+=您应该使用乘数=1,然后您将得到:

buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] + delta
buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] - delta
对于-=您可以使用乘数=-1,然后您将得到:

buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] + delta
buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] - delta
特别是对于您的代码,它可能看起来像这样(您可以使用boolean而不是int,并在函数中对值进行asign):


如果您有相同的代码,但对于符号,您可以使用eOperation而不是硬编码值-1/+1和int参数

,将
编码/解码
参数添加到函数调用中,如果您有编码版本,则将要添加的内容乘以
-1
。因此:

typedef enum {ENCODE = -1; DECODE = 1;} CODE_TYPE;

void delta_code(char *buffer, const unsigned int length, CODE_TYPE e);

void delta_code(char *buffer, const unsigned int length, CODE_TYPE e) 
  {
  char delta = 0;
  char original;
  unsigned int i;
  for (i = 0; i < length; ++i)
    {
    original = buffer[i];
    buffer[i] += delta*e;
    delta = (e<0)?original:buffer[i];
    }
  }
typedef枚举{ENCODE=-1;DECODE=1;}code\u类型;
无效增量代码(字符*缓冲区,常量无符号整数长度,代码类型e);
无效增量代码(字符*缓冲区,常量无符号整数长度,代码类型e)
{
字符增量=0;
原稿;
无符号整数i;
对于(i=0;idelta=(e如果您有相同的代码,但是对于符号,您可以在函数调用中添加一个
encode/decode
参数,如果您有编码版本,则将要添加的内容乘以
-1
。因此:

typedef enum {ENCODE = -1; DECODE = 1;} CODE_TYPE;

void delta_code(char *buffer, const unsigned int length, CODE_TYPE e);

void delta_code(char *buffer, const unsigned int length, CODE_TYPE e) 
  {
  char delta = 0;
  char original;
  unsigned int i;
  for (i = 0; i < length; ++i)
    {
    original = buffer[i];
    buffer[i] += delta*e;
    delta = (e<0)?original:buffer[i];
    }
  }
typedef枚举{ENCODE=-1;DECODE=1;}code\u类型;
无效增量代码(字符*缓冲区,常量无符号整数长度,代码类型e);
无效增量代码(字符*缓冲区,常量无符号整数长度,代码类型e)
{
字符增量=0;
原稿;
无符号整数i;
对于(i=0;i
#include <stdbool.h>

void delta_code(char *buffer, const unsigned int length, bool encode) 
{
    char delta = 0;
    unsigned int i;
    for (i = 0; i < length; ++i)
    {
        char next_delta;
        if (encode)
        {
            next_delta = buffer[i];
            buffer[i] -= delta;
        }
        else
        {
            buffer[i] += delta;
            next_delta = buffer[i];
        }
        delta = next_delta;
    }
}
当然,在realc中你可以这样做

      char temp;
      for (i = 0; i < length; ++i)
          delta = encode? (temp = buffer[i], buffer[i] -= delta, temp) : (buffer[i] += delta);
chartemp;
对于(i=0;i
只要这是一个“智力练习”,我不妨发布这篇文章,它抓住了编码/解码的对称性:

#include <stdbool.h>

void delta_code(char *buffer, const unsigned int length, bool encode) 
{
    char delta = 0;
    unsigned int i;
    for (i = 0; i < length; ++i)
    {
        char next_delta;
        if (encode)
        {
            next_delta = buffer[i];
            buffer[i] -= delta;
        }
        else
        {
            buffer[i] += delta;
            next_delta = buffer[i];
        }
        delta = next_delta;
    }
}
当然,在realc中你可以这样做

      char temp;
      for (i = 0; i < length; ++i)
          delta = encode? (temp = buffer[i], buffer[i] -= delta, temp) : (buffer[i] += delta);
chartemp;
对于(i=0;i
这里有一个似乎还没有人提出过的建议。您可以创建一个内核函数来对单个字符执行操作,并将其传入

typedef void (*delta_op)( char *value, char *delta );

void encode( char *value, char *delta )
{
    char prev = *value;
    *value += *delta;
    *delta = prev;
}

void decode( char *value, char *delta )
{
    *value -= *delta;
    *delta = *value;
}
然后将内核函数传递给主要部分

void encode_decode( char *buffer, unsigned int length, encode_op operation )
{
    char delta = 0;
    unsigned int i;
    for (i = 0; i < length; ++i)
    {
        operation( &buffer[i], &delta );
    }
}

但是它会很笨重而且很慢……就像
qsort
。因为所有的函数调用。

这里有一些似乎没有人提出过的建议。你可以创建一个内核函数来对单个字符执行操作,并将其传入

typedef void (*delta_op)( char *value, char *delta );

void encode( char *value, char *delta )
{
    char prev = *value;
    *value += *delta;
    *delta = prev;
}

void decode( char *value, char *delta )
{
    *value -= *delta;
    *delta = *value;
}
然后将内核函数传递给主要部分

void encode_decode( char *buffer, unsigned int length, encode_op operation )
{
    char delta = 0;
    unsigned int i;
    for (i = 0; i < length; ++i)
    {
        operation( &buffer[i], &delta );
    }
}

但是它会很笨重而且很慢……就像
qsort
。因为所有的函数调用。

就个人而言,我更喜欢将它们作为单独的函数。每个函数的名称都很清楚。不要误以为所有的代码重复都是不好的。你需要在合理和荒谬之间划清界限。@JimBalter-是的,我决定不指出“隐藏标签”:“什么…”那么你到底在想什么?毫无意义的复杂性、代码不可读性、维护噩梦,以及bug的可能性大大增加?(例如,Michael Liberman的解决方案被破坏。)从这个意义上说,Anish的解决方案是最不令人反感的——他保持了原始函数的完整性,只是将它们包装在一个“统一的外壳”中。但由于解码和编码是根本不同的操作,我不确定这样做的逻辑价值。这不像重载f