admin
|
|
« : Pa¼dziernik 20, 2010, 04:40:20 » |
|
Wska¼niki * Dotychczas, we wszystkich funkcjach które przedstawia³em, argumenty by³y przekazywanych do funkcji przez warto¶æ. Oznacza to, ¿e wywo³anie funkcji z parametrami, powodowa³o,¿e do funkcji przekazywane by³y by³y kopie warto¶ci zmiennych ale nie orygina³y. Oznacza to, ¿e warto¶æ pocz±tkowa zmiennej przekazanej do funkcji nie by³a modyfikowana przez ta funkcjê.
Wska¼niki s± odpowiednikiem adresu pamiêci w której umieszczono warto¶æ zmiennej. Stanowi± uzupe³nienie klasycznych zmiennych. Wska¼niki deklarowane s± podobnie jak inne zmienne, przed jej u¿yciem. Jedyn± ró¿nic± jest wpisanie gwiazdki przed nazw± zmiennej wska¼nikowej. Istotn± ró¿nica w porównaniu do deklaracji zmiennych jest to,¿e odwo³anie nastêpuje do wskazania adresu (wskazania!!!!).
Przyk³ad 1 -deklaracja zmiennej wska¼nikowej
using namespace std; main() {int *i, *a,b; char *ab_adr; system("pause");}
W programie zadeklarowano zmienne wska¼nikowe: i, a, ab_adr. Bardzo wa¿nym jest umiejêtno¶æ stwierdzenia jaka warto¶æ znajduje pod zmienn± wska¼nikow± (adresem wskazywanym przez wska¼nik). Nale¿y pamiêtaæ,¿e zmienna *a przedstawia warto¶æ która znajduje siê pod adresem a (a- to inna nazwa adresu).
Przyk³ad 2 - odczytywanie warto¶ci ukrytej pod adresem przekazywanym przez wska¼nik.
#include <cstdlib> #include <iostream>
using namespace std;
int main(int argc, char *argv[]) { int *i,*a,b; *i=1000; cout<<" w pamiêci komputera pod adresem: "<<i<<endl; cout<<"znajduje siê warto¶æ: "<<*i<<endl; system("PAUSE"); return EXIT_SUCCESS; }
Program kompiluje poprawnie jednak jego wywo³anie powoduje b³±d (WIN Vista). Dlaczego? Program napisany powy¿ej zapisuje w pamiêci pod przypadkowym adresem warto¶æ 1000. Problem polega na braku ustalonego miejsca w pamiêci w którym ma byæ zapisana liczba 1000. Miejsce to jest przypadkowe, je¿eli trafi na komórkê w którym jest umieszczona np. warto¶æ opisuj±ca rozdzielczo¶æ ekranu to zostanie ona zmieniona na inn±, co spowoduje zak³ócenia w pracy komputera. Na szczê¶cie systemy operacyjne chroni± istotne obszary pamiêci operacyjnej.
|
|
« Ostatnia zmiana: Maj 30, 2012, 10:16:51 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #1 : Listopad 24, 2010, 11:02:02 » |
|
Aby unikn±æ nieprzyjemnych sytuacji w przypadku zajêcia pamiêci przez zmienn±, konieczne jest poinformowanie kompilatora o wyszukaniu pierwszego wolnego adresu w pamiêci operacyjnej. Takim poleceniem jet polecenie new. Polecenie new powoduje przeniesienie warto¶ci wska¼niki pod najbli¿szy wolny adres pamiêci. Zbyt du¿a liczba zadeklarowanych zmiennych wska¼nikowych powoduje zajêcie pamiêci. Samoczynnie niestety nie mo¿e byæ ona zwolniona wobec tego konieczne jest jej zwolnienie przez polecenie zwolnienia pamiêci o czym w dalszej czê¶ci. Przyk³ad poprawnie dzia³aj±cego programu który wpisuje do wolnej pamiêci liczbê 1000. Przyk³ad 3. #include <cstdlib> #include <iostream> using namespace std;
int main(int argc, char *argv[]) {int *i=new int,*a=new int,b; *i=1000; cout<<" w pamiêci komputera pod adresem: "<<i<<endl; cout<<"znajduje siê warto¶æ: "<<*i<<endl; system("PAUSE"); return EXIT_SUCCESS; }
|
|
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #2 : Listopad 24, 2010, 11:16:29 » |
|
Zwolnienie zajmowanej pamiêci operacyjnej - polecenie delete
#include <cstdlib> #include <iostream> using namespace std;
int main(int argc, char *argv[]) {int *i=new int,*a=new int,b; *i=1000; cout<<" w pamiêci komputera pod adresem: "<<i<<endl; cout<<"znajduje siê warto¶æ: "<<*i<<endl; delete[]i; delete a; system("PAUSE"); return EXIT_SUCCESS; }
|
|
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #3 : Listopad 24, 2010, 11:31:11 » |
|
Dynamiczna deklaracja tablicy
#include <cstdlib> #include <iostream> using namespace std;
int main(int argc, char *argv[]) {int *i,*a=new int,z; i=new int[10]; for(z=0;z<10;z++){i[z]=z;} for(z=0;z<10;z++){ cout<<" w pamiêci komputera pod adresem: "<<i[z]<<endl;} delete[]i; delete a; system("PAUSE"); return EXIT_SUCCESS; }
|
|
« Ostatnia zmiana: Listopad 24, 2010, 11:36:10 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #4 : Listopad 24, 2010, 11:33:10 » |
|
Operator adresowy & - Je¿eli chcemy znale¼æ pod jakim adresem przechowywana jest zmienna z to wystarczy wprowadziæ operator adresowy &. Przyk³ad 5 #include <cstdlib> #include <iostream> using namespace std;
int main(int argc, char *argv[]) {int *i,*a=new int,z; i=new int[10]; for(z=0;z<10;z++){i[z]=z;} for(z=0;z<10;z++){ cout<<" w pamiêci komputera pod adresem: "<<i[z]<<endl; cout<<"zmienna z znajduje siê pod adresem: "<<&z<<endl;} delete[]i; delete a; system("PAUSE"); return EXIT_SUCCESS; }
|
|
« Ostatnia zmiana: Maj 30, 2012, 10:21:57 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #5 : Grudzieñ 01, 2010, 09:07:08 » |
|
Zadanie 6. Proszê napisaæ program który prosi o podanie piêciu liczb i umieszcza te liczby w pamieci komputera. Zmienne proszê zadeklarowaæ jako zmienne referencyjne. Po wprowadzeniu danych proszê wy¶wietliæ ich warto¶ci oraz adresy pod którymi s± przechowywane.
#include <cstdlib> #include <iostream>
using namespace std;
int main(int argc, char *argv[]) {int *a=new int, *b=new int, *c=new int,*d= new int, *e= new int; cout<<"Podaj pierwsz± warto¶æ: ";cin>>*a; cout<<"Podaj druga warto¶æ: ";cin>>*b; cout<<"Podaj trzecia warto¶æ: ";cin>>*c; cout<<"Podaj czwarta warto¶æ: ";cin>>*d; cout<<"Podaj piata warto¶æ: ";cin>>*e; cout<<endl<<"Pod aderem:"<<a<<" znajduje siê piersza wartosc= "<<*a; cout<<endl<<"Pod aderem:"<<a<<" znajduje siê piersza wartosc= "<<*a; cout<<endl<<"Pod aderem:"<<b<<" znajduje siê piersza wartosc= "<<*b; cout<<endl<<"Pod aderem:"<<c<<" znajduje siê piersza wartosc= "<<*c; cout<<endl<<"Pod aderem:"<<d<<" znajduje siê piersza wartosc= "<<*d; cout<<endl<<"Pod aderem:"<<e<<" znajduje siê piersza wartosc= "<<*e; cout<<endl; system("PAUSE"); return EXIT_SUCCESS; }
|
|
« Ostatnia zmiana: Grudzieñ 01, 2010, 09:20:53 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #6 : Grudzieñ 01, 2010, 09:39:26 » |
|
Zadanie 7. To co w zadaniu 6 tylko na tablicach
#include <cstdlib> #include <iostream>
using namespace std;
int main(int argc, char *argv[]) { int *i=new int[5]; int a; for (a=0;a<5;a++){cout<<"Podaj jakas liczbe : ";cin>>i[a];} for (a=0;a<5;a++){cout<<"Pod adresem: "<<&i[a]<<"znajduje sie liczba "<<i[a];cout<<endl;} system("PAUSE"); return EXIT_SUCCESS; }
|
|
« Ostatnia zmiana: Grudzieñ 01, 2010, 10:01:53 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #7 : Grudzieñ 01, 2010, 09:59:42 » |
|
PodsumowanieBardzo istotnym zagadnieniem jest sposób przekazywania danych do wnêtrza funkcji czyli argumentów funkcji. Z Pascala wiadomo ,¿e istnieje mo¿liwo¶æ przekazywania argumentu przez:
- warto¶æ, co polega na przekazaniu do funkcji kopii zmiennej-argumentu; zmienna wewnêtrzna funkcji (czyli kopia prywatna) mo¿e byæ modyfikowana, choæ na oryginaln± zmienn± zewnêtrzn± nie ma to wp³ywu.
- referencjê, co polega na wskazaniu funkcji lokalizacji oryginalnej zmiennej w pamiêci; to wskazanie mo¿e odbywaæ siê za pomoc± wska¼nika (operator *) lub przez referencjê (operator &).
Referencje i wska¼niki najczê¶ciej wykorzystywane s± w: tablicach, funkcjach.
|
|
« Ostatnia zmiana: Grudzieñ 01, 2010, 10:01:31 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #8 : Grudzieñ 01, 2010, 10:05:15 » |
|
Zadanie 8. Przyk³ad wykorzystania przekazywania zmiennej przez kopiê .
#include <cstdlib> #include <iostream>
using namespace std; void dodaj(double a); int main(int argc, char *argv[]) {double b=21; cout<<"Liczba b= "<<b<<endl; dodaj(b); cout<<endl<<"Liczba b po dzia³aniu= "<<b<<endl; system("PAUSE"); return EXIT_SUCCESS; } void dodaj(double a) {a=a+5.2; cout<<" Zwiêkszam liczbê o 5.2="<<a<<endl;}
W tym przyk³adzie pojawia siê mechanizm ochrony orygina³u (b). Dana b zosta³a przekazana do wnêtrza funkcji jako kopia. Funkcja j± przerobi³a dodaj±c 5.2, ale warto¶æ orygina³u nie uleg³a zmianie. Funkcja skopiowa³a sobie argument (warto¶æ zmiennej b), nie pracuj±c na oryginale. Warto¶æ zmiennej wewn±trz funkcji mo¿e byæ modyfikowana bez wp³ywu na ich warto¶æ poza funkcj±. Jest to przekazywanie zmiennej przez warto¶æ (by value).
|
|
« Ostatnia zmiana: Grudzieñ 01, 2010, 10:14:00 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #9 : Grudzieñ 01, 2010, 10:20:38 » |
|
Zadanie 9. Przyk³ad przedstawiaj±cy operacje wykonywane na oryginale argumentu.
#include <cstdlib> #include <iostream>
using namespace std; void dodaj(double &a); int main(int argc, char *argv[]) {double b=21; cout<<"Liczba b= "<<b<<endl; dodaj(b); cout<<endl<<"Liczba b po dzia³aniu= "<<b<<endl; system("PAUSE"); return EXIT_SUCCESS; } void dodaj(double &a) {a=a+5.2; cout<<" Zwiêkszam liczbê o 5.2="<<a<<endl;}
Po wprowadzeniu operatora &, funkcja zaczyna pracowaæ na oryginale. Zmiana warto¶ci argumentu b, nie jest tylko w jego wnêtrzu ale w ca³ym programie. Funkcja pracuje na orygina³ach swoich argumentów. Uwaga: Gdy argumenty s± przekazywane referencyjnie, przy nazwach pojawia siê operator & przy deklaracji i nag³ówku.
|
|
« Ostatnia zmiana: Grudzieñ 01, 2010, 10:22:49 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #10 : Grudzieñ 01, 2010, 11:08:55 » |
|
Zadanie 10. Proszê napisaæ program, który poprosi o wprowadzenie liczby z klawiatury. Po wprowadzeniu liczby, wy¶wietli jej warto¶æ, nastêpnie w funkcjach dodaj i odejmij odpowiedni wykona dodawanie i odejmowanie od tej liczby warto¶ci 5.5 i wy¶wietli wynik na ekranie. Na koniec wy¶wietli jeszcze raz warto¶æ wprowadzonej liczby. Do funkcji maj± byæ przekazane kopie liczby. #include <cstdlib> #include <iostream>
using namespace std; void dodaj(double a); void odejmij(double a); int main(int argc, char *argv[])
{double b; cout<<endl<<"Podaj liczbe: ";cin>>b; cout<<"Liczba b= "<<b<<endl; dodaj(b);cout<<endl; odejmij(b); cout<<endl<<"Liczba b po dzia³aniu= "<<b<<endl; system("PAUSE"); return EXIT_SUCCESS; } void dodaj(double a) {a=a+5.2; cout<<" Zwiêkszam liczbê o 5.2="<<a<<endl;} void odejmij(double a) {a=a+5.2; cout<<" Zmniejszam liczbê o 5.2="<<a<<endl;}
|
|
« Ostatnia zmiana: Grudzieñ 01, 2010, 11:54:28 wys³ane przez admin »
|
Zapisane
|
|
|
|
admin
|
|
« Odpowiedz #11 : Grudzieñ 01, 2010, 12:40:14 » |
|
Przeci±¿anie funkcji. Przeci±¿anie funkcji jest to mo¿liwo¶æ napisania w programie kilku funkcji o tej samej nazwie, lecz ró¿ni±cych siê miêdzy sob±: typem zwracanej wielko¶ci, liczb± argumentów lub typem argumentów. W programie przedstawionym poni¿ej zadeklarowa³em dwie funkcje o nazwie odejmij. Jedna z nich zwraca zmienn± typu double, druga zwraca warto¶æ pust± (void). Dodatkowo funkcje ró¿ni± siê liczb± argumentów pierwsza ma jeden argument, druga wymaga wprowadzenia dwóch argumentów.
#include <cstdlib> #include <iostream> using namespace std;
void dodaj(double a); void odejmij(double a); double odejmij( double a, double b); int odejmij(int c,int d){};
int main(int argc, char *argv[]) {double b; cout<<endl<<"Podaj liczbe: ";cin>>b; cout<<"Liczba b= "<<b<<endl; dodaj(b);cout<<endl; odejmij(b); cout<<endl<<"Liczba b po dzia³aniu= "<<b<<endl; system("PAUSE"); return EXIT_SUCCESS; } void dodaj(double a) {a=a+5.2; cout<<" Zwiêkszam liczbê o 5.2="<<a<<endl;} void odejmij(double a) {a=a+5.2; cout<<" Zwiêkszam liczbê o 5.2="<<a<<endl;} double odejmij( double a, double b) {a=a+b; return a;}
|
|
|
Zapisane
|
|
|
|
|