Vykdyti ir laukti
Amžinai programuotojams skirtuose žurnaluose ir Internet diskusijų srityse kyla klausimai, kaip pradėti vykdyti kitą programą (ypač daugeliui neaišku, kaip valdyti MS-DOS programas) ir palaukti, kol ji baigs darbą. Dažniausiai siūlomi sprendimai yra pakankamai sudėtingi, nes žaidžiama, pvz., pranešimų apie įvykius (Notify) analize.
Čia pasiūlomas paprastas, veikiantis ir lengvai suprantamas būdas C kalba. Man tik neaišku, kaip stipriai sistemą užima amžinas tikrinimo ciklas?
#include <windows.h> BOOL SpawnAndWait(LPSTR strDOSCall) { static WORD wRetCode = WinExec(strDOSCall, SW_HIDE); char szModuleName[128]; if (wRetCode < 32) return TRUE; // Klaida! while (GetModuleFileName(wRetCode, szModuleName, sizeof(szModuleName))) { // Laukti arba lygiagrečiai atlikti kokius nors kitus veiksmus // Gal būt patikrinti, ar ne per ilgai užtruko laukimas... } // Programa baigė darbą return FALSE; } // end SpawnAndWaitPateiktame pavyzdėlyje SpawnAndWait funkcijai perduodama OS failo vardas (geriausia .PIF). while cikle tikrinama, koks modulio vardo ilgis, - kai tikrinamas procesas baigia darbą, grąžinama nulinė reikšmė, - tai požymis, kad reikia baigti ciklinti.
union struktūra C kalboje
union yra specialus struktūros tipas labiau skirtas tipų persiklojimui. Jis aprašomas panašiai kaip struct, tačiau jam išskiriama tik tiek atminties, kiek reikia ilgiausiam laukui struktūroje, t.y. visi laukai naudoja tą pačią atmintį. Tai leidžia panaudoti tą pačią bitų seką, tačiau su skirtingomis jos prasmėmis.
Pvz.
union { int i; char c[4]; } myUnion; myUnion.i = 65; printf("Simbolis: %c\n", myUnion.c[0]);Toks fragmentas atspausdins A, nes 65 yra raidės A kodas.
Galima aprašyti ir savą union tipą, pvz.,
typedef union unionStruct { int i; char c[4]; } unionType; unionType U; U.c[0] = 'a'; printf("Union testas: %d\n", U.i);Toks fragmentas atspausdins 97, nes tai yra raidės a kodas.
Tokiu būdu galima išvengti kompiliatoriaus įspėjimų ir potencialiai neapibrėžtos elgsenos. Iš principo, galima perkloti bet kokius tipus, tačiau C kalboje (bet ne C++) yra taisyklė, kad teisėta skaityti union lauko reikšmę tol, kol nebuvo įrašyta ilgesnė reikšmė.
Apie perpildymo naudą
Visi programuotojai žino apie aritmetinį perpildymą (overflow) ir dauguma jų mano, kad tai yra labai blogai tai, ko reikia vengti bet kokia kaina. Galime paminėti siaubingų skaičiavimų klaidų atvejus, kai buvo pasirinktas per mažas kintamojo tipas, kad visais atvejais į jį sutilptų aritmetinės operacijos rezultatas. Taigi perpildymus reikėtų susekti ir, jei įmanoma, pažymėti statiniais analizatoriais. Taip mano dauguma, išskyrus, žinoma, protingus C programuotojus, labiau suprantančius apie bitus ir kaip viskas veikia, kurie žino, kad skaičių be ženklo (unsigned) aritmetinis perpildymas arba cikliškas atsukimas (pvz., 255+1=0) yra toli gražu ne nepageidautinas, o galingas įrankis ir gali būti panaudojamas norint pasiekti ką nors visiškai protingo. Netgi galima sakyti, kad tai yra geras patikrinimas, ar C programuotojas yra tikras C programuotojas, ar tik perbėgėlis iš kitos aukšto lygio kalbos. Mat tai yra ne dėl to, kad tai senutė 50 m. amžiaus ir primityvi kalba, o todėl, kad C kalba tarnauja žemo lygio dalykų programavimui, t. y. skirta tokiems programuotojams, kurie žino reikalo esmę.
Pvz., kešo (hash) reikšmės paskaičiavimo dalimi yra cikliškas atsukimas. Beje, jį galima panaudoti ir perpildymo patikrinimui, pvz.,
unsigned int a, b; // ... if (a+b < a ) { /* veiksmai perpildymo atveju */ }Papildomai skaitykite:
Tiesiog - Java
Kaip suliesėti?
Pradėkime su MFC!
C/C++: Ką reiškia "static"?
Programavimas Unix aplinkoje
Pitonas, kandantis sau uodegą!
C++: mutable - nauja kalbos savybė
Įvadas į Perl kalbą: Kas naudoja Perl?
AWK kalba - sena ir nuolat aktuali
Pirmasis Java įskiepis Lietuvoje
Visual C++ 5.0: greičiau ir daugiau
Programavimo kalbø klegesys
Programuotojus į savartyną!
Skriptai - ateities kalbos?
Ruby on Rails
Vartiklis