关于代码优化 替代 switch case

lsk_30516 2009-03-11 11:59:41
type中保存的是字段的类型。我的程序用了很多swit case,有什么好的替代方法替代switch case
type = indexField[ix].second;
switch(type)
{
case field_short:
ptr = new short[recordNum];
fread(ptr, sizeof(short), recordNum, fp);
break;
case field_int32:
ptr = new int[recordNum];
fread(ptr, sizeof(int), recordNum, fp);
break;
case field_uint32:
ptr = new unsigned int[recordNum];
fread(ptr, sizeof(unsigned int), recordNum, fp);
break;
case field_int64:
ptr = new DD_INT64[recordNum];
fread(ptr, sizeof(DD_INT64), recordNum, fp);
break;
case field_float:
ptr = new float[recordNum];
fread(ptr, sizeof(float), recordNum, fp);
break;
case field_double:
ptr = new double[recordNum];
fread(ptr, sizeof(double), recordNum, fp);
break;
case field_datetime:
ptr = new int[recordNum];
fread(ptr, sizeof(int), recordNum, fp);
break;
default:
printf("Unexpected db type %d\n", type );
break;
}
...全文
506 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
pocketmatrix 2009-03-15
  • 打赏
  • 举报
回复
一段开源代码,用于读取指定文件流,制定结构传入。大同小异。
FT_BASE_DEF( FT_Error )
FT_Stream_ReadFields( FT_Stream stream,
const FT_Frame_Field* fields,
void* structure )
{
FT_Error error;
FT_Bool frame_accessed = 0;
FT_Byte* cursor = stream->cursor;


if ( !fields || !stream )
return FT_Err_Invalid_Argument;

error = FT_Err_Ok;
do
{
FT_ULong value;
FT_Int sign_shift;
FT_Byte* p;


switch ( fields->value )
{
case ft_frame_start: /* access a new frame */
error = FT_Stream_EnterFrame( stream, fields->offset );
if ( error )
goto Exit;

frame_accessed = 1;
cursor = stream->cursor;
fields++;
continue; /* loop! */

case ft_frame_bytes: /* read a byte sequence */
case ft_frame_skip: /* skip some bytes */
{
FT_UInt len = fields->size;


if ( cursor + len > stream->limit )
{
error = FT_Err_Invalid_Stream_Operation;
goto Exit;
}

if ( fields->value == ft_frame_bytes )
{
p = (FT_Byte*)structure + fields->offset;
FT_MEM_COPY( p, cursor, len );
}
cursor += len;
fields++;
continue;
}

case ft_frame_byte:
case ft_frame_schar: /* read a single byte */
value = FT_NEXT_BYTE(cursor);
sign_shift = 24;
break;

case ft_frame_short_be:
case ft_frame_ushort_be: /* read a 2-byte big-endian short */
value = FT_NEXT_USHORT(cursor);
sign_shift = 16;
break;

case ft_frame_short_le:
case ft_frame_ushort_le: /* read a 2-byte little-endian short */
value = FT_NEXT_USHORT_LE(cursor);
sign_shift = 16;
break;

case ft_frame_long_be:
case ft_frame_ulong_be: /* read a 4-byte big-endian long */
value = FT_NEXT_ULONG(cursor);
sign_shift = 0;
break;

case ft_frame_long_le:
case ft_frame_ulong_le: /* read a 4-byte little-endian long */
value = FT_NEXT_ULONG_LE(cursor);
sign_shift = 0;
break;

case ft_frame_off3_be:
case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
value = FT_NEXT_UOFF3(cursor);
sign_shift = 8;
break;

case ft_frame_off3_le:
case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
value = FT_NEXT_UOFF3_LE(cursor);
sign_shift = 8;
break;

default:
/* otherwise, exit the loop */
stream->cursor = cursor;
goto Exit;
}

/* now, compute the signed value is necessary */
if ( fields->value & FT_FRAME_OP_SIGNED )
value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );

/* finally, store the value in the object */

p = (FT_Byte*)structure + fields->offset;
switch ( fields->size )
{
case (8 / FT_CHAR_BIT):
*(FT_Byte*)p = (FT_Byte)value;
break;

case (16 / FT_CHAR_BIT):
*(FT_UShort*)p = (FT_UShort)value;
break;

case (32 / FT_CHAR_BIT):
*(FT_UInt32*)p = (FT_UInt32)value;
break;

default: /* for 64-bit systems */
*(FT_ULong*)p = (FT_ULong)value;
}

/* go to next field */
fields++;
}
while ( 1 );

Exit:
/* close the frame if it was opened by this read */
if ( frame_accessed )
FT_Stream_ExitFrame( stream );

return error;
}
chenyingshu 2009-03-11
  • 打赏
  • 举报
回复
这个挺好的啊,效率挺高的,楼主为什么要换呢?
xuhb95083023 2009-03-11
  • 打赏
  • 举报
回复
这样写挺好的,如果想玩点技巧,少写几行代码,改成 template吧



template <typename T, std::size_t recordNum>
T** get_ptr() {
T* ptr[] = new T[recordNum];
fread(ptr, sizeof(T), recordNum, fp);
return ptr;
}

  • 打赏
  • 举报
回复
mark先
topwork 2009-03-11
  • 打赏
  • 举报
回复
这个效率不错,就用这个吧。
yshuise 2009-03-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 lsk_30516 的回复:]
那不还是要用switch case 吗 呵呵
[/Quote]
假如你能够获得一个具体类型:
type** p = get_ptr(1000);
就可以了。泛型的运用吧。
1900_in_bj 2009-03-11
  • 打赏
  • 举报
回复
楼主引出了一个经典的“惯用法”data-driven:
典型应用就是MFC对消息映射的处理。
具体解决方案见深入浅出MFC第三章MFC六大关键技术模拟之Message Mapping.
lsk_30516 2009-03-11
  • 打赏
  • 举报
回复
那不还是要用switch case 吗 呵呵
yshuise 2009-03-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lsk_30516 的回复:]
template <typename T>
T** get_ptr(std::size_t recordNum) {
T* ptr[] = new T[recordNum];
fread(ptr, sizeof(T), recordNum, fp);
return ptr;
}

上面的方法中的这个sizeof(T)怎么确定?T又不是参数
[/Quote]
如果你怕编译器推不出来,可以显示写:
int** p = get_ptr<int>(1000);
实际上编译器可以自己推出来的:
int** p = get_ptr(1000);
lsk_30516 2009-03-11
  • 打赏
  • 举报
回复
template <typename T>
T** get_ptr(std::size_t recordNum) {
T* ptr[] = new T[recordNum];
fread(ptr, sizeof(T), recordNum, fp);
return ptr;
}

上面的方法中的这个sizeof(T)怎么确定?T又不是参数
yshuise 2009-03-11
  • 打赏
  • 举报
回复
template <typename T> 
T** get_ptr(std::size_t recordNum) {
T* ptr[] = new T[recordNum];
fread(ptr, sizeof(T), recordNum, fp);
return ptr;
}


lingyin55 2009-03-11
  • 打赏
  • 举报
回复
up
diannaomingong 2009-03-11
  • 打赏
  • 举报
回复
我见过一种替代方法有点诡异的
先建立个 P{ p1,p2,p3,p4....}集合(具体实现你用数组向量啥的自便)
然后a=getIndexOf[x]替代
case x
1
a=p1
2
a=p2
3
...


oo 2009-03-11
  • 打赏
  • 举报
回复
代码确实不好看

改switch一般是预先填个表,然后查表处理
lsk_30516 2009-03-11
  • 打赏
  • 举报
回复
感觉switch case 多了有点影响可读性 使代码看上去有一坨坨的感觉。

64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧