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;i delta=(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