Temat C4. Stosowanie funkcji w językach C++ i Python

przez | 5 lutego 2020

Zapisy podstawy programowej realizowane w temacie:

I. Rozumienie, analizowanie i rozwiązywanie problemów
Zakres rozszerzony. Uczeń spełnia wymagania określone dla zakresu podstawowego, a ponadto:
1) w zależności od problemu rozwiązuje go, stosując metodę wstępującą lub zstępującą;
2) do realizacji rozwiązania problemu dobiera odpowiednią metodę lub technikę algorytmiczną i struktury danych

II. Programowanie i rozwiązywanie problemów z wykorzystaniem komputera i innych urządzeń cyfrowych.
Zakres rozszerzony. Uczeń spełnia wymagania określone dla zakresu podstawowego, a ponadto:
1) projektuje i tworzy rozbudowane programy w procesie rozwiązywania problemów, wykorzystuje w programach dobrane do algorytmów struktury danych, […]
2) stosuje zasady programowania strukturalnego i obiektowego w rozwiązywaniu problemów;
3) sprawnie posługuje się zintegrowanym środowiskiem programistycznym przy pisaniu, uruchamianiu i testowaniu programów;

I + II. Zakres rozszerzony. Uczeń spełnia wymagania określone dla zakresu podstawowego, a ponadto:
1) zapisuje za pomocą listy kroków, schematu blokowego lub pseudokodu, i implementuje w wybranym języku programowania, algorytmy poznane na wcześniejszych etapach […]: I

Spis treści

  1. Modele programowania
  2. Programowanie zstępujące i wstępujące
  3. Zalety stosowania podprogramów (funkcji)
  4. Definiowanie funkcji w językach C++ i Python
    1. Funkcje niezwracające wartości bez parametrów
    2. Funkcje niezwracające wartości z parametrami
    3. Funkcje zwracające wartość bez parametrów
    4. Funkcje zwracające wartość z parametrami

1. Modele programowania

Ze względu na modele programowania możemy wyróżnić:

Programowanie liniowe – program jest ciągiem instrukcji języka programowania. Nie wyróżnia się bloków strukturalnych, np. zawierających instrukcje warunkowe czy iteracyjne – są one tutaj realizowane za pomocą instrukcji skoku, powodującej przejście do określonego miejsca w programie. Nie wyodrębnia się również fragmentów programu w postaci procedur i funkcji.

Programowanie strukturalne – program ma określoną strukturę, w której można wyodrębnić deklaracje (modułów, zmiennych, stałych), definicje podprogramów (procedur i funkcji) oraz bloki instrukcji, w tym sterujących wykonaniem programu, np. warunkowych i iteracyjnych. W programowaniu strukturalnym stosowanie instrukcji skoku nie jest konieczne (w przeciwieństwie do programowania liniowego, gdzie jest niezbędne). W programowaniu strukturalnym zwykle każda dana, a co za tym idzie i zmienna, ma swój ściśle określony typ.

Programowanie modularne – koncepcja programowania modularnego stanowi rozszerzenie podejścia proceduralnego, w którym powtarzające się w programie ciągi instrukcji zapisuje się w postaci procedur i funkcji, nadających się do wielokrotnego wykorzystania.

W przypadku programowania modularnego dane i związane z nimi procedury są zebrane w modułach, które, zapisane pod unikatową nazwą, mogą być wykorzystywane w wielu programach. Moduł jest strukturą nadrzędną w stosunku do procedur i funkcji.

Programowanie obiektowe (zorientowane obiektowo) – program to zbiór obiektów, z których każdy posiada określone właściwości (związane z obiektem dane) i metody (operacje, jakie można na obiekcie wykonać). Metody opisane są za pomocą programowania strukturalnego. Programowanie obiektowe służy do realizacji złożonych projektów.

Programowanie zdarzeniowe – podobnie jak w programowaniu obiektowym, program to zbiór obiektów, jednak kolejność wykonywania instrukcji programu nie jest zdefiniowana przez programistę, lecz zależy od zaistnienia określonych zdarzeń, takich jak: naciśnięcie przez użytkownika przycisku myszy, wprowadzenie danej, upływ określonego czasu itp. Programowanie zdarzeniowe jest ściśle powiązane z tworzeniem interfejsu między programem i użytkownikiem. W przypadku gdy interfejs ten projektowany jest za pomocą narzędzi graficznych, mówimy o programowaniu wizualnym.

Niektóre metody programowania można stosować bez względu na wybrany język programowania.

Niektóre języki są jednak lepiej przystosowane do programowania określoną metodą, np. język C++ do programowania obiektowego.

2. Programowanie zstępujące i wstępujące

Wyróżniamy dwie przeciwstawne metody programowania

  • programowanie zstępujące (ang. top-down), czyli „z góry do dołu” – najpierw planuje się całość, a potem dochodzi do szczegółów;
  • programowanie wstępujące (ang. bottom-up), czyli „z dołu w górę” – ze szczegółowych elementów składa się całość.

W pierwszej metodzie („od ogółu do szczegółu”) zaczynamy od sformułowania zadania głównego, które następnie poddajemy analizie i dzielimy na mniejsze moduły (np. procedury lub funkcje), czasem aż do najbardziej elementarnych części, których zaprogramowanie nie jest skomplikowane. Jednocześnie na każdym etapie podziału określa się zakres danych, które mają być przetwarzane w określonej części programu, i wyniki, jakie mają zostać otrzymane. Ta metoda wykorzystywana jest w programowaniu strukturalnym.

W drugiej metodzie („od szczegółu do ogółu”) sytuacja wygląda odwrotnie – na początku określamy zestaw elementarnych zadań, których wykonanie jest konieczne do realizacji zadania głównego. Po wykonaniu niewielkich części przechodzimy do konstrukcji większych, na zadaniu głównym kończąc.

3. Zalety stosowania podprogramów (funkcji)

Podprogram (funkcja) to wyodrębniona część programu, mająca unikatową nazwę i ustalony sposób wymiany danych z innymi częściami programu.

Stosowanie funkcji umożliwia:

  • dzielenie zadania na mniejsze części – każda może być realizowana w oddzielnej procedurze lub funkcji;
  • wprowadzenie porządku do programu – zwiększenie jego czytelności i przejrzystości;
  • unikanie powtórzeń – fragmenty programu, które się powtarzają, są wyodrębnione w postaci funkcji;
  • łatwiejsze wyszukiwanie błędów i dokonywanie poprawek – w funkcji można zlokalizować błędy szybciej niż na długiej liście instrukcji programu głównego;
  • programowanie zespołowe – po uzgodnieniu postaci procedur lub funkcji każdy z członków zespołu może zająć się pracą nad „swoimi” procedurami lub funkcjami.

Zalety programowania strukturalnego są szczególnie widoczne przy pisaniu dużych programów, rozwiązujących złożone problemy – w przypadku mniejszych programów można tych zalet nie dostrzec.

Języki programowania mają zwykle zdefiniowane standardowe funkcje. Aby skorzystać z nich w tworzonych przez nas programach, nie musimy znać szczegółów ich implementacji, a jedynie nazwę, liczbę i typ parametrów oraz sposób działania.

W języku C++ używaliśmy funkcji głównej main(), od której rozpoczyna się każdy program. W języku Python korzystaliśmy na przykład z funkcji print()i input().W każdym z tych języków możemy deklarować też własne podprogramy.

4. Definiowanie funkcji w językach C++ i Python

W językach C++ i Python wszystkie podprogramy nazywane są funkcjami.

Dzielimy je na dwie grupy:

  • funkcje niezwracające wartości,
  • funkcje zwracające wartość.

Aby zastosować w programie własną funkcję, trzeba ją zdefiniować, a następnie wywołać.

W językach C++ i Python funkcje można definiować z parametrami lub bez parametrów.

C++
Definicja funkcji obejmuje:

  • nagłówek (zawierający nazwę, typ zwracanej wartości i ewentualnie listę parametrów),
  • treść (zawierającą instrukcje).
    opis_typu nazwa_funkcji(lista_parametrów_formalnych)
    {
    lista_instrukcji;
    return wartość;
    }

W języku C++ funkcja powinna być zdefiniowana przed pierwszym jej wywołaniem. Można też funkcję zadeklarować (określić typ, nazwę i parametry) przed pierwszym użyciem, a zdefiniować w dowolnym miejscu programu. Przed nazwą funkcji umieszczamy typ zwracanej wartości, a instrukcje tworzące funkcję wpisujemy w nawiasach klamrowych {}. W definicji funkcji lista parametrów formalnych oznacza typy i nazwy parametrów przekazywanych do funkcji. Można definiować funkcje również bez parametrów – w takim przypadku po nazwie funkcji pozostawia się puste nawiasy.


Definicja funkcji obejmuje:

  • nagłówek (zawierający słowo kluczowe def, nazwę i ewentualnie listę parametrów),
  • treść (zawierającą instrukcje).
    def nazwa_funkcji(lista_parametrów_formalnych):
        lista_instrukcji
        return wartość

W języku Python funkcję definiujemy w dowolnym miejscu programu (zazwyczaj na początku), ale przed pierwszym użyciem. Nie określamy typu funkcji ani typów parametrów formalnych funkcji – interpreter rozpozna je automatycznie (podobnie jak w przypadku zmiennych). Treść funkcji (lista_instrukcji i instrukcja return) musi być przesunięta w prawo przynajmniej o jedną spację względem nagłówka funkcji (przyjęte jest wcięcie składające się z czterech spacji).

4.1. Funkcje niezwracające wartości bez parametrów

Funkcja nie zwraca wartości, dlatego instrukcja return nie musi wystąpić (a jeśli występuje, to nie może określać wartości).

Aby wywołać funkcję niezwracającą wartości, należy umieścić nazwę funkcji w odpowiednim miejscu programu głównego. W przypadku braku parametrów nawiasy po nazwie funkcji pozostawiamy puste.

C++
Definicja funkcji niezwracającej wartości ma postać:

void nazwa_funkcji (lista parametrów) // brak zwracanej wartości
{
    lista_instrukcji;
}

Umieszczenie przed nazwą funkcji określenia typu void oznacza, że funkcja nie zwraca żadnej wartości.

Wywołanie funkcji ma postać:

nazwa_funkcji(lista_parametrów_aktualnych);
lub
nazwa_funkcji();


Definicja funkcji niezwracającej wartości ma postać:

def nazwa_funkcji(lista_parametrów_formalnych):
lista_instrukcji

Wywołanie funkcji ma postać:

nazwa_funkcji(lista_parametrów_aktualnych)
lub
nazwa_funkcji()

Przykład 1. Stosowanie funkcji niezwracającej wartości bez parametrów

Napiszemy program umożliwiający wyprowadzenie na ekranie monitora napisu „uśmiechnij się”, a pod nim piętnastu „uśmiechów”: :-).

Zdefiniujemy funkcję uśmiechy(), której zadaniem będzie wyprowadzenie w jednym wierszu dwudziestu „uśmiechów”.

C++
W języku C++ zdefiniujemy funkcję typu void (czyli bez zwracanej wartości) i bez parametrów


W języku Python zdefiniujemy funkcję niezwracającą wartości i bez parametrów

Ćwiczenie 1. Stosujemy funkcję niezwracającą wartości bez parametrów

  1. Otwórz plik TC4_c1_p1.cpp lub TC4_c1_p1.py. Uruchom program.
  2. Uzupełnij kod programu podany w przykładzie 1. tak, aby w wyniku otrzymać dodatkowy rząd piętnastu „uśmiechów” o jeden wiersz niżej.
  3. Zapisz plik pod nazwą Usmiechanie_15 i uruchom program.

4.2. Funkcje niezwracające wartości z parametrami

W bardziej rozbudowanych programach stosuje się funkcje z parametrami. Program główny komunikuje się funkcją przez przekazywanie parametrów.

Aby wywołać funkcję niezwracającą wartości z parametrami, należy umieścić nazwę funkcji z parametrami aktualnymi (nazywanych też argumentami) w odpowiednim miejscu programu głównego. W momencie wywołania funkcji w miejsce parametrów formalnych (nazwanych też parametrami) są wprowadzane parametry aktualne – zmienne lub wyrażenia (w szczególności konkretne wartości).

C++
W języku C++ lista parametrów formalnych zawiera określenie typów i nazw zmiennych.

Przykłady:
void Zadanie1(int a)
void Zadanie2(float x, float y, int i)

Uwaga: Jeśli parametry są tego samego typu, zapis typu float x, y , dopuszczalny przy deklaracji zmiennych, jest niepoprawny.


W języku Python lista parametrów formalnych zawiera określenie nazw zmiennych. Nie określamy typów parametrów formalnych funkcji – interpreter rozpozna je automatycznie (podobnie jak w przypadku typu funkcji).

Przykłady:
def Zadanie1(a)
def Zadanie2(x, y, i)

Przykład 2. Stosowanie funkcji niezwracającej wartości z parametrem

Do programu wyświetlającego „uśmiechy” dodamy możliwość zmiany liczby wyprowadzanych uśmiechów (w przykładzie 1. stale była równa 15).
Funkcję usmiechy definiujemy z jednym parametrem formalnym n.

C++
Zmienna n jest parametrem formalnym funkcji, dlatego nie trzeba jej dodatkowo deklarować, gdyż parametr formalny jest traktowany jak zmienna lokalna.
Funkcję usmiechy wywołujemy w funkcji main() z odpowiadającym jej parametrem aktualnym (argumentem) m


Funkcję usmiechy wywołujemy w programie głównym z odpowiadającym jej parametrem aktualnym (argumentem) m.

Ćwiczenie 2. Stosujemy funkcję niezwracającą wartości z parametrem

  1. Korzystając z pliku TC4_c1_p1.cpp lub TC4_c1_p1.py., zmodyfikuj program zgodnie z opisem podanym w przykładzie 2.
  2. Zapisz plik pod nazwą Usmiechanie_n i przetestuj program dla różnych danych.
  3. W programie zmodyfikowanym w punkcie 1. zmień sposób wywołania funkcji na wywołanie:
    1. z wyrażeniem usmiechy(2*m + 1); zapisz plik pod nazwa Usmiechanie_a,
    2. z konkretną wartością usmiechy(8); usuń wprowadzanie danych z klawiatury; zapisz plik pod nazwa Usmiechanie_b,
    W każdym z przypadków sprawdź działanie programu.

4.3. Funkcje zwracające wartość bez parametrów

Funkcja zwracająca wartość oblicza (wyznacza) pewną wartość i odsyła tę wartość do funkcji wywołującej. Mówimy, że funkcja zwraca wartość.

Funkcje zwracające wartość muszą zawierać instrukcję returnz wartością, która ma być zwrócona do funkcji wywołującej. Zwracana wartość może być stałą, zmienną lub wyrażeniem.

C++
Przykłady:
return a*b;
return Wynik;

W języku C++ funkcję można wywołać, umieszczając wynik w zmiennej.

Przykład:
suma = suma_kwadrat();

Funkcję można wykorzystać jako element wyrażenia lub instrukcji.

Przykład:
cout << suma_kwadrat();

Można również (w przypadku, gdy nie jest nam potrzebny wynik) wywołać funkcję poprzez nazwę, podobnie jak w przypadku funkcji typu void, np. suma_kwadrat();


Przykłady:
return a*b
return wynik

W języku Python funkcję można wywołać, umieszczając wynik w zmiennej.

Przykład:
suma = suma_kwadrat()

Funkcję można wykorzystać jako element wyrażenia lub instrukcji.

Przykład:
print(suma_kwadrat())

Można również (w przypadku, gdy nie jest nam potrzebny wynik) wywołać funkcję poprzez nazwę, podobnie jak w przypadku funkcji niezwracającej wartości, np. suma_kwadrat()

Przykład 3. Stosowanie funkcji zwracającej wartość bez parametrów

Zdefiniujemy funkcję suma_kwadrat bez parametrów, obliczającą sumę kwadratów dwóch liczb całkowitych.

C++
W programie w języku C++ zmienne x i y zostały zadeklarowane jako zmienne globalne.


W programie w języku Python zmienne x i y są zmiennymi globalnymi

Ćwiczenie 3. Stosujemy funkcję zwracającą wartość bez parametrów

  1. Otwórz plik TC4_c3_p3.cpp lub TC4_c3_p3.py. Uruchom iprzetestuj program dla różnych danych.
  2. Zdefiniuj dodatkowo funkcję roznica_kwadrat() zwracającą wartość różnicy kwadratów liczb. Wywołaj funkcję w programie głównym. Zapisz plik pod nazwą Suma_roznica_kwadratow_bp.

W przypadku funkcji bez parametrów, aby przekazać do nich dane, musieliśmy zastosować tzw. zmienne globalne (widoczne w dowolnym miejscu programu) – w funkcjach i w programie głównym – w programach z przykładu 3. są to zmienne x i y.

Niezależnie od zmiennych globalnych można w funkcji stosować zmienne lokalne.

W funkcji usmiechy() w języku C++ (przykłady 1. i 2.) zmienna i jest lokalna. W języku C++ zmienne globalne deklarujemy poza funkcjami, a zmienne lokalne – wewnątrz funkcji.

Więcej informacji na temat zmiennych globalnych i lokalnych w językach C++ i Python przedstawimy w temacie C5.

4.4. Funkcje zwracające wartość z parametrami

Parametr to wartość przekazywana funkcji, a wartość zwracana to wartość przekazywana z funkcji.

Przykład 4. Stosowanie funkcji zwracającej wartość z parametrami

Funkcję suma_kwadrat, obliczającą sumę kwadratów dwóch liczb, zdefiniujemy z parametrami.
W momencie wywołania funkcji w miejsce parametrów formalnych a i b zostaną wprowadzone wartości parametrów aktualnych x i y, wprowadzane z klawiatury.

C++

W przykładzie 4. funkcja suma_kwadrat wylicza dla podanych parametrów aktualnych, np. a = 3 i b = 4, wynik równy 25 i odsyła tę wartość do programu głównego.

Ćwiczenie 4. Stosujemy funkcję zwracającą wartość z parametrem

  1. Otwórz plik TC4_c3_p3.cpp lub TC4_c3_p3.py. Zmodyfikuj program zgodnie z kodem podanym w przykładzie 4.
  2. Zapisz plik pod nazwą TC4_c4_p4 i wykonaj program dla różnych danych.

Zadania

  1. Otwórz plik TC4_z1.cpp lub TC4_z1.py. Zdefiniuj funkcję usmiechy_kolumna() wyświetlającą piętnaście „uśmiechów” w kolumnie. Zmodyfikuj program, aby kolejno wyświetlały się „uśmiechy” w wierszu, w kolumnie i znów w wierszu oraz w kolumnie. Zapisz plik pod nazwą Uśmiechy_wiersz_kolumna.
  2. Napisz program, który umożliwi wyświetlenie w kolejnych czterech wierszach dowolnego znaku. Zdefiniuj funkcję z parametrem, której zadaniem będzie wypisywanie tego znaku. Parametrem jest znak. Zapisz plik pod nazwą Uśmiechy_wiersz_kolumna.
    Wskazówka: W języku C++ typ zmiennej znakowej to char.
  3. Otwórz plik TC4_c4_p4.cpp lub TC4_c4_p4.py zapisany w ćwiczeniu 4. Zdefiniuj funkcję funkcję roznica_kwadrat z dwoma parametrami zwracającą wartość różnicy kwadratów liczb. Zapisz plik pod nazwą Suma_roznica_kwadratow_zp. Przetestuj program dla różnych danych.
  4. Zastosuj funkcję suma_kwadrat, zdefiniowaną w ćwiczeniu 4., do sprawdzenia warunku, czy z trzech liczb naturalnych, wprowadzonych z klawiatury, można zbudować trójkąt prostokątny.
  5. Napisz program obliczający pole powierzchni prostopadłościanu, którego podstawą jest kwadrat o boku a i o wysokości b (a, b – wprowadzane z klawiatury). Do obliczenia pola zastosuj dwie funkcje: obliczającą pole prostokąta o bokach a i b i obliczającą pole kwadratu o boku a.
  6. Napisz program zliczający liczby ujemne i nieujemne wśród n liczb wprowadzanych z klawiatury. Zdefiniuj procedurę Zliczaj (z jednym parametrem, określającym n), która będzie zliczała liczby.
  7. Dla zainteresowanych

  8. Napisz program, który wyświetli na ekranie monitora trójkąt prostokątny składający się ze znaków „$”, którego przyprostokątne mają długość 10 znaków dolara (w każdym wierszu jest o jeden znak dolara mniej). Zdefiniuj odpowiednie funkcje.
  9. W programie tworzonym w zadaniu 7. wprowadź możliwość pytania o wymiary trójkąta prostokątnego. Zdefiniuj odpowiednią funkcję.
  10. Korzystając z funkcji utworzonych w zadaniach 7. i 8, narysuj choinkę (o kształcie trójkąta równoramiennego).
  11. Zadanie dla dwóch osób: Każda z osób projektuje zadanie według własnego pomysłu (można wzorować się na zadaniach z tego tematu) – formułuje treść zadania, pisze specyfikację i przekazuje zadanie drugiej osobie, aby napisała program. Potem program wraca do autora zadania, który sprawdza, czy jest zgodny ze specyfikacją i testuje go dla różnych danych.