co spusti kompilovanie programu vytvoreneho v editore, alebo ak
si ulozil program na pasku ako subor s menom "fred" iba napis:
#include fred
Ked znova prevladne klud, precitaj si kapitoly o jazyku a o
kniznici - alebo aspon cez ne prebehni aby si nadobudol
vseobecny obraz co je v nich. Kapitolu o chybach mozes citat ked
sa naskytne potreba (samozrejme ze ju mozno nebudes potrebovat
nikdy......)
1.2 Klavesnica Spektrum.
Klavesnica sa pouziva cely cas v mode malych pismen. Stlacenim
klavesy sa vysle ACCII kod odpovedajuceho maleho pismena, alebo
cislice. Medzernik sa nemeni. Stlacenie ENTER vysle hodnotu 10
(odpovedajucu NEWLINE alebo LINE-FEED) namiesto 13
(odpovedajucej CARRIAGE RETURN). C totiz pouziva znak NEWLINE
'\n' ako terminator riadku a nie CARRIEGE RETURN '\r'.
Symbol shift je slabo zmeneny: jeho stlacenim spolu s inou
klavesou sa vzdy vysle ASCII kod cerveneho symbolu vyryteho na
klavese a nie klucove slovo BASICu.
Toto zahrnuje symboly <=,<> a >= na Q W a E klavesach ktorym sa
priradia hodnoty 29, 31 a 30. Mozu byt pouzite v tvojich
programoch namiesto dvojznakovych kombinacii: <=,!= a >=.
Symbol shift stlaceny spolu s klavesou I, vysle hodnotu 'koniec
suboru' (EOF) -1 a zobrazi sa ako CHR$(137) na obrazovke. Toto
sa pouziva na uloncenie suborov vkladanych z klavesnice, najme
zdrojoveho textu, ktory je vstupom do kompilatora.
Pri vystupe na obrazovku symbol CHR$(137) vytvori hodnota 255
namiesto klucoveho slova COPY. Toto je sposobene tym, ze ked
program skusa zobrazit C EOF - hodnota -1, tuto najprv prevedie
na 255.
Caps shift je tiez mierne zmeneny. Stlacenie Caps shift spolu s
6 normalne vysle hodnotu 10, ale tato je teraz vysielana
klavesou ENTER. Caps shift a 6 teraz vysiela 16. Hodnoty
vysielane stlacenim Caps shift spolu s 0 alebo 5 su teraz
premenene tak, ze CAPS SHIFT 0 (DELETE) vysle 8, zatialco CAPS
SHIFT 5 vysle 12.
1.3 Subory na Spektre.
Tento odsek popisuje sposob ako bol HISOFT C prisposobeny
Spektru a zameriava sa na system vstup-vystup, ktory je hlavnou
castou prisposobenia. Zacneme so zakladnymi vedomostami o
Spektre a o vstupno-vystupnych funkciach C.
Funkcie, ktore su v standardnej kniznici su modelovane podla
funkcii v UNIX systeme. Vstup a vystup v C je robeny seriovo cez
"files". Tieto subory pokryvaju nielen to co je bezne chapane
ako subor (na paske, na disku), ale tiez vstup z klavesnice a
vystup na display.
Vstup a vystup na Spektre je organizovany podobne cez "streams".
Vyznamne odlisenie na Spektre je kazetova paska, ktora nema
'stream'. Cez to vsetko HISOFT C kompilator umoznuje pristup na
kazetu rovnako ako pristup na ine zariadenia. Z hladiska
programatora v C sa toto javi ako by vstup a vystup boli
nezavisle na zariadeni.
V C programe su tri standardne subory. Standardny vstup "stdin",
standardny vystup "stdout" a standardny vystup chyby "stderr".
Tieto su priradene kanalu klavesnice, hornej obrazovke, hornej
obrazovke (znova). Pri pismenach sa uskutocnuju niektore
preklady.
Vstup a vystup na ine zariadenia je robeny do suborov s pouzitim
"file-pointers". File-pointery pouzivane pre vstup a vystup v C
sa pouzivaju na reprezentaciu cisla kanalu na Spektre. Su typu
pointer-to-FILE, takze su kompatibilne s file pointermi na inych
systemoch, ale v skutocnosti ich hodnoty (ako zoradenie bitov)
je iba cislo kanalu pre Spektrum. Pismena vstupuju z klavesnice
s Pouzitim standardnej funkcie getchar() a vystup na obrazovku
ide cez putchar(c). Toto odpoveda getc(0) a putc(c,0).
Pred pouzitim getc alebo putc si musis overit, ze mas
file-pointer. Mozes pouzit 0 ako file-pointer pre klavesnicu a
obrazovku ako bolo uvedene vyssie. Tiez mozes pouzit kanal 1 pre
klavesnica/dolna cast obrazovky, 2 pre hornu obrazovku a 3 pre
printer.
Pre kazetu a mikrodrive musis volat "fopen" aby si dostal
file-pointer. File pointer pre kazetu bude specialny (16). Pre
mikrodrive bude najvyssie cislo neotvoreneho kanalu (normalne
15, ak je uz otvoreny, potom 14).
Naviac mozes otvorit kanal aj inym sposobom - z BASICu, alebo
rutinou v strojovom kode - a potom iba odovzdat cislo kanalu do
getc, alebo putc. NESKUSAJ toto s kazetou, alebo mikrodrivom,
pretoze I/O system by bol velmi zmateny.
Vsetky vstupy a vystupy na kazetu, alebo mikrodrive (obidva v
odkazoch ako paska) sa uskutocnuju programami na urovni pismen
pouzitim funkcii getc(fp) a putc(c,fp). Pismena sa zbieraju do
blokov funkciami C runtime predtym ako sa ulozia na pasku do
suboru. Vstupy a vystupy, ktore robi kompilator sa uskutocnuju
rovnako ako v uzivatelovych programochn takze mozes vytvarat,
alebo citat zdrojove subory v C.
Pred citanim z pasky, alebo pisanim na pasku je nutne zavolat zo
standardnej kniznice rutinu fopen(filename,mode). Pri vystupe
toto vytvori blok hlavicky a napise ho na pasku, zatialco pri
vstupe tato funkcia hlada na paske blok prislusnej hlavicky. Na
citanie, alebo pisanie znakov sa mozu potom pouzit getc a putc a
konecne fclose usporiada a napise posledny blok filu pri
vystupe. Pamet pre buffer bloku je tiez usporiadana pomocou
fopen a fclose.
Ked je system pripraveny nahravat na kazetu, zmeni farbu okraja
na cervenu asi na 5 sec pred vykonanim. Potom mozeme spustit
nahravanie. Pri vstupe je cerveny okraj zobrazeny asi 1 sec co
znaci, ze kazeta sa moze prehravat. Ked program precita blok,
kazeta sa musi zastavit, aby mohol program spracovat obsah bloku
a potom znovu spustit, ked pozaduje dalsi blok. Kompilator je
schopny kompilovat zdrojovy text z bloku aj vtedy ked kazetu
nechame bezat.
1.7 Ukazky programov.
Na ukazku niektoryvh zakladnych postupov programovania v C sme
pre zaciatocnikov urobili niekolko kratkych programov ktore sa
mozu napisat,zkompilovat a spustit.
1.7.1 Eratosthenove sito.
Tento program vyuziva algoritmus znamy ako "Eratosthenove sito"
na vypocet vsetkych prvocisiel az do 8190. Ak si napises podobny
program v Spectrum BASICU potesis sa ako fantasticky sa zvacsila
rychlost pouzitim C.
/* SIEVE BENCHMARK from June 84 BYTE */
/* vypocet prvocisel pomocou Eratosthenovho sita */
#define NTIMES 10 /* pocet behov sita */
#define SIZE 8190 /* velkost ciselneho pola */
#define FALSE 0
#define TRUE 1
char flag[SIZE+1];
main ()
{
int i, j, k, count, prvoc; printf(" %d iteracie: ",NTIMES);
for (i=1; i<= NTIMES; i++) {
count=0;
for (j=0; j<=SIZE; j++)
flag[j] = TRUE ;
for (j=0; j<= SIZE; j++) {
if (flag[j] == TRUE ) {
prvoc = j + j + 3 ;
for (k=j+prvoc; k<= SIZE; k += prvoc)
flag[k] = FALSE ; /* odstrani nasobky */
count ++;
}
}
}
printf(" %d prvoc.\n", count) ;
}1.7.2 Prevody cisel.
Tento program nie je elegantny, ale dovoluje vkladat decimalne
cisla az do 5 cislic, ktore sa zobrazia v hexadecimalnej a aj
binarnej forme. Funkcia readn, ktora nacitava decim. cislo, je
velmi jednoducha a prekvapujuco lahko krachuje. Ak vlozis viac
ako 5 cislic, alebo ak su to neni len cisla, potom sa neda
povedat aky bude vysledok. Tu je jedno zo zlatych pravidiel C -
mozes robit cokolvek, ale vsetky chyby su len TVOJ problem !
/* Program na prevod DEC na HEX a BIN */
main ()
{
int n;
char b[17]; printf("\nPrevod cisla: ");
n = readn(); binary(n,b);
printf("\nToto je %x v HEX a %s v BIN forme\n",n,b);
} /* Koniec hlavneho programu *//* definavanie funkcii readn() a binary(n,d) */
int readn() /* nacita DEC cislo do 5 znakov */
{
char s[5];
int i, c, total;
i=0;
while ((c=getchar())!='\n')
s[i++] = c;
total=0;
for (c=0; c<i; ++c)
total=total *10 + s[c] - '0';
return total;
}binary(num,digits) /* prevod cisla na binarny retazec */
int num;
char digits[]; /* alebo char *digits; */
{
int i, c;
for (i=15; i>-1; --i)
{
c= num & 1 << i; /* postupne deli s 2 */
digits[i] = c ? '1' : '0';
}
digits[16]= 0;
}1.7.3 RS - 232 system.
Pred nahratim C compilera nastav baud rozsah (baud rate)
RS-232 . FORMAT "b";baud_rate
potom otvor kanal 4 na seriove prepojenie
OPEN #4;"b"Teraz nahraj compiler a napis tento program. Ked ho skompilujes,
mozes primat alebo posielat subory cez RS-232 .Tento program je
idealny ak si vytvaras zdrojovy text na inom pocitaci ako QL a
nemas inu moznost ako poslat Spectru text. Zapametaj si, ze ked
sa kedikolvek vratis do BASICU, compilator mozes spustit bez
toho aby si stratil text
RANDOMIZE USR 25200/* posielanie a primanie suborov cez RS-232
najprv musi byt otvoreny seriovy kanal #4 */
#define FILE int /* ukazkove konstanty pre program */
#define EOF -1
#define UNIXEOF 4
#difine CPMEOF 26
main () /* zaciatok programu */
{
int c, i, sw, ueof;
char s[20];
FILE *fp;
do
{ printf("Meno suboru: ");
i = 0;
while ((c=getchar())!='\n')
{ /* cita meno suboru pokial nestlacis ENTER */
s[i++] = c;
if (i==19) /* nie viac ako 19 znakov */
break;
}
s[i] = '\0'; /* znacka- koniec retazca */
printf("\nStlac: \n0) pre citanie\n1) pre zapis\n");
printf("a ENTER\n\n");
sw = getchar()-'0';
if (sw)
fp = fopen(s,"r"); /* otvory subor len pre citanie */
else
fp = fopen(s,"w"); /* otvory subor len pre zapis */
while ((c=getchar())!='\n')
; /* prazdny prikaz: vycisti input buffer */
if (fp==0) /* fp=0 ak je error */
printf("\nFile ERROR !\n");
}
while (fp==0); printf("\nStlac:\n0) pre UNIX \n1) pre CP/M\n");
printf("\nkoncovy znak suboru, potom stlac ENTER\n\n");
c = getchar()-'0';
if (c) /* urcenie koncoveho znaku suboru */
ueof = CPMEOF;
else ueof = UNIXEOF;
while ((c=getchar())!='\n')
; /* prazdny prikaz: vycisti input buffer */
if (sw)
sendfile(fp,ueof); /* posle subor von cez RS-232 */
else
readfile(fp,ueof); /* nacita subor dnu cez RS-232 */
fclose(fp); /* zatvori subor */
} /* KONIEC HLAVNEHO PROGRAMU */sendfile(fp,eofu) /* definovanie sendfile */
int fp, eofu;
{ int c;
printf("\nVystup...\n");
while (c=getc(fp))!=EOF) /* nacitaj znak pokim nieje EOF*/
putc(c,4); /* posli znak na RS-232 */
putc(eofu,4); /* ukoncenie suboru koncovym znakom */
printf("\nSubor odoslany.\n");
} /* koniec sendfile */