Изменение размера 1D и 2D массива переменной длины - PullRequest
0 голосов
/ 01 марта 2019

С включением массивов переменной длины в C99 и последующих версиях работает следующая программа.

#include <stdio.h>

int main(void)
{
    int i, numFibs;
    printf ("How many Fibonacci numbers do you want (between 1 and 75)? ");
    scanf ("%i", &numFibs);
    if (numFibs < 1 || numFibs > 75) 
    {
        printf ("Bad number, sorry!\n");
        return 1;
    }
    unsigned long long int   Fibonacci[numFibs];
    Fibonacci[0] = 0;          // by definition
    Fibonacci[1] = 1;          // ditto
    for ( i = 2;  i < numFibs;  ++i )
    {
        Fibonacci[i] = Fibonacci[i-2] + Fibonacci[i-1];
    }
    for ( i = 0;  i < numFibs;  ++i )
    {
        printf ("%llu  ", Fibonacci[i]);
        printf ("\n");
    }
    return 0;
}

Но когда я пытаюсь реализовать следующую программу, она работает нормально до <= 9, при любом значении> 9 программа не занимает более 9 элементов в массиве.

Почему?

#include <stdio.h>

int main()
{
    int a=0;
    int arr[a];
    printf("Enter number of rows: ");
    scanf("%d", &a);
    printf("\nNo of rows to be entered: %d\n", a);
    for(int j=0; j<a; j++)
    {
        printf("Enter array element[%d]: ", j);
        scanf("%d", &arr[j]);
    }
    for(int j=0; j<a; j++)
    {
        printf("Entered array element [%d]: %d", j, arr[j]);
        printf("\n");
    }
    return 0;
}

Ниже приведен пример для двумерного массива, который работает до тех пор, пока значение b <= 2, после того, как программа завершится с ошибкой сегментации.Почему? </p>

#include <stdio.h>

int main()
{
    int b=0;
    int arr[b][2];
    printf("Enter number of rows: ");
    scanf("%d", &b);
    printf("No of rows to be entered: %d", b);
    for(int i=0; i<b; i++)
    {
        for(int j=0; j<2; j++)
        {
            printf("Enter array element[%d][%d]: ", i, j);
            scanf("%d", &arr[i][j]);
        }
    }
    printf("\n");
    for(int i=0; i<b; i++)
    {
        for(int j=0; j<2; j++)
        {
            printf("Enter array element[%d][%d]: %d", i, j, arr[i][j]);
            printf("\n");
        }
    }
    return 0;
}

В приведенном выше примере динамическое получение строки и столбца будет неправильным, но динамическое получение строки работает.если вы берете столбцы динамически, это также приведет к сбою.

Есть ли другой способ решения этих проблем без malloc ()?

Версия GCC, работающая на компьютере: -

C: \ Users \ gahlot> gcc -v Использование встроенных спецификаций.COLLECT_GCC = gcc COLLECT_LTO_WRAPPER = c: / mingw / bin /../ libexec / gcc / mingw32 / 6.3.0 / lto-wrapper.exe Цель: mingw32 Настраивается с помощью: ../src/gcc-6.3.0/configure -build = x86_64-pc-linux-gnu --host = mingw32 --target = mingw32 --with-gmp = / mingw --with-mpfr --with-mpc = / mingw --with-isl = / mingw -префикс = / mingw --disable-win32-registry --with-arch = i586 --with-tune = универсальный --enable-languages ​​= c, c ++, objc, obj-c ++, fortran, ada --with-pkgversion ='MinGW.org GCC-6.3.0-1' --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs--with-libiconv-prefix = / mingw --with-libintl-prefix = / mingw --enable-libstdcxx-debug --enable-libgomp --disable-libvtv --enable-nls Модель потока: win32 gcc версия 6.3.0 (MinGW.org GCC-6.3.0-1)

Ответы [ 2 ]

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

Это не делает то, что вы думаете:

int a=0;
int arr[a];
printf("Enter number of rows: ");
scanf("%d", &a);

Как только массив определен с заданным размером, даже если этот размер не является константным выражением, размер массива фиксирован,Размер не привязан к текущему значению a.Также недопустимо создавать массив размером 0.

Это прописано в разделе 6.7.6.2p5 стандарта C:

Если размер является выражением, котороене является целочисленным константным выражением: если оно встречается в объявлении в области действия прототипа функции, оно обрабатывается так, как если бы оно было заменено *;в противном случае каждый раз, когда он оценивается, он должен иметь значение больше нуля.Размер каждого экземпляра типа массива переменной длины не изменяется в течение его времени жизни.

В этом случае размер массива определяется одной переменной, однако размер можетопределяться любым выражением.Например:

int f()
{
    int a, b, c;
    scanf("%d", &a);
    b=3;
    c=9;
    return sqrt(a) * (b - c) + sin(b);
}

...

int arr[f()];

Если вы определили arr таким образом, даже если бы вы могли изменить размер, как бы вы ожидали, что это произойдет?

Что касается ваших вторых и третьих частейкода иногда работает, а иногда нет, это означает, что вы вызываете неопределенное поведение .В обоих случаях это вызвано созданием массива, в котором хотя бы одно измерение равно 0, и последующей попыткой его использовать.

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

Размер VLA определяется в точке, где встречается объявление.

  • Вы не можете изменить их размер впоследствии
  • Выражение размера не должно иметь значение0 или даже быть отрицательным.
...