mgr inż. Wacław Libront * Bobowa 2019

ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu

Lekcja 4

Funkcje w C++

  1. schemat
  2. gwiazdki
  3. odległość
  4. zasięg
  5. parametry
  6. zadania
  7. rozwiązania

Czym jest funkcja (procedura)? To zestaw instrukcji, które opisujemy jednym słowem, które porządkują strukturę programu przez podział na logiczne fragmenty, i które potem możemy wielokrotnie używać w programie głównym. Dzięki takiej organizacji skracamy kod programu, porządkujemy go w logicznie uporządkowane fragmenty, możemy go szybciej poprawiać oraz możemy pisać biblioteki funkcji, z których będziemy mogli korzystać w innych programach. W bibliotekach języka C++ mamy mnóstwo gotowych funkcji, na przykład wykorzystywane już pow i sqrt z biblioteki cmath.


Schemat funkcji

typ nazwa (parametry){ instrukcje; return wartość; }

lub funkcja która nie zwraca żadnych wartości, tzw. procedura

void nazwa (parametry){ instrukcje;… }


Uwagi o funkcjach


Zadanie - Gwiazdki
Napisz funkcję GWIAZDKI, która „rysuje” na ekranie prostokąt z gwiazdek. Parametry funkcji W i K – ile wierszy i kolumn. Dane wczytujemy z klawiatury w programie głównym. Zmodyfikuj program tak, aby środek prostokąta wypełniony był kropkami (brzeg z gwiazdek).

void GWIAZDKI(int W, int K){
  for (int i=1;i<=W;i++){
    for (int j=1;j<=K;j++) 
	cout << "*";
    cout << endl;
  }
}
void GWIAZDKI_1(int W, int K){
  for (int i=1; i <= W; i++){
    for (int j=1; j <= K; j++) 
    	if (i==1 || i==W || j==1 || j==K) 
	  cout << "*";
    	else cout << "-";
    cout << endl;
  }
}
...
int wiersz,kolumna;
cout << "Podaj wiersze: ";
cin >> wiersz;
cout << "Podaj kolumny: ";
cin >> kolumna;
GWIAZDKI(wiersz,kolumna);
GWIAZDKI_1(wiersz, kolumna);		

Zadanie - Odległość
Oblicz odległość pomiędzy dwoma punktami A i B układu współrzędnych. Z klawiatury wpisujemy cztery wartości współrzędnych dwóch punktów A(x1,y1) i B(x2,y2).

float ODL(float x1, float y1, float x2, float y2){
  return sqrt(pow(x2-x1,2)+pow(y2-y1,2));
}
...
cout << ODL(1,1,3,3) << endl;

UWAGA. Ponieważ używamy funkcji matematycznych pow i sqrt, dlatego należy zadeklarować bibliotekę cmath.


Zasięg zmiennych - zmienne globalne i lokalne
Programy się komplikują, zaczynamy używać wielu zmiennych i nazwy tych zmiennych mogą się powtarzać – będą takie same w programie głównym i w funkcjach. Bez problemu można definiować zmienne o takich samych nazwach, ale powinniśmy stosować kilka zasad:


Zadanie – Silnia
Napisz funkcję SILNIA z jednym parametrem N, która zwraca wartość silni. Sprawdź, czy parametr jest liczbą naturalną z przedziału 1-100. Sprawdź działanie funkcji wypisując na ekranie wartość 5!. Sprawdź działanie funkcji wypisując na ekranie wartości kolejnych silni dla liczb 1-100.

int SILNIA(int N){
  int s=1;
  for (int i=1; i<=N; i++)
    s=s*i;
  return s;
}

int main(){
  cout << SILNIA(5) << endl;
}

Przekazywanie parametrów – wartość i referencja
Przekazywanie parametrów przez wartość jest naturalne – wszystkie poprzednie funkcje tak miały – wstawialiśmy jako parametry dane, na których były wykonywane obliczenia i funkcja zwracała wynik – parametry wstawiane do funkcji nie ulegały zmianie. Przekazywanie przez referencję daje dodatkowe możliwości – funkcja może zmieniać wartości przekazywanych do funkcji parametrów.

Po co to wszystko? Jeszcze większe możliwości dla programistów, bo funkcja może zwracać więcej niż jedną wartość i wygodniej operować złożonymi strukturami danych np. tablicami. Programowanie naprawdę się komplikuje (na własne życzenie programisty), jeśli zmienne globalne przekazywane przez referencję mają takie same nazwy jak lokalne.


Zadanie -referencje
Jakie wartości pojawią się na ekranie po wykonaniu funkcji ZAMIANA_W i ZAMIANA_R? Funkcja ZAMIANA_W przekazuje parametry przez wartość, a funkcja ZAMIANA_R przez referencję. Obie funkcje zamieniają pomiędzy sobą przekazane wartości.
void ZAMIANA_W(int x, int y){
  int p=x; 
  x=y; 
  y=p;
}
void ZAMIANA_R(int &x, int &y){
  int p=x; 
  x=y; 
  y=p;
}
...
int a=1;
int b=2;
ZAMIANA_W(a,b);
cout << a << " " << b << endl;
ZAMIANA_R(a,b);
cout << a << " " << b << endl;		

Zadanie - Zagadka ze zmiennymi
W programie głównym zdeklarowano zmienną „i”, której nadano wartość 7. Funkcja US też posługuje się swoją wewnętrzną zmienną „i”. Ile „uśmieszków” wypisze na ekranie program?

void US(int ile){
  for(int i=1;i<=ile;i++)
    cout<<":-)";
  }
...
int i=7;
US(i);		

Dobry styl programowania

W jaki sposób pisać programy, żeby kodować szybciej i bez błędów? Oto kilka wskazówek.


Zadania

1) Napisz funkcje obliczające: pole powierzchni i obwód: kwadratu, prostokąta, koła, trójkąta, sześciokąta foremnego, trapezu. Wprowadź dane z klawiatury i wylicz wartości za pomocą funkcji. Sprawdź czy parametry funkcji są większe zera.

2) Napisz funkcje obliczające: pole powierzchni i objętość kuli, prostopadłościanu, stożka, ostrosłupa. Wprowadź dane z klawiatury i wylicz wartości za pomocą funkcji. Sprawdź czy parametry funkcji są większe zera.

3) Napisz funkcję KWADRATOWA, która wymaga trzech parametrów rzeczywistych: a, b, c, i która wyliczy i wypisze na ekranie pierwiastki równania kwadratowego. Jeśli równanie nie ma rozwiązań – funkcja wypisuje komunikat „brak pierwiastków”.

4) Napisz funkcję ULAMEK z jednym parametrem X, która zwraca wynik poniższego ułamka. Wylicz wartość ułamka dla kolejnych liczb naturalnych w przedziale 1..100.

5) Napisz funkcję o nazwie NEWTON z dwoma parametrami N i K, która w wyniku podaje wartość symbolu Newtona opisanego wzorem. Sprawdź, czy wpisane liczby są naturalne.


Przykładowe rozwiązania zadań
Jedynie ciężka umysłowa praca i zrozumienie działania programu może nauczyć programowania!

//zadanie 1
double KwadratPole(double bok){
	return bok*bok;
}
double KwadratObwod(double bok){
	return 4*bok;
}
double KoloPole(double r){
	return M_PI*r*r;
}
double KoloObwod(double r){
	return 2*M_PI*r;
}
...
cout << "Wpisz liczbę: ";
double liczba;
cin >> liczba;
cout << " Pole kwadratu=" << KwadratPole(liczba) << endl;
cout << "Obwód kwadratu=" << KwadratObwod(liczba) << endl;
cout << "     Pole koła=" << KoloPole(liczba) << endl;
cout << "    Obwód koła=" << KoloObwod(liczba) << endl;
cout << endl;
//zadanie 2
double KulaPole(double r){
	return 4*M_PI*r*r;
}
double KulaObjetosc(double r){
	return 4.0/3.0*M_PI*r*r*r;
}
double SzescianPole(double bok){
	return 6*bok*bok;
}
double SzescianObjetosc(double bok){
	return bok*bok*bok;
}
...
cout << "Wpisz liczbę: ";
double liczba;
cout << "         Pole kuli=" << KulaPole(liczba) << endl;
cout << "     Objętość kuli=" << KulaObjetosc(liczba) << endl;
cout << "    Pole Sześcianu=" << SzescianPole(liczba) << endl;
cout << "Objętość Sześcianu=" << SzescianObjetosc(liczba) << endl;

//zadanie 3
void KWADRATOWA(double a, double b, double c){
	double delta=b*b-4*a*c;
	if (delta >= 0){
		double x1=(-b-sqrt(delta))/(2*a);
		double x2=(-b+sqrt(delta))/(2*a);
		cout << "x1=" << x1 << endl;
		cout << "x2=" << x2 << endl;
	}
	else cout << "brak pierwiastków" << endl;
}
...
cout << "y(x)=x*x-3*x+2" << endl;

KWADRATOWA(1,-3,2);
//zadanie 4
double ULAMEK(int Y){
	double X=Y;
	//return X+(X+(X+(X+(X+(X+X)/X)/X)/X)/X)/X;
	//albo
	double W;
	W=X+(X+(X+(X+(X+(X+X)/X)/X)/X)/X)/X;
	return W;
}
//zadanie 5
int SILNIA(int N){
	int s=1;
	for (int i=1; i<=N;i++)
        s=s*i;
	return s;
}

int NEWTON(int N, int K){
	double NE=SILNIA(N)/(SILNIA(K)*SILNIA(N-K));
	return NE;
}
//zadanie 6

//SZABLON
#include <stdlib.h>	//system
#include <iostream>	//cout
#include <iomanip>	//fixed
#include <cmath>	//pow
using namespace std;
int main(){
  setlocale(LC_ALL, "");


  system("pause");
}