Обращение структурированного массива с помощью рекурсивной функции - PullRequest
1 голос
/ 30 января 2020

Итак, я получил эту структуру

typedef struct Sarray{
  int *items;
  int size;
}Tarray;

Учитывая массив типа [1] [2] [3] [4] [5]

я построил такую ​​функцию

void ArrayReverse (Tarray *a){
    int tmp,i;
    if (a->size<=1)
        return;
    tmp=(a->items[0]);
    (a->items[0])=(a->items[a->size]);
    (a->items[a->size])=tmp;
    a->size=a->size-1;

    ArrayReverse(a+1);
}

Результат странный

0 2 3 4 5

Идея состояла в том, чтобы дать следующий адрес (a + 1), чтобы a-> items [0] было бы 2 во втором цикле. Что не так, как я могу это реализовать?

Ответы [ 2 ]

1 голос
/ 30 января 2020

В этих операторах

(a->items[0])=(a->items[a->size]);
(a->items[a->size])=tmp;

вы получаете доступ к памяти за пределами выделенного массива, поскольку действительный верхний индекс равен a->size - 1.

Вместо уменьшения члена данных size на один

a->size=a->size-1;

Вы должны уменьшить его на два.

a->size=a->size-2;

Кроме того, функция изменяет значения элементов данных size и items исходного объекта, переданных в качестве аргумента. Поэтому после выхода из функции состояние исходного объекта будет изменено.

И это выражение

a+1

не имеет смысла, поскольку вы передали функции указатель на один объект тип Tarray.

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

#include <stdio.h>
#include <stdlib.h>

typedef struct Sarray
{
    int *items;
    size_t size;
} Tarray;

void ArrayReverse ( Tarray *t )
{
    if ( ! ( t->size < 2 ) )
    {
        int tmp = t->items[0];
        t->items[0] = t->items[t->size - 1];
        t->items[t->size - 1] = tmp;

        t->size -= 2;
        ++t->items;

        ArrayReverse( t );

        t->size += 2;
        --t->items;
    }
}

int main(void) 
{
    Tarray t = { 0 };
    size_t n = 5;

    t.items = malloc( n * sizeof( int ) );

    if ( t.items != NULL ) t.size = n;

    for ( size_t i = 0; i < t.size; i++ )
    {
        t.items[i] = ( int )( i + 1 );
    }

    ArrayReverse( &t );

    for ( size_t i = 0; i < t.size; i++ )
    {
        printf( "%d ", t.items[i] );
    }

    putchar( '\n' );

    free( t.items );

    return 0;
}

Выход программы:

5 4 3 2 1
0 голосов
/ 30 января 2020

Новая версия кода является этой.

void ArrayReverse (Tarray *a,int i){
int tmp;
if(a->size <= a->lenght/2)
    return;
tmp=a->items[i];
a->items[i]=a->items[a->size-1];
a->items[a->size-1]=tmp;
a->size=a->size-1;
i++;
ArrayReverse(a,i);}

Я изменил прототип функции со счетчиком i.

...