То, что вы пытаетесь сделать, невозможно сделать каким-либо изящным способом. Невозможно надежно обращаться к последовательным элементам структуры в виде массива. В настоящее время принятый ответ - это взлом, а не решение.
Правильным решением было бы переключиться на массив, независимо от того, сколько работы ему потребуется. Если вы используете enum-константы для индексации массива (как предложил @digEmAll в своем теперь удаленном ответе), имена и код будут такими же понятными, как и ваши.
Если вы все еще не хотите или не можете переключиться на массив, единственный более или менее приемлемый способ сделать то, что вы пытаетесь сделать, - это создать «индекс-массив» или «map-». массив "(см. ниже). C ++ имеет специальную языковую функцию, которая помогает элегантно ее реализовать - указатели на члены. В C вы вынуждены эмулировать эту функцию C ++, используя offsetof
macro
static const size_t values_offsets[] = {
offsetof(values, v_move),
offsetof(values, v_read),
offsetof(values, v_suck),
/* and so on */
};
static const size_t quantities_offsets[] = {
offsetof(quantities, qtt_move),
offsetof(quantities, qtt_read),
offsetof(quantities, qtt_suck),
/* and so on */
};
А если теперь вам дано
values v;
quantities q;
и индекс
int i;
вы можете генерировать указатели на отдельные поля как
int *pvalue = (int *) ((char *) &v + values_offsets[i]);
int *pquantity = (int *) ((char *) &q + quantities_offsets[i]);
*pvalue += *pquantity;
Конечно, теперь вы можете перебирать i
любым удобным для вас способом. Это также далеко не элегантно, но, по крайней мере, несет некоторую степень надежности и обоснованности, в отличие от любого уродливого взлома. Все это можно сделать, чтобы выглядеть более элегантно, обернув повторяющиеся фрагменты в соответственно названные функции / макросы.