Фибоначчи и возвращение массива - PullRequest
0 голосов
/ 21 апреля 2011
long fibonacci(int ceiling)
{
  int counter;
  long num1 = 1, num2 = 1, sum;
  int arr[ceiling+1];
  for (counter = 1; counter < ceiling; counter++)
    {
      arr[counter] = num1;
      //printf("%d\n", num1); //prints sequence
      sum = num1+num2;
      num1 = num2;
      num2 = sum;
    }
  return arr;
}

Прямо сейчас, если я попытаюсь получить доступ к этому массиву, скажем, с помощью int a = fibonacci(10);, он без жалоб. Однако, если я пытаюсь получить доступ к отдельному элементу, например, a[1], он говорит мне, что

подписанное значение не является ни массивом, ни указателем

Что я делаю не так?

Ответы [ 7 ]

4 голосов
/ 21 апреля 2011

.. если я пытаюсь получить доступ к отдельному элементу, например, [1], или что-то еще.

int a = fibonacci(10);

a - целочисленная переменная, а не массив дляиспользуйте оператор [] для него.

Определение метода должно быть -

int* fibonacci(int ceiling)
{
    // ...
    return arr ;
}

int *a = fibonacci(10) ;

Теперь вы можете использовать оператор [] для a. Однако то, что вы возвращаете, является ссылкой на локальную переменную (то есть, находящуюся в стеке), которая является неправильной.Вы должны динамически распределять память для массива, используя malloc, а затем free it.

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

Вы не можете вернуть массив как таковой из функции в C (или C ++).

То, что в настоящее время делает ваш код: он неявно распадает массив int [] на указатель int *, а затем неявно преобразует int * в long, а затем возвращает long. Это не указатель или массив, и, следовательно, оператор индекса не может быть применен к нему.

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

Вы можете:

  • выделить массив с помощью malloc () и вернуть указатель (но затем вы должны выяснить, кто собирается освободить () выделение, и убедиться, что это произойдет ровно один раз); или

  • передать указатель на массив и заполнить массив этим указателем (теперь вызывающий объект отвечает за создание и управление массивом) - это, вероятно, обычный подход в C; или

  • создать структуру, которая оборачивает массив, и вернуть один из них (или, в этом отношении, передать указатель на один).

Также обратите внимание, что int arr[ceiling + 1]; является конструкцией C99; это не допускается ни в стандартном «традиционном» C (C89 и т. д.), ни в стандартах C ++. В этих языках размер массивов должен быть известен во время компиляции.

В C ++ вы также можете передавать массив по ссылке или использовать boost::array (который является «структурой, которая оборачивает массив», но также использует перегрузку операторов, чтобы сделать его более прозрачным, как массив).

1 голос
/ 21 апреля 2011

Самый простой способ решить эту проблему - выделить массив на месте вызова и передать его в функцию Фибоначчи для заполнения.

void fibonacci(int n, int arr[])
0 голосов
/ 21 апреля 2011

Лучшая версия с исправленными ошибками:

#include <stdio.h>
int fibonacci(int ceiling, int *arr)
{
  int counter;
  long num1 = 1, num2 = 1, sum;
  if(arr == NULL)
      return -1;
  for (counter = 0; counter < ceiling; counter++) {
      arr[counter] = num1;
      //printf("%d\n", num1); //prints sequence
      sum = num1+num2;
      num1 = num2;
      num2 = sum;
  }
  return 0;
}
int main (int argc, char const* argv[])
{
    int ceiling = 10;
    int arr[ceiling + 1];
    fibonacci(ceiling, arr);
    return 0;
}
0 голосов
/ 21 апреля 2011

Более важно, чем то, что было сказано, вы должны подумать о распределении памяти.Использование только int arr[ceiling+1]; создаст память для переменной с областью действия в этой функции.Поэтому вы можете вернуть указатель на массив в ячейке памяти, который может быть перезаписан.Вместо этого используйте malloc

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

Он должен возвращать long *, а arr должен быть long *, который захватывает память из кучи, так как a) вы хотите, чтобы ваш массив сохранялся после возврата функции и b) все ваши операнды имеют тип long:

long* fibonacci(int ceiling)
{
  int counter;
  long num1 = 0, num2 = 1, sum; //F is seeded with F(0) = 0, F(1) = 1
  long* arr = malloc((ceiling+1)*sizeof(long));
  //include ceiling in the loop since you have ceiling+1 elements
  for (counter = 0; counter <= ceiling; counter++)
    {
      arr[counter] = num1;
      //printf("%d\n", num1); //prints sequence
      sum = num1+num2;
      num1 = num2;
      num2 = sum;
    }
  return arr;
}
0 голосов
/ 21 апреля 2011

Вы должны вернуть int [], а не long

EDIT: Извините, смешанный C #:)

int* fibonacci(int ceiling)
....

// вызов

int *a = fibonacci (10);
int val = a[20];
...