• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wskaźniki i funkcja

Object Storage Arubacloud
+1 głos
575 wizyt
pytanie zadane 25 czerwca 2016 w C i C++ przez SebekMakaron Obywatel (1,290 p.)
#include <iostream>

using namespace std;

void Dereferencja(string *imie, string *nazwisko)
{
     nazwisko = NULL;
     string nazwa;

     cout<<"Podaj imie: ";
     cin>>*imie;

     if(nazwisko == NULL){
          cout<<"Podaj nazwisko: ";
          cin>>nazwa;
     }
     nazwisko = &nazwa;
     cout<<*nazwisko<<endl;
}

int main(){

    string imie, nazwisko;

    Dereferencja(&imie, &nazwisko);

    cout<<imie<<endl;
    cout<<nazwisko;

     return 0;
}

Witam. Mam pytanie dlaczego nie wyświetla mi nazwiska z int main()? Czy może ten kod jest zły?

4 odpowiedzi

+1 głos
odpowiedź 25 czerwca 2016 przez Sedi Stary wyjadacz (10,200 p.)
wybrane 25 czerwca 2016 przez SebekMakaron
 
Najlepsza

Jak widzę te wszystkie bzdury napisane przez ludzi, którym wydaje się, że wiedzą, co piszą, to mnie krew zalewa.

Krótko i na temat

  • Jeśli do funkcji przesyłasz wskaźnik poprzez "gwiazdkę", możesz zmienić tylko jej wartość
  • Znaczek "&", oznacza, że przekazujesz albo adres albo oryginały wartości. Zależnie od kontekstu.
  • Jeśli zapisałbyś takie cudo:
nazwisko=&nazwa;
  • Oznaczałoby to, że nazwisko ma mieć taki sam adres jak nazwa. Natomiast do funkcji przekazałeś tylko wartość. Żeby powyższy zapis zadziałał, potrzebowałbyś przesłać ampersandem (&) oryginalny adres. Lepszym pomysłem byłoby zapisanie bez &. Oraz oczywiście dodanie: gwiazdki przed nazwiskiem, jak to przy wskaźnikach.

Pozdrawiam

+2 głosów
odpowiedź 25 czerwca 2016 przez criss Mędrzec (172,590 p.)

Wewnątrz funkcji Dereferencja tworzysz stringa nazwa. To jest obiekt lokalny i przestaje istnieć po wykonaniu funkcji. Także skoro do nazwisko przypisujesz adres nazwa to po wykonaniu funkcji (nazwa przestaje istnieć), nazwisko nie wskazuje już na nic konkretnego.

komentarz 25 czerwca 2016 przez SebekMakaron Obywatel (1,290 p.)
Dzieje się tak tylko w przypadku wskaźnika? Zwykła zmienna np. int a = b; została by normalnie zwrócona do programu mimo że 'b' jest lokalna zmienna a zmienna 'a' jest zwracana i zostaje w niej już ta wartość zmiennej lokalnej 'b'? Jeśli dobrze to wytłumaczyłem i jest to prawdą to dużo mi wyjaśniłeś dzięki
1
komentarz 25 czerwca 2016 przez criss Mędrzec (172,590 p.)
W przypadku "zwykłych zmiennych" po prostu kopiujesz wartość z jednego miejsca do drugiego. Tutaj jednak przypisujesz do wskaźnika inny adres komórki, który może stać sie nieaktualny (tzn. nie bezie tam juz tego co oczekujesz) i tak sie dzieje tutaj.
+1 głos
odpowiedź 25 czerwca 2016 przez p0m0 Obywatel (1,190 p.)
edycja 25 czerwca 2016 przez p0m0

Wiem!!!

W funkcji Dereferencja() string *nazwisko oznacza, że jest to wskaźnik na stringa. Następnie ustawiasz ten wskaźnik na NULL, a następnie nadpisujesz go tym nazwisko = &nazwa; i ostatecznie nazwisko w Dereferencja jest wskaźnikiem na stringa nazwa.

Aby działało trzeba by było to zrobić tak:

#include <iostream>

using namespace std;

void Dereferencja(string *imie, string *nazwisko)
{
     *nazwisko = "";//nazwisko = NULL;
     string nazwa;

     cout<<"Podaj imie: ";
     cin>>*imie;

     if(*nazwisko == ""){//if(nazwisko == NULL){
          cout<<"Podaj nazwisko: ";
          cin>>nazwa;
     }
     *nazwisko = nazwa;//nazwisko = &nazwa;

     cout<<*nazwisko<<endl;
}

int main(){

    string imie, nazwisko;

    Dereferencja(&imie, &nazwisko);

    cout<<imie<<endl;
    cout<<nazwisko;

     return 0;
}

Uwaga!!!

string imie i string nazwisko z maina nie ma zbyt dużo związku z string *imie i string *nazwisko z Dereferencja().

Jedyny ich związek jest taki, że wykonując to: Dereferencja(&imie, &nazwisko); ustawiamy wskaźniki string *imie i string *nazwisko tak, że wskazują na string imie i string nazwisko z maina.

1
komentarz 25 czerwca 2016 przez Sedi Stary wyjadacz (10,200 p.)
Dlaczego nie mają zbyt dużego związku ?
komentarz 25 czerwca 2016 przez p0m0 Obywatel (1,190 p.)

Jak napisałem: Jedyny ich związek jest taki, że wykonując to: Dereferencja(&imie, &nazwisko); ustawiamy wskaźniki string *imie i string *nazwisko tak, że wskazują na string imie i string nazwisko z maina.

Ich nazwy nie mają tu znaczenia. W funkcji Dereferencja() zamiast zmiennych string *imie, string *nazwisko mogło by być string *a, string *b, a cała funkcjia wyglądała by tak:

void Dereferencja(string *a, string *b)
{
     *b= "";//b= NULL;
     string nazwa;
 
     cout<<"Podaj imie: ";
     cin>>*a;
 
     if(*b== ""){//if(b== NULL){
          cout<<"Podaj nazwisko: ";
          cin>>nazwa;
     }
     *b= nazwa;//b= &nazwa;
 
     cout<<*b<<endl;
}

I program miał by takie same działanie.

Nie mają zbyt dużego związku, gdyż string *nazwisko z funkcji Dereferencja to wskaźnik na stringa, zaś string nazwisko to string lokalny funkcji main(). W pewnym momencie kodu przypisujesz do jednej z tych zmiennych wskaźnik na drugą, ale potem jest ona ustawiona na NULL.

komentarz 25 czerwca 2016 przez Sedi Stary wyjadacz (10,200 p.)
W Twoim przykładzie po wykonaniu zmienna b trwale zmieni wartość na tą podaną przez użytkownika. NULL nie ma tu nic do rzeczy
0 głosów
odpowiedź 26 czerwca 2016 przez SebekMakaron Obywatel (1,290 p.)
edycja 26 czerwca 2016 przez SebekMakaron

W jaki sposób mogę zwrócić dwa wyniki z jednej funkcji używając do tego wskaźników i referencji?

#include <iostream>

using namespace std;

int Dereferencja(int *jeden, int *dwa)
{
     int t_jeden = *jeden;
     int t_dwa = *dwa;

     *jeden = t_jeden + t_dwa;
     *dwa = t_jeden * t_dwa;

     return *dwa;
}

int main(){

     int j = 1, d = 2;

     Dereferencja(&j, &d);

     cout<<j<<endl<<d;

     return 0;
}

Treść zadania:

"Napisz funkcje która pobiera dwa argumenty i zwraca dwa odrębne wyniki. Jednym z wyników powinien być iloczyn obu argumentów, a drugim ich suma. Ponieważ funkcja może bezpośrednio zwrócić tylko jedną wartość, druga wartość powinna być zwrócona poprzez parametr wskaźnika albo referencji."

Prosiłbym o spojrzenie na treść zadania i moje rozwiązanie kogoś kto ma większe pojęcie o c++ niż ja. Ogólnie kod spełnia zadanie ale czy jest poprawny ze strony standardów czy tym podobne?

Podobne pytania

+1 głos
2 odpowiedzi 380 wizyt
pytanie zadane 31 maja 2016 w C i C++ przez Arkadiusz Sieczak Początkujący (400 p.)
0 głosów
2 odpowiedzi 519 wizyt
pytanie zadane 25 grudnia 2020 w C i C++ przez dark41 Użytkownik (760 p.)
0 głosów
2 odpowiedzi 358 wizyt
pytanie zadane 24 listopada 2018 w C i C++ przez eSpring Początkujący (270 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...