zwiększanie wartości zmiennej kiedy ona sama jest wykorzystywana

0

Jak dokonuje się zwiększanie wartości jakiejś zmiennej gdy jest ona wykorzystywana przez samą siebie w momencie przypisania. Mianowicie mam na myśli że mam jakąś zmienną np.
zmienna = 1, a potem zwiększam jej wartość o 1 czyli zmienna = zmienna + 1 i w tym momencie trafia do tej zmiennej wartość 2, potem znowu następuję przypisanie zmienna = zmienna + 1 i w zmiennej siedzi już 3 itd. Jak to się odbywa że jakaś zmienna przypisuje sobie konkretną wartość w momencie kiedy jest ona w użyciu

4

tmp = x+1
x = tmp

1

Nie jest to w pełnym sensie zagadnienie teoretycznej algorytmiki. W teorii wszystko jest doskonałe, przypisanie trwa nieskończenie mało czasu itd...

Jest to problem impelmentacyjny, i rzeczywiście w warunkach współbieżności / przerwań / programów wielowątkowych.
W C jest "Undefined Behaviour"

Co wiecej, jak to jest jakiś długi integerer przekraczający "naturalną" dla platformy długość, scenariuszy negatywnych jest więcej, niż sobie wyobrażasz np 255+1 = ... różnie, 255, 256, 0 ...

Ale to rzecz zupełnie losowa, milion razy trafi ok, milion pierwszy kiszka. To trzeba raczej dobrze kodować (są na to sposoby), niż potwierdzać lipnymi testami.

Sądzę, żeby to dyskutować na gruncie języka (np C) i podanej bardzo szczegółów sytuacji ( CPU, architektura, przykład kodu)

piotrek1998 napisał(a):

... gdy jest ona wykorzystywana przez samą siebie w momencie przypisania

Nie jest to całkiem ściśle poweidziane, choć akurat rozumiem co miałeś na myśli
To KOD wykorzystuje zmienną. Zmienna jest czymś biernym

1

To po prostu wina syntaxu, który wszędzie jest podobny, ale ma inne znaczenie, zmienna = zmienna + 1, w językach c/c++ i paru innych to jest przypisanie, w matematyce jest to znak równości.

Dla przykładu ten sam przykład w matematyce będzie wyglądał tak zmienna \gets zmienna + 1

Z takiej linijki kodu, kompilator generuje sobie AST i wykonuje, w tym wypadku mamy jedną stałą zmienną o wartości 1 i jedną, którą musi wyłuskać z pamięci do rejestru, dodać razem w rejestrze i wynik przypisać pod adres w pamięci, na którą wskazuje zmienna, adres tej zmiennej możesz sobie sprawdzić wpisując np: %p lub %lx,

printf("%p", &zmienna)
2
stivens napisał(a):

tmp = x+1
x = tmp

Jeśli zmienne są w rejestrach to nawet nie trzeba tmp, bo procesory operacje jak dodawanie realizują w miejscu (przynajmniej z punktu widzenia asemblera, bo pod spodem nie wiem jak tam ten cały register renaming działa)

1

@Szalony Programista2:

W najmniejszym stopniu nie jest to sprawa syntaxu.

Syntaktyka dotyczy tego, jak (źródła programu) mają być zbudowane, aby były poprawne. W C (i olbrzymiej większości języków) kod niosący ryzyko wielowątkowe (pewność awarii ran na jakiś czas) jest poprawny syntaktycznie

To semantyka określa jak coś działa (jak skutkuje). Np w języku C mogło by być określone semantycznie, że cała instrukcja do średnika jest atomowa (bo czemu nie) ... tyle że w C tak NIE JEST (pewnie w niewielu jest, to by spowalniało).

4

Jak sobie wejdźmy sobie na Godbolta to zobaczymy, że zapis:

#include <stdio.h>

int main() {
    int zmienna;
    zmienna = zmienna + 1;
}

Tłumaczy się do

main:
        push    rbp
        mov     rbp, rsp
        add     DWORD PTR [rbp-4], 1
        mov     eax, 0
        pop     rbp
        ret

Czyli nasz dzielny kompilator przetwarza nam zapis składni języka wyższego poziomu na dodanie wartości równej jeden (drugi operand instrukcji add) do adresu wskazywanego przez rejestr rbp (który to wskazuje na wierzchołek stosu) przesunięty o 4 bajty (czyli rozmiar inta).

Na niskim poziomie komputer nie operuje na zmiennych, lecz na adresach i wskaźnikach.

3

najpierw jest przeliczana nowa wartość, a potem dopiero uaktualniana.

x = 2 * x + 3

najpierw jest obliczane 2 * x + 3, a potem dopiero wynik trafia do zmiennej x.

Na poziomie języka programowania, bo jak tam jest pod spodem, jakie kody w kodzie maszynowym są odpalane i jakie optymalizacje robi kompilator, tym już niekoniecznie trzeba się interesować, o ile interesuje nas samo koncepcyjne zrozumienie na poziomie języka programowania wysokiego poziomu.

zmienna = 1, a potem zwiększam jej wartość o 1 czyli zmienna = zmienna + 1 i w tym momencie trafia do tej zmiennej wartość 2, potem znowu następuję przypisanie zmienna = zmienna + 1 i w zmiennej siedzi już 3 itd. Jak to się odbywa że jakaś zmienna przypisuje sobie konkretną wartość w momencie kiedy jest ona w użyciu

raczej pomyśl o tym, że
x' = x + 1

x' - x prim

to koncepcyjnie są inne wartości - to, co jest teraz w zmiennej, a to, co będzie później. Nawet jeśli są trzymane w tej samej zmiennej.

0

Bo przeczytałem gdzieś że żeby jedna i ta sama zmienna mogła zmienić swoją wartość to najpierw jest obliczana wartość przypisania, czyli jak mniemam chodzi o to:

let zmienna = 0;
zmienna = zmienna + 1

potem ta wyliczona wartość jest pamiętana na boku bez związku z jakąkolwiek zmienną, a na końcu ta nowo wyliczona wartość trafia do tej zmiennej

let zmienna = 1
1
piotrek1998 napisał(a):

Bo przeczytałem gdzieś że żeby jedna i ta sama zmienna mogła zmienić swoją wartość to najpierw jest obliczana wartość przypisania, czyli jak mniemam chodzi o to:
potem ta wyliczona wartość jest pamiętana na boku bez związku z jakąkolwiek zmienną, a na końcu ta nowo wyliczona wartość trafia do tej zmiennej

To wszystko prawda (zwykle), tylko że tego nie da się tego przedstawić w wysokopoziomowych językach jak JavaScript czy nawet C. Żeby to zrozumieć trzeba przejść do poziomu assemblera (lub jakiegoś pseuda assemblera)

1

Taki kod

zmienna = zmienna + 2;

to jest praktycznie dokładnie to samo co

tmp = zmienna + 2;
zmienna = tmp;

1 użytkowników online, w tym zalogowanych: 0, gości: 1