将结构复制到另一个结构的成员

时间:2014-04-14 12:12:04

标签: c struct memcpy copying sdcc

我正在使用SDCC 3.4,这是一个乐器的MIDI项目,而且我正在努力解决这个问题...我甚至发现某些事情难以解释,所以在这里我尝试做一个更好的例子。基本上,我正在扫描按钮按下,发送MIDI信息并相应地点亮LED。我需要的是一种数据库,其中包含与每个按钮相关的所有数据,其中一部分必须是常量的(按钮和LED的ID),并且部件可以是可变的,因为可以由用户改变。在初始化阶段,我需要将常量部分分配给结构并保持变量部分不变。当用户修改按钮的功能时,我需要覆盖变量部分并保持常量部分不变。

// A structure for the constant part
typedef struct
{
  unsigned char btnID; // this holds the n. of input pin for the button
  unsigned char ledID; // this holds the n. of output pin for the LED
} sBtnConst;

// A structure for the variable part
typedef struct
{
  unsigned char CCnum; // this holds the CC number to send
  unsigned char CCval; // this holds the CC value tu send
} sBtnVar;

// A structure containing all data
typedef struct
{
  sBtnConst c;
  sBtnVar v;
} sButton;

// Declare an array of button structures
// These will contain both the constant and the variable data
sButton Button[4];

// Now initialize a constant structure for the constant part
const sBtnConst cBtnDefinitions[4] =
{
  { 15, 0 },
  { 14, 1 },
  { 10, 8 },
  { 12, 5 },
};

现在,我需要做的是将cBtnDefinitions[]的全部内容复制到Button[]->c如果我这样做

memcpy(&Button->c, &cBtnDefinitions, sizeof(cBtnDefinitions));

数据按顺序复制到c和v中,而不仅仅是在成员c中。

main loop()中的其余代码如下所示:

void doButton(sButton *btn, unsigned char value)
{
  LitLED(btn->c.ledID, !value);
  SendMidiCC(btn->v.CCnum, btn->v.CCval);
}

// This is a callback function called every time a button has been pushed
void aButtonHasBeenPushed(unsigned char ID, unsigned char value)
{
  unsigned char i;
  for (i=0; i<NUM_OF_BUTTONS; ++i)
    if (i == Button[i].c.btnID)
      doButton(&Button[i], value);
}

当然我可能有不同类型的按钮,所以我可以将sButton结构用于其他目的,并让它们全部由相同的功能处理。

1 个答案:

答案 0 :(得分:1)

您总是需要一个循环,因为源cBtnDefinitions是一个连续的内存区域,而目标由4个独立的内存区域组成。

您可以使用memcpy

执行此操作
int i;
for (i = 0; i < 4; ++i) {
    memcpy(&Button[i].c, cBtnDefinitions + i, sizeof(sBtnConst));
}

但是一个简单的任务也适用于GCC:

int i;
for (i = 0; i < 4; ++i) {
    Button[i].c = cBtnDefinitions[i];
}