0Pricing
C++ Academy · Урок

Указатели на функции

Передавайте функции как аргументы

«Указатели на функции» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Что такое указатель на функцию?

Указатель на функцию хранит адрес функции, чтобы Вы могли косвенно вызвать её или передать как данные.

  • Тип кодирует сигнатуру.
  • Он позволяет функциям принимать поведение в качестве параметра.
#include <iostream>

int add(int a, int b) { return a + b; }

int main() {
    int (*op)(int, int) = add;
    std::cout << op(3, 4) << '\n';
    return 0;
}

Объявление типа

Объявление int (*op)(int, int) читается так: op — указатель на функцию, принимающую два целых числа и возвращающую целое число. Круглые скобки вокруг *op обязательны.

#include <iostream>

int square(int x) { return x * x; }

int main() {
    int (*fn)(int) = square;
    std::cout << fn(5) << '\n';
    return 0;
}

Вызов через указатель

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

#include <iostream>

void greet() { std::cout << "Hello\n"; }

int main() {
    void (*g)() = greet;
    g();
    (*g)();
    return 0;
}

Передача функций в качестве аргументов

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

#include <iostream>

int apply(int x, int (*fn)(int)) { return fn(x); }
int doubler(int n) { return n * 2; }

int main() {
    std::cout << apply(10, doubler) << '\n';
    return 0;
}

Выбор во время выполнения

Поскольку указатель на функцию является переменной, Вы можете решить, какую функцию вызвать, пока программа выполняется.

#include <iostream>

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int main() {
    bool wantAdd = true;
    int (*op)(int, int) = wantAdd ? add : sub;
    std::cout << op(8, 3) << '\n';
    return 0;
}

Массивы указателей на функции

Храните несколько указателей на функции в массиве, чтобы создать простую таблицу диспетчеризации, индексируемую значением.

#include <iostream>

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }

int main() {
    int (*ops[2])(int, int) = {add, mul};
    std::cout << ops[0](2, 3) << ' ' << ops[1](2, 3) << '\n';
    return 0;
}

Использование typedef

Синтаксис указателя перегружен. Псевдоним typedef или using присваивает типу понятное имя.

#include <iostream>

using BinOp = int(*)(int, int);
int add(int a, int b) { return a + b; }

int main() {
    BinOp op = add;
    std::cout << op(6, 7) << '\n';
    return 0;
}

Указатели на функции и алгоритмы

Стандартные алгоритмы принимают вызываемые объекты, и обычная функция подходит в качестве такого объекта. Здесь предикат подсчитывает четные числа.

#include <iostream>
#include <vector>
#include <algorithm>

bool isEven(int n) { return n % 2 == 0; }

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5, 6};
    int c = std::count_if(v.begin(), v.end(), isEven);
    std::cout << "Evens: " << c << '\n';
    return 0;
}

Ограничение: нет состояния

Обычный указатель на функцию не может хранить захваченные данные. Если Вам нужно сохранять контекст между вызовами, используйте глобальные переменные или перейдите к более функциональным вызываемым объектам.

#include <iostream>

int counter = 0;
int next() { return ++counter; }

int main() {
    int (*fn)() = next;
    std::cout << fn() << ' ' << fn() << ' ' << fn() << '\n';
    return 0;
}

Преобразование лямбд без захвата

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

#include <iostream>

int main() {
    int (*fn)(int) = [](int x) { return x + 100; };
    std::cout << fn(1) << '\n';
    return 0;
}

Нулевые указатели на функции

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

#include <iostream>

int main() {
    int (*fn)(int) = nullptr;
    if (fn) {
        std::cout << fn(5) << '\n';
    } else {
        std::cout << "No function set\n";
    }
    return 0;
}

Быстрая проверка

Проверьте своё понимание ограничений указателей на функции.

Повторение

Вы узнали об указателях на функции:

  • они хранят адрес функции и вызываются так же, как сама функция
  • они позволяют передавать поведение в качестве параметра и создавать таблицы диспетчеризации
  • псевдонимы делают их тип понятным
  • они не могут хранить состояние, но лямбды без захвата преобразуются в них

Далее Вы познакомитесь с std::function, который может хранить любой вызываемый объект, в том числе объект с состоянием.

Часто задаваемые вопросы

Урок «Указатели на функции» бесплатный?

Да — полный текст урока «Указатели на функции» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Указатели на функции»?

Передавайте функции как аргументы Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Указатели на функции»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Указатели на функции
  2. std::function
  3. std::bind
  4. Выбор вызываемых объектов
← Назад к C++ Academy