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

#c #arrays #function

#c #массивы #функция

Вопрос:

Я пытаюсь написать функцию, которая будет принимать несколько индексов и делать что-то на основе значений в массиве по этим индексам. Если я не объявляю массивы в качестве аргументов функции (которая всегда будет работать с одними и теми же двумя массивами) Я получаю, что X / Y не были объявлены в этой области, но если я попытаюсь их объявить, я получу «ошибка: объявление ‘X’ как многомерного массива должно иметь границы для всех измерений, кроме первого», и границы неизвестны до выполнения.

Есть ли какой-либо способ сделать это в функции, или я должен каждый раз явно писать код в main?

Код:

 double foo(int A, int B, int t){//A, B, and t are indices 
  int x = X[A][t]-X[B][t]; //X and Y are 2D arrays
  int y = Y[A][t]-Y[B][t];
  double d;
  //do some math ...
  return d;
}

int main{
.
.
.
int X[nPeople][tMax]={0};
int Y[nPeople][tMax]={0};
.
.
.
for(int t=0; t<tMax; t  ){
  for(int n=0; n<nPeople; n  ){
    foo(n,a,t);
  }
}
.
.
.
return 0;
}
  

Комментарии:

1. Предложение: распределять X и Y динамически

2. Используйте std::vector<std::vector<int>>

3. Если вы не передаете массивы в качестве аргументов, они должны быть глобальными…

4. Это массивы в стиле C. Весь фрагмент на самом деле является кодом C, а не C , иначе foo это был бы метод класса, где X и Y являются закрытыми членами, также довольно хорошо разрешающий области имен. Но для объявления без знания размера во время компиляции: да, либо создайте их int * и распределяйте динамически, либо сделайте их vector экземплярами для большей безопасности.

5. Re: ‘int X[nPeople][tMax]={0};» — если размеры массива неизвестны во время компиляции, этот код недопустим на C . Некоторые компиляторы предоставляют такое чудовище, как расширение. Как говорили другие, используйте std::vector . Это то, для чего она была разработана.

Ответ №1:

Существует несколько способов:

1- Используйте встроенную библиотеку std::vector со следующим включением:

 #include <vector>
  

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

 std::vector<std::vector<int> > 
  

2. Используйте глобальные переменные. Переменные, которые объявлены вне функций, считаются глобальными, поэтому они будут видны каждой функции под ней. Хотя это не считается хорошей практикой кодирования из-за ошибок, которые это может вызвать в крупномасштабной проблеме, если вы достаточно уверены, что это не будет представлять угрозы для безопасности / чистоты вашего кода, продолжайте использовать это!

3. Используйте динамически распределяемые массивы и передавайте указатели в качестве параметров, чтобы вы могли работать с любым размером, который вы хотите

Ответ №2:

Существует несколько способов, которыми функция может работать с данными:

  • Используйте глобальные данные:

     std::vector<std::vector<int>> X;
    std::vector<std::vector<int>> Y;
    
    double foo(int A, int B, int t){ //A, B, and t are indices 
      int x = X[A][t]-X[B][t]; // X and Y are global 2D arrays
      int y = Y[A][t]-Y[B][t];
      double d;
      //do some math ...
      return d;
    }
      

    к сожалению, показано слишком много раз в примере кода, но (изменяемый) глобальный имеет много проблем (трудно тестировать, трудно повторно использовать код, трудно рассуждать о коде)

  • Передайте их в качестве аргументов:

     double foo(const std::vector<std::vector<int>>amp; X, // X and Y are 2D arrays
    
               const std::vector<std::vector<int>>amp; Y, // As we can see, so unneeded comment
               int A, int B, int t){ //A, B, and t are indices 
      int x = X[A][t]-X[B][t];
      int y = Y[A][t]-Y[B][t];
      double d;
      //do some math ...
      return d;
    }
      
  • свяжите их с помощью класса:

     class C
    {
        std::vector<std::vector<int>> X;
        std::vector<std::vector<int>> Y;
     public:
        double foo(int A, int B, int t){ //A, B, and t are indices 
          int x = X[A][t]-X[B][t]; // X and Y are member 2D arrays (it should be trivial (`this->` might help), so comment not needed neither)
          int y = Y[A][t]-Y[B][t];
          double d;
          //do some math ...
          return d;
        }
    };
      

    позаботьтесь о создании согласованных классов и избегайте класса god (которые в основном имеют то же значение по умолчанию, что и global).