Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Nie do końca rozumiem referencje.

Ostatnio zmodyfikowano 2017-06-13 21:18
Autor Wiadomość
krokots
Temat założony przez niniejszego użytkownika
Nie do końca rozumiem referencje.
» 2017-06-13 13:03:42
Cześć. Ucze się C++ od kilku dni i jakoś do tej pory nie jestem w 100% pojąć działanie referencji. Robię np coś takiego :

C/C++
#include <iostream>

using namespace std;

int a = 1, b = 1;

int & retInt1( int & i )
{
    return i;
}

int retInt2( int & i )
{
    return i;
}

int main()
{
    int * ptr_1, * ptr_2;
    ptr_1 = & retInt1( a );
    //ptr_2 = &retInt2(a); //To nie będzie działać
    cout << "Adr a : " << & a << endl;
    cout << "Adr b : " << & b << endl;
    cout << "Adr f1 : " << & retInt1( a ) << endl;
    //cout << "Adr f2 : " << &retInt2(a) << endl; //To też
}
Chciałem sobie zobaczyć, jaka jest różnica w funkcjach "int" a "int&", jak się zachowują wartości zwracane itp.
Czemu nie da się przypisać do "ptr_2" adresu &retInt2(a) ? Myślałem, że to powinno przypisać adres (jakiejś) zmiennej która powstanie w wyniku funkcji "retInt2".
P-162480
DejaVu
» 2017-06-13 14:27:29
http://cpp0x.pl/kursy/Kurs-C++​/Poziom-3​/Przekazywanie-argumentow-funk​cji-przez-referencje​/356

C/C++
#include <iostream>

void wypisz( int & iLiczba )
{
    std::cout << "Wartosc liczby wynosi: " << iLiczba << std::endl;
    iLiczba += 10;
    std::cout << "Wartosc liczby wynosi: " << iLiczba << std::endl;
}

int main()
{
    int iNaszaLiczba = 7;
    std::cout << "Nasza liczba = " << iNaszaLiczba << std::endl;
    wypisz( iNaszaLiczba );
    std::cout << "Nasza liczba = " << iNaszaLiczba << std::endl;
    return 0;
}
Sprawdź co wypisuje ten program w ostatniej linijce gdy argument funkcji posiada referencję i gdy jej nie posiada.

W skrócie:
  • brak referencji = posiadasz kopię danych w funkcji
  • jest referencja = posiadasz dostęp do oryginalnych danych w funkcji
P-162482
Monika90
» 2017-06-13 14:59:45
Myślałem, że to powinno przypisać adres (jakiejś) zmiennej która powstanie w wyniku funkcji "retInt2".
Ale tam nie powstaje żadna zmienna, jest tylko sama wartość zwrócona z funkcji. C++ nie pozwala na pobranie jej adresu, gdyby można było pobrać ten adres to i tak nic nie można by z nim zrobić, bo ta zwrócona z funkcji wartość, chwilę później, przestaje istnieć.
P-162483
krokots
Temat założony przez niniejszego użytkownika
» 2017-06-13 15:16:17
Dzięki. Właściwie w między czasie już mnie olśniło. Czyli w uproszczeniu:
dla funkcji
C/C++
int & retInt1( int & i )
{
    return i;
}
zwracana jest dokładnie ta sama zmienna "i" co jest przy return. Ma ona już swój adres więc można go przypisać do pointera.
Dla funkcji
C/C++
int retInt2( int & i )
{
    return i;
}
zwracana jest kopia "i" która jest stałą dosłowną.
Czyli pisanie
C/C++
//ptr_2 = &retInt2(a); //To nie będzie działać
To tak samo, jakbym pisał coś w tym stylu:
C/C++
//ptr_2 = &1; //To nie będzie działać
Czyli chciałem mieć adres jakiejś stałej, która była kopią poprzedniego "i". Tak ja to przynajmniej rozumiem.
P-162484
Monika90
» 2017-06-13 15:54:30
Tak, podobnie nie można zrobić tego: &(2+2), tylko "stała dosłowna" to nie jest termin jakiego się używa w C++, w końcu nie ma tu stałej - typem 1 jest int, a nie const int. W C++ wyrażenie takie jak 1, 2+2, retInt2(a), nazywa się prvalue, a retint1(a) to lvalue. Nie możesz pobrać adresu prvalue, ponieważ po prostu nie ma obiektu, którego adres można by było pobrać. Choć są sposoby by wymusić materializację obiektu tymczasowego i by przedłużyć mu życie.
P-162485
krokots
Temat założony przez niniejszego użytkownika
» 2017-06-13 20:04:55
Dzięki. Jeszcze nie interesowałem się 'lvalue' ani 'prvalue' podczas swojej nauki, ale będę już wiedział.
Najprościej - "&" przy funkcji zmusza ją do zwrócenia dokładnie tej samej zmiennej jaka jest przy "return".
Jeżeli bym zrobił funkcje w takiej wersji:
C/C++
int & retInt3( int i )
{
    return i;
}
To rozumiem, że dało by się potem zrobić
C/C++
ptr_3 = & retInt3( a );
Choć wynik będzie jakimiś śmieciami.
P-162499
DejaVu
» 2017-06-13 20:56:20
Niestety piszesz błędny kod.
P-162508
mateczek
» 2017-06-13 21:05:44
masz :P
C/C++
#include <iostream>

using namespace std;
int & inc( int & i ) {
    i++;
    return i;
}


int main()
{
    int zmienna = 15;
    inc( zmienna ) -= 20;
    cout << zmienna << endl;
}
P-162509
« 1 » 2
  Strona 1 z 2 Następna strona