[ EArthquake @ 02.02.2005. 18:07 ] @


moze li se u c-u zameniti vrednost dve varijable bez uvodjenja trece


dakle da se uradi sledece samo bez temp varijable

int a
int b
int temp

main()
{
a = 6;
b = 7;

printf("Vrednost a je %d ",a);
printf("Vrednost b je %d ",b);
temp = b;
b = a;
a = temp;
printf("Vrednost posle zamene a je %d ",a);
printf("Vrednost posle zamene b je %d ",b);
}



izvinjavam se ako ima gresaka u kodu nenaviknut sam na tastaturu koju trenutno kotristim pa mi se mozda omakla neka a mrzi me da isravljam

ovo mitanje me cisto zanima ima li nacina ne treba mi neto posebno

iako ja licno sumnjam da ima
[ _alokiN_ @ 02.02.2005. 18:17 ] @
Ima, znam da sam jednom bio naleteo na kod koji to radi :)) Ne znam vise tacno kako, ali je radjeno preko operacija sa bitovima (XOR). Ako slucajno nadjem, postovacu..
[ Sundance @ 02.02.2005. 18:19 ] @
a = a ^ b
b = a ^ b [ = a ^ b ^ b = a ]
a = a ^ b [ = a ^ a ^ b = b ]

ili ljepše u asembleru:

xor eax, ebx
xor ebx, eax
xor eax, ebx

Mislim da ima verzija i sa + i - :>

[Ovu poruku je menjao Sundance dana 02.02.2005. u 19:20 GMT+1]
[ EArthquake @ 02.02.2005. 18:20 ] @


to mi palo na pamet dok sam putovao busom u novi sad (4 sata traje voznja)
i dok sam razmisljao i obnavljano upravljanje memorijom u c-u

pa se moj stedljivi duh setio kako jos jedna varijabla zauzima vise prostora :))))))
[ 3emyh @ 02.02.2005. 18:23 ] @
a=a+b;
b=a-b; /*Sad je b=a*/
a=a-b; /*a=b*/

Bilo nekad u Racunarima u Dejanovim pitalicama
[ EArthquake @ 02.02.2005. 18:24 ] @
eto kako ustedeti 2 bajta :))))


korisno nema sta
[ Sundance @ 02.02.2005. 18:25 ] @
Evo i sa + i -:
a = a - b
b = a + b [ = a - b + b = a]
a = b - a [ = a - a + b = b]
[ Sundance @ 02.02.2005. 18:34 ] @
I još malo.. :)

a = a * b
b = a / b [ = a * b / b = a ]
a = a / b = [ = a * b / a = b]

a = a / b
b = a * b [ = a / b * b = a]
a = b / a [ = a / a * b = b]

__asm {
push [x]
push [y]
pop [x]
pop [y]
}


[ yooyo @ 02.02.2005. 23:44 ] @
a ^= b ^= a ^= b;

yooyo
[ zvrba @ 03.02.2005. 07:56 ] @
[quote]yooyo:
Code:
a ^= b ^= a ^= b;


Ovo nije ispravan C, tj. izaziva undefined behaviour. U istom izrazu vise puta mijenjas vrijednost varijable bez sequence pointa izmedju.

Ukratko: razni kompajleri mogu generirati razliciti kod koji nece napraviti ono sto bi trebao. Ispravno je sa 3 odvojene naredbe.
[ EArthquake @ 03.02.2005. 10:31 ] @
stvarno mi ne ide u glavu kako mi nisu pale na pamet matematicke operacije


@sundance
dobro nemoj da preterujes vise

sad kad sam video princip....



mnogo sam se iznervirao


svojom nesposobnoscu naranvo
[ Milos Stojanovic @ 03.02.2005. 14:05 ] @
Mislim da je xor ipak najispravniji, jer kod ostalih rešenja može doći do prekoračenja. (mada onom sabiranju i oduzimanju to ne bi trebalo da smeta)
U svakom slučaju xor je najbrži od svih ponuđenih ;)
[ leka @ 03.02.2005. 14:08 ] @
Dobro, posto smo se nahvalili mozemo li poceti malo da kritikujemo ova resenja? Dakle u kakvim situacijama ova resenja rade, a u kakvim ne rade? :)
[ leka @ 03.02.2005. 14:11 ] @
Citat:
ZVRBA: Ovo nije ispravan C, tj. izaziva undefined behaviour. U istom izrazu vise puta mijenjas vrijednost varijable bez sequence pointa izmedju.

Ukratko: razni kompajleri mogu generirati razliciti kod koji nece napraviti ono sto bi trebao. Ispravno je sa 3 odvojene naredbe.

zvrba, svaki C kompajler koji postuje standard bi trebalo bez problema to da kompajlira...
[ yooyo @ 03.02.2005. 14:38 ] @
Citat:
zvrba:

Ovo nije ispravan C, tj. izaziva undefined behaviour. U istom izrazu vise puta mijenjas vrijednost varijable bez sequence pointa izmedju.

Ukratko: razni kompajleri mogu generirati razliciti kod koji nece napraviti ono sto bi trebao. Ispravno je sa 3 odvojene naredbe.


Cudno... meni je ovo radilo i pod Turbo C-om...

Inace... probao sam gornji primer u MSVC 7.1 i evo rezultata:
Code:

void main (void)
{
 int a = 10, b = 20;
 printf("\n%d %d", a, b);
 a ^= b ^= a ^= b;
 printf("\n%d %d", a, b);
}

ASM izlaz izgleda ovako:

push 20
push 10
call printf

push 10
push 20
call printf



Kompajler je provalio da je u pitanju zamena vrednosti 2 broja i potpuno je izbacio code koji to radi!!!

yooyo
[ dejandj @ 05.02.2005. 19:05 ] @
A stvar (na zalost) nije beskorisna, neki stariji win kompajleri (bcc5.5 npr) imaju limit broja variabli (odredjenog tipa, long int npr.)...

[ Sundance @ 17.06.2005. 03:43 ] @
Naletjeh sl. na temu: http://www.elitesecurity.org/tema/36766/0 pa se sjetih ove :)

U biti je zvrba u pravu, gcc sa opcijom -Wsequence-point (odnosno -Wall) na gornji yooyo-ov program daje upozorenje:

Citat:
warning: operation on `a' may be undefined


dok MS VC++ 8.0b2 ne daje upozorenje čak ni sa /W4 :/

Premda oba daju točan (isti) output...

Ali kako netko reče...likove koji pišu ovakav kod bi trebalo bacit kroz prozor :)
[ itf @ 17.06.2005. 17:51 ] @
Hehehe... vidim da nitko nije mislio na overflow? Cast rjesenjima sa XOR-om, no pokusajte to sa vrijednostima poput 32000 i 32001, a nek se zamjenjuju podaci tipa integer :) Nije valjda da ne radi??? E pa stvarno...
[ Sundance @ 21.06.2005. 06:11 ] @
Rješenje preko XOR-a je jedino od svih type-agnostic.
[ zvrba @ 21.06.2005. 07:48 ] @
Citat:
Sundance: Rješenje preko XOR-a je jedino od svih type-agnostic.


Nije. ne radi sa floating-pointom. osim ako ne koristis ruzne castove.

Sto se tice +/- nad FP varijablama, rezultat "zamjene" ne mora biti identican pocetnim brojevima radi zaokruzivanja u FP aritmetici.

Sve skupa, IMO, ovo je zanimljiva matematicka mozgalica sa NULA primjene u praksi.

Bezveze narusava citljivost programa, a nije ni efikasno koliko bi moglo biti imajuci u vidu da mnogi procesori imaju instrukcije tipa XCHG koje atomicki zamjenjuju sadrzaj registra sa drugim registrom ili memorijskom lokacijom (ili cak ponekad memorija <-> memorija).
[ Sundance @ 21.06.2005. 08:38 ] @
Nema to veze :) To što za FP ne postoje logičke instrukcije (nekakav fxor :) ili podrška u samom jeziku ne znači XOR neće raditi, ukoliko se ručno implementira bit-po-bit. E sad, kod neće biti bogzna koliko lijep...ali daleko od toga da neće radit.

Praktična primjena nije ni bitna, earth je pitao da li je moguće :)

A osim toga, xor je za razliku od xchg upariv, a xchg reg, [mem] je ekstremno spora i nepreporučljiva instrukcija :)
[ srki @ 21.06.2005. 10:22 ] @
Ako koristis xor naredbe jedne za drugom a sa istim argumentima onda ti dzabe sto je upariv.
[ Sundance @ 21.06.2005. 10:36 ] @
Može bit upariv se nekim drugim kodom, nema to veze, ne pišem ja ručno XOR nego kompajler. Teško da će ne izvući paralelizam kad se troše svega 2 registra.
[ MilosSavic @ 22.06.2005. 06:22 ] @

Pozdravi,
morao sam makar na malkice da se ukljucim, zato sto temu pokrenuse jedan od mojih poznanika, a na njoj ucestvovase jos jedan, te bih da pohvalim posebno ovog drugog :) /* nedaj se Dundjere, dobro je da fica ide */
Ono sto mi je stvarno drago, jeste da mogu da vidim da je konacno proslo vreme sitnih kafanskih trikova, malverzacija, korupcije i varanja na izborima zarad 2 bajta memorijskih i 4 takta procesorskoga vremena... Sto je jos gore, ti trikovi su toliko otrcani da ce svaki kompajler pa cak i moj yapcc da ih prepozna... Dajte ljudi u 21. smo veku, znate sta je jos prvi haker svih vremena kome je Njutnova jabuka padala na glavu 18 godina rekao na dodeli Tjuringove nagrade zarad svoga posla oko proceduralnog jezika Fortrana: "Dajte batalite te imperativne jezike, u njima nikada necete raziviti pravu programersku intuiciju, niti cete steci pravi osecaj za racunarsko racunanje. Programirajte u mom FP-u".. korisna stvar taj fp, malo restrikcija na kocoperenje funkcija viseg reda i super jezicak :)
Tako i ja Vama moji dragi polaznici, porucujem, okanite se kafanskih trikova, to nije prava stvar, prava stvar su znoj, suze, radost, pomesana osecanja, lozenje dok ste vi na vasim pravim racunarskim projektima.... Sve ostalo je bandera :) Jebote, C je bandera :)
Ah setih se pre par godina, bejah bio srednjoskolac, te sam mom profanu na pismenom napisao a ^= a, a on me lepo oterao u tri lepe zajedno sa sve ispisanom funkcijom myprintf koja bese vrvela od bajnih unix sistemskih poziva napisanih asm inline :) Upravu je bio covek, a tada sam mu i oca i majku i prvi red na sahrani...

Srdacni pozdravi Milos

P.S Pravila ne postujem, sh nije s, te ako hocete mozete ovo odma izbaciti... ali mali izliv emocija nije na odmet
[ zvrba @ 24.06.2005. 10:34 ] @
Citat:
Sundance: A osim toga, xor je za razliku od xchg upariv, a xchg reg, [mem] je ekstremno spora i nepreporučljiva instrukcija :)


Nepreporucljiva za sto? Nekad nije brzina jedino sto te zanima. XCHG reg,mem je atomicka za razliku od ekvivalentne sekvence MOV instrukcija. Sto moze biti jako bitno u MP sustavima.
[ Sundance @ 02.07.2005. 23:44 ] @
Citat:
zvrba: Nepreporucljiva za sto?


Uparivanje sa drugim instrukcijama. Ne preporuča se u praktično svim priručnicima za optimizaciju, od Agner Foga, do službenih Intelovih.

Citat:
Nekad nije brzina jedino sto te zanima. XCHG reg,mem je atomicka za razliku od ekvivalentne sekvence MOV instrukcija. Sto moze biti jako bitno u MP sustavima.


Bullshit. Zamjena dviju varijabli kao memorijskih lokacija nije atomička na x86 bez korištenja nekih apstraktnih koncepata, a osim toga mislim da i XOR prima LOCK prefix, kad već sereš u vezi MP sustava.

Mislim čemu sve ovo? Moraš li svaki put ispasti "najpametniji" ?
[ zvrba @ 03.07.2005. 07:36 ] @
Citat:
Sundance: Bullshit. Zamjena dviju varijabli kao memorijskih lokacija nije atomička na x86 bez korištenja nekih apstraktnih koncepata

ja sam napisao xchg reg,mem varijantu. sugavi intel nazalost nema mem,mem instrukcija (osim movs). xchg automatski zakljucava memoriju i ne treba mu lock prefix.


Citat:
Mislim čemu sve ovo? Moraš li svaki put ispasti "najpametniji" ?

Cemu? Zato sto dajes genericke izjave tipa "xchg reg, mem nije preporucljiva". Zivis u svom malom svijetu opterecn brzinom izvrsavanja i ne padaju ti napamet ikakve druge stvari.. I onda drugima dajes "savjete" iz svoje vise nego ogranicene perspektive.