Как перебрать составной литеральный массив

Как я могу выполнить итерацию по массиву составных литералов, чтобы я мог напечатать book_id и value?

#include <stdio.h>
#include <string.h>

typedef struct {
    int book_id;
    char value;
} BookCode;

typedef struct {
    BookCode *codes;
} Books;

int main() {
    Books MyBooks[] = { 
        (BookCode[]){ {1, 'a'},{2, 'b'} },
        (BookCode[]){ {1, 'd'},{2, 'c'}, {3, 'f'} },
    };  

    int i,j;
    int n1 = sizeof(MyBooks)/sizeof(MyBooks[0]);
    for(i = 0; i < n1; i++){
        printf("%d\n", i); 
        // how to iterate over compound literal array?
    }   
    return 0;
}

person user1024718    schedule 03.10.2015    source источник


Ответы (1)


как перебирать составной литеральный массив?

Вы не можете.

По крайней мере, без предоставления дополнительной информации о количестве элементов, которые несут два массива BookCode, то есть 2 и 3. Эта более поздняя информация теряется при назначении двух массивов элементы указателя MyBooks. Он больше не может быть рассчитан во время выполнения.

Что вы могли бы сделать, так это определить дозорное значение и добавить его экземпляр, например стопорный элемент, в конец каждого массива BookCode. Таким образом, размер каждого массива может быть (повторно) рассчитан во время выполнения.

Это, например, можно сделать, как показано ниже:

#include <stdio.h>
#include <string.h>

typedef struct
{
  int book_id;
  char value;
} BookCode;

#define BOOKCODE_STOPPER {-1, '\0'}
static const BookCode BookCodeStopper = BOOKCODE_STOPPER;

typedef struct
{
  BookCode *codes;
} Books;

size_t get_codes_count(Books * books)
{
  BookCode * bc = books->codes;

  while (bc->book_id != BookCodeStopper.book_id
      && bc->value != BookCodeStopper.value)
  /* doing "while (memcmp(bc, &BookCodeStopper, sizeof BookCodeStopper)" might be faster. */
  {
    ++bc;
  }

  return bc - books->codes;
}

int main(void)
{
  Books books[] = {
    {(BookCode[]) {{1, 'a'}, {2, 'b'}, BOOKCODE_STOPPER}},
    {(BookCode[]) {{1, 'd'}, {2, 'c'}, {3, 'f'}, BOOKCODE_STOPPER}}
  };

  size_t n1 = sizeof books / sizeof books[0];
  for (size_t i = 0; i < n1; ++i)
  {
    printf("%zu\n", i);

    size_t s = get_codes_count(books + i);
    for (size_t j = 0; j < s; ++j)
    {
      printf("Book code %zu: id=%d, value=%c\n", j, books[i].codes[j].book_id,
          books[i].codes[j].value);
    }
  }

  return 0;
}

Этот подход подразумевает, что по крайней мере одна возможная комбинация кодов книг никогда не появится. В приведенном выше примере я выбрал для этого {-1, '\0'}.

person alk    schedule 03.10.2015
comment
Добавление комбинации должно сделать это. Спасибо - person user1024718; 04.10.2015