Funkcje#

Wstęp#

Funkcje są fundamentalnym elementem programowania w C++, umożliwiając pakowanie fragmentów kodu w wydajne, wielokrotnego użytku sekcje kodu, przeznaczone do wykonywania określonych zadań. Funkcje można wywoływać wielokrotnie w programie, co ułatwia organizację kodu i pomaga uniknąć jego powtarzania. Funkcje ułatwiają również debugowanie kodu.

Na tej stronie opisano podstawy korzystania z funkcji w C++, w tym:

Struktura i składnia funkcji#

W C++ funkcje muszą być deklarowane z typem zwracanym, nazwą i parametrami. Podstawowa składnia jest następująca:

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

Części funkcyjne

Opis

return_type

Typ danych zwracany przez funkcję. Oto kilka typowych opcji:

  • void — nie zwraca niczego
  • int — zwraca wartość całkowitą
  • double — zwraca liczbę zmiennoprzecinkową
  • bool — zwraca wartość true true lub false
  • char — zwraca pojedynczy znak
  • const char* — zwraca ciąg tekstowy
  • typy zdefiniowane przez użytkownika — zwracają obiekt struktury struct lub obiekt klasy

function_name

Nazwa funkcji.

parameters

Opcjonalnie. Lista parametrów typu, rozdzielona przecinkami, zapisana jako type name, gdzie type określa typ danych parametru, a name to identyfikator używany do uzyskania dostępu do tej wartości w funkcji. Parametry otrzymują wartości wejściowe po wywołaniu funkcji.

result

Opcjonalnie. Wartość zwracana przez funkcję. Jeśli argument return_type funkcji return_type jest różny od void, ta wartość musi zostać podana, a jej typ musi dokładnie odpowiadać podanemu argumentowi return_type return_type.

Uwaga: Funkcja musi zawsze zostać zadeklarowana przed jej wywołaniem lub należy podać prototyp funkcji.

Prototypy funkcji#

W C++ kod jest czytany od góry do dołu. Oznacza to, że funkcja musi być znana kompilatorowi, zanim będzie można ją wywołać.

Prototyp funkcji pozwala używać funkcji przed napisaniem jej pełnego kodu. Dzięki temu możesz zachować main() na początku programu, a definicje funkcji umieścić później, gdzie są łatwiejsze do uporządkowania i odczytania.

Bez prototypu konieczne byłoby zdefiniowanie każdej funkcji powyżej main(), co może utrudniać śledzenie projektów w miarę ich rozrastania się.

Zdefiniuj prototyp funkcji (poza int main())

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

Wywołaj funkcję wewnątrz int main()

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

  greeting();
}

Napisz ciało funkcji po

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

Definiowanie i wywoływanie funkcji#

Functions with No Parameters#

Jeśli funkcja nie wymaga danych wejściowych, można ją zdefiniować bez parametrów. Użyj void jako typu zwracanego, jeśli funkcja nie zwraca wartości.

Zdefiniuj funkcję (poza int main())

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

Wywołaj funkcję wewnątrz 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#

Do funkcji można również dodawać parametry, które umożliwiają przekazywanie informacji, które funkcja ma wykorzystać.

Uwaga: Tekst można przekazywać za pomocą ciągów w stylu języka C (const char*) lub ciągów w stylu języka C++ (std::string).

Zdefiniuj funkcję (poza int main())

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

Wywołaj funkcję z parametrem wewnątrz 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");
}

Wartości zwracane#

Funkcje mogą odsyłać dane do wywołującego za pomocą słowa kluczowego return Pozwala to na przechwytywanie i wykorzystywanie danych wyjściowych w projekcie.

Zdefiniuj funkcję (poza int main())

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

Wywołaj funkcję z parametrem wewnątrz 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));
}

Przechodząc przez odniesienie#

Domyślnie C++ przekazuje parametry funkcji przez wartość, co oznacza, że ​​funkcja otrzymuje kopię oryginalnej zmiennej. Zmiany wprowadzone wewnątrz funkcji nie wpływają na oryginalną wartość.

Zdefiniuj funkcję (poza int main())

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

Wywołaj funkcję z parametrem wewnątrz 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
}

Aby umożliwić funkcji modyfikację oryginalnej zmiennej, parametry można przekazać przez odniesienie, korzystając z symboli &.

Zdefiniuj funkcję (poza int main())

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

Wywołaj funkcję z parametrem wewnątrz 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
}

Przekazywanie przez odniesienie pozwala funkcjom na aktualizowanie zmiennych zdefiniowanych poza funkcją bez zwracania wartości.

Funkcje wywołania zwrotnego#

Funkcja wywołania zwrotnego to funkcja przekazywana do innej funkcji i wywoływana automatycznie po wystąpieniu określonego zdarzenia.

Wywołania zwrotne są powszechnie stosowane w przypadku zdarzeń takich, jak naciśnięcie przycisku lub aktualizacja czujnika.

Zamiast wywoływać funkcję samodzielnie, projekt wywołuje ją za Ciebie, gdy zdarzenie nastąpi.

Zdefiniuj funkcję wywołania zwrotnego (poza int main())

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

Zarejestruj wywołanie zwrotne wewnątrz 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#

Każda funkcja wywołania zwrotnego musi spełniać określony podpis, który definiuje:

  • Typ zwracany

  • Liczba parametrów

  • Typy parametrów

Wymagany podpis jest określany przez API. Funkcja wywołania zwrotnego musi dokładnie odpowiadać temu podpisowi.

// 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);

Nazwy parametrów mają charakter opisowy i mogą się różnić, ale typ zwracany, kolejność parametrów i typy parametrów muszą być dokładnie takie same.

Funkcje z argumentami domyślnymi#

Funkcje mogą definiować wartości domyślne dla jednego lub większej liczby parametrów. Argument domyślny jest używany, gdy podczas wywołania funkcji dla danego parametru nie podano wartości.

Zasady dotyczące argumentów domyślnych:

  • Domyślne argumenty muszą być ostatnimi parametrami w definicji funkcji.

  • Gdy parametr ma wartość domyślną, wszystkie parametry po nim również muszą mieć wartości domyślne.

  • Jeśli funkcja określa argumenty domyślne w swoim prototypie, wartości domyślne nie mogą być ponownie określone w definicji funkcji.

Zdefiniuj funkcję (poza 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();
    }
}

Wywołaj funkcję wewnątrz int main()

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

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

  Brain.Screen.newLine();

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