【问题标题】:What's the best way to do a lookup table in C?在 C 中做查找表的最佳方法是什么?
【发布时间】:2010-08-04 18:19:26
【问题描述】:

我正在开发一个嵌入式 C 项目。我有一个 LCD 显示器,每个字符都有一个 5x7 点阵。要显示特定字符​​,您必须移动与要打开的点相关的 5 个字节。所以我需要用一个键制作某种查找表,我可以在其中传入一个 ASCII 字符,并返回一个包含 5 个字节的数组...... 例如,像这样调用这个函数,

GetDisplayBytes('A');

应该返回一个这样的数组...

C[0] = 0x7E : C[1] = 0x90 : C[2] = 0x90 : C[3] = 0x90 : C[4] = 0x7E

在 C 中最好的方法是什么?

【问题讨论】:

  • 您的速度和内存统计数据是多少:速度有多快,内存有多少?
  • 好吧,我可能会将其存储在闪存中,这样我就不会占用宝贵的 RAM。我还没有任何具体的速度或尺寸要求,但我猜最小的优先于最快的。
  • 没有一个答案指定这一点,但我相信数组应该是静态的。

标签: c lookup-tables


【解决方案1】:

我会为您要使用的连续 ASCII 块创建数组。数据。像这样的:

uint8_t displayBytesLetters[] = 
{
  0x73, 0x90, 0x90, 0x90, 0x73, // 'A'
  .
  .
  .
};

uint8_t displayBytesDigits[] = 
{
  0x12, 0x15, 0x25, 0x58, 0x80, // '0'
  .
  .
  .
};

那么你的GetDisplayBytes() 是这样的:

uint8_t *GetDisplayBytes(char c)
{
  if (isdigit(c))
    return &displayBytes[5*(c - '0')];
  else if (isupper(c))
    return &displayBytes[5*(c - 'A')];
  else
    return NULL;
}

将返回的指针传递给任何输出数据的函数:

void DoDisplay(uint8_t *displayBytes)
{
  int i;
  for (i = 0; i < 5; i++) 
  {
     SendOutput(displayBytes[i]);
  }
}

【讨论】:

  • 这很好,但如果我不想让每个 ASCII 值都可用于打印,该怎么办。假设我只想要大写字母、数字和几个符号 (,!,?)。在那种情况下,您的方法不会要求我使用不必要的内存空间。
  • @Jordan S,然后对每个非连续的 ascii 块使用不同的查找表。我会用一个例子来编辑我的答案。
  • 然后,代替(c - 'A'),编写一个函数/宏,将您支持的ASCII字符作为输入,并返回一个索引号作为输出(有点像迷你哈希函数) .您可能还想处理非法字符输入。
  • 您是否介意添加一个示例,说明如何调用 GetDisplayBytes 以展示如何遍历 5 个字节。
  • @Jordan S, GetDisplayBytes() 不需要迭代字节,是吗?我认为进行显示的例程将需要它。我添加了一个我认为您要问的示例。
【解决方案2】:
typedef char LCDDATA[5];   

LCDDATA lcdTable[256] = { {0,0,0,0,0},  // char 0
                          {.....},       // char 1
                        }

LCDDATA GetDisplayBytes(char chr)
{
     return lcdTable[chr];
}

这基本上是在制作一个数组。

【讨论】:

  • 没有理由不能像 Carl 那样使用这种方法。
  • +1 用于正确打字而不是玩算术游戏。不过有一些小事:你的原型应该是LCDDATA GetDisplayBytes(unsigned char chr),而且类型名称使用全部大写是不寻常的,通常这些是为宏保留的。
  • @Jens:我曾经使用宏做过这个,并且习惯了。
  • 为数组创建类型定义是非常值得怀疑的。我不确定这是否会编译(函数声明器上的数组返回类型)。数组应该包裹在 struct 中,以确保可以分配 LCDDATA 项,并且不会发生数组自动衰减。
猜你喜欢
  • 1970-01-01
  • 2011-07-10
  • 2012-07-30
  • 2010-09-18
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
相关资源
最近更新 更多