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
|
|
|
|
|