Zajęcia wyrównawcze z informatyki FUNKCJE I PO


Zajęcia wyrównawcze z informatyki

Semestr 4   Grupa 1   Sekcja 36

0x01 graphic

Wskaźniki, referencje i podprogramy

Czym jest wskaźnik?

Wskaźnik jest to zmienna przechowująca adres komórki pamięci. Używając wskaźników możemy bezpośrednio manipulować zawartością pamięci przez co uzyskujemy możliwość budowy wydajnych algorytmów. Wskaźników używamy z dwóch powodów:

Aby zrozumieć ideę posługiwania się wskaźnikami należy zrozumieć w jaki sposób programista korzysta z pamięci.

Pamięć komputera

Pamięć komputera zorganizowana jest w ciąg występujących po sobie komórek. Każda komórka ma rozmiar 1 bajta (8 bitów) i ma niepowtarzalny adres, który spełnia rolę jej identyfikatora. Pierwsza komórka pamięci ma adres 0. Każda następna ma adres o jeden większy od swej poprzedniczki. Adres ostatniej komórki zależy od wielkości pamięci zainstalowanej w komputerze (pamięć RAM i plik wymiany). Na rysunku 1 przedstawiono fragment pamięci.

0x01 graphic

Rysunek 1. Fragment pamięci komputera

Jeżeli zmienna wskaźnikowa ma wartość zero oznacza to, że nie wskazuje na żaden obszar pamięci. Komórka pamięci o adresie 0 jest zarezerwowana dla systemu operacyjnego i nie może być wykorzystywana przez aplikacje użytkownika. Do oznaczania tej komórki pamięci w języku C została zadeklarowana specjalna stała o nazwie NULL.

Deklaracja zmiennej

Deklaracja zmiennej to w istocie rezerwowanie dla niej miejsca w pamięci. Po rezerwacji możemy do tego obszaru zapisywać informacje jak również z niego je odczytywać. Dostęp do tych danych może być realizowany na dwa sposoby:

Przykład 1:

// Rezerwacja pamięci dla zmiennych A, B, C

int main()

{

int A;

char C;

float B;

}

Na rysunku 2 przedstawiono fragment pamięci przed (rys. 2a) i po deklaracji trzech zmiennych A, B, C (rys. 2b).

0x01 graphic

Rysunek 2. Przykładowy wynik deklaracji zmiennych

W zależności od rodzaju zmiennej, komórki pamięci, które zostają przydzielone tej zmiennej, są zerowane (zmienne statyczne) lub pozostawiane bez zmian — zawierają przypadkowe wartości (zmienne automatyczne).

Operator wyłuskania *

Operator wyłuskania jest zwany także operatorem dostępu pośredniego lub dereferencją. Ogólna postać wywołania jest następująca:

*identyfikator_zmiennej;

Jeżeli operator wyłuskania * użyty jest przed zmienną podczas jej deklaracji to oznacza, że deklarowana zmienna jest wskaźnikiem do danego typu.

Przykład 2:

int *p; //zmienna p jest wskaźnikiem do danych typu int

Jeżeli operator wyłuskania * znajduje się przed zmienną, która już wcześniej została zadeklarowana to oznacza wartość przechowywaną pod adresem.

Przykład 3:

int *p; //zmienna p jest wskaźnikiem do danych typu int

.

.

*p = 12; //do obszaru pamięci wskazywanego przez zmienną

//wskaźnikową p zostanie wpisana wartość 12

Operator adresu &

Operator adresu & służy do pozyskiwania adresu zmiennej. Ogólna postać wywołania jest następująca:

&identyfikator_zmiennej;

Jeżeli operator adresu & użyty jest przed zmienną podczas jej deklaracji to oznacza, że deklarowana zmienna jest referencja (inną nazwą tej samej zmiennej).

Przykład 4:

int main()

{

float a; //deklaracja zmiennej a typu float

float *p; //deklaracja zmiennej wskaźnikowej p typu float

float &r=a; //deklaracja referencji r do zmiennej a;

}

UWAGA!!! Nie należy mylić jednoargumentowych operatorów & i * z dwuargumentowymi operatorami & (bitowy iloczyn logiczny) i * (operator mnożenia).

Przykład 5:

int main()

{

float a=3.14; //(1)

float *p=NULL; //(2)

p = &a; //(3)

printf("%f",*p); //(4)

}

Na rysunku 3a przedstawiono zawartość pamięci po wykonaniu (1) i (2) linii kodu (przykład 5). Rysunek 3b przedstawia zawartość pamięci po wykonaniu całego kodu. Podane w przykładzie numery komórek pamięci są tylko przykładowe.

0x01 graphic

Rysunek 3. Ilustracja przykładu 5

Referencje

Referencja jest aliasem (inną nazwą). Referencja zostaje utworzona przez zainicjowanie jej nazwą innej zmiennej, będącej celem referencji. Od tego momentu referencja działa jak alternatywna nazwa celu. Wszystkie operacje związane z referencją w rzeczywistości dotyczy jej obiektu docelowego. Referencje mają prawie te same możliwości, co wskaźniki, ale posiadają dużo prostszą składnię.

Tworzenie referencji

Referencję tworzy się, zapisując typ obiektu docelowego, operator referencji (&) oraz nazwę referencji.

typ &nazwa_referencji = cel_referencji;

Przykład 6:

#include <stdio.h>

#include <conio.h>

int main()

{

int A;

int &rA = A;

A = 3;

printf(" A = %d\nrA = %d", A, rA);

rA = 4;

printf(" A = %d\nrA = %d", A, rA);

_getch();

return 0;

}

Własności referencji.

Czym jest funkcja?

Funkcja jest to podprogram, operujący na danych i zwracający wartość. Każdy program w języku C (C++) zawiera przynajmniej jedną funkcję, main(). Gdy program rozpoczyna działanie, funkcja main() jest wywoływana automatycznie. Może ona wywoływać inne funkcje, które z kolei mogą wywoływać kolejne funkcje. Każda funkcja posiada nazwę, gdy ta nazwa zostanie napotkana przez program, przechodzi on do wykonywania kodu zawartego wewnątrz tej funkcji. Nazywa się to wywołaniem funkcji. Gdy zakończy się wykonywanie funkcji działanie programu jest wznawiane od instrukcji następującej po wywołaniu tej funkcji.

Parametry do funkcji można przekazywać poprzez:

Poszczególne elementy listy należy rozdzielać przecinkami.

Deklaracja funkcji

Deklaracja funkcji jest bardzo podobna do definicji funkcji z tą jednak różnicą, że nie umieszczamy w niej ciała funkcji (klamry również są pomijana) a na końcu wstawiam średnik.

Deklaracja funkcji ma postać:

Typ_wyniku nazwa_funkcji ( lista parametrów );

Przykład 7:

int silnia(int n); //deklaracja funkcji - prototyp

int main()

{

int n,w;

w=silnia(n); // wywołanie funkcji

prntf("%d\n",w);

return 0;

}

int silnia(int n) //definicja funkcji

{

int i,k=1;

for(i=2;i<=n;i++)

{

k=k*i;

}

return k;

}

Deklaracja funkcji jest elementem opcjonalny, to znaczy jej występowanie w programie nie jest obowiązkowe. Niemniej są sytuacje, gdy oprócz definicji funkcji w programie musimy umieścić jej deklarację (inna nazwa to prototyp). Taka sytuacja ma miejsce, gdy tworzymy swój własny zbiór funkcji (moduł), aby zawarte w nim funkcje były dostępne w innych modułach na początku modułu musimy umieścić deklaracje funkcji. Inny przypadek występuje wtedy, gdy definicja funkcji znajduje się w tym samym pliku, ale poniżej wywołania funkcji (przykład 7). W takiej sytuacji, aby funkcja była widoczna musimy na początku pliku umieścić jej prototyp.

Definicja funkcji ma postać

Definicja funkcji ma postać:

Typ_wyniku nazwa_funkcji ( lista parametrów )

{

deklaracje;

instrukcje;

return wynik;

}

Definicja funkcji składa się z nagłówka i ciała funkcji. Nagłówek zawiera typ wyniku, nazwę funkcji i listę parametrów. Ciało funkcji to wszystkie instrukcje znajdujące się pomiędzy nawiasami klamrowymi. Ciało funkcji może zawierać deklaracje stałych, deklaracje zmiennych, deklaracje używanych przestrzeni nazw, wywołania innych funkcji. Jeżeli funkcja zwraca wynik to musi również zawierać słowo kluczowe return. W przypadku wykonywania instrukcji zawartych wewnątrz funkcji natrafienie na słowo return powoduje zakończenie wykonywania funkcji.

Dobrym zwyczajem jest nadawanie funkcji nazwy sugerującej jej przeznaczenie bądź zagadnienie, które realizuje. Nie jest to jednak wymóg formalny a jedynie zalecenie pomagające w łatwiejszym posługiwaniu się funkcjami.

Przekazywanie parametrów przez wartość

Jeżeli do funkcji chcemy przekazać parametr poprzez wartość to element listy parametrów powinien mieć postać:

typ_zmiennej identyfikator_zmiennej

Przykład 8:

int silnia(int n)

{

//pozostałe instrukcje

}

float suma(float a, float b)

{

//pozostałe instrukcje

}

Przekazywanie parametrów przez wskaźnik

Jeżeli do funkcji chcemy przekazać parametry przez wskaźnik to element listy parametrów powinien mieć postać:

typ_zmiennej *identyfikator_zmiennej

Przykład 9:

int silnia(int *n)

{

//pozostałe instrukcje

}

float suma(float *a , float *b)

{

//pozostałe instrukcje

}

Przekazywanie parametrów przez referencję.

Jeżeli do funkcji chcemy przekazać parametry przez referencję to element listy parametrów powinien mieć postać:

typ_zmiennej &identyfikator_zmiennej

Przykład 10:

int silnia(int &n)

{

//pozostałe instrukcje

}

float suma(float &a , float &b)

{

//pozostałe instrukcje

}

Tabela 1. Porównanie różnych sposobów przekazywania parametrów.

Przekazywanie parametrów przez

wartości

wskaźniki

referencje

float suma(float a, float b)

{

return a+b;

}

float suma(float *a, float *b)

{

return *a+*b;

}

float suma(float &a, float &b)

{

return a+b;

}

void sqr(float x)

{

x=x*x;

}

void sqr(float *x)

{

*x=(*x)*(*x);

}

void sqr(float &x)

{

x=x*x;

}

Jakie znaczenie ma sposób przekazywania parametrów?

Jeżeli pewien parametr przekazywany jest poprzez wartość oznacza to, że w momencie wywołania funkcji tworzona jest kopia tego parametru i to właśnie na tej kopii wykonywane są wszystkie operacje wewnątrz funkcji. Natomiast oryginalny parametr nie podlega modyfikacji.

Tabela 2. Wyniki wywołania funkcji sqr() dla różnych sposobów przekazywania parametrów.

Definicja funkcji

void sqr(float x)

{

x=x*x;

}

void sqr(float *x)

{

*x=(*x)*(*x);

}

void sqr(float &x)

{

x=x*x;

}

Wywołanie funkcji

int main()

{

x=3;

sqr(x);

printf("x = %f",x);

getch();

return 0;

}

int main()

{

x=3;

sqr(&x);

printf("x = %f",x);

getch();

return 0;

}

int main()

{

x=3;

sqr(x);

printf("x = %f",x);

getch();

return 0;

}

Wynik

x = 3

x = 9

x = 9

Jeżeli pewien parametr przekazywany jest poprzez wskaźnik lub referencję to również tworzona jest kopia parametru z tym tylko, że zawiera ona adres komórki pamięci. Jeżeli dokonamy modyfikacji danych znajdujących się pod tym adresem to oczywiście zmiany te będą widoczne również poza funkcją. Własność tą można wykorzystać do przekazywania z funkcji więcej niż jednego wyniku. Jednakże, jeżeli zostanie ona użyta niewłaściwie może doprowadzić do błędnego działania programu. W niektórych sytuacjach błędy te mogą być bardzo trudne do znalezienia i usunięcia.

Podprogramy nie zwracająca wyniku — procedury.

Jeżeli chcemy zbudować podprogram, który nie zwraca wyniku to należy jako typ podać void. W tak zdefiniowanym podprogramie można używać słowa kluczowego return bez parametrów.

Przykład 11:

void WyswInt(int A)

{

printf("%d\n",A);

}

Ponieważ funkcja nie zwraca wyniku, więc również nie możemy wykorzystywać jej do tworzenia wyrażeń.

Sposób wywołania funkcji z przykładu 11 przedstawiono w przykładzie 12.

Przykład 12:

#include <stdio.h>

int main()

{

int A=10;

WyswInt(17);

WyswInt(A);

return 0;

}

Podprogramy bezargumentowe

Jest to szczególny przypadek podprogramu, który do prawidłowego działania nie wymaga wprowadzania danych. Przykładem może być funkcja _getch().

Przykład 13:

float Pi(void)

{

return (M_PI);

}

Jeżeli chcemy wywołać funkcję bez parametrową to nawiasy występujące po jej nazwie pozostawiamy puste. Nawiasów tych nie można pominąć gdyż służą one kompilatorowi do rozróżnienia funkcji od innych elementów języka takich jak stałe i zmienne.

Przykład 14:

#include <conio.h>

int main()

{

getch();

return 0;

}

Przydatne funkcje matematyczne

W pliku nagłówkowym math.h lub cmath znajdują się deklaracje przydatnych funkcji matematycznych. W tabeli 3 zostały one wymienione i krótko opisane.

Tabela 3. Funkcje matematyczne zadeklarowane w pliku nagłówkowym math.h

Funkcja

Opis

sin

sinus

cos

cosinus

tan

tangens

sinh

sinus hiperboliczny

cosh

cosinus hiperboliczny

tanh

tangens hiperboliczny

acos

arkuc cosinus

asin

arkus sinus

atan

arkus tangens

atan2

arkus tangens

ceil

zaokrągla do liczby całkowitej większej od argumentu

floor

zaokrągla do liczby całkowitej mniejszej od argumentu

exp

funkcja wykładnicza ex

sqrt

pierwiastek

pow

potęgoa

log

logarytm naturalny

log10

logarytm dziesiętny

fabs

wartość bezwzględna

fmod

reszta z dzielenia

Przykładowy program wykorzystujący wskaźniki, referencje i funkcje.

//--- Deklaracja modulow ----------------------------------------------------

#include "stdafx.h"

#include <conio.h>

#include <math.h>

//--- Deklaracje podprogramów -----------------------------------------------

float WczytajDane(char * Napis);

bool SprTrojkat(float a, float b, float c);

float PoleTrojkata(float a, float b, float c);

void wPoleIObwod(float a, float b, float c, float *p, float *o);

void rPoleIObwod(float a, float b, float c, float &p, float &o);

void Menu(void);

//--- Definicja funkcji main -------------------------------------------------

int _tmain(int argc, _TCHAR* argv[])

{

float a,b,c,p,o;

char z;

printf("Program obliczajacy pole trojkata.\n\n");

printf("Podaj dlugosci bokow potwierdzając kazda z nich naciskajac enter.\n\n");

a=WczytajDane("A = ");

b=WczytajDane("B = ");

c=WczytajDane("C = ");

if(SprTrojkat(a,b,c))

{

while(true)

{

Menu();

z=getch();

switch(z)

{

case '1': p=PoleTrojkata(a,b,c);

printf("\nPole trojkata = %10.3f\n",p);

break;

case '2': wPoleIObwod(a,b,c,&p,&o);

printf("\nPole trojkata = %10.3f\n",p);

printf("\nObwod trojkata = %10.3f\n",o);

break;

case '3': rPoleIObwod(a,b,c,p,o);

printf("\nPole trojkata = %10.3f\n",p);

printf("\nObwod trojkata = %10.3f\n",o);

break;

case 'k':

case 'K': return 0;

default: printf("Bledny wybor.");

}

}

}

else

{

printf("\nZ odcinkow o podanych dlugosciach nie mozna zbudowac trojkat");

printf("\nProgram zakonczony - nacisnij dowolny klawisz.");

_getch();

}

return 0;

}

//--- Definicje funkcji -----------------------------------------------------

//---------------------------------------------------------------------------

//funkcja przeznaczona do wczytywania danych typu float

//napis - opis wczytywanej wartosci przekazywany przez wskaznik

//wynik zwracany przez return

float WczytajDane(char * Napis)

{

float d;

do

{

printf("\t");

printf(Napis);

scanf("%f",&d);

}

while(d<=0);

return d;

}

//---------------------------------------------------------------------------

//funkcja sprawdzajaca czy z podanych bokow mozna zbudowac trojkat

//a, b, c - dlugosci bokow przekazywane przez wartosc

//wynik zwracany przez return

bool SprTrojkat(float a, float b, float c)

{

bool w=true;

if (a+b<=c) w = false;

if (a+c<=b) w = false;

if (b+c<=a) w = false;

return w;

}

//---------------------------------------------------------------------------

//funkcja obliczajaca pole trojkata

//a, b, c - dlugosci bokow przekazywane przez wartosc

//wynik zwracany przez return

float PoleTrojkata(float a, float b, float c)

{

float s,p;

p = (a+b+c)/2;

s = sqrt(p*(p-a)*(p-b)*(p-c));

return s;

}

//---------------------------------------------------------------------------

//funkcja obliczajaca pole i obwod trojkata

//a, b, c - dlugosci bokow przekazywane przez wartosc

//s - pole powierzchni przekazywane przez wskaznik

//o - obwod trojkata przekazywany przez wskaznik

void wPoleIObwod(float a, float b, float c, float *s, float *o)

{

float p;

*o = (a+b+c);

p=*o/2;

*s = sqrt(p*(p-a)*(p-b)*(p-c));

}

//---------------------------------------------------------------------------

//funkcja obliczajaca pole i obwod trojkata

//a, b, c - dlugosci bokow przekazywane przez wartosc

//s - pole powierzchni przekazywane przez referencje

//o - obwod trojkata przekazywany przez referencje

void rPoleIObwod(float a, float b, float c, float &s, float &o)

{

float p;

o = (a+b+c);

p=o/2;

s = sqrt(p*(p-a)*(p-b)*(p-c));

}

//---------------------------------------------------------------------------

//procedura wyswietlajaca menu

//nie wymaga danych wejciowych

//nie zwraca wyniku

void Menu(void)

{

printf("\nWybierz opcje:\n\n");

printf("\t1 - Oblicz pole trojkata.\n");

printf("\t2 - Oblicz pole i obwod trojkata. (wskaznik)\n");

printf("\t3 - Oblicz pole i obwod trojkata. (referencja)\n");

printf("\tk - Zakoncz program.\n");

}

Zadania do samodzielnego wykonania

Zadanie 1

Napisz podprogram obliczajcy największy wspólny podzielnik dwóch liczb. Następnie wykorzystaj go do znalezienia największego wspólnego podzielnkia trzech liczb (wywołując go ponownie - argumentami powinnien być wynik pierwszego wywołanai oraz trzecia liczba).

Zadanie 2

Napisz podprogram obliczający całkę funkcji jednej zmiennej zadanej wzorem f(x) = a sin(t) + b a następnie użyj go w funkcji main. Współczynniki a, b, poczatek i koniec całkowania oraz lizbe przedziałów na które ma zostać podzielona funkcja podcałkowa użytkownik ma podawać z klawiatury.

Zadanie 3

Napisz funkcje do rezerwacji i zwalniania pamięci dla tablicy jednowymiarowej oraz do wczytywania danych z klawiatury i wyświetlania zawartości tablicy na ekranie.

Zadanie 4

Napisz funkcje do rezerwacji i zwalniania pamięci dla tablicy dwuwymiarowej oraz do wczytywania danych z klawiatury i wyświetlania zawartości tablicy na ekranie.

Zadanie 5

Napisz podprogram zwracajacy największy i najmniejszy element macierzy oraz pozycje na których się znajdują.

Zadanie 6

Napisz funkcję realizujacą mnożenie macierzy. Parametrami wejściowymi powinny być obie macierze (argumenty) oraz ich wymiary. Wynikiem natomiast iloczyn tych macierzy. Ponadto w programie wykorystaj wcześniej stworzone funkcje do rezerwacji, zwalnianai, wczytywania i wyświetlania macierzy.



Wyszukiwarka

Podobne podstrony:
zajęcia wyrównawcze vol I
jak pracować z dz mającymi trud w czyt i pis, WYRÓWNAWCZE, zajęcia wyrównawcze
Systemy rezerwacji turystycznej, TiR-materiały na zajęcia i kolosy, Informatyka w turystyce
Laboratorium Elektroenergetyki zajęcia 1 materiały informacyjne
klub Mlodego czytelnika, WYRÓWNAWCZE, zajęcia wyrównawcze
Ćw. usprawniających percepcję ruch, WYRÓWNAWCZE, zajęcia wyrównawcze
zajecia wyrownawcze 1
KL 4 JĘZYK POLSKI ZAJĘCIA WYRÓWNAWCZE
Technologie Informacyjne zajęcia organizacyjne Informacje ogólne
zajęcia wyrównawcze kl.II (1), Scenariusze, konspekty, klasa II
zajęcia wyrównawcze kl.II (3), Scenariusze, konspekty, klasa II
trudnosci w czytaniu i pisaniu, WYRÓWNAWCZE, zajęcia wyrównawcze
1.Drugie zajęcia wyrównawcze KONSPEKT DS, Zaawansowane materiały i nanotechnologia UJ, CHEMIA, Chemi
Jak pracuję z dzieckiem dyslektycznym, WYRÓWNAWCZE, zajęcia wyrównawcze
Specyficzne trudności w uczeniu się, WYRÓWNAWCZE, zajęcia wyrównawcze
Zajęcia dydaktyczno 1, nauczanie zintegrowane, Zajęcia wyrównawcze
Zajęcia nr 3 i 4 równania i funkcje
gloska G-zaj wyr., WYRÓWNAWCZE, zajęcia wyrównawcze

więcej podobnych podstron