Возвращает массив со всеми целыми числами от a до b

В упражнении сказано: "Создайте функцию с двумя параметрами a и b, которые являются целыми числами, и функция вернет массив целых чисел с каждым числом от a до b.

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

void exc(int a, int b){
  int i,k=0,d[k];
  for(i=a;i<=b;i++){
  d[k]=i;
  k++;
  printf("%d ",d[k]);
  }
}

int main(void){
 int c,d;
 printf("Give first integer: ");
 scanf("%d",&c);
 printf("Give second integer: ");
 scanf("%d",&d);
 exc(c,d);
 system("pause");
}

Проблема в том, что если я ставлю, например, c = 2 и d = 5, программа вернет что-то вроде 2088806975 16384 1 2293536 вместо 2 3 4 5. Где проблема? Благодаря

Ответ 1

Для начала

Если ваш main() имеет тип возврата int, не забывайте return значение из него!

int main(void)
{
   /* code here */

   return 0;
}

Проблема 1

По

d[k]=i;
k++;
printf("%d ", d[k]);

Я думаю, вы имели в виду

d[k]=i;
printf("%d ", d[k]);
k++;

в противном случае вы будете печатать каждый элемент массива "next" каждый раз, который будет последним концом массива на последней итерации цикла.

Проблема 2

int i,k=0,d[k];

Вы создаете массив d размера k, где k равно 0. Я думаю, вы предназначались для автоматического изменения размера массива при написании k++, но это не так. Массив создается с нулевыми элементами, а затем его размер на все время.

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

int d[b-a+1];

К сожалению, это, скорее всего, тоже неверно. Он использует функцию Variable Length Arrays (или "VLAs" ); хотя расширение компилятора GCC (и, кстати, C99) действительно разрешает это (и неясно, включено ли у вас это расширение и/или разрешено использовать его в вашей домашней работе), я буду считать, что вы не выполняете/не выполняете не), сам язык не позволяет массив с динамическим размером.

Что я могу сказать о динамическом размере?

Я имею в виду, что переменные a и b зависят от пользовательского ввода: они неизвестны во время компиляции. В общем случае размер массива должен быть известен во время компиляции.

Примечание. Если вы используете это, ваш код может компилироваться без ошибок, и ваша программа может даже казаться запущенной и работать корректно. Однако вы будете полагаться на то, что называется "Undefined Behavior", и ваш код может перестать работать или даже сбой в любое время из-за любого числа случайных, непредсказуемых факторов. Даже если это выглядит так, недействительно. Не делай этого!

Решение

К счастью, есть способ выделить блок памяти с правильным размером для ваших элементов, когда вы не знаете элементы до запуска вашей программы. Он называется "динамическое распределение", и он включает вызов функции:

int *d = malloc(sizeof(int) * (b-a+1));

Вы можете использовать тот же синтаксис (d[k]) для доступа к "элементам" в этом "массиве" или блоке памяти, но впоследствии вы должны вручную освободить память:

free(d);

Возможная проблема 3

Ваше задание говорит о возврате массива из функции, но вы этого не делаете. Вместо этого вы просто создаете, заполняете и печатаете массив в одной и той же функции (что кажется немного бессмысленным).

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

Если это так, готовый код выглядит примерно так:

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

int *exc(int a, int b)
{

  int i, k = 0;
  int *d = malloc(sizeof(int) * ((b-a)+1));

  for (i=a; i<=b; i++) {
     d[k]=i;
     k++;
  }

  return d;
}

int main(void)
{
 int a,b,i,*ar;

 printf("Give first integer: ");
 scanf("%d",&a);
 printf("Give second integer: ");
 scanf("%d",&b);

 ar = exc(a,b);

 for (i=0; i < (b-a+1); i++) {
    printf("%d ", ar[i]);
 }

 free(ar);

 system("pause");
 return 0;
}

Отказ от ответственности: я ржавый на C, поэтому в готовом коде могут быть несколько синтаксических ошибок.

Надеюсь, это поможет!

Ответ 2

Размер d всегда равен 0. Так как вы инициализируете его как d[k]. Вместо этого вы должны сделать что-то вроде d[b-a+1].

Update:

Кроме того, порядок ваших утверждений неверен, см. ответ pmg.

Обновление 2:

Ваш код фактически не возвращает массив, который вы создаете, и он не будет работать, если вы не создадите массив в куче (т.е. используя malloc/бесплатно).

Ответ 3

Порядок инструкций неверен

  d[k]=i;                          // d[0] = 42;
  k++;                             // ...
  printf("%d ",d[k]);              // print d[1]

Ответ 4

Сначала необходимо выделить память для массива, используйте malloc с количеством целых чисел, которые вам нужно назначить

Кроме того, чтобы быть верным оператору проблемы, функция возвращает указатель на массив, поэтому основная функция может распечатать его, а не выполнять функцию exec.

Ответ 5

Выполнение домашней работы somebodys всегда несколько плохое, но, очевидно, OP не имеет понятия, как подходить к этой конкретной проблеме, поэтому здесь приведен полный пример распределения динамической памяти (чрезмерно прокомментированный).

#include <stdio.h>
#include <stdlib.h> /* required for malloc() and free() */

/* function that retuns a pointer to int type of data */
int *create_array(int a, int b)
{
    int *array;
    int array_size = b - a + 1; /* assuming that 'a' is always smaller than 'b' */
    int i;

    array = malloc( array_size * sizeof(int) ); /* allocate memory for the array */
    if(array == NULL) exit(EXIT_FAILURE); /* bail out if allocation fails */

    /* assign the values into array */
    for(i = 0; i < array_size; ++i)
        array[i] = a++;

    /* return a pointer to our allocated array */
    return array;
}

int main(void)
{
    int *array;
    int i, a = 42, b = 50;

    /* and now we can call the function to create the array */
    array = create_array(a, b);

    /* print results */
    for(i = 0; i < b - a + 1; ++i)
        printf("%d\n", array[i]);

    /* always remember to free the data after you are done with it */
    free(array); 

    return 0;
}

Ответ 6

Вы неправильно объявляете массив d в своем коде:

int d[k];

должен быть:

int d[b-a+1];

Edit:

Кроме того, как и другие опубликованные, неправильный порядок показа:

d[k]=i;
k++;
printf("%d ",d[k]);

должен быть:

d[k]=i;
printf("%d ",d[k]);
k++;

потому что иначе вы "теряете" первое значение, когда k==0.

Ответ 7

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

Вы получаете доступ к данным из памяти за пределами безопасности определенного хранилища данных. Это должно быть ошибка, потому что результаты не определены. Данные за конец вашего массива могут быть использованы для чего угодно. И так как ваш массив равен нулю, все заканчивается.

Ответ 8

Есть пара проблем. Во-первых, d не возвращается из exc. Конечно, вы не должны просто возвращать его с момента его выделения в стеке. Во-вторых, printf вызывается после того, как вы увеличиваете k. Это печатает следующий элемент в d, а не тот, значение которого вы только что заполнили. Наконец, d не имеет выделенного для него пространства, так как k всегда 0, когда создается d.

Ответ 9

Это происходит потому, что вы выделяете память для d в стеке. Если вы переместите объявление этого объекта вне функции, все будет в порядке.