Предпочтительным методом итерации по структуре является создание функции, которая возвращает значение или адрес поля с заданным индексом.Обратите внимание, что если порядок элементов в структуре изменяется, эта функция также должна измениться:
int * Index_Of(unsigned int index, mach_msg_header_t * p_struct)
{
switch (index)
{
case 0: return (int *) &(p_struct->msgh_bits);
case 1: return (int *) &(p_struct->msgh_size);
case 2: return (int *) &(p_struct->msgh_remote_port);
case 3: return (int *) &(p_struct->msgh_local_port);
case 4: return (int *) &(p_struct->msgh_reserved);
case 5: return (int *) &(p_struct->msgh_id);
}
return 0;
}
Просто помните, что рассматривать структуру как смежные поля (члены) не рекомендуется, так каккомпилятору разрешено добавлять отступы между элементами структуры.Таким образом, любой метод доступа к полям, кроме имени, опасен и приведет к очень сложным ошибкам.
Кстати, обрабатывать каждое поле как int
также опасно.Если какой-либо из типов будет изменен на что-то другое, например double
, ваш код сломается.Компилятор не поймает ошибку, потому что приведение говорит компилятору, что ВЫ знаете, что делаете.
Вы можете «перевернуть картинку» и реализовать шаблон Visitor :
struct Visitor_Void
{
void (*fn_msgh_bits)(mach_msg_bits_t);
void (*fn_msgh_size)(mach_msg_size_t);
void (*fn_msgh_remote_port)(mach_port_t);
void (*fn_msgh_local_port)(mach_port_t);
void (*fn_msgh_reserved)(mach_msg_size_t);
void (*fn_msgh_id)(mach_msg_id_t);
};
void Visit_Members(mach_msg_header_t * p_header,
struct Visitor_Void * p_visitor)
{
(p_visitor->fn_msgh_bits)(p_header->msgh_bits);
(p_visitor->fn_msgh_size)(p_header->msgh_size);
(p_visitor->fn_msgh_remote_port)(p_header->msgh_remote_port);
(p_visitor->fn_msgh_local_port)(p_header->msgh_local_port);
(p_visitor->fn_msgh_reserved)(p_header->msgh_reserved);
(p_visitor->fn_msgh_id)(p_header->msgh_id);
return;
}