Darmowe Forum
Maj 16, 2024, 12:26:32 *
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Forum zostało uruchomione!
 
   Strona główna   Pomoc Zaloguj się Rejestracja  
Strony: [1]
  Drukuj  
Autor Wątek: Argumenty funkcji przekazywane przez referencje  (Przeczytany 5313 razy)
admin
Administrator
Ekspert
*****
Wiadomości: 821


Email
« : 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« Odpowiedz #7 : Grudzień 01, 2010, 09:59:42 »

Podsumowanie
Bardzo 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Administrator
Ekspert
*****
Wiadomości: 821


Email
« 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
Strony: [1]
  Drukuj  
 
Skocz do:  

Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC | Sitemap

Polityka cookies
Darmowe Fora | Darmowe Forum

magicbears federacjagarmanii2023forum galaxyace forumdlahistorykow filtrowa36