c - 启用 const 数组的部分

标签 c multidimensional-array embedded

我有四个const char[][] 数组,每个数组大约有 50 个元素,每个元素包含另外 40 个值,这些值将被发送到图形 LCD,以绘制某个字母,数字、符号、……

现在的问题是,我正在开发一个资源非常有限的嵌入式系统。虽然所有四个数组在我之前工作的项目中都很有用,我需要大部分字符,但现在我只需要其中的 5 或 10 个。

我可以从数组中删除不需要的字符,但我希望有更好的方法来禁止将这些字符写入 RAM/FLASH。

我正在考虑使用 #ifdef#endif。但是对每个元素都这样做,代码会变得困惑。

还有其他方法吗?

提前致谢!

编辑:

现在,我有 #ifdef#endif 用于更大的部分,例如:

#define ARRAY1_BIG_LETTERS
#define ARRAY1_SMALL_LETTERS
#define ARRAY1_NUMBERS
#define ARRAY1_OTHER

#define ARRAY2_BIG_LETTERS
#define ARRAY2_SMALL_LETTERS
#define ARRAY2_NUMBERS
#define ARRAY2_OTHER

...

但是,我仍然需要对内容进行更精细的控制。

编辑 2:

这是(较小的)数组之一:

const char writting_8x8[][9] = {
    #ifdef ARRAY1_OTHER
    {32, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0},                        /*   */
    {45, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0},                        /* - */
    {46, 0 , 0 , 96 , 96 , 0 , 0 , 0 , 0},                      /* . */
    {58, 0 , 0 , 108 , 108 , 0 , 0 , 0 , 0},                    /* : */
    {61, 0 , 36 , 36 , 36 , 36 , 36 , 0 , 0},                   /* = */
    #endif
    #ifdef ARRAY1_NUMBERS
    {48, 0 , 62 , 81 , 73 , 69 , 62 , 0 , 0},                   /* 0 */
    {49, 0 , 0 , 66 , 127 , 64 , 0 , 0 , 0},                    /* 1 */
    {50, 0 , 98 , 81 , 73 , 73 , 70 , 0 , 0},                   /* 2 */
    {51, 0 , 34 , 73 , 73 , 73 , 54 , 0 , 0},                   /* 3 */
    {52, 0 , 24 , 20 , 18 , 127 , 16 , 0 , 0},                  /* 4 */
    {53, 0 , 47 , 73 , 73 , 73 , 49 , 0 , 0},                   /* 5 */
    {54, 0 , 60 , 74 , 73 , 73 , 48 , 0 , 0},                   /* 6 */
    {55, 0 , 1 , 113 , 9 , 5 , 3 , 0 , 0},                      /* 7 */
    {56, 0 , 54 , 73 , 73 , 73 , 54 , 0 , 0},                   /* 8 */
    {57, 0 , 6 , 73 , 73 , 41 , 30 , 0 , 0},                    /* 9 */
    #endif
    #ifdef ARRAY1_BIG_LETTERS
    {65, 0 , 126 , 17 , 17 , 17 , 126 , 0 , 0},                 /* A */
    {66, 0 , 127 , 73 , 73 , 73 , 54 , 0 , 0},                  /* B */
    {67, 0 , 62 , 65 , 65 , 65 , 34 , 0 , 0},                   /* C */
    {68, 0 , 127 , 65 , 65 , 65 , 62 , 0 , 0},                  /* D */
    {69, 0 , 127 , 73 , 73 , 73 , 65 , 0 , 0},                  /* E */
    {70, 0 , 127 , 9 , 9 , 9 , 1 , 0 , 0},                      /* F */
    {71, 0 , 62 , 65 , 73 , 73 , 122 , 0 , 0},                  /* G */
    {72, 0 , 127 , 8 , 8 , 8 , 127 , 0 , 0},                    /* H */
    {73, 0 , 0 , 65 , 127 , 65 , 0 , 0 , 0},                    /* I */
    {74, 0 , 48 , 64 , 64 , 64 , 63 , 0 , 0},                   /* J */
    {75, 0 , 127 , 8 , 20 , 34 , 65 , 0 , 0},                   /* K */
    {76, 0 , 127 , 64 , 64 , 64 , 64 , 0 , 0},                  /* L */
    {77, 0 , 127 , 2 , 4 , 2 , 127 , 0 , 0},                    /* M */
    {78, 0 , 127 , 2 , 4 , 8 , 127 , 0 , 0},                    /* N */
    {79, 0 , 62 , 65 , 65 , 65 , 62 , 0 , 0},                   /* O */
    {80, 0 , 127 , 9 , 9 , 9 , 6 , 0 , 0},                      /* P */
    {81, 0 , 62 , 65 , 81 , 33 , 94 , 0 , 0},                   /* Q */
    {82, 0 , 127 , 9 , 9 , 25 , 102 , 0 , 0},                   /* R */
    {83, 0 , 38 , 73 , 73 , 73 , 50 , 0 , 0},                   /* S */
    {84, 0 , 1 , 1 , 127 , 1 , 1 , 0 , 0},                      /* T */
    {85, 0 , 63 , 64 , 64 , 64 , 63 , 0 , 0},                   /* U */
    {86, 0 , 31 , 32 , 64 , 32 , 31 , 0 , 0},                   /* V */
    {87, 0 , 63 , 64 , 60 , 64 , 63 , 0 , 0},                   /* W */
    {88, 0 , 99 , 20 , 8 , 20 , 99 , 0 , 0},                    /* X */
    {89, 0 , 7 , 8 , 112 , 8 , 7 , 0 , 0},                      /* Y */
    {90, 0 , 113 , 73 , 69 , 67 , 0 , 0 , 0},                   /* Z */
    {200, 0 , 56 , 69 , 70 , 69 , 40 , 0 , 0},                  /* Č */
    #endif
    #ifdef ARRAY1_SMALL_LETTERS
    {97, 0 , 32 , 84 , 84 , 84 , 120 , 0 , 0},                  /* a */
    {98, 0 , 127 , 68 , 68 , 68 , 56 , 0 , 0},                  /* b */
    {99, 0 , 56 , 68 , 68 , 68 , 40 , 0 , 0},                   /* c */
    {100, 0 , 56 , 68 , 68 , 68 , 127 , 0 , 0},                 /* d */
    {101, 0 , 56 , 84 , 84 , 84 , 8 , 0 , 0},                   /* e */
    {102, 0 , 8 , 126 , 9 , 9 , 0 , 0 , 0},                     /* f */
    {103, 0 , 24 , 164 , 164 , 164 , 124 , 0 , 0},              /* g */
    {104, 0 , 127 , 4 , 4 , 120 , 0 , 0 , 0},                   /* h */
    {105, 0 , 0 , 0 , 125 , 64 , 0 , 0 , 0},                    /* i */
    {106, 0 , 64 , 128 , 132 , 125 , 0 , 0 , 0},                /* j */
    {107, 0 , 127 , 16 , 40 , 68 , 0 , 0 , 0},                  /* k */
    {108, 0 , 0 , 0 , 127 , 64 , 0 , 0 , 0},                    /* l */
    {109, 0 , 124 , 4 , 24 , 4 , 120 , 0 , 0},                  /* m */
    {110, 0 , 124 , 4 , 4 , 120 , 0 , 0 , 0},                   /* n */
    {111, 0 , 56 , 68 , 68 , 68 , 56 , 0 , 0},                  /* o */
    {112, 0 , 252 , 68 , 68 , 68 , 56 , 0 , 0},                 /* p */
    {113, 0 , 56 , 68 , 68 , 68 , 252 , 0 , 0},                 /* q */
    {114, 0 , 68 , 120 , 68 , 4 , 8 , 0 , 0},                   /* r */
    {115, 0 , 8 , 84 , 84 , 84 , 32 , 0 , 0},                   /* s */
    {116, 0 , 4 , 62 , 68 , 36 , 0 , 0 , 0},                    /* t */
    {117, 0 , 60 , 64 , 32 , 124 , 0 , 0 , 0},                  /* u */
    {118, 0 , 28 , 32 , 64 , 32 , 28 , 0 , 0},                  /* v */
    {119, 0 , 60 , 96 , 48 , 96 , 60 , 0 , 0},                  /* w */
    {120, 0 , 108 , 16 , 16 , 108 , 0 , 0 , 0},                 /* x */
    {121, 0 , 156 , 160 , 96 , 60 , 0 , 0 , 0},                 /* y */
    {122, 0 , 100 , 84 , 84 , 76 , 0 , 0 , 0},                  /* z */
    {154, 0 , 8 , 85 , 86 , 85 , 32 , 0 , 0},                   /* š */
    {158, 0 , 100 , 85 , 86 , 77 , 0 , 0 , 0},                  /* ž */
    {232, 0 , 56 , 69 , 70 , 69 , 40 , 0 , 0}                   /* č */
    #endif
};

我预先选择要使用的值。所以这可能需要以某种方式使用预处理器来完成......

最佳答案

首先,我建议您创建结构列表。此外,你的显示器是 8x8,但你只使用 6x8(你的边框总是 0),如果你用简单的字符替换第一个,你不必写评论“它实际上是什么字母”。还有一个技巧可以将“终止符”(或停止序列)添加到表中。然后您不必知道数组大小(我假设您正在循环查找数组以找到正确的字母)。所以:

typedef struct _dsp_letter {
  const char ascii;
  const char pixels[6];
} dsp_letter_t;

const dsp_letter_t writing[] = {
  #ifdef ARRAY1_OTHER
    {' ', { 0 , 0 , 0 , 0 , 0 , 0 } },
    {'-', { 0 , 0 , 0 , 0 , 0 , 0 } },
    {'.', { 0 , 96 , 96 , 0 , 0 , 0 } },
    {':', { 0 , 108 , 108 , 0 , 0 , 0 } },
    {'=', { 36 , 36 , 36 , 36 , 36 , 0 } },
    #endif
    // ...
    { 0 }
}

使用看起来像:

int i = 0;
while (writing[i].ascii != 0) {
    // do stuff, add if or anything
    ++i;
}

该更改需要更改显示功能,但节省的内存可能是值得的。

这是一方面。 现在,这就是区别 const char str[] = "Str"; 和 const char *pStr = "Str"; ?

尺寸!

const char str[] = "My long C-style string";
const char *pStr = "My long C-style string";

printf("str: %d vs pStr: %d", sizeof(str), sizeof(pStr));
// str: 23 vs pStr: 8

const char str[] 分配在堆栈上,它实际上是数组,在运行时写入数据。

const char *pStr 在堆上分配,在运行时只有指向数据的指针被写入它,数据在应用程序的全局内存中。

这是什么意思? onst char writting_8x8[][9] = { ... }; 正在分配大量内存。在嵌入式设备上,这可能是……好吧,假设我不推荐它。

要做什么? 您可以将所有大数组拆分成较小的数组。

typedef struct _dsp_letter {
    const char ascii;
    const char pixels[6];
} dsp_letter_t;

#ifdef ADD_OTHER
const dsp_letter_t other[] = {
    {' ', { 0 , 0 , 0 , 0 , 0 , 0 } },
    {'-', { 0 , 0 , 0 , 0 , 0 , 0 } },
    {'.', { 0 , 96 , 96 , 0 , 0 , 0 } },
    {':', { 0 , 108 , 108 , 0 , 0 , 0 } },
    {'=', { 36 , 36 , 36 , 36 , 36 , 0 } },
    { 0 }
};
#endif ADD_OTHER

#ifdef ADD_SMALL
const dsp_letter_t small[] = {
    {'a', { 0 , 0 , 0 , 0 , 0 , 0 } },
    {'b', { 0 , 0 , 0 , 0 , 0 , 0 } },
    {'c', { 0 , 96 , 96 , 0 , 0 , 0 } },
    {'d', { 0 , 108 , 108 , 0 , 0 , 0 } },
    { 0 }
};
#endif ADD_SMALL

现在您可以在编译时或运行时将它们全部放在一个地方

编译时(就像你之前的一样):

const dsp_letter_t *writting[] = {
#ifdef ADD_OTHER 
    other,
#endif
#ifdef ADD_SMALL 
    small,
#endif
    0
};

或运行时:

#define ADD_OTHER 1
#define ADD_SMALL 0

int size = ADD_OTHER + ADD_SMALL;
int i = 0;
dsp_letter_t **writting = (dsp_letter_t *writting(malloc)(size* sizeof (dsp_letter_t *writting));

#ifdef ADD_OTHER 
writting[i++] = other;
#endif

#ifdef ADD_SMALL 
writting[i++] = small;
#endif

你可以使用它:)

不幸的是,如果不把 #ifdef ... endif 放在整个地方,我不知道如何做得更好:/

关于c - 启用 const 数组的部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25788178/

相关文章:

C 在读取 .ppm 时不转到下一行

C 如何防止随机变量重复相同的数字

c - 我应该相信 C 中的短通常是 2 个字节吗?

javascript - 按数字对多维数组 alpha 进行排序

c - int** 与 int[const][const] 差异

c# - 多维数组的自定义迭代?

android - android中如何从串口接收数据

c - 选择性删除字符串中的特定字符

testing - 协议(protocol)栈开发的嵌入式测试

c - 在嵌入式处理器中调用 main() 之前,我应该将 LR 设置为什么?