Динамичный массив

Рейтинг: 0Ответов: 2Опубликовано: 30.10.2014

Надо рандомно выбрать массив данных с частотой, чтоб сыграть мелодию

char midi_1[][] = {
  {2217, 2349, 2349, 2489, 2637, 2637, 2793, 2793, 2489, 2489},
  {2217, 2349, 2349, 2489, 2637, 2637},
  {2217, 2349, 2349, 2489, 2217, 2349, 2349, 2489, 2217, 2349, 2349, 2489, 2637, 2637}
};

Вся загвоздка в том, что длина массива с мелодией может быть любая, компилятор это не принимает (an array can't have elements of this type).

Как ещё можно реализовать эту задачу?

Обновление

Если очень просто, мне нужно получить рандомный массив, но массивы могут быть разной длины. Что-то вроде midi_1[rang(0, 2)].

В js это могло бы выглядеть как-то так: http://code.re/6L5

Ответы

▲ 3

@Fangog, что-то в таком духе пойдет?

#include <stdio.h>    // здесь I/O
#include <stdlib.h>   // здесь rand()
// а этот "инклюд" нужен только для теста с генератором случайных чисел
// будем инициализировать его текущим количеством секунд с 1/1/1970
#include <time.h>

/* 
   Вот это массивы чисел, которые вы определяете перед компиляцией,
   "забиваете" в текст программы.
   Насколько помню, у вас что-то о треках,
   тогда каждый массив это трек, который предстоит случайно выбрать.
   Имена массивов совершенно произвольны (в рамках синтаксиса и др. правил языка C
*/
int a0[] = {2217, 2349, 2349, 2489, 2637, 2637, 2793, 2793, 2489, 2489};
int a1[] = {12217, 12349, 12349, 12489, 12637, 12637};
int a2[] = {32217, 32349, 32349, 32489, 32217, 32349, 32349, 32489, 32217, 32349, 32349, 32489, 32637, 32637};

// макрос дает размер массива в ЭЛЕМЕНТАХ (не байтах)
#define SZA(x) sizeof(x) / sizeof(x[0])

// этот макрос сократит количество буковок, которые пришлось бы набивать
// им мы инициализируем элемент массива midi_1[], в котором храним указатель на трек и длину трека
#define DCL(x) {x, SZA(x)}

// структура элемента массива, котрый описывает треки
// существенное отличие от записи в JS
// midi_1 [] = { {1,2,3}, {1,2}, ... {1,2,3,4,5}};
// в том, что в отличие от JS C не связывает с массивом его размер(!)
// об этом мы сами должны думать (что и делаем, описывая эту структуру)
struct a {
  int *a,  // указатель на первое число трека
      sz;  // количество чисел в треке
} midi_1 [] = {DCL(a0), DCL(a1), DCL(a2)};
// midi_1 [] - массив этих структур, размер определяется при заполнении

int 
main(int ac, char *av[]) 
{
  srand(time(0));
  struct a *p = midi_1 + (rand() % SZA(midi_1));
  // p -- указывает на случайный описатель трека
  int i;

  // печатаем последовательно все числа трека
  for (i = 0; i < p->sz; i++)
    printf ("%d ", p->a[i]);
  puts("");

  return puts("End") == EOF;
}

Если есть вопросы, попозже вечером попробую ответить.

Update

Добавил комментариев, надеюсь стало понятней, почему делаю именно так.

▲ 2

Попробуйте вот так:

int *midi_1[] = {
    (int[]){2217, 2349, 2349, 2489, 2637, 2637, 2793, 2793, 2489, 2489},
    (int[]){2217, 2349, 2349, 2489, 2637, 2637},
    (int[]){2217, 2349, 2349, 2489, 2217, 2349, 2349, 2489, 2217, 2349,
             2349, 2489, 2637, 2637}
};

(украдено отсюда, проверка).

Подумайте о том, как код узнает о размерах каждой из строк вашего массива.