首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否需要将LUT数组重构为case语句?

是否需要将LUT数组重构为case语句?
EN

Stack Overflow用户
提问于 2014-06-08 15:30:32
回答 1查看 150关注 0票数 0

我获得了以下LUT (查找表),用于检索伪PChar的显示名称(您知道,所有这些预定义的PChars都是皮肤下的整数):

代码语言:javascript
复制
const
  RT_MIN = DWORD(RT_CURSOR);
  RT_MAX = DWORD(RT_MANIFEST);

  ResourceTypes: array [RT_MIN..RT_MAX] of PChar = (
    'Hardware-dependent cursor',
    'Bitmap',
    'Hardware-dependent icon',
    'Menu',
    'Dialog box',
    'String-table entry',
    'Font directory',
    'Font',
    'Accelerator table',
    'Application-defined resource (raw data)',
    'Message-table entry',
    'Hardware-independent cursor',
    nil, { unknown, reserved or not used }
    'Hardware-independent icon',
    nil, { unknown, reserved or not used }
    'Version',
    'Dialog Include',
    nil, { unknown, reserved or not used }
    'Plug and Play',
    'VxD',
    'Animated cursor',
    'Animated icon',
    'HTML resource',
    'Side-by-Side Assembly Manifest'
  );

我在将其重写为case语句时会有什么好处/缺点吗?这样做有什么好处/坏处吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-08 21:47:23

我认为使用数组是最快的方法。如果您查询ResourceTypes[2],程序将首先查看ResourceTypes[2]、取消引用PChar并输出以零结尾的字符串。如果编译器是智能的,它可以识别字符串是不可更改的,因此它可以将所有字符串直接放置在数组中,因此您将保存一个取消引用操作。(对于那些对它感兴趣的人,可以使用像HxD这样的十六进制编辑器查看内存内容,以检查这是否属实)。

未来可能出现的另一个问题可能是以下场景:假设微软定义了一种非常特殊的新资源类型,因此它得到了大量类似于$FFFF的资源类型。如果您正在使用case of,您可以简单地添加2行代码来添加这种新的资源类型。如果有一个查找表(或LUT,这个缩写对我来说是新的),那么您就会遇到问题,因为您需要创建一个大小为65535的数组,其内容仅为nils的99%。

我会通过创建一个函数来完成这个任务:

代码语言:javascript
复制
function GetHumanFriendlyResourceTypeName(AResourceType: PChar): string;
begin
  if not Is_IntResource(AResourceType) then
  begin
    result := AResourceType;
  end
  else
  begin
    case Integer(AResourceType) of
      Integer(RT_CURSOR):
        result := 'Hardware-dependent cursor';
      Integer(RT_BITMAP):
        result := 'Bitmap';
      Integer(RT_ICON):
        result := 'Hardware-dependent icon';
      Integer(RT_MENU):
        result := 'Menu';
      Integer(RT_DIALOG):
        result := 'Dialog box';
      Integer(RT_STRING):
        result := 'String-table entry';
      Integer(RT_FONTDIR):
        result := 'Font directory';
      Integer(RT_FONT):
        result := 'Font';
      Integer(RT_ACCELERATOR):
        result := 'Accelerator table';
      Integer(RT_RCDATA):
        result := 'Application-defined resource (raw data)';
      Integer(RT_MESSAGETABLE):
        result := 'Message-table entry';
      Integer(RT_GROUP_CURSOR):
        result := 'Hardware-independent cursor';
      Integer(RT_GROUP_ICON):
        result := 'Hardware-independent icon';
      Integer(RT_VERSION):
        result := 'Version';
      Integer(RT_DLGINCLUDE):
        result := 'Dialog Include';
      Integer(RT_PLUGPLAY):
        result := 'Plug and Play';
      Integer(RT_VXD):
        result := 'VxD';
      Integer(RT_ANICURSOR):
        result := 'Animated cursor';
      Integer(RT_ANIICON):
        result := 'Animated icon';
      Integer(RT_HTML):
        result := 'HTML resource';
      Integer(RT_MANIFEST):
        result := 'Side-by-Side Assembly Manifest';
      else
        result := Format('(Unknown type %d)', [Integer(AResourceType)]);
    end;
  end;
end;

下面是代码的演示:

代码语言:javascript
复制
procedure TForm1.Button1Click(Sender: TObject);
begin
  // Hardware-dependent icon
  ShowMessage(GetHumanFriendlyResourceTypeName(MAKEINTRESOURCE(3)));

  // (Unknown type 123)
  ShowMessage(GetHumanFriendlyResourceTypeName(MAKEINTRESOURCE(123)));

  // AVI
  ShowMessage(GetHumanFriendlyResourceTypeName(PChar('AVI')));
end;

性能不如解决方案中的性能高,但此函数有以下几个优点:

  1. 这个函数更容易阅读,因为每个RT_常量都站在它的友好人名前面。因此,代码维护也要好得多。在LUT中,友好的人名可能会被意外地交换(因为在每个友好的人名前面没有注释表示官方的RT_常量名称)。
  2. 如果标识符未知,此函数也会显示一个友好的字符串“(未知类型123)”。
  3. 如果字符串不是预定义类型(RT_),此函数也将取消它的引用。
  4. 使用此函数,可以将字符串静态地国际化到资源字符串中,也可以通过查询转换函数/字符串来动态地国际化应用程序。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24107719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档