void f(float * x, float * y) {
* y = -- * x;
x = y;
++ * x;
}
Mamy dwa wskaźniki, y oraz x. W pierwszej linii tej funkcji (linia nr 5 u Ciebie) do wartości y (czyli do pola w pamięci, na które wskazuje wskaźnik y) przypisujemy wartość pola, na którą wskazuje wskaźnik x, ale również pomniejszamy wartość tego pola o 1. W następnej linii mamy przypisanie - stąd teraz x wskazuje na y. Na koniec zwiększamy wartość znajdującą się w polu, na które wskazuje x.
Mamy krótką analizę, to możemy działać.
Do funkcji przekazujesz dwa wskaźniki: jeden wskazuje na początek tablicy, bo tab jest równoważny &tab[0] oraz x, który w rzeczywistości wskazuje na &tab[1]. (Tutaj pragnę nadmienić, że w linii 13 masz zbędne wyłuskanie i pobranie referencji, wystarczy x = (tab + 1)).
Wobec tego, mamy f(&tab[0], &tab[1]).
L:5 -> przypisanie: do tab[1] przypisujemy wartość -- *(tab) = --tab[0], więc dostajemy, że tab[1] = 4.0
L:6 -> teraz mówimy, że x = y, stąd w rzeczywistości mamy tab = (tab + 1)
L:7 -> zwiększamy wartość w polu, na które wskazuje x, ale x wskazuje na (tab + 1) Poprzednio, w L:5 tab[1] = 4.0, stąd w tej linii tab[1] = 5.0
Ostatecznie na koniec funkcji mamy:
x = tab + 1, y = tab + 1, więc *x = *y = tab[1] = 5.0
I wszystko się zgadza.