Przesyłanie wskaźnika przez wartość.

0

Mam następujący dylemat:
Dlaczego jedna funkcja operuje na kopiach, a druga na wartościach oryginalnych?
Jak to się ma do stosu?

  1. W przypadku obu wywołań funkcji, przesyłane są do niej adresy wskaźników (jako argumenty formalne funkcji)
  2. W momencie wywołania funkcji, na stos odkładana jest ramka stosu. W przypadku funkcji swap1(), parametrem funkcji jest adres wskaźnika pa oraz pb, w przypadku swap2 kolejno &pc oraz &pd.
  3. W funkcji do wskaźnika x przypisywana jest wartość wskaźnika y(adres zmiennej a) i odwrotnie: do wskaźnika y, przypisywana jest wartość wskaźnika x(adres zmiennej b). Jest to więc tak na prawdę przypisanie wartości wskaźników -> adresów zmiennych.

I teraz pytanie zasadnicze: W obu przypadkach w funkcjach są tworzone kopie wskaźników na potrzeby funkcji, ale pierwsza funkcja operuje na zmiennych lokalnych, a druga na zmiennych na rzecz których została wykonana, czyli po za ramką stosu. Dobrze to rozumiem?

int main()
{
    int a = 666, b = 2137;
    int *pa= &a;
    int *pb= &b; 
    printf ("%d, %d\n", *pa, *pb);
    swap1(pa, pb); 
    printf ("%d, %d\n", *pa, *pb);
    
    int c = 1, d = 999;
    int *pc= &c;
    int *pd= &d; 
    printf ("%d, %d\n", *pc, *pd);
    swap2(pc, pd);
    printf ("%d, %d\n", *pc, *pd);
}

void swap1(int *x, int *y)
{
    int *temp = x;  
    x = y;
    y = temp;
}

void swap2(int *x, int *y)
{
    int *temp = x;  
    *x = *y;         
    *y = *temp;
}
3
  1. Źle. Parametrami są wskaźniki. Przekazywane są ich kopie.
  2. Piszesz w C albo C++ (ciężko określić bez sensownych tagów), żadne stosy nie powinny ciebie na tym poziomie interesować.
  3. Nie rozumiem co masz na myśli.

Zalecam lekturę: Przekazywanie parametru przez wartość i referencję

Jak ci to robi różnicę, użyj using some_type = int* i zobacz czy będzie dla ciebie czytelniej zrozumieć zasadę działania gdy podmienisz some_type z int* na int*.

1

Za bardzo sobie komplikujesz to w głowie. W jednej funkcji zamieniasz wskaźniki by pokazywały na inne wartości, a w drugiej wykonujesz kopie wartości do innych wskaźników.

0

Programuję w C, referencja mnie nie dotyczy.
Przerabiam książkę "Wskaźniki w języku C - przewodnik" Richarda Reese i stąd pytanie gdyż materiał mocno zahacza o pojęcie stosu.

2

Powinno być tak:

void swap3(int *x, int *y)
{
    int tmp = *x; // kopia wartości wskazywanej, a nie kopia wskaźnika!
    *x = *y;
    *y = tmp;
}

twój swap1 nie robi nic, bo podmienia sobie argumenty funkcji (wskaźniki).
twój swap2 jest błędny, bo robisz kopie wskaźnika, zamiast kopię wskazywanej wartości, więc efektywnie ustawiasz wartość wskazywaną przez x na wartość wykazywaną przez y (nadpisujesz, a nie zamieniasz miejscami wartości).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.