Programuotojus į savartyną!
(pagal Jerry Pournelle*); 1996-08-25)Dauguma kompiuterio vartotojų niekada nerašė programų. Iš dalies, tai yra teisinga, juk ir knygas leidžia tik rašytojai (Lietuvoje ir tai negalioja, ypač kompiuterinės tematikos knygoms, - jas rašo kas tik netingi, o dažniausiai tie, kurie mažiausiai tai sugeba. Ir pirštu rodyti nereikia - paimkit pirmą papuolusią ir... kas turi akis - težiūri...)
Tačiau, iš kitos pusės, būtų gerai, kad kompiuteris darytų, ką mes norime - tačiau kaip pagerinti jo darbą žinome tik patys. Gal iš tikro tikroji kompiuterių revoliucija bus tada, kai programavimas bus panašus į raštingumą. Knygas juk rašome ne visi, tačiau kiekvienas, net neturintis didesnių literatūrinių sugebėjimų, sugeba sukurpti laiškelį ar pardavimo sutartį. Visuomenė šioje srityje nepriklauso nuo išsilavinusio elito, tai kodėl ji turi priklausyti nuo kompiuterių specialisto?
Prieš keletą metų beveik kiekvienas, dirbantis su kompiuteriu, šiek tiek programavo. Senais laikais pasirodęs Turbo Basic sukrėtė Microsoft kaip kamuolinis žaibas - iki kaulų smegenų. Keli metai aplaidumo vos neparklupdė firmos - ji susiėmė netrukus išleido dvi naujas MS Bacic versijas. Ir taip įsivažiavo su šia kalba, kad iki šiol negali sustoti.
Taigi tais senais laikais kiekvienas ką nors žinojo apie programavimą ar bent Pascal. Pasaulis dar nebuvo padalintas į dvi - programuotojų ir vartotojų - kastas. Kiekvienas buvo ir tuo ir tuo.
Tada atėjo C!
Neaišku, kodėl C taip greitai išplito. Tai draugiška profesionalui, tačiau priešiška vidutiniokui kalba. Ją sunku išmokti. Reikia tapti vos ne meistru, kad galėtum sukurti kokią nors naudingą programą. Tačiau ji sukurdavo artimas asembleriui programas, žymiai greitesnes ir mažesnės apimties, nei Pascal ar Basic. Ir dar daugiau, ji buvo nepriklausoma nuo platformos.
Šiais laikais geležis žymiai galingesnė ir programos dydis ir greitis ne tokie svarbūs. Todėl C yra stichinė nelaimė. Ji leidžia transliuoti bet ką, net visišką nesąmonę. O tai reiškia, kad programuotojui savo galvoje reikia turėti ne prastesnį kompiliatorių. Suprasti, kas parašyta, reikia daugiau laiko, nei perrašyti iš naujo.
Visai nebūtina mokytis C, kad galėtume rašyti naudingas programas. Tiesiog stebina, kaip greitai galima sukurti veikiančias ir reikalingas programytes, naudojant Visual basic ar Delphi. Jie patys žino daug apie Windows ir meniu, mygtukus ir visa kitą.
O gal tikrai?
*) Džeris Purnelis (Jerry Eugene Pournelle, 1933-2017) amerikiečių mokslininkas, dirbęs operacijų tyrimų ir žmogaus veiksnių srityse, rašytojas fantastas, eseistas, žurnalistas ir vienas pirmųjų tinklaraštininkų (blogerių, Chaos Manor). Jo žurnalistika buvo daugiausia skirta kompiuteriams, astronomijai ir kosmoso tyrimams. Parašė gausų fantastinių romanų ciklą su veiksmu CoDominium visatoje, Liuciferio kūjis (1977; su L Niven) ir daugelį kitų; o taip pat romanizavo filmą Pabėgimas iš Beždžionių planetos (1973). Jis pasiūlė keletą dėsnių, pvz., Silicis pigesnis už geležį (t. y., komputerį pigiau atnaujinti neii pakeisti). Vienu jo dėsnių buvo ir geležinis biurokratijos dėsnis:
Bet kokioje biurokratijoje žmonės, atsidavę pačios biurokratijos labui, visada valdo, o tie, kurie atsidavę tikslams, kurių turi siekti biurokratija, turi vis mažėjančią įtaką, o kartais ir visiškai pašalinami.
Į ten, kur ir reikia
Operacinės sistemos duomenis į diską užrašo ne iškart. Papildomai juos buferizuoja ir C kalbos paprogrėmės. Tačiau kartais yra būtina, kad, prieš atliekant kai kuriuos veiksmus, duomenys jau būtų įrašyti į diską.
16-os bitų terpėse (MS-DOS ar Windows 3.1), kuriose yra veiksni bent Smartdrv.exe 4.0 versija yra du pasirinkimai:
- naudoti funkciją _commit;<>
- prijungti Commode.obj failą ir kviesti funkciją fflush.
Kitaip yra 32-ių bitų Windows terpėse, kurios turi vidinį diskų buferizavimą. Todėl tėra vienintelis būdas - naudoti Commode.obj failą ir funkciją fflush. Šios technikos pavyzdys:
#include <stdio.h> #include <ofstream.h> void main() { DirbkSuFailu(); DirbkSuKituFailu(); } void DirbkSuFailu() { FILE * CFileBuf; // Atidaryti failą ir atlikti keletą rašymo operacijų fflush(CFileBuf); _commit(_fileno(CFileBuf)); // Keipinys į "fflush" visus buferius persiūs operacinei sistemai // Antrasis kreipinys į "_commit" privers Smartdrv.exe // užrašyti juos į diską. } void DirbkSuKituFailu() { ofstream CXXFileBuf; // Atidaryti failą ir atlikti keletą rašymo operacijų CXXFileBuf.flush(); _commit(CXXFileBuf.rdbuf()->fd()); }
Ar C++ - tai vien tik pagerintas C?
Kartais C ir C++ skirtingai traktuoja simbolines konstantas ar eilutes. Pavyzdžiui, paimkim tokią programytę:
#include <stdio.h> int main() { printf("Simbolio plotis:%d\n", sizeof('x')); return 0; } /* end main */Ji, sutransliuota kokiu nors ANSI C kompiliatoriumi, atspausdins sizeof(int) reikšmę, t.y. dažniausiai 2 PC kompiuteriuose ir 4 - Unix mašinose.
Tačiau kaip C++, ji spausdins sizeof(char) reikšmę, kuri dažniausiai yra 1. Taigi, va!
Kitas skirtumėlį parodo šis pavyzdėlis:
#include <stdio.h> char buf[5] = "abcde"; int main() { printf("%s\n", buf); return 0; } /* end main */Tai leistina C, bet klaidinga C++! Simbolių eilutė baigiasi kodu '\0', o jam nėra vietos masyve. C kalboje programuotojas rizikuoja, nes kai kurios funkcijos, pvz., printf gali veikti kitaip, nei tikėtasi.
void: Į tuščias reikšmes (2024-06-26)
I'll get me to a place more void (Pasitrauksiu į vietą tuštesnę), V. Šekspyras
Pirmiausia void tipas buvo įtrauktas į Algol 68 kalbą. Iš visų void prasmių pirmiausia į galvą ateina esantis be, neturintis, netekęs.
Pradinė C kalbos idėja buvo, kad jos funkcijos apibrėžia ne tik parametrų, bet ir rezultato tipą. Pvz., nurodant kad funkcija gražina sveiką skaičių, reikia apibrėžti:
int suma (int a, int b) { }
Tai leidžia C kompiliatoriui patikrinti, ar funkcija tikrai gražina int reikšmę.![]()
Tačiau kyla klausimas, - ką daryti, jei norime turėti procedūrą, o ne funkciją? Kai kurios kitos kalbos funkcijoms ir procedūros turi skirtingą sintaksę, tačiau C ir daugelyje šiuolaikinių kalbų teturime tik funkcijas, tad reikia kažkaip nurodyti, kad ji negražina reikšmės (arba, kitais žodžiais, kad gražina nieką ar tuščią reikšmę). Čia naudingu ir tapo void, pvz.,
void veiksmas(int c) { ... }Bet dar Algol 68 laikais void prasmė išsiplėtė ne vien nurodant, kad funkcija negražina reikšmės jis tapo tipu. T.y. tokiu tipu, kuris gali įgauti bet kokią reikšmę; o tai kiek suglumina pradedantįjį ar tai reiškia, kad funkcija gražina void tipą? Tai ką iš tikro void, kaip tipas, reiškia?!
C kalboje iš tikro galima paskelbti kintamąjį, turintį void tipą. Kai paskelbiate sveiko tipo kintamąjį
int kintamasis;
kompiliatorius jam išskiria atmintį (pvz., 4 baitus), bet ką jis išskirs, jei nurodysime
void kintamasis;Vienintele prasme, kai gali egzistuoti void tipas, yra jei galime kintamajam išskirti reikiamą atminties kiekį. Sprendimu yra turėti void tipo nuorodas nuorodos visad užima tą patį atminties kiekį, nors jos kiekis ir priklauso nuo sistemos. Tad nuoroda gali būti į bet ką:
void *kintamasis;Bet kaip reiktų suprasti nuorodą? Galima manyti, kad nuoroda nurodo atminties bloko pradžią, bet toks požiūris turi problemą, nes nežinome, į kokios apimties elementus nurodoma, tad sutrinka aritmetika su nuorodomis, pvz., į kokią atminties vietą bus kreipiamasi *(kintamasis+20) atveju?! Jei kintamasis būtų apibrėžtas kaip int *kintamasis;, tai adreso paskaičiavimas būtų analogiškas kintamasis+20*sizeof(int)
Jei nuorodos kintamojo tipas yra void, vienintele prasminga sizeof(void) reikšme būtų 0. Tačiau tada tokia aritmetika neveikia ir nuo C99 aritmetika su void nuorodomis neleidžiama. Ankstesniuose standartuose neaiškumas kai kur laikyta sizeof(void)=sizeof(char).
Tačiau visada galima pasinaudoti kastinimu, pvz.,
(int *)kintamasis+20Dar pastebėkime, kad funkciją galima iškviesti nenurodant, kam priskiriama reikšmė, pvz.:
sum(1, 2)Be to, mažai žinoma, kad C kalboje iš tikro galima panaudoti išraiškas, jų reikšmės niekam nepriskiriant, pvz.,
2+3;
Bet jei norima aiškiai nurodyti, kad išraiškos reikšmė nenaudojama, irgi galima panaudoti kastingą void, t. y.
(void)(2+3);
Papildomai skaitykite:
Vykdyti ir laukti
Unix komandinės eilutė
C/C++: Ką reiškia "static"?
Pirmasis Java įskiepis Lietuvoje
C++: mutable - nauja kalbos savybė
Sunkus Linux posūkis nuo C link Rust
Įvadas į Perl kalbą: Kas naudoja Perl?
Visual C++ 5.0: greičiau ir daugiau
Džonas Bakas FORTRAN tėvas
Programavimo kalbų istorija
Tcl kalba - iš susierzinimo
Java 8: Optional prieš null
JavaScript pradžiamokslis
Skriptai - ateities kalbos?
Pradėkime su MFC!
Kaip suliesėti?
Kobolo motina
Vartiklis