Jeste jeden C kviz na nedelni vecer

Pavel Troller patrol na sinus.cz
Pondělí Září 20 05:29:10 CEST 2010


Zdravim,
  ano, je to Pi, je to z OCCC, a zajemcum o dalsi vymakane C programy
doporucuji stranku http://www.cise.ufl.edu/~manuel/obfuscate/obfuscate.html .
Nad nekterymi programy zustava rozum stat. Treba program Flipper - umoznuje
otocit libovolny textovy soubor podle diagonaly, takze udela ze radku sloupce
a naopak - no, tohle jeste neni zase takovy kumst - ale kdyz s nim otocite
jeho vlastni zdrojak, jde stale zkompilovat a dela to same :-). 
  A Balua by mohl inspirovat program Adder, ktery scita 2 cisla a jeho 
zdrojovy text ma podobu ASCII schematu dvoubitove binarni scitacky :-).
Je az neuveritelne, co se tam da najit, clovek by rekl, ze kdyz by neco z toho
predhodil kompilatoru, ze pocitac prinejmensim imploduje do cerne diry, ale
ne, ona vetsina jde opravdu zkompilovat a dela, co ma!
  Jsou tam naproste silenosti, ale jejich studium, jak zde v perfektni analyze
ukazal wek, cloveku priblizi nejedno tajemstvi C, ktere pak muze nekdy pouzit
v trosku praktictejsich situacich :-).
  Zdravi Pavel.

> Je to pi, a je to velmi pekne - nie je to nahodou z OCCC?.
> 
> Pointa je, ze tomu kruhu sa moze zvacsit priemer (pri zachovani jeho "struktury) a bude to stale ratat dobre.
> 
> Rata to totiz plochu (v premennej F) a priemer (v premennej OO). Kedze plocha je pi*d*d/4, t.j. F=pi*OO*OO/4, ten vyraz v printf (4.*-F/OO/OO) je vlastne "otocenim" tohoto vztahu, a vysledkom je pi (v tejto verzii je F=-202 a OO=-16).
> 
> Ako prve je treba si ten program poriadne pozriet, lebo v duchu OCCC sa pouzivaju zamerne podobne vyzerajuce retazce. Je tam premenna OO (dvakrat velke O), inicializacna hodnota 00 (dve nuly, to v C je nula v osmickovom zapise ;-) ) a funkcia F_OO(), ktora je volana hned na zaciatku main(), je definovana hned za main() a je to vlastne len ta "gula".
> 
> No a "gula" funguje na zaklade expanzie makra, ktoreho meno je _ (podciarnik), a medzi nimi su tie minuska. Ten vyraz z makra je ukonceny bodkociarkou, takze to minusko funguje ako obratenie znamienka F. Este poznamenajme, ze F (aj OO, len tam to nie je dolezite) je inicializovany na nulu a potom sa len dekrementuje, cely cas hned po prvom dekremente je zaporne.
> 
> Vyraz z makra:
> F-->00 || F-OO--;
> 
> je logicky OR, ktoreho vysledok je zahadzovany (nie je nijako pouzity - to v C je v poriadku). Dovod je tu ten, ze u logickych operatoroch sa v C nevyhodnocuje druhy vyraz, ak je z prveho vyrazu jasny vysledok. Este treba vediet, ze v C znamena F-- postdekrement, t.j. sa najprv pouzije hodnota vyrazu F a potom sa dekrementuje. Ten druhy podvyraz je len take klamanie telom: vypocita sa F-OO ale vysledok sa zahodi, no a potom sa urobi ten postdekrement OO.
> 
> Takze ten vyraz sa da prepisat do ludskej reci ako
> 
> if (F > 0) { 
>   // tu je uz jasne, ze vysledok log.OR = 1, takze sa nic ine nerobi
>   // lenze F je nula alebo zaporne, takze sem sa program na zaciatku riadku nedostane 
> } else {
>   OO = OO -1;
> }
> F = F - 1;
> 
> Lenze hned druha expanzia makra v tom riadku (a aj vsetky dalsie) ma uz pred sebou to minus, ktore sa uplatni na F v tej uvodnej podmienke, takze uz sa v dalsich "instanciach" makra v danom riadku prechadza prvou vetvou toho "if" a nie druhou, t.j. sa uz OO nedekrementuje.
> 
> A preto OO sa dekrementuje len raz v kazdom riadku, a F sa dekrementuje raz pre kazdy vyskyt _.
> 
> Pekne, ze? (teda aspon v tak zvratenom slova zmysle ako je C samotne zvratene...) ;-)
> 
> wek
> 
> 
> On Sun, 19 Sep 2010 22:54:26 +0200
> Tomáš Dresler <dresler na hw.cz> wrote:
> 
> > Vzpominam-li dobře, není to PI?
> > 
> > Tomas
> > 
> > -----Original Message-----
> > From: hw-list-bounces na list.hw.cz [mailto:hw-list-bounces na list.hw.cz] On
> > Behalf Of Pavel Troller
> > Sent: Sunday, September 19, 2010 9:32 PM
> > To: HW-news
> > Subject: OT: Jeste jeden C kviz na nedelni vecer
> > 
> > 
> > Zdravim,
> >   tak schvalne, kdo prijde na to, co priblizne vypocita tento program
> > a jaky je jeho algoritmus :-).
> >   Pavel
> > 
> > #include <stdio.h>
> > #define _ F-->00 || F-OO--;
> > long F=00,OO=00;
> > main(){F_OO();printf("%1.3f\n", 4.*-F/OO/OO);}F_OO()
> > {
> >             _-_-_-_
> >        _-_-_-_-_-_-_-_-_
> >     _-_-_-_-_-_-_-_-_-_-_-_
> >   _-_-_-_-_-_-_-_-_-_-_-_-_-_
> >  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> >  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> > _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> > _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> > _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> > _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> >  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> >  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
> >   _-_-_-_-_-_-_-_-_-_-_-_-_-_
> >     _-_-_-_-_-_-_-_-_-_-_-_
> >        _-_-_-_-_-_-_-_-_
> >             _-_-_-_
> > }
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list


Další informace o konferenci Hw-list