Неверное присвоение массива при смещении элемента структуры - PullRequest
0 голосов
/ 23 марта 2019

Мне нужно «удалить» некоторые элементы из структуры. Например, пусть это будут годы. Поэтому я должен найти их в моей структуре, переместить их и отобразить новую структуру без них.

Наш профессор сказал, что мы должны использовать указатели на структуры. И я не понимаю. Я имею в виду, с моей точки зрения, структуры работают как массивы, но с некоторыми спецификациями.

for(i = 0; i < n; ++i) {
    if ( yr == (mvbs+i) -> releaseYear) {
        for (i = pos; i < n - 1; i++)
        (mvbs+i ) -> udk = (mvbs+i+1) -> udk; //int
        (mvbs+i) -> name = (mvbs+i+1) -> name; //char
        (mvbs+i) -> genre = (mvbs+i+1) -> genre;//char
        (mvbs+i) -> creator = (mvbs+i+1) -> creator;//char
        (mvbs+i) -> releaseYear = (mvbs+i+1) -> releaseYear;//int
        (dtbs+i) -> day = (dtbs+i+1) -> day;//int
        (dtbs+i) -> month = (dtbs+i+1) -> month;//int
        (dtbs+i) -> year = (dtbs+i+1) -> year;//int
    }
}

Я предполагаю, что это должно сместить данные в "удаленное" пространство, но я получаю неверное присвоение массива со всеми символами.

Вот мои struct с

struct date { 
    int day; 
    int month; 
    int year; 
}; 

date datebase[100], *dtbs=datebase; 

struct movies { 
    int udk; 
    char name[10]; 
    char genre[10]; 
    char creator[10];
    int releaseYear; 
    struct date movieRental; 
}; 

movies mooviebase[100], *mvbs=mooviebase;

1 Ответ

0 голосов
/ 23 марта 2019

Неправильное присвоение массива при смещении элемента структуры

Предупреждение, если я правильно сделаю отступ для вашего кода, это:

for(i = 0; i < n; ++i)
{
  if ( yr == (mvbs+i) -> releaseYear)
  {
    for (i = pos; i < n - 1; i++)
      (mvbs+i ) -> udk = (mvbs+i+1) -> udk; //int
    (mvbs+i) -> name = (mvbs+i+1) -> name; //char
    (mvbs+i) -> genre = (mvbs+i+1) -> genre;//char
    (mvbs+i) -> creator = (mvbs+i+1) -> creator;//char
    (mvbs+i) -> releaseYear = (mvbs+i+1) -> releaseYear;//int
    (dtbs+i) -> day = (dtbs+i+1) -> day;//int
    (dtbs+i) -> month = (dtbs+i+1) -> month;//int
    (dtbs+i) -> year = (dtbs+i+1) -> year;//int
  }
}

, но это не то, что вы хотите, потому что только udk перемещается в цикле и для всех других элементов k значение n-1 (я полагаю pos <= n - 1), так что вы делаете, например, (mvbs+n-1) -> name = (mvbs+n) -> nameи n видимый размер, который вы выходите из инициализированной части массива или может быть вне массива.

Конечно, вы пропустили добавить {}, чтобы сделать:

for(i = 0; i < n; ++i)
{
  if ( yr == (mvbs+i) -> releaseYear)
  {
    for (i = pos; i < n - 1; i++) {
      (mvbs+i ) -> udk = (mvbs+i+1) -> udk; //int
      (mvbs+i) -> name = (mvbs+i+1) -> name; //char
      (mvbs+i) -> genre = (mvbs+i+1) -> genre;//char
      (mvbs+i) -> creator = (mvbs+i+1) -> creator;//char
      (mvbs+i) -> releaseYear = (mvbs+i+1) -> releaseYear;//int
      (dtbs+i) -> day = (dtbs+i+1) -> day;//int
      (dtbs+i) -> month = (dtbs+i+1) -> month;//int
      (dtbs+i) -> year = (dtbs+i+1) -> year;//int
    }
  }
}

Однако, во-первых, что такое pos ?и поскольку вы повторно используете / модифицируете переменную i во встроенном для , вы не можете управлять случаем, когда несколько записей имеют одинаковый releaseYear

Возможнопервый для должен быть на pos , а не на i , чтобы быть более последовательным и удалять записи pos с поискомгод.

После встроенного для остается на один элемент меньше, поэтому вам нужно уменьшить n

Обратите внимание, если есть несколько последовательных записей, имеющихгод поиска вы можете оптимизировать, чтобы обходить их одновременно, а не делать по одному.

Тип элементов совместим с прямым копированием, поэтому код можно упростить до:

pos = 0;

while(pos < n)
{
  if ( yr == (mvbs+pos) -> releaseYear)
  {
    for (i = pos; i < n - 1; i++) {
      *(mvbs+i ) = *(mvbs+i+1)
    }
    n -= 1;
  }
  else
    pos += 1;
}

и, наконец, вы можете использовать memmove вместо того, чтобы делать копию самостоятельно элемент за элементом:

pos = 0;

while(pos < n)
{
  if ( yr == (mvbs+pos)->releaseYear)
  {
    if (pos == --n)
      /* it was the last entry */
      break;
    memmove(mvbs+pos, mvbs+pos+1, (n-pos)*sizeof(movies));
  }
  else
    pos += 1;
}

Наш профессор сказал, что мы должны использоватьуказатели на структуры

Вы уже используетеуказатель, потому что вы не делаете, например, mooviebase[pos], а используете mvbs + offset , но этот указатель никогда не изменяется, и вам требуется дополнительное смещение, поэтому ваш указатель бесполезен, вы можете сделать, например:

movies * ptr = mooviebase;
movies * sup = mooviebase + n;

while (ptr != sup)
{
  if (yr == ptr->releaseYear)
  {
    if (ptr == --sup)
      /* it was the last entry */
      break;
    memmove(ptr, ptr+1, (sup - ptr)*sizeof(movies));
  }
  else
    ptr += 1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...