Вернуть массив со всеми целыми числами от a до b - PullRequest
10 голосов
/ 12 апреля 2011

В упражнении написано «Создайте функцию с двумя параметрами 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. В чем проблема? Спасибо

Ответы [ 9 ]

7 голосов
/ 12 апреля 2011

Для начинающих

Если ваш 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++;

в противном случае вы печатаете «следующий» элемент массива каждый раз, который будет один за концом массива на последней итерации цикла.

Задача 2

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

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

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

int d[b-a+1];

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

Что я подразумеваю под динамическим размером?

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

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

Решение

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

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, поэтому готовый код может иметь несколько синтаксических ошибок.

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

3 голосов
/ 12 апреля 2011

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

Обновление:

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

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

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

2 голосов
/ 12 апреля 2011

Выполнение домашних заданий у кого-то всегда плохо, но, очевидно, 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;
}
2 голосов
/ 12 апреля 2011

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

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

2 голосов
/ 12 апреля 2011

Порядок выписок неверен

  d[k]=i;                          // d[0] = 42;
  k++;                             // ...
  printf("%d ",d[k]);              // print d[1]
1 голос
/ 12 апреля 2011

Вы неправильно объявляете массив 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.

0 голосов
/ 12 апреля 2011

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

0 голосов
/ 12 апреля 2011

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

0 голосов
/ 12 апреля 2011

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

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

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