VIP
Witam
Księga Gości
Chat
Forum
SETI@home
Bramka GG
CoToDlaNiego

Algorytmy
Programowanie
C++
PHP
Sortowanie
Drzewa BST
Listy
Stos
Kolejki
Kopce
TPB itd.

HOWTO
Linux & Windows
Linux - Bash
Linux - Chroot
mIRC
Działanie TCP
Kraków
SPMP

Galeria
Kiepscy
Wystawa '01
Wesele Idola '02
Wesele Owada '03
Wesele Emilki '06

Linki
Znajomi
Moje www
Informatyka
Drzewo rodzinne
Na Przyzbie

DownLoad
Reklama www
Zlecenie.avi
vanBasco 2.52
vanBasco 2.52 Foto
karaoke-polskie.pdf
karaoke-polskie.rar
karaoke-polskie.r00

Komunikacja
ZTM Warszawa
PKP Warszawa

Brw - Waw
Brw - Łow
Waw - Brw
Pod - Waw

Programowanie w C++

Liczba odwołań : 17141
autor : Tomasz Czwarno


  1. Funkcje bezrezultatowe i rezultatowe w C++.

  1. Funkcja bezrezultatowe.
  2. Funkcja rezultatowe.
  1. Wskaźniki i odnośniki w C++.
  1. Wskaźniki
  2. Odnośniki
  1. Zmienne statyczne i dynamiczne w C++.
  1. Zmienne statyczne
  2. Zmienne dynamiczne
  1. Funkcje rezultatowe zwykłe, wskaźnikowe i odnośnikowe w C++.
  2. Klasy
  1. Sekcje
  2. Konstruktory i Destruktory
  3. Metody
  4. Funkcje operatorowe
  1. Operator 1 argumentowy (!) umieszczony w klasie
  2. Operator 1 argumentowy (!) umieszczony poza klasą
  3. Operator 1 argumentowy następnikowy (++) umieszczony w klasie
  4. Operator 1 argumentowy następnikowy (++) umieszczony poza klasą
  5. Operator 1 argumentowy poprzednikowy (++) umieszczony w klasie
  6. Operator 1 argumentowy poprzednikowy (++) umieszczony poza klasą
  7. Operator 2 argumentowy (=) umieszczony w klasie
  8. Operator 2 argumentowy (+) umieszczony poza klasą

1.Funkcje bezrezultatowe i rezultatowe w C++.

   O tym czy funkcja ma być, rezultatowe czy nie decyduje sama jej deklaracja. Dla funkcji bezrezultatowe jest to 'void', wiąże się to z tym, że nie istnieje zmienna tego typu, więc uznaje się ja za bezrezultatową. Natomiast funkcja rezultatowa jest to każda funkcja, której typ rezultatu jest różny od 'void'.


a) Funkcja bezrezultatowa Powrót

#include <iostream.h>

void fun(int &par)   // typ rezultatu 'void' - bezrezultatowy
{
	++par;
	return;
}

int main(void)
{
	int fix = 10;
	fun(fix);       // wywołanie funkcji
	cout << fix;	// 11
return 0; }

   Zastosowanie odnośnika jako parametru funkcji, powoduje faktyczne operacje na skojarzonym z nim argumencie.I tak, jeśli wywołaliśmy funkcje fun(fix) to operacja ++ptr da ten sam rezultat co fix++.


b) Funkcja rezultatowa Powrót

#include <iostream.h>

int fun(int par)
{
	++par;
	return;
}

int main(void)
{
	int fix = 10;
	cout  << fun(fix);	// 11
	cout  << fix;		// 10
	return 0;
}
2.Wskaźniki i odnośniki Powrót

a) Wskażniki Powrót

    Wskaźnikiem jest zmienna, której można przypisać wskazanie. Wyrażenie *ptr jest nazwą chwilową zmiennej i może wskazywać wiele zmiennych. W jednej chwili *ptr wskazuje 1 zmienna ale zaraz może wskazywać 2 zmienną.


int main(void)
{
	int fix1 = 10, 
	    fix2 = 20;
	int *ptr;

	ptr = &fix1;
	cout << *ptr;	// 10
	*ptr = 11;	// ptr[0] = 11
	cout << *ptr;	// 11
	cout << fix1;	// 11

	ptr = &fix2;
	cout << *ptr;	// 20
	*ptr = 22;
	cout << *ptr;	// 22
	cout << fix2;	// 22

	ptr = 0;
	cout << *ptr;	// Błąd !!!

	return 0;
}

    Kiedy przypiszemy wskaźnikowi wskazanie puste, użycie nazwy *ptr jest zabronione do chwili przypisania mu nazwy zmiennej tego samego typu co wskaźnik.

   Jeśli wskaźnik wskazuje element tablicy int arr = {10, 20, 30}; to :


	// Przypisanie wskazania na 1 element tablicy
	int *ptr = arr;		// 10
	
	// Przypisanie wskazania na 2 element tablicy	
	int *ptr = arr + 1;	// 20
	
	// Wskazanie 2 element tablicy
	*(ptr + 1);	// 20

	// Wskazanie 2 element tablicy
	ptr[1]; 	// 20

	// Wskazanie 2 element tablicy 
	ptr += 1;	// 20

   Własności wskaźników i operacje na nich :


int main(void)
{
	int arr[3] = {10, 20, 30};
	int *ptr = arr;

	// Własności int oraz operatora ++
	int par = 1;
	cout << par << endl;	// 1
	cout << par++ << endl;	// 1
	cout << par << endl << endl;	// 2
	
	cout << par << endl;	// 2
	cout << ++par << endl;	// 3
	cout << par << endl << endl;	// 3
	
	// Własności ptr oraz operatora ++
	cout << *ptr << endl;	// 10
	// Wskazuje element nastepujący po wskazanym
	// Opracowanie nie modifikuje wskaźnika
	cout << *ptr++ << endl;	// 10	// *ptr++ = ptr++[0]
	cout << *ptr << endl << endl;	// 20

	cout << *ptr << endl;	// 20
	// Wskazuje element nastepny po wskazanym
	// Opracowanie modifikuje wskaźnik
	cout << *++ptr << endl;	// 30	// *++ptr
	cout << *ptr << endl << endl;	// 30

	cout << *ptr << endl;	// 30
	// Wskazuje ten sam element w tablicy
	// Opracowanie modyfikuje wskazania
	// Zwieksza wartość tego elementu w tablicy
	cout << ++*ptr << endl;	// 31	// ++*ptr = ++ptr[0]
	cout << *ptr << endl << endl;	// 31

	cout << *ptr << endl;	// 31
	// Wskazuje ten sam element w tablicy
	// Opracowanie nie modyfikuje wskazania
	// Zwieksza wartość tego elementu w tablicy
	cout << ptr[0]++ << endl;	// 31	// ptr[0]++
	cout << *ptr << endl << endl;	// 32

	// Wyświetlenie zawartości tablicy
	ptr = arr;
	for(int x = 0; x < 3; x++)
		cout << *ptr++ << endl;

	return 0;
}
b) Odnośniki Powrót

    Jeśli zainicjujemy odnośnik do zmiennej, to nazwa odnośnika stanie się trwała nazwą zmiennej (synonimem), a każda operacja na odnośniku będzie operacja na zmiennej.


int main(void)
{
	int fix = 10;
	int &ref = fix;

	ref = 20;
cout << ref << endl; // 20 cout << fix << endl; // 20 fix = 30; cout << fix << endl; // 30 cout << ref << endl; // 30 return 0; }
3. Zmiennych statycznych i dynamiczne Powrót

    Komputer na mikroprocesorze Intel 80-86 i działający w systemie MS-DOS dzieli pamięć na obszary zwane segmentami. Segment ma maksymalny rozmiar 64kB i jest podzielony na 3 obszary (Obszar danych statycznych, sterta i stos). Stos to obszar zmiennych automatycznych. Sterta to obszar zmiennych dynamicznych. Granica miedzy nimi jest ruchoma. W obszarze zmiennych statycznych przechowywane są zmienne statyczne i zewnętrzne.


a) Zmienne statyczne Powrót

   Zmienne statyczne w momenci utworzenia istnieją w pamięci komputera aż do końca działania programu. Przez cały jago czas.

    Klasyczny przykład błędu, funkcja zwraca wartość zmienne lokalnej po wyjściu z funkcji, ale zmienna lokalna już nie istnieje.


int &fun(void)
{
	int loc = 10;
	loc++;
	return loc;
}

int main(void)
{
	cout << fun() << endl;	// Błąd !!!
	return 0;
}

    Zastosowanie zmiennej statycznej likwiduje ten błąd.

int &fun(void)
{
	static int loc = 10;
	loc++;
	return loc;
}

int main(void)
{
	cout << fun() << endl;	// 11
	cout << fun() << endl;	// 12
	return 0;
}
b) Zmienne dynamiczne Powrót

    Zmienne dynamiczne są szczególnie przydatne, w momencie kiedy nie wiadomo od początku ile pamięci potrzeba. Pamięć zajętą przez zmienne dynamiczne trzeba konieczne zwolnić.


int main(void)
{
	int tab[3];	// Zainicjowanie 3 elementowej tablicy
	return 0;
}

int main(void)
{
	int x = 3;
	int tab[x];	// Błąd !!!
	return 0;
}

    Błąd ten można zlikwidować inicjując tablice dynamicznie.

int main(void)
{
	int x = 3;
	int *tab = new int[x];
	delete [] tab;
	return 0;
}
4. Funkcje rezultatowe z rezultatem zwykłym, wskaźnikowym i odnośnikowym. Powrót

    Poniżej przedstawione są 3 funkcje których działanie jest identyczne.


#include <iostream.h>

// rozwiązanie zwykłe
int fun1(int *arr, int par)
{
	return arr[sizeof(arr) - par];
}

// rozwiązanie wskaźnikowe
int *fun2(int *arr, int par)
{
	return &arr[sizeof(arr) - par];
}

// rozwiązanie odnośnikowe
int &fun3(int *arr, int par)
{
	return arr[sizeof(arr) - par];
}

int main(void)
{
	int tab[] ={10, 20, 30, 40, 50};
	cout << fun1(tab, 0) << endl;
	cout << *fun2(tab, 0) << endl;
	cout << fun3(tab, 0) << endl;
	return 0;
}
5. Klasy Powrót

a) Sekcje Powrót

    Składniki klasy możemy umieścić w 3 sekcjach private, public, protected . Wybór sekcji zależy od tego co zamierzamy zrobić z klasa. Gdy umieścimy składniki w sekcji private uniemożliwimy tym używanie ich poza klasą. W sekcji public składniki tam umieszczone będą mogły być używane przez wszystkie funkcje i składniki. Składniki w sekcji protected mogą być używane przez składniki jego klasy, funkcje zaprzyjaźnione oraz składniki jego klas pochodnej. W sekcjach umieszcza się składniki obiektu klasy oraz konstruktory, destruktory, metody i funkcje operatorowe.


b) Konstruktory i Destruktory Powrót

    Konstruktor klasy służy do inicjowania elementów struktury (klasy). W tym miejscu decydujemy jak będą wyglądały obiekty naszej klasy. Kiedy projektujemy dosyć skomplikowaną klasę (np. używamy wskaźniki) należy wyposażyć ją w konstruktor kopiujący, który wykona tzw. kopiowanie głębokie. Gdy nawet nie umieścimy konstruktora kopiującego, domyślnie konstruktor kopiujący zostanie umieszczony w klasie i wykonuje kopiowanie płytkie. Zalecane jest stosowanie konstruktora kopiującego kiedy np składnikami obiektu klasy są wskaźniki na jakieś elementy. Wiąże się to z destruktorami, które są składnikami wywołanymi tuż przed zniszczeniem obiektów klasy przez system. Destruktory stosuje się również kiedy stosujemy wskaźniki, gdyż kiedy system zniszczy np wskaźnik, który jest składnikiem obiektu klasy, nie usunie wskazania tego wskaźnika, który będzie zalegał pamięć. Z tego powodu stosuje się destruktory. Wracając do konstruktora kopiującego i destruktora. Kiedy stworzymy jakiś obiekt klasy, który jako składnik ma właśnie wskaźnik, to musimy tu zastosować konstruktor kopiujący, który wykona kopiowanie głębokie. Kopiowanie płytkie odpada gdyż kopiując obiekt klasy ze wskaźnikiem, skopiujemy tylko wskaźnik ale wskazanie pozostanie takie samo dla dwóch obiektów. I kiedy destruktor zniszczy obiekt pierwszy (zniszczy wskaźnik i wskazanie) ale kiedy będzie niszczył obiekt drugi będzie niszczył coś co już nie istnieje. Może to spowodować do załamania systemu.


c) Metody Powrót

    Metody są to funkcje klasy wywoływane na rzecz obiektu.


d) Funkcje operatorowe Powrót

    Funkcje operatorowe jedno lub dwu argumentowe służą do zdefiniowania operacji operatorowych na obiektach klasy. Funkcje operatorowe mogą być umieszczone w ciele funkcji lub poza nią, z tym że jeśli umieścimy je poza klasa musimy musimy ją zaprzyjaźnić z klasą.


i) Operator 1 argumentowy (!) umieszczony w klasie Owad Powrót

// np. !a - a.operator!()
void operator!(void)
{
	x = 0;
}
ii) Operator 1 argumentowy (!) umieszczony poza klasą Owad. Powrót

// np. !a - operator!(a)
friend void operator!(Owad &par)	// Umieszczone gdzieś w klasie
void operator!(Owad &par)
{
	par.im = 0;
}
iii) Operator 1 argumentowy następnikowy (++) umieszczony w klasie Owad. Powrót

//np. a++ - a.operator++(0)
void operator++(int)
{
	x = 0;
}
iv) Operator 1 argumentowy następnikowy (++) umieszczony poza klasą Owad. Powrót

// np. a++ - operator++(a, 0)
friend void operator++(Owad &par, int)	// Umieszczone gdzieś w klasie
void operator!(Owad &par)
{
	par.x = 0;
}
v) Operator 1 argumentowy poprzednikowy (++) umieszczony w klasie Owad. Powrót

// np. ++a - a.operator++()
void operator++(void)
{
	x = 0;
}
vi) Operator 1 argumentowy poprzednikowy (++) umieszczony poza klasą Owad. Powrót

// np. ++a - operator++(a)
friend void operator++(Owad &par)	// Umieszczone gdzieś w klasie
void operator++(Owad &par)
{
	par.x = 0;
}
vii) Operator 2 argumentowy (=) umieszczony w klasie Owad. Powrót

// np. a = b - a.operator=(b)
Rozpatrzmy 3 aspekty: a = b, a = b = c, a = a. 
Dla jasności Lewy element to this, a Prawy to par

// To rozwiązanie realizuje tylko a = b, 
// przy a=b=c za b=c zostanie zwrócone void
   
&operator=(Owad &par)	
{
	// Użycie return *this wiąże się z & - &operator
	this->x = par.x;
	// Jest to typowe użycie wskaźnika, 
	// gdy chcemy zmienić wartość wejściową
	return *this;
}

// To rozwiązanie jest już lepsze od poprzedniego gdyż 
// przy a=b=c za b=c zostanie zwrócone b.

Owad &operator=(Owad &par)	
{
	this->x = par.x;
}

// To rozwiązanie jest kolejnym ulepszeniem 
// zabezpieczającym przed operacja a = a

Owad &operator=(Owad &par)
{
	if(this != &par) {
		this->x = par.x;
		return *this;
	}
	return *this;
}
viii) Operator 2 argumentowy (+) umieszczony poza klasą Owad. Powrót

// np. a + b - operator+(a, b)
friend Owad &operator+(Owad &parL, Owad &parR)	// Umieścic gdzieś w klasie
Owad operator+(Owad &parL, Owad &parR)
{
	return parL.x + par.R;
}

Wszelkie prawa zastrzeżone (c) 2001 Tomasz Czwarno - owad (na) czwarno.pl

Sondy
Wigilia 2001
Kraków 2002
Karaoke 2003

Logowanie
Login :
  
Hasło :
  

  






One-Word-A-Day

PJWSTK

PHP != HTML