Функции#

Введение#

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

На этой странице рассматриваются основы использования функций в C++, включая:

Структура и синтаксис функций#

В C++ функции должны быть объявлены с указанием типа возвращаемого значения, имени и параметров. Базовый синтаксис выглядит следующим образом:

return_type function_name(parameters) {
  // Code to execute when the function is called
  return result;  // Optional, used to return a value
}

Функциональные части

Описание

return_type

Тип данных, возвращаемый функцией, некоторые распространенные варианты:

  • void — Ничего не возвращает
  • int — Возвращает целое число
  • double — Возвращает число с плавающей запятой
  • bool — Возвращает true или false
  • char — Возвращает один символ
  • const char* — Возвращает текстовую строку
  • пользовательские типы — Возвращает struct или объект класса

function_name

Название функции.

parameters

Необязательно. Разделенный запятыми список типизированных параметров, записанный как type name, где type указывает тип данных параметра, а name — идентификатор, используемый для доступа к этому значению внутри функции. Параметры получают входные значения при вызове функции.

result

Optional. The value returned by the function. If the function’s return_type is not void, this value must be provided and its type must exactly match the specified return_type.

Примечание: Функция всегда должна быть объявлена ​​до ее вызова, или вы должны предоставить прототип функции.

Функциональные прототипы#

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

Прототип функции позволяет использовать функцию до написания её полного кода. Это позволяет размещать main() в начале программы, а определения функций — позже, где их легче организовать и прочитать.

Без прототипа вам пришлось бы определять каждую функцию выше main(), что может затруднить отслеживание проекта по мере его развития.

Определите прототип функции (вне int main())

// The function's prototype
void greeting();

Вызов функции внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  greeting();
}

Тело функции следует написать после

void greeting() {
  Brain.Screen.print("Hello!");
}

Определение и вызов функций#

Functions with No Parameters#

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

Определите функцию (вне int main())

// Define a function to display a message
void greeting() {
    Brain.Screen.print("Hello!");
}

Вызов функции внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Call the function to display the message
  greeting();
}

Functions with Parameters#

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

Примечание: Текст можно передавать с помощью строк в стиле C (const char*) или строк C++ (std::string).

Определите функцию (вне int main())

// Define a function with a parameter
void namedGreeting(const char* name) {
    Brain.Screen.print("Hello, %s!", name);
}

Вызовите функцию с параметром внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Call the function to display the message
  namedGreeting("Stranger");
}

Возвращаемые значения#

Функции могут отправлять данные обратно вызывающей стороне, используя ключевое слово `return ). Это позволяет перехватывать и использовать выходные данные в вашем проекте.

Определите функцию (вне int main())

// Define a function that multiplies numbers by 2
int timesTwo(int number) {
    return number * 2;
}

Вызовите функцию с параметром внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Display the return value
  Brain.Screen.print("%d", timesTwo(2));
}

Проходя мимо ссылки#

По умолчанию в C++ параметры функции передаются по значению, то есть функция получает копию исходной переменной. Изменения, внесенные внутри функции, не влияют на исходное значение.

Определите функцию (вне int main())

// Add 1 to the number
void addOne(int number) {
  number++;
}

Вызовите функцию с параметром внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  int value = 5;
  addOne(value);
  // "value" will still be 5
}

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

Определите функцию (вне int main())

// Add 1 to the number
void addOne(int& number) {
  number++;
}

Вызовите функцию с параметром внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  int value = 5;
  addOne(value);
  // "value" will now be 6
}

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

Функции обратного вызова#

Функция обратного вызова — это функция, которая передается в другую функцию и вызывается автоматически при возникновении определенного события.

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

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

Определите функцию обратного вызова (вне int main())

// Create a callback function
void onPressed() {
  Brain.Screen.print("Screen pressed!");
}

Зарегистрируйте функцию обратного вызова внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Call onPressed whenever the screen is pressed
  Brain.Screen.pressed(onPressed);
}

Callback Signatures#

Каждая функция обратного вызова должна соответствовать определенной сигнатуре, которая определяет:

  • Тип возвращаемого значения

  • Количество параметров

  • Типы параметров

Требуемая подпись определяется API. Функция обратного вызова должна точно соответствовать этой подписи.

// This callback function cannot include any parameters
void callback(void);

// This callback function includes four parameters
void callback(axisType axis, double x, double y, double z);

Названия параметров являются описательными и могут различаться, но тип возвращаемого значения, порядок параметров и типы параметров должны точно совпадать.

Функции с аргументами по умолчанию#

Функции могут задавать значения по умолчанию для одного или нескольких параметров. Аргумент по умолчанию используется, если при вызове функции для этого параметра не указано значение.

Правила для аргументов по умолчанию:

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

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

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

Определите функцию (вне int main())

// Required parameter first, default parameter last
void greeting(const char* name, int repeatCount = 1) {

    for (int i = 0; i < repeatCount; i++) {
        Brain.Screen.print("Hello, %s!", name);
        Brain.Screen.newLine();
    }
}

Вызов функции внутри int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Say what name to greet (EXP) and
  // use default value for repeatCount (1)
  greeting("EXP");

  Brain.Screen.newLine();

  // Overrides the default value to 3
  greeting("EXP", 3);
}

// Required parameter first, default parameter last
void greeting(const char* name, int repeatCount = 1) {

    for (int i = 0; i < repeatCount; i++) {
        Brain.Screen.print("Hello, %s!", name);
        Brain.Screen.newLine();
    }
}

int main() {
    vexcodeInit();

    // Say what name to greet (EXP) and
    // use default value for repeatCount (1)
    greeting("EXP");

    Brain.Screen.newLine();

    // Overrides the default value to 3
    greeting("EXP", 3);
}