kingkong kingkong -4 years ago 85
C Question

Iterate through enums in C?

let's say I have a couple of hardware registers which are defined within an enum:

typedef enum registers
{
REG1 = 0,
REG2 = 1,
REG3 = 2,
REG4 = 4,
REG5 = 6,
REG6 = 8,

REG_MAX,


}

I have default values for these registers(actually not decided in which way to define them, #define, array or enum...):

// This is just conceptual, not really an enum, array or #define :)
typedef enum values
{
VALUE_REG1 = A,
VALUE_REG2 = B,
VALUE_REG3 = C,
VALUE_REG4 = 53,
VALUE_REG5 = 88,
VALUE_REG6 = 24,

MAX_NUM_REG_VALUES
}


I have a function which can read the hardware registers:

uint8 readRegs(uint8 regaddr);


Now I would like to loop through the register enum, and on each element call the readRegs() function and compare it to the enum reg_values. It looks like:

registers regs;
reg_values values;
uint8 readfromregs;

for (regs = REG1; regs <= REG_MAX; regs++)
{
readfromregs = readRegs(regs);
for (values = VALUE_REG1; reg_values <= MAX_NUM_REG_VALUES; reg_values++)
{
if (readfromregs != values)
{
// Value not correct
}

else
{
// value correct
}
}
}


This will not work because it's not possible to iterate in enum in this way. Does anybody have a better solution? How to define the construct enum reg_values ?
The enum registers must be fix (this can not be changes to array).

Answer Source

I'd probably define a struct

struct RegInfo
{
    registers number;
    values defaultValue;
}

Then I would create an array matching the register number to the default value

struct RegInfo registerInfo[] =
{
    { REG1, VALUE_REG1 },
    { REG2, VALUE_REG2 },
    { REG3, VALUE_REG3 },
    { REG4, VALUE_REG4 },
    { REG5, VALUE_REG5 },
    { REG6, VALUE_REG6 },
};

Now to iterate the registers:

for (int i = 0 ; i < sizeof registerInfo / sizeof(RegInfo) ; ++i)
{
    values value = readFromReg( registerInfo[i].number);
    if (value != registerInfo[i].defaultValue)
    {
         // Not the default
    }
}

If you want an inner loop foe each value, same trick except the array can be directly of the values

values allValues[] = { VALUE_REG1, Value_REG2, ... , VALUE_REG6 };

There is a risk that you'll forget to put new values/registers in the relevant array, but that's what unit testing is for.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download