将两个功能合二为一

时间:2013-04-15 04:29:30

标签: 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_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];
 }
}

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

5 个答案:

答案 0 :(得分:2)

如果你有相同的代码但是有一个符号,你可以在你的函数调用中添加一个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];
    }
  }

答案 1 :(得分:2)

只要这是一个“智力练习”,我不妨发布这个,它捕获了编码/解码的对称性:

#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;
    }
}

编辑:OP提到了语言功能。如果C有一个广义的后缀减法,说=-就像postfix --一样,它在减法之前返回左侧的值,那么你可以这样做:

   for (i = 0; i < length; ++i)
       delta = encode? (buffer[i] =- delta) : (buffer[i] += delta);

当然,在真正的C中你可以做到

      char temp;
      for (i = 0; i < length; ++i)
          delta = encode? (temp = buffer[i], buffer[i] -= delta, temp) : (buffer[i] += delta);

答案 2 :(得分:1)

我同意所有人说这样做很糟糕。它使您的程序效率降低,代码变得笨拙(从而降低了可读性)。如果您在实施设计时遇到过这样的障碍,您可能需要重新考虑您的设计以及为什么这样的要求甚至存在。

所有这一切,你可以做这样的事情:

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];
        }
    }
}

并称之为:

char buffer[] = "Whatever your buffer is supposed to be";
delta_operation (buffer, strlen(buffer), ENCODE);

答案 3 :(得分:1)

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

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

buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] + delta

对于 - =你可以使用乘数= -1然后你会得到:

buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] - delta

特别是对于你的代码,它可能看起来像那样(你可以使用boolean而不是int并将函数中的值作为对象):

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

  if (shouldDecode == 1)
    delta = buffer[i];
  else
    delta = original;

 }
}

或更“优雅”的解决方案(Anish Ram的贡献):

typedef enum
{
    ENCODE = -1,
    DECODE = 1
} eOperation;

并使用eOperation代替硬编码值-1 / + 1和int参数

答案 4 :(得分:0)

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

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 );
    }
}

所以你这样打电话:

encode_decode( buffer, length, encode );
encode_decode( buffer, length, decode );

尽管如此......它会很笨拙而且很慢......就像qsort一样。因为所有函数调用。