在索引较高的C中启动数组

在索引较高的C中启动数组,c,arrays,C,Arrays,我有一个数字阵列,其中包含8x8 LED显示屏的二进制坐标 现在,我想有相同的,但字符。这很简单,因为索引是数字本身的字符 所以索引1将显示1,索引2将显示2,依此类推 我想有一个数组,从索引号65和更高的开始 其思想是传递一个字符数组,并为每个字符获取等效的ASCII数和atoi,然后循环遍历数组以选择正确的数据 如何从索引65开始 我原以为每次从atoi得到一个值时减去65是可以的,但不知怎么的,这感觉是错的 这样我可以说A等于0,B等于1,依此类推 #define ZERO {0,1,1,

我有一个数字阵列,其中包含8x8 LED显示屏的二进制坐标

现在,我想有相同的,但字符。这很简单,因为索引是数字本身的字符

所以索引1将显示1,索引2将显示2,依此类推

我想有一个数组,从索引号65和更高的开始

其思想是传递一个字符数组,并为每个字符获取等效的ASCII数和atoi,然后循环遍历数组以选择正确的数据

如何从索引65开始

我原以为每次从atoi得到一个值时减去65是可以的,但不知怎么的,这感觉是错的

这样我可以说A等于0,B等于1,依此类推

#define ZERO {0,1,1,0},{1,0,0,1},{1,0,0,1},{1,0,0,1},{1,0,0,1},{0,1,1,0}
#define ONE {0,0,1,0},{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,1,0},{0,1,1,1}
#define TWO {0,1,1,0},{1,0,0,1},{0,0,0,1},{0,0,1,0},{0,1,0,0},{1,1,1,1}
#define THREE {1,1,1,1},{0,0,1,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,1,1}
#define FOUR {0,0,0,1},{0,0,1,1},{0,1,0,1},{1,1,1,1},{0,0,0,1},{0,0,0,1}
#define FIVE {1,1,1,1},{1,0,0,0},{1,1,1,0},{0,0,0,1},{1,0,0,1},{0,1,1,0}
#define SIX {0,0,1,1},{0,1,0,0},{1,0,0,0},{1,1,1,1},{1,0,0,1},{0,1,1,0}
#define SEVEN {1,1,1,1},{0,0,0,1},{0,0,1,0},{0,1,0,0},{1,0,0,0},{1,0,0,0}
#define EIGHT {0,1,1,0},{1,0,0,1},{0,1,1,0},{1,0,0,1},{1,0,0,1},{0,1,1,0}
#define NINE {0,1,1,0},{1,0,0,1},{0,1,1,1},{0,0,0,1},{0,0,1,0},{0,1,0,0}

byte numbers[10][6][4]={
  {ZERO},
  {ONE},
  {TWO},
  {THREE},
  {FOUR},
  {FIVE},
  {SIX},
  {SEVEN},
  {EIGHT},
  {NINE},
};

不,不能更改C中的起始数组索引。它将始终为零

如果在每次访问中手动减法太麻烦,您可以制作一个宏或函数来自动执行该操作

例如:

byte** map(const char c)
{
    return numbers[c-'0'];
}

不,不能更改C中的起始数组索引。它将始终为零

如果在每次访问中手动减法太麻烦,您可以制作一个宏或函数来自动执行该操作

例如:

byte** map(const char c)
{
    return numbers[c-'0'];
}

您可以提供一个索引来跳过某些数组成员,如下所示:

byte numbersAndLetters[][6][4]={
  {ZERO},
  {ONE},
  {TWO},
  {THREE},
  {FOUR},
  {FIVE},
  {SIX},
  {SEVEN},
  {EIGHT},
  {NINE},
['A'] = {LETTER_A}, // Instead of hardcoding 65, use 'A'
  {LETTER_B}
  ...
};
这种形式的初始值设定项允许您跳过某些元素,使它们保持默认的初始化状态

注意:对于只能作为更大语法结构的一部分使用的项目,使用
#define
通常不是一个好主意。例如,您定义的十位数字不能在数组初始值设定项之外使用,它们周围需要大括号。您应该以内联方式定义它们,并添加注释以保持清晰:

byte numbers[][6][4]={
  {{0,1,1,0},{1,0,0,1},{1,0,0,1},{1,0,0,1},{1,0,0,1},{0,1,1,0}}, // Zero
  {{0,0,1,0},{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,1,0},{0,1,1,1}}, // One
  ..
}

您可以提供一个索引来跳过某些数组成员,如下所示:

byte numbersAndLetters[][6][4]={
  {ZERO},
  {ONE},
  {TWO},
  {THREE},
  {FOUR},
  {FIVE},
  {SIX},
  {SEVEN},
  {EIGHT},
  {NINE},
['A'] = {LETTER_A}, // Instead of hardcoding 65, use 'A'
  {LETTER_B}
  ...
};
这种形式的初始值设定项允许您跳过某些元素,使它们保持默认的初始化状态

注意:对于只能作为更大语法结构的一部分使用的项目,使用
#define
通常不是一个好主意。例如,您定义的十位数字不能在数组初始值设定项之外使用,它们周围需要大括号。您应该以内联方式定义它们,并添加注释以保持清晰:

byte numbers[][6][4]={
  {{0,1,1,0},{1,0,0,1},{1,0,0,1},{1,0,0,1},{1,0,0,1},{0,1,1,0}}, // Zero
  {{0,0,1,0},{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,1,0},{0,1,1,1}}, // One
  ..
}
不要这样做。(这是对您的请求的常见错误解决方案。)

你可能会遇到一些推荐信,这些推荐信建议你可以像

    int  a[10]={5,6,7,8,9,10,11,12,13,14};
    int *pA=a-5;
现在,
pA[5]
将引用数组的第一个元素

不要这样做

该标准允许由于创建无效指针而导致pA生成陷阱的实现。指针不要求在对象外部有效 指向该对象末端或该对象末端的一个元素

在许多情况下,这种类型的代码可以工作,但不需要这样做。这应该避免

有关加法运算的参考C99 6.5.6加法运算符,其中加法运算的一个操作数是指针:“如果指针操作数和结果都指向同一数组对象的元素,或超过数组对象的最后一个元素,则求值不应产生溢出,否则,行为未定义。”

不要这样做。(这是对您的请求的常见错误解决方案。)

你可能会遇到一些推荐信,这些推荐信建议你可以像

    int  a[10]={5,6,7,8,9,10,11,12,13,14};
    int *pA=a-5;
现在,
pA[5]
将引用数组的第一个元素

不要这样做

该标准允许由于创建无效指针而生成pA将创建陷阱的实现。指针不需要在对象外部有效 指向该对象末端或该对象末端的一个元素

在许多情况下,这种类型的代码可以工作,但不需要这样做,应该避免



关于加法运算,参考C99 6.5.6加法运算符,其中加法运算的一个操作数是指针:“如果指针操作数和结果都指向同一数组对象的元素,或指向数组对象最后一个元素的元素,则求值不应产生溢出,否则,行为未定义。“

只需在索引到数组之前进行减法运算。这些预处理器定义有什么原因吗?在
{NINE}之后不应该有
?@JohnBupit:这是为了更容易自动生成代码而明确允许的。@重复数据消除器的定义只是为了可读性。它们有什么问题?在索引到数组之前进行减法。这些预处理器定义有什么原因吗?在
{NINE}之后不应该有
?@JohnBupit:这是为了更容易自动生成代码而明确允许的。@重复数据消除器的定义只是为了可读性。它们有什么问题吗?如果要添加..,10应该是92。。Z@cup你说得对-我应该完全省略第一个索引,因为编译器比我更擅长计数。也许最好使用comments位于行的开头,如/*Zero*/,以将可读信息放在将首先读取的位置。谢谢@dasblinkenlight。这是我添加#define之前的实际情况。我添加#define只是因为可读性。我现在需要计算出来,看看哪个解决方案更适合。如果要添加一个,10应该是92。。Z@cupY你是对的-我应该完全省略第一个索引,因为编译器比我更擅长计数。也许最好在行的开头使用注释,如/*Zero*/,将可读信息放在第一个读取的位置。谢谢@dasblinkenlight。这是我添加#define之前的实际方式。我添加了#define只是因为使用可读性。我现在需要解决它,看看哪个解决方案更适合。