2.3 — Funkcje puste (funkcje nie zwracające wartości)

W poprzedniej lekcji (2.1 -- Wprowadzenie do funkcji) wskazaliśmy, że składnia definicji funkcji wygląda następująco:

returnType identifier() // identifier replaced with the name of your function
{
// Your code here
}

Chociaż pokazaliśmy przykłady funkcji, które mają typ zwracany void, nie omawialiśmy, co to oznacza. W tej lekcji omówimy funkcje zwracane przez typ void.

Void zwracane wartości

Funkcje nie są wymagane do zwracania wartości do obiektu wywołującego. Aby poinformować kompilator, że funkcja nie zwraca wartości, używany jest typ zwracany void . Na przykład: funkcja

#include <iostream>

// void oznacza, że funkcja nie zwraca wartości wywołującemu
void printHi()
{
    std::cout << "Hi" << '\n';

    // Ta funkcja nie zwraca wartości, więc nie ma instrukcji return potrzebne
}

int main()
{
    printHi(); // OK: funkcja printHi() jest wywoływana, żadna wartość nie jest zwracana

    return 0;
}

W powyższym przykładzie funkcja printHi ma przydatne zachowanie (wypisuje „Cześć”), ale nie musi zwracać niczego do osoby wywołującej. Dlatego printHi otrzymuje void typ powrotu.

Po wywołaniu main wywołania printHi, kod w printHi wykonuje się i zostaje wydrukowane „Hi”. Na koniec printHi sterowanie powraca do main i program kontynuuje działanie.

Funkcja, która nie zwraca wartości, nazywa się funkcja nie zwracająca wartości (lub funkcja pusta).

Funkcja Void nie potrzebuje instrukcji return

Funkcja void automatycznie powróci do osoby wywołującej na końcu funkcji. Nie ma instrukcji return. wymagane.

Instrukcja return (bez wartości zwracanej) może zostać użyta w funkcji void -- taka instrukcja spowoduje powrót funkcji do osoby wywołującej w momencie wykonania instrukcji return. To samo dzieje się na końcu funkcji. W związku z tym umieszczanie pustej instrukcji return na końcu funkcji void jest zbędne:

#include <iostream>

// void oznacza, że funkcja nie zwraca wartości wywołującemu
void printHi()
{
    std::cout << "Hi" << '\n';

    return; // powiedz kompilatorowi, aby wrócił do wywołującego - jest to zbędne, ponieważ powrót i tak nastąpi na końcu funkcji!
} // funkcja zwróci tutaj funkcję wywołującą

int main()
{
    printHi();

    return 0;
}

Najlepsza praktyka

Nie umieszczaj instrukcji return na końcu funkcji zwracanej bez wartości. funkcja.

Funkcji pustych nie można używać w wyrażeniach wymagających wartości

Niektóre typy wyrażeń wymagają wartości. Na przykład:

#include <iostream>

int main()
{
    std::cout << 5; // ok: 5 to literał, który wysyłamy do konsoli w celu wydrukowania
    std::cout << ;  // błąd kompilacji: brak podanej wartości

    return 0;
}

W powyższym programie wartość do wydrukowania musi zostać podana po prawej stronie std::cout <<. Jeśli nie zostanie podana żadna wartość, kompilator zgłosi błąd składniowy, ponieważ drugie wywołanie std::cout tego nie zrobi podaj wartość do wydrukowania, powoduje to błąd.

Rozważmy teraz następujący program:

#include <iostream>

// void oznacza, że funkcja nie zwraca wartości wywołującemu
void printHi()
{
    std::cout << "Hi" << '\n';
}

int main()
{
    printHi(); // OK: funkcja printHi() jest wywoływana, żadna wartość nie jest zwracana

    std::cout << printHi(); // compile error

    return 0;
}

Pierwsze wywołanie printHi() jest wywoływane w kontekście, który nie wymaga wartości. Ponieważ funkcja nie zwraca wartości, jest to w porządku.

Drugie wywołanie funkcji printHi() nie zostanie nawet skompilowane. Funkcja printHi posiada parametr void zwraca typ, co oznacza, że nie zwraca wartości próbuje wysłać wartość zwracaną przez printHi Do std::cout do wydrukowania. std::cout nie wie, jak sobie z tym poradzić (jaką wartość wyśle?). W związku z tym kompilator oznaczy to jako błąd. Będziesz musiał skomentować ten wiersz kodu, aby kod się skompilował.

Wskazówka

Niektóre instrukcje wymagają podania wartości, a inne nie.

Kiedy mamy instrukcję składającą się tylko z wywołania funkcji (np. najpierw printHi() w powyższym przykładzie), wywołujemy funkcję ze względu na jej zachowanie, a nie wartość zwracaną. W tym przypadku możemy wywołać funkcję nie zwracającą wartości lub możemy wywołać funkcję zwracającą wartość i po prostu zignorować wartość zwracaną.

Gdy wywołujemy funkcję w kontekście wymagającym wartości (np. std::cout), w takim kontekście możemy jedynie podać wartość funkcje zwracające wartość.

#include <iostream>

// Funkcja, która nie zwraca wartości
void returnNothing()
{
}

// Funkcja zwracająca wartość
int returnFive()
{
    return 5;
}

int main()
{
    // Podczas samodzielnego wywoływania funkcji nie jest wymagana żadna wartość
    returnNothing(); // ok: możemy wywołać funkcję, która nie zwraca wartości
    returnFive();    // ok: możemy wywołać funkcję, która zwraca wartość i zignorować tę zwracaną wartość

    // Podczas wywoływania funkcji w kontekście wymagającym wartości (np. std::cout)
    std::cout << returnFive();    // ok: możemy wywołać funkcję, która zwraca wartość, a wartość zostanie użyta
    std::cout << returnNothing(); // błąd kompilacji: nie możemy wywołać funkcji, która zwraca void w tym kontekście

    return 0;
}

Zwracanie wartości z funkcji void jest błędem kompilacji

Próba zwrócenia wartości z funkcji, która nie zwraca wartości, zakończy się błędem kompilacji:

void printHi() // Ta funkcja nie zwraca wartości
{
    std::cout << "In printHi()" << '\n';

    return 5; // błąd kompilacji: próbujemy zwrócić wartość
}

Czas quizu

Pytanie nr 1

Sprawdź następujące programy i określ, co generują, lub czy nie zostaną skompilowane.

1a)

#include <iostream>

void printA()
{
    std::cout << "A\n";
}

void printB()
{
    std::cout << "B\n";
}

int main()
{
    printA();
    printB();

    return 0;
}

Pokaż rozwiązanie

1b)

#include <iostream>

void printA()
{
    std::cout << "A\n";
}

int main()
{
    std::cout << printA() << '\n';

    return 0;
}

Pokaż rozwiązanie

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
125 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze