C : массив указателей на функции

#c #pointers

 

Вопрос:

Скажем, у нас есть 2 функции

 foo() { cout << "Hello"; }
foo2() { cout << " wolrd!"; }  

как я могу создать массив указателей (скажем a , b ), a указывающих на foo() и b на foo2() ? моя цель состоит в том, чтобы сохранить эти указатели в массиве A, а затем выполнить цикл над A для выполнения этих функций.

 

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

1. Поскольку вы используете C , а не C, используйте std::function не необработанные указатели.

2. @Jepessen Вам не нужно std::function столько времени, сколько требуется. Обычный тип указателя функции также будет работать для данного случая.

3. @Jepessen: нам следует избегать необработанного указателя на владение. обычный указатель может быть в порядке.

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

5. @Jarod42 my goal is to store these pointers in an array A, then loop over A to execute these functions. , на мой взгляд std::function , является лучшим, более чистым и безопасным решением для достижения его цели. Тогда, очевидно, можно использовать необработанные указатели.

Ответ №1:

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

using FunPtrType = void(*)();

FunPtrType arr[]{&foo,  &foo2};
// or
std::array<FunPtrType, 2> arr2{&foo,  &foo2};

// ... do something with the array of free function pointers
// example
for(auto fun: arr2)
    fun();

 

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

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

2. я получаю сообщение «неполный тип недопустим» в строке std::массивlt;FunPtrType, 2gt; arr2{amp;foo, amp;foo2}; есть идеи?

3. а ты #include lt;arraygt; ? Вам не нужно указывать параметры шаблона, начиная с C 17: godbolt.org/z/jMME54r75 Ах, и вы забыли указать тип возврата ваших функций foo() ==gt; void foo()

4. @eerorika (IMO) использование делает типы указателей функций более читаемыми, чем some retunr type(*)( a lot of arguments) легко редактируемыми во всей базе кода.

5. @eerorika дело стиля. Некоторые могут возразить, что void (*arr[])() {amp;foo, amp;foo2}; это менее читабельно. Это больше похоже на какую-то лямбду, пострадавшую от транспортного инцидента

Ответ №2:

Существует простая реализация:

 #include lt;iostreamgt; #include lt;vectorgt; using namespace std; // Defining test functions void a(){coutlt;lt;"Function A"lt;lt;endl;} void b(){coutlt;lt;"Function B"lt;lt;endl;}  int main() {  /*Declaring a vector of functions   Which return void and takes no arguments.  */  vectorlt;void(*)()gt; fonc;  //Adding my functions in my vector  fonc.push_back(a);  fonc.push_back(b);  //Calling with a loop.  for(int i=0; ilt;2; i  ){  fonc[i]();  }  return 0; }    

 

Ответ №3:

В наши дни нет необходимости в типах, просто используйте auto .

 #include lt;iostreamgt; void foo1() { std::cout lt;lt; "Hello"; } void foo2() { std::cout lt;lt; " world!"; } auto foos = { amp;foo1, amp;foo2 }; int main() { for (auto foo : foos) foo(); }  

 

Ответ №4:

Есть два эквивалентных способа сделать то, что вы хотите:

Способ 1

  #include lt;iostreamgt; void foo()  {   std::cout lt;lt; "Hello"; } void foo2()  {   std::cout lt;lt; " wolrd!";    }   int main() {    void (*a)() = foo;// a is a pointer to a function that takes no parameter and also does not return anything    void (*b)() = foo2;// b is a pointer to a function that takes no parameter and also does not return anything      //create array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter  void (*arr[2])() = { a, b};    arr[0](); // calls foo     arr[1](); //calls foo1    return 0; }   

Метод 1 может быть выполнен здесь.

Способ 2

  #include lt;iostreamgt; void foo()  {   std::cout lt;lt; "Hello"; } void foo2()  {   std::cout lt;lt; " wolrd!";    }   int main() {    //create array(of size 2) that can hold pointers to functions that does not return anything  void (*arr[2])() = { foo, foo2};    arr[0](); // calls foo     arr[1](); //calls foo1    return 0; }   

Способ 2 может быть выполнен здесь.