JĘZYK PROGRAMOWANIA BASIC, QBASIC

STRUKTURA JEZYKA PROGRAMOWANIA na przykładzie języka BASIC


Każdy jezyk programowania ma swoją

Elementy jezyka programowania

Jezyk programowania sklada się z:

 Slowa kluczowe i funkcje, uzupelnione parametrami i argumentami, moga być użyte do tworzenia instrukcji, czyli poleceń dla komputera.

 Deklaracje sa czymś w rodzaju informacji dla komputera o tym, co mają reprezentowac wyszczególnione w nich nazwy i wielkosci.

 Operatory to znaki reprezentujące dzialania arytmetyczne i logiczne.


 Slowa kluczowe

 Slowo kluczowe jest podstawowym elementem instrukcji.
Instrukcja moze skladac sie z jednego lub kilku slow kluczowych, ktore moga byc uzupelnione parametrami.

Przykladem slowa kluczowego w Basicu jest PRINT.
Print wymaga dodatkowych patrametrow - co komputer ma drukowac.

Przykladem pelnej instrukcji jest
PRINT a, b, c
- drukuj; zawartosc; zmiennych; o; nazwach; a, b, c.

Samo PRINT oznacza "Drukuj pusty wiersz"

Przyklady innych slow kluczowych w jezyku Basic:

GOTO (skocz do),
INPUT (wprowadz),
IF (jesli),
END (koniec), 
READ (czytaj),
DO (rób).

 Deklaracje

Są to informacje umieszczane na poczatku programu i przeznaczone dla interpretera czy kompilatora.

Przykladem jest deklaracja w Basicu

DEFINT I-N
ktora kompilator rozumie tak:
wszystkie zmienne zaczynajace sie na litery I, J, K, M i N (od I do N) maja byc zmiennymi typu INTEGER, czyli typu liczb calkowitych.

lub (bardziej uniwersalna, zwałaszcza w nowszych wersjach)
DIM I, J, K, L, M, N AS INTEGER

Ogólnie:
DIM zmienna AS typ

Typy zmiennych:
     INTEGER      A 16-bit signed integer variable.
     LONG         A 32-bit signed integer variable.
     SINGLE       A single-precision 32-bit floating-point variable.
     DOUBLE       A double-precision 64-bit floating-point variable.
     STRING * n%  A fixed-length string variable n% bytes long.
     STRING       A variable-length string variable.



Inna deklaracja: 
DIM wyniki (1 TO 100)
lub
DIM wyniki(100)
deklaruje tablice jednowymiarowa w zakresie 1 do 100 o nazwie WYNIKI - w ktorej mozna pomiescic 100 liczb,
o adresach Wyniki(1)...Wyniki(100).

DIM tabl1 (100, 20) tablica 2-wymiarowa

 Operatory

 Podstawowe typy operatorow: operatory arytmetyczne, operator przypisania, operatory relacji i operatory logiczne.

 Operatory arytmetyczne:
  Operator          Dzialane     P    rzyklad
     ^              potega                    2^3 (2 do potegi 3-ciej)
     *              mnozenie              3*4
     /              dzielenie                 4/2
     +             dodawanie             2+3
     -             odejmowanie       6-4

OPERATOR PRZYPISANIA  
ma symbol rownosci (=).

 Zmienna = wartość
Operator ten nadaje zmiennej umieszczonej po jego lewej stronie  wartosc stalej lub wyrazenia po jego prawej stronie.

 Np. instrukcja
  a = 3
 oznacza - do  zmiennej A przypisz wartosc (stala) 3.

 ODL = (a + b) / c
 oznacza: wylicz wartosc wyrazenia po prawej stronie znaku = i przypisz  ja zmiennej ODL.

 Znak = jest tu OPERATOREM PRZYPISANIA wartosci a nie znakiem rownosci,  wystepujacym w matematyce.

 Przyklad
 A = A + 5   
oznacza - do wartosci zmiennej A dodaj stala 5 i wynik  umiesc z powrotem w zmiennej A.
 Uwaga!!  Znak rownosci (=) jest rowniez operatorem relacji. Funkcja,  ktora pelni symbol = zalezy od postaci instrukcji, w ktorej zostal  uzyty.

 OPERATORY RELACJI (porownania) sluza do porownania 2 wielkosci.
 Wynik porownania moze byc prawda lub falszem.
 Operator    Sprawdza relacje    Zapis wyrazenia
  =           rownosci                        X = Y
  <>          nierownosci                 X < > Y
  <           mniejszy niz                    X < Y
  >           wiekszy niz                    X > Y
  < =         mniejszy lub rowny      X < = Y
  > =        wiekszy lub rowny        X > = Y

 Typowym zastosowaniem tych operatorow jest instrukcja typu   IF X = Y THEN instrukcja
(Jesli wartosc zmiennej X jest rowna  wartosci zmiennej Y, to wykonaj instrukcje za slowem kluczowym THEN)

 Jesli wartosc X nie jest rowna wartosci Y, to nie wykonuj tej  instrukcji.

 Bardziej ogolnie instrukcje warunkowa w QBasic zapiszemy:

  IF X operator_relacji THEN   
        
instrukcja#1
         instrukcja#2
         ............
         instrukcja#n
  END IF
  instrukcja#(n+1)

 Jesli zapisana operatorem relacja miedzy X i Y jest prawdziwa, to wykonuj instrukcje miedzy THEN i END IF (#1 do #n).
Jezeli relacja nie jest prawdziwa to przeskocz do wykonywania instrukcji #(n+1).

Fragment miedzy IF a END IF nazywa sie blokiem IF.

OPERATORY LOGICZNE to operatory umozliwiajace konstruowanie nawet bardzo skomplikowanych relacji, wykorzystywanych w instrukcjach warunkowych.
Operatory te to:
 NOT, AND, OR, XOR, EQV, IMP.

Najczesciej uzywa sie operatorow AND (i), OR (lub) i NOT (nie).
Te 3 operatory wystarcza do zapisania dowolnego warunku.

Przyklady:
  IF X > 5 AND X <= 10 THEN PRINT X
  - jesli X jest wieksze od 5 i (rownoczesnie) X jest mniejsze lub   rowne 10 to wydrukuj wartosc X.

 IF X  <= 5 OR X >= 10 THEN PRINT X
  Jesli X jest mniejsza lub rowna 5 LUB wieksza od 10 to drukuj X.

 Instrukcje
IF NOT A=C THEN PRINT A-C
(jesli nie jest prawdziwa relacja  A=C to drukuj A-C)
 mozna zastapic instrukcja 
IF A<>C THEN PRINT A-C
(jesli A nie jest  rowne C to drukuj A-C).

 Wynik dowolnej relacji moze byc prawdziwy albo falszywy.
 BASIC zapisuje prawdze jako -1 a falsz jako 0.
 Mozna to sprawdzic uruchamiajac prosty program
  PRINT 2 = 2
  PRINT 3-=2
  PRINT 5 < 4
  PRINT 5 > 4

 Funkcje

 Funkcje, zwane tez operatorami funkcyjnymi, sluza do otrzymywania w programie wartosci bedacej wynikiem dokonania pewnych operacji na argumencie lub argumentach funkcji.

W jezyku BASIC mamy miedzy innymi funkcje o nazwie SQR - Square Root - pierwiastek kwadratowy.
Np. 
A = SQR(144)
wywoluje funkcje z argumentem 144.
Fragment programu:
 ALFA = 1
 w = SIN(ALFA)
 przypisuje do zmiennej ALFA wartosc 1 i nastepnie oblicza sinus z 1 radiana - standardowa jednostka miary kata jest radian a nie stopien.

Funkcje, ktore zostaly zaprogramowane w kompilatorze (inerpreterze) nazywamy funkcjami wewnetrznymi.

Programista moze zdefiniowac swoje wlasne funkcje.
Np. przypuścmy, że amy  liczyc wielokrotnie wartosc wyrazenia
 -B - SQR(B^2-4*A*C/(2*A)
dla ulatwienia mozna zdefiniowac wlasna funkcje, nazwac ja dowolnie, np. PIERW1(A,B,C).

Obok funkcji matematycznych w jezykach programowania istnieje wiele innych funkcji, np. funkcja o nazwie ASC,  zamieniajaca znak na jego kod ASCII.
 Np.
PRINT ASC("R")
drukuje liczbe 82, ktora jest kodem ASCII litery R.
Cudzysłów zamykajacy argument funkcji jest elementem wymaganym w BASICu.

 Biblioteki


Wykonanie mnozenia czy dzielenia 2 liczb wymaga dziesiatek dzialan w jezyku maszynowym.
Kompilatory sa tak zbudowane, ze nie tlumacza kazdej operacji arytmetycznej na kody maszynowe, tylko korzystaja z gotowych programow w jezyku maszynowym, zapisanych w osobnym zbiorze
zwanym biblioteka.
Jesli kompilator ma np. przetlumaczyc na jezyk maszynowy instrukcje A=B/C to wykonujac tlumaczenie, zaznacza w okreslony sposob, ze nalezy do tego tlumaczenia dołączyć program
(w jezyku maszynowym) na dzielenie 2 liczb.
Taki program, dzielenia, zwany procedura, zapisany jest w osobnym zbiorze, zwanym  r u n  t i m e  l i b r a r y, wlasciwym dla danego kompilatora.
W trakcie tlumaczenia programu, kompilator zaznacza wszystkie miejsca, w ktorych nalezy posluzyc sie procedurami zawartymi w bibliotece. 
Nastepnie program LINK EDITOR, wchodzacy w sklad kompilatora, przeglada przetlumaczony na kody maszynowe program i uzupelnia go wszystkimi procedurami, ktore beda konieczne
do jego wykonania.
 Programowanie w jezyku ASSEMBLER moze dac czasem duze korzysci w stosunku do programowania w jezykach wysokiego poziomu.
Na przyklad rozwiazanie jakiegos zadania wymaga wykonania kilku tysiecy operacji dzielen liczb calkowitych przez 2.
Wszystkie operacje dzielenia zapisane w postaci W=A/B  beda wykonane przez procedure wczytana z biblioteki do programu wynikowego, w trakcie jego tlumaczenia na jezyk maszynowy.
Procedura ta zawiera kilkadziesiat instrukcji maszynowych.
Tymczasem wszedzie tam, gdzie B=2, dzielenie moze byc wykonane za pomoca jednego rozkazu maszynowego, przesuwajacego bity o jedno miejsce w prawo.
Jesli potrafimy zapisac fragment programu, w ktorym wystepuja owe dzielenia przez dwa, za pomoca jezyka ASSEMBLER, to czas wykonania operacji zostanie skrocony kilkadziesiat razy.


TWORZENIE PROGRAMU

 Warunkiem podstawowym powstania programu komputerowego jest istnienie problemu czy zagadnienia, ktore chcemy rozwiazac za pomoca komputera
i musi sie ponadto opłacać napisanie programu (powtarzalnosc zadan, stopien trudnosci itd.).

 Algorytm

Algorytm to przepis, wg ktorego chcemy rozwiazac postawiony problem.

Algorytm – w matematyce oraz informatyce skończony, uporządkowany ciąg jasno zdefiniowanych czynności, koniecznych do wykonania pewnego rodzaju zadań.
Słowo "algorytm" pochodzi od starego angielskiego słowa algorism, oznaczającego wykonywanie działań przy pomocy liczb arabskich

Algorytm to jednoznaczny przepis przetworzenia w skończonym czasie pewnych danych wejściowych do pewnych danych wynikowych.

Komputery przetwarzają przekazywane im informacje z wykorzystaniem algorytmów.
Program jest algorytmem zapisanym w języku zrozumiałym dla maszyny (asemblerze).
Każdy poprawny kod maszynowy da się przełożyć na zestaw instrukcji dla teoretycznego modelu komputera – maszyny Turinga

Algorytm jako taki nie ma nic wspolnego z komputerem - jest to opis metody rozwiazania, bez wnikania jakimi srodkami, czy za pomoca jakich urzadzen.
Dla wielu typowych zagadnien algorytmy zostaly opracowane na dlugo przed pojawieniem sie komputerow.
Niektore z algorytmow pochodza z czasow starozytnych.
Przed rozpoczeciem wymyślania algorytmu nalezy zajrzec do odpowiedniej literatury.

Wybor wlasciwego algorytmu jest podstawa sukcesu w pisaniu programu.

 Redagowanie programu - kodowanie

W procesie kodowania zapisuje sie zlecenia okreslone w algorytmie za pomoca elementow konkretnego jezyka programowania.

Najbardziej racjonalny program powinien skladac sie z osobnych modulow - podprogramow dla kazdego wyodrebnionego zadania.

Taki system pisania programow ma wiele zalet, a 2 najwazniejsze to:
Kazdy podprogram powinien tak napisany i udokumentowany, by mozna bylo z niego latwo korzystac.
Ogolna zasada - nigdy za duzo komentarzy.
Bardzo waznym elementem jest wprowadzanie danych i wydruk wynikow.
Operator nie powinien miec watpliwosci co nalezy wprowadzic z klawiatury.
Jezeli program wymaga wpisywania duzej liczby danych, najlepiej zaprojektowac go tak, by dane byly wczytywane z uprzednio zredagowanego zbioru.
Wydruk wynikow rowniez decyduje o funkcjonalnosci programu.
Wyniki powinny byc wypisane na drukarce w sposob przejrzysty, z naglowkami i tytulami.



   QBasic

 I. Wprowadzenie

QBasic dostarczany z systemem DOS 5.0 i 6 jest programem interpretacyjnym.
Program jest zintegrowany z edytorem tekstu.
Edytor wspolpracujacy z QBasic jest zmodyfikowanym nieco edytorem EDIT. Sa 2 programy - EDIT.COM i QBASIC.EXE, powiazane ze soba.
Nie posiadajac QBASIC.EXE nie mozemy korzystac z edytora EDIT.

 Uruchomienie programu:

 QBASIC [Enter]  lub  QBASCIC Nazwa_pliku
Naciskamy Esc i mozna wpisywac program.
Zapis programu przez Alt F S lub Alt F A (sAve As).
Wyjscie do menu gornego przez Alt lub Alt i litera menu gornego.
Opuszczenie QBasic przez opcje eXit z menu File.
Program najlepiej wpisywac malymi literami.
Jesli jest to slowo kluczowe to po nacisnieciu Enter, slowo zostanie zamienione na duze litery.
Pozostale slowa beda wpisane malymi literami.

Skróty klawiszowe w QBasic

Shift F1 - help
F6 - tryb bezpośredni / tryb programowy - przełaczanie
Shift F5 - uruchomienie programu
F1 na słowie programu - pomoc do słowa
F4 - ekran wynikowy

Uwaga!
Apostrof umieszczony w wierszu programu powoduje, ze caly tekst na prawo od niego jest komentarzem i nie ma wplywu na przebieg wykonania programu.


Typy zmiennych:

     INTEGER      A 16-bit signed integer variable. (16 bitowa liczba całkowita ze zanakiem)
     LONG         A 32-bit signed integer variable. (32 bitowa liczba całkowita ze zanakiem))

     SINGLE       A single-precision 32-bit floating-point variable (rzeczywista, 32-bitowa, pojedynczej precyzji).
     DOUBLE       A double-precision 64-bit floating-point variable. (rzeczywista, 64-bitowa, podwójnej precyzji).

     STRING * n%  A fixed-length string variable n% bytes long. (zmienna łańcuchowa o ustalonej długościn% bajtów)
     STRING       A variable-length string variable. (zmienna łańcuchowa o zmiennej długości)



Deklarowanie zmiennych:

 Np. po napisaniu:
  DEFINT K, S          ' deklarujemy zmienne typu integer [Enter],
 Po nacisnieciu klawisza Enter, wiersz przyjmie postac:
 DEFINT K, S           ' deklarujemy zmienne typu integer
zadeklarowane zostały zmienne typu INTEGER - zaczynające się na K i S.

W nowszych wersjach Basica bardziej uniwersalna jest deklaracja:
DIM zmienna AS typ
jeśli typ licxb całkowitych - INTEGER to
DIM zmienna AS INTEGER
np. DIM k, s AS INTEGER



Sposoby deklarowania zmiennych w QBasicu

Pierwszy sposób 

W QBasic można  deklarować typ zmiennych poprzez podanie tylko pierwszej litery nazwy zmiennej.

np.   DEFINT K, S  
Wszystkie zmienne zaczynajace sie na zadeklarowana litere (tu K i S) bedą tego samego typu (tu INTEGER).

Interpretator odrzucil dalsze litery w nazwach i ponadto ustawil pierwsze litery w kolejnosci alfabetycznej.

 DEFINT
jest skrotem od  define integer i informuje QBasic (interpretator lub kompilator),  ze zmienne wypisane po deklaracji DEFINT maja byc typu calkowitego (integer) - o dlugosci 2 bajtow.

Analogicznie mozna definiowac zmienne innych typow, np.

DEFLNG - zmienne calkowite dlugie, o dlugosci 4 bajtow.

np. DEFLNG L-N - wszystkie zmienne o nazwach zaczynajacych sie na litery z przedzialu L do N (L, M, N lub l, m, n) beda traktowane jako zmienne typu dlugich liczb calkowitych.
 
DEFSNG
- deklaracja zmiennych rzeczywistych 4 bajtowych (single precision  - pojedynczej dokladnosci),

np.  DEFSNG O-R  lub DEFSNG O, P, R

 DEFDBL - double precision - podwojnej dokladnosci

 np. DEFDBL S-U

 DEFSTR - deklaracja zmiennych znakowych - typu STRING - (lancuch)

 np. DEFSTR W-Z

W nowszych wersjach Basica zalecana deklaracja metoda:
DIM zmieanna AS typ, czyli, gdzi typ to: INTEGER, LONG, SINGLE, DOUBLE, STRING
NP. DIM zmienna1  AS LONG

 Znaki to symbole graficzne kodow ASCII o numerach od 32 do 127.
Sa wsrod oprocz m.inn. liter  rowniez cyfry. Cyfra to tez znak. Kilka cyfr umieszczonych jedna za druga moze reprezentowac liczbe, ale moze byc traktowanych jako ciag symboli graficznych.
 
Drugi sposob deklarowania typu to zakonczenie nazwy zmiennej odpowiednim symbolem:

 %  dla zmiennych INTEGER          - calkowite 2 bajtowe
 &      -"-       LONG INTEGER     - calkowite 4 bajtowe
 !      -"-       SINGLE PRECISION - rzeczywiste pojed. dokl. 4 bajtowe
 #      -"-       DOUBLE PRECISION - rzeczywiste podwojnej dokl. 8 bajtowe
 $      -"-       STRING VARIABLE - zmienne typu znakowego

Przykład
REM ABCQ7.BAS
REM Porownywanie liter
CLS
INPUT "Wpisz litere "; lit1$
INPUT "Wpisz litere "; lit2$
IF lit1$ < lit2$ THEN
  PRINT lit1$, lit2$
ELSE
 PRINT lit2$, lit1$
END IF
 
Trzeci sposób deklarowania zmiennych:

W nowszych wersjach Basica bardziej uniwersalna jest deklaracja:
DIM zmienna AS typ
gdzie typem moze być: INTEGER, LONG, SINGLE, DOUBLE, STRING
np. DIM k, s AS INTEGER

Przykład programu:
DIM a AS INTEGER
DIM b AS LONG
DIM c AS DOUBLE
CLS
a = 5
b = 10
c = 5#
PRINT b / c



Uwaga!.
 Zmienna, ktorej nazwa nie jest ujeta w zadnej deklaracji i nie jest zakonczona zadnym ze znakow (%, &, !, # czy $),
jest przez interpretator deklarowana jako zmienna typu SINGLE PRECISION - rzeczywista, pojedynczej dokladnosci, 4 bajtowa.

Stale typu znakowego moga mieć dlugosc od 0 do 32767 bajtow.
Aktualna liczba bajtow zajmowana w pamieci operacyjnej przez zmienna typu znakowego zalezy od dlugosci przypisanej do niej stalej.
Jesli w programie mamy np. 2 instrukcje
  nazwisko1$ = "Roman Goc"
  nazwisko2$ = "Sebastian Zajaczkowski"
to kazda ze zmiennych zajmuje w pamieci operacyjnej liczbe bajtow odpowiednia do dlugosci przypisanej do niej stalej znakowej (tu nazwiska).
 Zmienne rozpoczynajace sie na okreslona litere moga byc w programie deklarowane wielokrotnie, za kazdym razem jako innego typu.
Każda nowa deklaracja anuluje poprzednią.
Ponadto w momencie zmiany typu danej zmiennej, jej wartość jest zerowana.
Takie metody deklarowania stosuje sie przy pisaniu bardzo dlugich programow, kiedy zaczyna brakowac miejsca w pamieci komputera.
Poczatkujacym programistom nie poleca sie jednak wielokrotnego deklarowania tych samych zmiennych.

 Przykladowy program z definicja typow
 DEFINT K, S
 PRINT start, KONIEC    'wydruk na ekranie zawartosci zmiennych
 start = 10             'przypisanie wartosci do zmiennej start
 KONIEC = 50            ' -"-                             koniec
 PRINT start, KONIEC



 Uruchomienie programu wymaga nacisniecia Shift+F5.

W wiekszosci przypadkow wystarcza nacisniecie klawisza funkcyjnego F5, ktore jest rozkazem kontynuowania wykonywania programu.
Shift+F5 uruchamia program od pierwszego wiersza, a F5 od wiersza, gdzie program zostal zatrzymany.
 Po nacisnieciu Shift+F5 z ekranu znika dotychczasowy obraz i pokazuje sie tzw. ekran wynikowy.

 Dla powyzszego przykladu wyniki sa nastepujace:
  0     0
  10    50

 Zmienne, ktorym nie przypisano zadnych wartosci, maja wartosc 0.
W innych jezykach programowania nie musi to byc prawda i lepiej w programie podstawiac wartosc dla kazdej zmiennej. Przestrzeganie tej zasady pozwoli uniknac niespodzianek.
Dobra praktyka przy pisaniu programow jest umieszczenie na poczatku instrukcji  CLS, ktora powoduje wyczyszczenie ekranu.
Przerwanie programu w przypadku nie konczenia jego dzialania nastepuje przez Ctrl + Pause / Break.

 Piszac program mozna w kazdej chwili korzystac z funkcji HELP.
Gdy kursor znajduje sie na danym slowie kluczowym i nacisniemy F1, to pokaza sie informacje dotyczace tego slowa.
Informacji pomocniczych HELP jest czesto wiecej niz miesci jeden ekran.
Chcac je obejrzec naciskamy klawisz F6 dwukrotnie.

Dowolny fragment tekstu pomocniczego mozemy przekopiować do okna redagowania programu:


 II. ELEMENTY JEZYKA QBasic


 Tryby pracy w programie QBasic
 
 Po wywolaniu programu QBasic mamy 2 mozliwosci korzystania z niego, zwane trybami pracy:
 W trybie programowym kursor znajduje sie w gornym, duzym oknie edytora.
Wpisywane instrukcje sa umieszczone w pamieci komputera, a ich wykonanie nastepuje po nacisnieciu Shift+F5.
 Przejscie do trybu natychmiastowego nastepuje w wyniku nacisniecia klawisza F6.
Kursor przeskakuje do malego okna na dole ekranu, zatytulowanego Immediate.
W trybie tym zakonczenie instrukcji wcisnieciem Enter jest rownoznaczne poleceniem wykonania instrukcji.

Tryb natychmiastowy pozwala korzystac z programu jak z kalkulatora.
Przyklad
Naciskamy F6 i przechodzimy do trybu natychmiastowego.
Piszemy:
 PRINT 3.14*7^2 lub ? 3.14*7^2  i <Enter>

Znika dotychczasowy obraz i pojawia sie ekran wynikowy i ostatnia widoczna na nim wielkosc - 153.86 - jest wynikiem wykonania instrukcji wpisanej w trybie natychmiastowym.
Wcisniecie dowolnego klawisza przywraca poprzednia postac ekranu, z oknami do redagowania programu i wpisywania instrukcji do natychmiastowego wykonania.
Powrot do trybu programowego przez F6.
Tryb natychmiastowy jest pomocny podczas uruchamiania programow.
W trybie tym sa dostepne wszystkie zmienne uzywane w programie.
Jezeli w trakcie wykonywania programu wystapil blad i nastapilo zatrzymanie programu, to mozemy przejsc do trybu natychmiastowego i wyswietlic wartosci dowolnych zmiennych.

 QBasic pozwala na "przywolanie" ekranu wynikowego w dowolnym momencie redagowania programu. Realizuje to nacisniecie klawisza F4.

 Deklaracje typow zmiennych


 W językach programowania rozroznia sie 3 podstawowe typy zmiennych i stalych:

 Dla kazdej zmiennej, uzytej w programie, musi byc zarezerwowana w komputerze pewna liczba komorek pamieci, zalezna od typu zmiennej.

Te rezerwacje pamieci zapewniaja deklaracje, umieszczone na poczatku programu.

 D e k l a r a c j a  jest informacja dla informatora, ze w programie uzyte beda zmienne o wymienionych nazwach i typach wynikajacych z rodzaju deklaracji.

 Obok zmiennych, w programie wystepuje stale, ktore tez moga byc typu  Integer, Real i String.

 Zmienna to nazwa, do ktorej moze byc przypisana wartość. Ta wartosc nazywa sie stałą.

W instrukcji
   liczbauczniow = 342
liczbauczniow (nie moze byc polska litera) to zmienna,  a 342 to stala, czyli konkretna liczba.
Pokazana instrukcja przypisuje stala 342 do zmiennej liczbauczniow.

 Stala nie musi byc przypisana do zmiennej.
Np. w instrukcji
 PRINT 8 / 3
wystepuje slowo kluczowe PRINT i 2 stale: 8 i 3.

 QBASIC nie wymaga obowiazkowego deklarowania zmiennych na poczatku programu.
Uzycie zmiennej niezadeklarowanej powoduje przydzielenie dla niej odpowiedniego obszaru pamieci. J
est to wiec deklaracja domyslna, realizowana przez komputer, bez udzialu programisty.

 W QBasicu, jesli nie napiszemy programu bez zadnych deklaracji typu zmiennych,
to wszystkie wystepujace w nim zmienne sa typu SINGLE PRECISON (liczby rzeczywiste pojedynczej precyzji - czterobajtowe).

 Wiele innych jezykow programowania wymaga bezwzglednie deklarowania wszystkich zmiennych, jakie beda uzyte w programie.

 Zmienne typu INTEGER

Zmienne typu INTEGER - zmienne, do ktorych moga byc przypisane tylko liczby calkowite.
Zmienne calkowite typu INTEGER maja dlugosc 2 bajtow.
W 2 bajtach mozemy zapisac liczby calkowite od -32768 do +32767.

Zmienne LONG INTEGER - dlugie liczby calkowite maja dlugosc 4 bajtow.
Moga do nich byc przypisane liczby od -2147483648 do +2147483647.
Zmienne te mozemy deklarowac kilkoma sposobami.
Deklaracje ogolne sa postaci:
 DEFINT A-K
 DEFLNG L-N
Drugi sposob deklarowania to zakonczenie nazwy zmiennej symbolem % (INTEGER) lub & (LONG INTEGER).

Symbole na koncu maja wyzszy priorytet od deklaracji ogolnych.

W programie w ktorym wystapi deklaracja ogolna
 DEFINT A-K     ' (zmienne na A i K typu INTEGER)
zmienna o nazwie dane& bedzie zmienna typu LONG INTEGER.

Stale typu integer tworzymy dodaniem do liczby symbolu % lub &,

np. 123% bedzie stala typu INTEGER, a 1
2345678& typu LONG INTEGER.

Zmienne typu REAL

Sa to zmienne, do ktorych mozemy przypisac liczby rzeczywiste.
W QBasic mozna deklarowac 2 rodzaje zmiennych i stalych rzeczywistych:

 Deklaracje maja postac:
  DEFSNG O-R
  DEFDBL S-U
lub konczac nazwe wykrzyknkiem ! - SINGLE PRECISON 
albo symbolem # - DOUBLE PRECISION.

Uwaga!.
Zmienna nie ujeta w deklaracji i nie zakonczona zadnym ze znakow %, &, ! czy &

jest traktowana przez QBasic jako zmienna typu SINGLE PRECISON (tak jak zakonczona znakiem !).

 Jesli napiszemy program bez zadnych deklaracji zmiennych, to wszystkie zmienne beda typu SINGLE PRECISION.

 Stale pojedynczej precyzji to liczby 7-cyfrowe, a podwójnej precyzji - 16 cyfrowe.

Przedziały, w ktorych mieszcza sie te liczby mozna odczytac w tekscie HELP sekwencja:
 Shift F1, (Enter)
 podprowadzamy kursor pod napis QBasic Environment Limits i naciskamy Enter,
 kursor pod napis Name, String and Numeric Limits [Enter].

 Zmienne znakowe

Nazwa tego typu zmiennej to STRING VARIABLE.
Do zmiennych tego typu mozna przypisywac znaki.
Znaki to symbole graficzne kodow ASCII o numerach od 32 do 127. Są wśród nich rowniez (m.in. oprocz liter) i cyfry.
Cyfra to tez znak. Kilka cyfr umieszczonych jedna za druga moze reprezentowac liczbe ale moze tez byc traktowanych jako ciag symboli graficznych.
 
Zmienne typu STRING deklarujemy w postaci
  DEFSTR W-Z  
(moga byc inne litery - tu zaczynajace sie na W i Z)
lub przez zakonczenie nazwy zmiennej symbolem $,  np. nazwisko$

Stale znakowe (typu STRING) tworzymy przez ujecie w cudzyslow ciagu znakow. 

Np. wizytowka="Jan Kowalski".
W typ wypadku zmienna o nazwie wizytowka musi byc zmienna znakowa, a wiec na poczatku programu, w ktorym zostala uzyta musi byc umieszczona deklaracja ogolna,
np.  DEFSTR W
 Stale typu znakowego moga miec dlugosc od 0 do 32767 bajtow.
Aktualna liczba bajtow zajmowana w pamieci operacyjnej przez zmienna typu znakowego zalezy od dlugosci przypisanej do niej stalej.

Jezeli w programie mamy 2 instrukcje
 nazwisko1$ = "Roman Goc"
 nazwisko2$ = "Sebastian Kolodziejski"
to kazda ze zmiennych zajmuje w pamieci operacyjnej liczbe bajtow  odpowiednia do dlugosci przypisanej do niej stalej zankowej (tu nazwiska).

Zmienne rozpoczynajace sie na okreslona litere moga byc w programie deklarowane wielokrotnie, za kazdym razem innego typu.
Kazda nowa deklaracja anuluje poprzednia. Ponadto w momencie zmiany typu danej zmiennej, jej wartosc jest zerowana.
Takie metody stosuje sie przy pisaniu bardzo dlugich programow, gdy zaczyna brakowac miejsca w pamieci komputera.
Uwaga!. Poczatkujacym programistom nie poleca sie jednak wielokrotnego deklarowania tych samych zmiennych.

 Konwersja typow

 W rygorystycznym podejsciu do programowania, do zmiennych danego typu przypisujemy stale tego samego typu.
Czesto zachodzi jednak potrzeba zamiany typu stalej.
Mozna tego dokonac za pomoca specjalnych funkcji ale QBasic dokonuje tej zamiany automatycznie, gdy zachodzi taka potrzeba w procesie przypisywania stalej do zmiennej.
 Np. wykonanie instrukcji
  liczba% = 321.45
odbywa sie w ten sposob, ze stala SINGLE PRECISION zostaje zaokraglona do najblizszej liczby calkowitej (tu 321)
i przypisana jako 2-bajtowa liczba calkowita do zmiennej  liczba%  typu integer.
Stała, nie moze miec wartosci spoza przedzialu dozwolonego dla danego typu.

Np.proba wykonania instrukcji a%=42335.5 spowoduje wystapienie bledu i zatrzymanie wykonywania programu (max 32767).

 Uwaga!  Dla zmiennych liczbowych dowolnego typu nie mozna przypisac stalych znakowych, a do zmiennych typu znakowego nie mozna przypisac stalych liczbowych.
 Tak wiec instrukcja
  liczba# = "123" jest bledna,  spowoduje zatrzymanie wykonywania programu i pojawienie sie na ekranie komunikatu bledu  Type Mismatch, co znaczy pomieszanie typow.

Poprawna jesta natomiast instrukcja  znaki$="123"
Na zmiennych znakowych nie mozna robic operacji arytmetycznych.
Jedynym wyjatkiem jest operacja oznaczona operatorem +.
Jest to dodawanie znakow (liter, cyfr) przypisanych do zmiennych, a nie liczb, jakie te znaki pozornie przedstawiaja.

 Przyklad
 Wpisujemy do edytora programu QBasic program
  zmienna1$ = "123"
  zmienna2$ = "456"
  zmienna3$ = zmienna1$ + zmienna2$
  PRINT zmaienna3$
i uruchamiamy przez Shift+F5.  Wynikiem jest ciag znakow 123456.
Zmieniajac instrukcje dodawania znakow do postaci
 zmaenna3$ = zmienna2$ + zmaenna1$
otrzymamy w wyniku wykonania ciag znakow  456123.

 Zmiany typu zmiennej mozna dokonac za pomoca jednej z funkcji konwersji typow:
 CDBL  - Convert to DouBLe precision
 CSNG  -  -"-       SiNGle -"-
 CINT  -  -"-       INTeger
 CLNG  -  -"-       LoNGinteger

 Przyklad
 PRINT 1 / 3, CDBL(1 / 3)
da w wyniku:  .3333333      .3333333333333333
 
QBasic posiada takze specjalne funkcje zamieniajace stale liczbowe na tale znakowe i odwrotnie.
Sa one wykorzystywanew przy zapisie liczb na dysku w zbiorach o dowolnym dostepie.

Np. CVD  ConVert Double - zwraca liczbe podwojnej precyzji otrzymana  z lancucha 8-bajtowego
    CVDMBF  zwraca licze podwojnej precyzji w formacie Microsoftu
    CVI  ConVert Integer - zwraca liczbe calkowita z lancucha 2-bajtowego
    CVL  CoVert to Longinteger - zwraca dluga liczbe calkowita z lancucha
                                 4-bajtowego
    CVS  Convert to Single - zwraca liczbe pojed. precyzji z lanc. 4-bajt.
    CVSMBF zwraca liczbe poj. prec. w formacie Microsoftu
    MKD$ - zamienia liczbe podwojnej precyzji w lancuch 8-bajt.
    MKDMBF$ - zmienia liczbe podw. precyzji formatu IEEE na lancuch
              w formacie binarnym Microsoft
    MKI$ - przeksztalaca liczbe calkowita na lancuch 2-bajtowy
    MKL$ - przeksztalaca liczbe calkowita typu LONG na lancuch 4-bajtowy
    MKS$ - przeksztalca wartosc pojed. precyzji na lancuch 4-bajt.
    MKSMBF$ - przeksztalca wyrazenie pojed. precyzji formatu IEEE na
              lancuch formatu binarnego Microsoft

 Cel deklarowania zmiennych

 Deklarowanie typow zmiennych i stalych ma 2 glowne cele:
 Piszac program, w ktorym operujemy tylko liczbami calkowitymi, mniejszymi od 32767, mozemy zadeklarowac zmienne jako liczby calkowite 2-bajtowe INTEGER.
Piszac ten sam program, bez zadnych deklaracji typow zmiennych, operujemy liczbami SINGLE PRECISION, z ktorych kazda zajmuje 4 bajty.
 Operacje arytmetyczne na liczbach calkowitych wykonywane sa przez komputer szybciej niz na liczbach rzeczywistych.
 Z drugiej strony, zmienne pojedynczej precyzji (SINGLE PRECISION) nie zawsze daja wynik z zadowalajaca dokladnoscia - 7 cyfr znaczacych,
tj. w przyblizeniu +-1*10^-7, czyli 0.000001%.  7 cyfr znaczacych pozwala na dokladny zapis sum mniejszych od 10000000. 
Chcac operowac liczbami wiekszymi niz 7-cyfrowe, deklarujemy zmienne jako DOUBLE PRECISION.
Pozwala to na poslugiwanie sie liczbami 16-cyfrowymi, co zapewnia wystarczajaca dokladnosc w praktycznie wszystkich zagadnieniach.
 Jezyki programowania bardziej doskonale niz BASIC maja jeszcze wieksze mozliwosci deklarowania typow zmiennych, np. liczb calkowitych 1-bajtowych, liczb calkowitych dodatnich czy liczb zespolonych, zmiennych typu data.
 Deklarowanie typu wielkosci wystepujacych w programie jest konieczne do poprawnego dzialania programu.
Wszystkie informacje sa zapisane w pamieci operacyjnej w postaci ukladow 0 i 1 w kolejnych komorkach (bajtach) tej pamieci.
Program musi byc poinformowany jak interpretowac zawartosc pamieci.
Np. niech 2 kolejne komorki pamieci zawieraja nastepujacy uklad bitow:
01001111
01001011
Zawartosc tych komorek, odczytana jako znaki, to litery OK.
Ten sam uklad odczytany jako liczba calkowita 2-bajtowa to 20299.
Bez deklaracji typu wielkosci, zapisanej w tych komorkach, program nie potrafi jej prawidlowo odczytac.

 Wprowadzanie danych do programu

 Najbardziej elementarnym sposobem wprowadzania danych jest wpisywanie ich za pomoca klawiatury.
QBasic posiada instrukcje INPUT, przewidziana do tego celu.
 By zapoznac sie ze sposobem poslugiwania sie ta instrukcja wpisujemy do edytora programu QBasic
 INPUT
i naciskamy klawisz F1. Naciskamy dwukrotnie klawisz F6 i za pomoca klawiszy kierunkowych mozemy obejrzec caly tekst pomocniczy dla slowa INPUT.

INPUT reads input from the keyboard or a file. LINE INPUT reads a line of up to 255 characters from the keyboard or a file.

INPUT [;] ["prompt"{; | ,}] variablelist
LINE INPUT [;] ["prompt";] variable$
INPUT #filenumber%, variablelist
LINE INPUT #filenumber%, variable$

    ţ prompt          An optional literal string that is displayed before
                      the user enters data. A semicolon after prompt appends
                      a question mark to the prompt string.
    ţ variablelist    One or more variables, separated by commas, in which
                      DATA entered from the keyboard or read from a file is
                      stored. Variable names can consist of up to 40
                      characters and must begin with a letter. Valid
                      characters are A-Z, 0-9, and period (.).
    ţ variable$       Holds a line of characters entered from the keyboard
                      or read from a file.
    ţ filenumber%     The number of an open file.

    ţ INPUT uses a comma as a separator between entries.
      LINE INPUT reads all characters up to a carriage return.
    ţ For keyboard input, a semicolon immediately after INPUT keeps the
      cursor on the same line after the user presses the Enter key.

Example:
    CLS
    OPEN "LIST" FOR OUTPUT AS #1
    DO
        INPUT "   NAME:       ", Name$  'Read entries from the keyboard.
        INPUT "   AGE:        ", Age$
        WRITE #1, Name$, Age$
        INPUT "Add another entry"; R$
    LOOP WHILE UCASE$(R$) = "Y"
    CLOSE #1
    'Echo the file back.
    OPEN "LIST" FOR INPUT AS #1
    CLS
    PRINT "Entries in file:": PRINT
    DO WHILE NOT EOF(1)
        LINE INPUT #1, REC$  'Read entries from the file.
        PRINT REC$           'Print the entries on the screen.
    LOOP
    CLOSE #1
    KILL "LIST"


 Wiersz
 INPUT [;] ["prompt"{; | ,}] variablelist
nalezy rozumiec tak:
 INPUT jest elementem, ktory musi wystapic w instrukcji,  po slowie INPUT mozemy, ale nie musimy wpisac srednik (;), nastepnie mozemy ale nie musimy wpisac dowolny tekst zamkniety cudzyslowami i zakonczony srednikiem (;)
albo przecinkiem (,), na koncu musi sie znajdowac nazwa zmiennej lub kilka nazw rozdzielonych przecinkami.

 Najprostsza instrukcja czytania danych z klawiatury ma postac:
 INPUT a12
Wykonanie tej instrukcji spowoduje wyswietlenie na ekranie znaku zapytania (?) i program bedzie czekal na wpisanie z klawiatury stalej, ktora ma byc przypisana do zmiennej o nazwie a12.
Wpisanie stalej konczymy wcisnieciem klawisza Enter. Jesli wpisana z klawiatury stala nie jest tego typu co zmienna, do ktorej ma byc przypisana, to mozliwe sa 2 przypadki:
 a) nastapi konwersja typu stalej do typu zmiennej i przypisanie tej stalej     do zmiennej a12
 b) wykonanie programu zostanie zatrzymane z powodu niemoznosci dokonania     konwersji typu.

I instrukcja
  INPUT liczba1, liczba2, liczba3
zostanie wykonana po wpisaniu z klawiatury 3 liczb rozdzielonych przecinkami i wcisnieciu Enter.
W instrukcji INPUT powinno sie zawsze umieszczac informacje dla operatora, jakie wielkosci ma wprowadzic.

Przykladem moze byc:
 INPUT "Podaj 3 liczby z przedizlu 0 do 100"; n1, n2, n3

 Instrukcja LINE INPUT sluzy do wprowadzenia jednej stalej znakowej, ktora moze zawierac w sobie przecinki.
W instrukcji INPUT przecinek jest znakiem oddzielajacym stale i nie moze byc wczytany do zmiennej.
W instrukcji LINE INPUT dopiero [Enter] jest znakiem konca stalej i rownoczesnie sygnalem do jej przypisania do zmiennej umieszczonej w tej instrukcji.

Np. instrukcja
  LINE INPUT "Podaj imiona rodzenstwa "; imiona$
umozliwia przypisanie do zmiennej znakowej imiona$ kilku grup znakow (np. imion) rozdzielonych przecinkami.
 QBasic jest tak napisany, ze wpisanie z klawiatury stalej, ktora nie moze byc przypisana do zmiennej, umieszczonej w instrukcji INPUT lub LINE INPUT, nie zatrzymuje wykonywania programu, tylko powrot do poczatku wykonania instrukcji czytania danych.

Przyklad:
 INPUT "Podaj liczbe uczniow w klasie "; liczbauczniow%
 i wpisujemy (zamiast liczby) slowo trzydziesci.
Na ekranie pojawia sie  komunikat
 Redo from start
co znaczy - wykonaj od poczatku i program czeka na ponowne wprowadzenie danej lub danych.

 Instrukcje
  INPUT #filenumber, variablelist
  LINE INPUT #filenumber%, variable$
slużą do wczytania danych znajdujacych sie w zbiorze zapisanym na dysku.
Wymagaja one uprzedniego polaczenia programu z danym zbiorem danych.

 DATA i READ - umieszczanie danych w programie

 Jedna z metod wprowadzenia danych do programu jest umieszczenie ich w tym programie na stale.
Dane umieszcza sie w wierszach rozpoczynajacych sie slowem kluczowym DATA.
Dane te przypisywane sa do zmiennych instrukcja READ.

Przykladem takiego rozwiazania jest fragment programu

  REM  DATA...READ
  CLS
  DATA 12, 23, 45, 74, 86, 345, 11
  READ a1, a2, a3, a4, a5, a6, a7


ktorego wykonanie spowoduje przypisanie liczb 12, 23,..11 do  zmiennych a1, a2, ...a7.
Dane z instrukcji DATA moga byc czytane tylko raz.
Dane te mozna jednak odtworzyc instrukcja RESTORE.
Instrukcja DATA moze znajdowac sie w dowolnym miejscu programu, na przyklad na koncu.

DATA specifies values to be read by subsequent READ statements.
READ reads those values and assigns them to variables.
RESTORE allows READ to reread values in specified DATA statements.

DATA constant[,constant]...
READ variablelist
RESTORE [line]

    ţ constant        One or more numeric or string constants specifying
                      the data to be read. String constants containing
                      commas, colons, or leading or trailing spaces are
                      enclosed in quotation marks (" ").
    ţ variablelist    One or more variables, separated by commas, that are
                      assigned data values. Variable names can consist of up
                      to 40 characters and must begin with a letter. Valid
                      characters are A-Z, 0-9, and period (.).
    ţ line            The label or line number of a DATA statement. If line
                      is omitted, the next READ statement reads values in
                      the first DATA statement in the program.

    ţ DATA statements can be entered only at the module level. They cannot
      be used in procedures.

Example:
    FOR i% = 1 TO 3
        READ a%, b$
        PRINT a%, b$
        RESTORE
    NEXT i%
    DATA 1, "Repeat"


 Ten sposob wprowadzania danych ma te zalete, ze raz wpisane dane staja sie integralna czescia programu i nie wymagaja wpisywania za pomoca klawiatury przy kazdorazowym jego uruchomieniu. Wada tej metody jest to, ze zmiana danych wymaga przeredagowania programu.
 Metode takiego zapamietywania danych razem z programem, stosujemy w takich przypadkach, gdy dane do programu nie wymagaja zmian, sa zawsze takie same.
Przykladem moze byc program pelniacy role slownika jezyka obcego.

 Wyprowadzanie wynikow

 Dwie podstawowe metody wyprowadzania wynikow dzialania programu to wyswietlenie ich na ekranie monitora lub wydrukowanie na drukarce.
Trzeci sposob to zapisanie wynikow do zbioru na dysku, celem pozniejszego zapoznania sie z nimi - wyswietlenia na ekranie i ewentualnego wydrukowania.
 Zapisywanie wynikow na dysku jest w wielu przypadkach etapem posrednim realizacji duzego zadania za pomoca programow komputerowych.
Jeden program wykonuje jakis etap obliczen, zapisuje wyniki do zbioru na dysku, a inny program wczytuje zawartosc tego zbioru, ktora stanowi dla niego dane
wejsciowe.

 Podstawowa instrukcja wyswietlania wynikow ma postac

  PRINT [<lista  LPRINT [<lista 

np. 
PRINT wyn1, wyn2, wyn3
w ktorej wyn1, wyn2, wyn3 to nazwy zmiennych, w ktorych zapamietane zostaly wyniki dzialania programu.

 Wydrukowanie wymaga instrukcji

  LPRINT wyn1, wyn2, wyn3
i drukarki podlaczonej do komputera, wlaczonej do sieci i odpowiednio przygotowanej - ON LINE.

PRINT writes data to the screen or to a file.
LPRINT prints data on the printer LPT1.

PRINT [#filenumber%,] [expressionlist] [{; | ,}]
LPRINT [expressionlist] [{; | ,}]

    ţ filenumber%       The number of an open file. If you don't specify a
                        file number, PRINT writes to the screen.
    ţ expressionlist    A list of one or more numeric or string expressions
                        to print.
    ţ {; | ,}           Determines where the next output begins:
                          ; means print immediately after the last value.
                          , means print at the start of the next print zone.
                            PRINT zones; are; 14; Characters; wide.

Example:
    OPEN "TEST.DAT" FOR OUTPUT AS #1
    PRINT #1, USING "##.###  "; 12.12345
    CLOSE
    OPEN "TEST.DAT" FOR INPUT AS #1
    INPUT #1, a$
    PRINT a$
    LPRINT "This is a line"; 1
    LPRINT "This is a line",
    LPRINT 2


 Uzycie przecinka powoduje wydruk na poczatku nastepnej strefy (strefa ma 14 znakow); uzycie srednika wydruk bezposrednio po ostatnim elemencie.

Zamiast PRINT mozna napisac znak pytajnika (?).

 PRINT USING <wyrazenie wyswietla lancuchy lub liczby z uzyciem okreslonego formatu

Formaty lancuchowe:
 "!" - tylko pierwszy znak lancucha bedzie wyswietlany
 print using
 "\ n spacji\"  wyswietlonych bedzie n+2 znakow lancucha. Jesli n+2
 bedzie wieksze od dlugosci lancucha to z prawej strony dodawane beda
 spacje
 "&"  wyswietlony bedzie caly lancuch
Formaty liczb:
 #  reprezentuje kazda wyswietlana cyfre w tekscie

PRINT [#filenumber%,] USING formatstring$; expressionlist [{; | ,}]
LPRINT USING formatstring$; expressionlist [{; | ,}]

    ţ filenumber%       The number of an open sequential file.
    ţ formatstring$;    A string expression containing one or more
                        #format specifiers#.
    ţ expressionlist    A list of one or more numeric or string expressions
                        to print, separated by commas, semicolons, spaces,
                        or tabs.
    ţ {; | ,}           Determines where the next output begins:
                          ; means print immediately after the last value.
                          , means print at the start of the next print zone.
                            PRINT zones; are; 14; Characters; wide.
Example:
    a = 123.4567
    PRINT USING "###.##"; a
    LPRINT USING "+###.####"; a
    a$ = "ABCDEFG"
    PRINT USING "!"; a$
    LPRINT USING "\ \"; a$


                     Characters that format a numeric expression
 #    Digit position.                    ş -     Placed after digit, prints
 .    Decimal point position.            ş       trailing sign for negative
 ,    Placed left of the decimal point,  ş       numbers.
      prints a comma every third digit.  ş $$    Prints leading $.
 +    Position of number sign.           ş **    Fills leading spaces with *.
^^^^  Prints in exponential format.      ş **$   Combines ** and $$.

                     Characters used to format a string expression
 &    Prints entire string.              ş \ \   Prints first n characters,
 !    Prints only the first character    ş       where n is the number of
      of the string.                     ş       blanks between slashes + 2.

                     Characters used to print literal characters
       character as a literal.            ş       table is printed as a
                                         ş       literal.

 Zrozumienie znaczenia poszczegolnych elementow instrukcji PRINT i formatow wynikow wymaga wiele czasu i praktyki - najlepiej analizowac i zmieniac gotowe przyklady
- np. QBPR1.BAS i QBPR2.BAS

REM  QBPR1.BAS ' Nazwa programu
REM Wczytywanie liczb, znaków, sumy, wydruk – komentarz odnossnie funkci programu
CLS ' Kasowanie ekranu
DEFDBL A-L ' Deklaracja zmiennych A-L jako Long
DEFSTR P-Z ' Deklaracja zmiennych A-L jako String
INPUT "Wpisz dowolna liczbe "; lb1 ' Wprowadzenie liczby
INPUT "wpisz inna liczbe "; lb2
INPUT "Wpisz znaki "; znak1 ' Wprowadzenie znaku
INPUT "wpisz znaki "; znak2
lb3 = lb1 + lb2
znak3 = znak1 + znak2
PRINT lb1, lb2, lb3 ' Wydruk na ekranie
PRINT znak1, znak2, znak3
PRINT lb1; lb2; lb3
PRINT znak1; znak2; znak3
PRINT "lb1="; lb1, "lb2="; lb2, "lb3=lb1+lb2="; lb3
END ' Koniec programu


REM QBRPR2.BAS
REM Wydruk liczb z uzyciem formatowania
CLS
DEFDBL A-L
a = 100
b = 3
c = a / b
PRINT c, c, c
PRINT
PRINT c; c; c
PRINT
PRINT USING "###.###"; c; c; c
PRINT
PRINT USING "+###.####"; c; c; c
PRINT USING "+#######.####"; c; c; c
PRINT USING "+######.####"; c; c; c
PRINT USING "+#########.####"; c; c;

 Zmienne tablicowe

 Jezyki programowania oferuja proste i wygodne rozwiazanie umozliwiajace operowanie duza iloscia danych tego samego typu.
Oparte jest ono na wprowadzeniu zmiennych tablicowych.

 DIM <lista definiuje max. wartosci indeksow tablic i rezerwuje na nie odpowiednia  ilosc pamieci

 np. 
DIM A(20),  DIM cena(20,30),  DIM cena(1 TO 1000)


 Ostatnia deklaracja oznacza zarezerwowanie miejsca na 1000 liczb rzeczywistych pojedynczej dokladnosci (SINGLE PRECISION),
o wspolnej nazwie cena, a umieszczone w niej stale maja miec numery od 1 do 1000. 
Jest to tablica jednowymiarowa i posiada 1000 elementow.

 Odwolanie sie do jakiegos elementu tablicy wymaga podania jej nazwy i numeru elementu (wskaznika).
 Np. suma = cena(25) + cena(890)

 Numeracja elementow tablicy w deklaracji nie musi zaczynac sie od 1, lecz od innej liczby, np.
   DIM wyniki(101 TO 200)

Zadeklarowania zmiennej tablicowej mozna dokonac podajac tylko jedna liczba wymiaru, co oznacza, ze numeracja zaczyna sie od 0, np.
   DIM wzrost(50)

 BASIC pozwala tez na poslugiwania sie tablicami wielowymiarowymi, np.

 DIM rezultaty(1 TO 30, 1 TO 9) AS INTEGER
rezerwuje w pamieci komputera miejsce na 30x9=270 liczb typu integer.

Dowolny element tablicy 2-wymiarowej identyfikowany jest 2-ma wskaznikami,
Np. rezultaty(10, 7)

 Tablice moga miec wiecej wymiarow, np.

  DIM polozenie%(1 TO 10, 1 TO 20, 1 TO 30)

 QBasic pozwala deklarowac tablice o 60 wymiarach, ale w praktyce rzadko stosuje sie tablice wieksze niz 3-4-wymiarowe.
Najmniejsza tablica moze zajmowac 1 bajt, najwieksza 64KB.

Z danych tych mozna wyliczyc, ze tablica typu SINGLE PRECISION moze miec najwyzej 16384 elementy (64x1024/4).
Deklaracja DIM kub(30,30,30) usiluje stworzyc tablice o 29791 elementach (31x31x31), a to jest ok. 13000 elementow wiecej niz pozwala na to jezyk QBasic.

 Opis DIM z Helpu:

DIM declares an array or specifies a data type for a nonarray variable.
REDIM declares or resizes a dynamic array, erasing any previous values.

DIM [SHARED] variable[(subscripts)] [AS type]
             [,variable[(subscripts)] [AS type]]...
REDIM [SHARED] variable(subscripts) [AS type]
               [,variable(subscripts) [AS type]]...

    ţ SHARED        Specifies that variables are shared with all SUB or
                    FUNCTION procedures in the module.
    ţ variable      The name of an array or variable.
    ţ subscripts    Dimensions of the array, expressed as follows:

                    [lower TO] upper [,[lower TO] upper]...

                    lower    The lower bound of the array's subscripts. The
                             default lower bound is zero.
                    upper    The upper bound.

    ţ AS type       Declares the data type of the array or variable
                    (INTEGER, LONG, SINGLE, DOUBLE, STRING, or a
                    user-defined data type).

    ţ DIM declares either static or dynamic arrays. Unless array storage has
      been determined by $STATIC, $DYNAMIC, or COMMON, arrays dimensioned
      with numbers are static and arrays dimensioned with variables are
      dynamic. REDIM always declares dynamic arrays.
    ţ Static array storage is allocated when you start a program and
      remains fixed. Dynamic array storage is allocated while a program runs.

Example:
    ' $DYNAMIC
    DIM a(49, 49)
    REDIM a(19, 14)



 Pętla

 Pętla (loop) to fragment programu, ktory jest wykonywany wielokrotnie.
 
Ogolna postac petli:

 ROZPOCZECIE petli
  instrukcja 1
  ............
  instrukcja n
 KONIEC petli


 FOR ... NEXT

 Powtarza blok instrukcji podana ilosc razy.

 FOR <licznik> = <start TO <koniec>  [step]
  lista_instrukcji
NEXT <licznik>

Przyklad:
  CLS
  FOR k = 1 TO 20 STEP 1
    PRINT k
  NEXT k
  PRINT "Koniec petli"

FOR jest slowem kluczowym rozpoczynajacym petle.
Zmienna <licznik> - tutaj k nazywa sie zmienna sterujaca lub wskaznikiem petli.
Pierwsza jedynka w tym wierszu to dolna granica petli. 
TO (do) to slowo kluczowe.
Liczba 20 jest gorna granica petli. STEP (krok) to slowo kluczowe.
Ostatnia liczba 1 po slowie kluczowym okresla wielkosc kroku petli.
Liczba 1 jest wartoscia domyslna i mozna w tym przypadku fragment  STEP 1  pominac.
Pierwszy wiersz (rozpoczecie petli) jest rozumiany przez komputer tak:
dla k zmieniajacego sie od 1 do 20 z krokiem (przyrostem) 1 wykonuj instrukcje zawarte w petli.
W tym przypadku jedyna instrukcja w petli jest
PRINT k.
Zakonczenie petli - NEXT k - jest dla komputera poleceniem - wez nastepna wartosc k.

 Inne przyklady instrukcji rozpoczynajacych petle:

  FOR k = 1 TO 20 STEP 3
 FOR k = -10 TO 10
 FOR k = 0 TO -20 STEP -1

Opis z Helpu:

Repeats a block of statements a specified number of times.

FOR counter = start TO end [STEP increment]
    [statementblock]
NEXT [counter [,counter]...]

     counter          A numeric variable used as the loop counter.
     start and end    The initial and final values of the counter.
     increment        The amount the counter is changed each time through
                       the loop.


Example:
    FOR i% = 1 TO 15
        PRINT i%
    NEXT i%
    FOR i% = 7 TO -6 STEP -3
        PRINT i%
    NEXT i%



 DO WHILE ... LOOP


 DO WHILE warunek
   instrukcja_1  
    ............
   instrukcja _n
LOOP

  Np.
  DO WHILE k <= 20
   k = k + 1
   PRINT k
  LOOP

Wyniki:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


 DO WHILE jest dla komputera poleceniem - wykonuj petle (blok miedzy DO WHILE i LOOP) , dopoki warunek jest prawdziwy.

 Inny wariant
DO ... LOP WHILE

  DO
    instrukcje
    .........

  LOOP WHILE warunek

W tym przypadku warunek powtarzania bloku zapisany jest w wierszu konczacym petle.
 Przyklad
  DO
   k = k + 1
   PRINT k
  LOOP WHILE k <= 20


Wyniki:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21



Roznice miedzy do.. loop while oraz do until .. loop

 DO
  k = k + 1
  PRINT k
 LOOP UNTIL k = 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20



 Help z QBasic:
Repeats a block of statements while a condition is true or until a condition
becomes true.

DO [{WHILE | UNTIL} condition]
    [statementblock]
LOOP

DO
    [statementblock]
LOOP [{WHILE | UNTIL} condition]

    ţ condition    A numeric expression that Basic evaluates as true
                   (nonzero) or false (zero).

Example:
    i% = 0
    PRINT "Value of i% at beginning of loop is  "; i%
    DO WHILE i% < 10
        i% = i% + 1
    LOOP
    PRINT "Value of i% at end of loop is  "; i%
 
LOOP



 DO UNTIL ... LOOP


  DO UNTIL warunek
    instrukcja _1
     ............
   instrukcja_n 
  LOOP

 DO UNTIL warunek jest poleceniem dla komputera - wykonuj tak dlugo az zostanie spelniony postawiony warunek.

Chcac wydrukowac liczby od 1 do 20 musimy wpisac do komputera program"
 DO UNTIL k = 20
  k = k + 1
  PRINT k
 LOOP

Wyniki:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20




 Warunek wykonywania petli moze byc przeniesiony do ostatniego wiersza.
DO ... LOOP UNTIL

 DO

  k = k + 1
  PRINT k
 LOOP UNTIL k = 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20



 Petla w petli


 Jezyki programowania pozwalaja na umieszczanie kolejnych petli, jedna w drugiej.

 Przyklad:
 CLS
 FOR i = 1 TO 4
   FOR k = 1 TO 5
    PRINT i, k
   NEXT k
 NEXT i

Wyniki:
1             1
1             2
1             3
1             4
1             5
2             1
2             2
2             3
2             4
2             5
3             1
3             2
3             3
3             4
3             5
4             1
4             2
4             3
4             4
4             5




 Program moze zawierac wiele petli wzajemnie sie obejmujacych (zagniezdzonych).
Kazda petla wewnetrzna musi się zawierac calkowicie w obrebie  petli zewnetrznej.

 Np.
  FOR K=...
   instrukcja1
    FOR i=..
     instrukcja2
      FOR j=..
       instrukcja3
      NEXT j
      instrukcja4
    NEXT i
   instrukcja5
  NEXT k


 Przyklady programow z petla

 Zadanie 1 - obliczenie sumy kolejnych liczb calkowitych od n1 do n2, czyli znalezienie wartosci wyrazenia:

 n1+(n1+1)+(n1+2)+...(n2-1)+n2 -  - program ABCQ3.BAS

REM abcq3.bas
REM Program liczy sume liczb od podanej wartosci N1 do podanej N2
CLS
PRINT "Program liczy sume liczb od N1 do N2"
PRINT
INPUT "Podaj n1, n2 "; n1, n2
sum = 0
FOR k = n1 TO n2
sum = sum + k
NEXT k
PRINT
PRINT "Suma liczb od "; n1; " do "; n2; " = "; sum
END


Program liczy sume liczb od N1 do N2

Podaj n1, n2
1, 10

Suma liczb od 1 do 10 = 55


 Zadanie2 - obliczenie n!
 n!=1*2*3*4*...(n-1)*n  -  - program ABCQ4.BAS

REM ABCQ4.BAS
CLS
PRINT "Program liczy n! (n silnia) dla n < 35"
PRINT
PRINT "  N! = 1*2*3*4...*n "
PRINT
INPUT "Podaj n "; n
silnia = 1
FOR k = 1 TO n
silnia = silnia * k
NEXT k
PRINT
PRINT n; "!="; silnia
END


Wyniki:
Program liczy n! (n silnia) dla n < 35

  N! = 1*2*3*4...*n

Podaj n 10

10!=3628800


 Instrukcje warunkowe IF

 Najprostsza forma instrukcji warunkowej jest
  IF warunek THEN instrukcja
 w ktorej warunek jest wyrazeniem logicznym

 Przyklad
  CLS
  INPUT "Podaj liczby a,b "; a, b
  IF a<b THEN PRINR a;"<";b
  IF a>b THEN PRINR a;">";b
  IF a+b THEN PRINR a;"=";b
  PRINT "Koniec testu"

 Wynikiem relacji prawdziwej jest -1, a falszywej 0.
 Widac to po uruchomieniu programu ABCQ5.BAS

 IF warunek THEN blok 
 Ten wariant umozliwia wykonanie calego bloku instrukcji w przypadku gdy warunek jest prawdziwy.

' Przyklad ABCQ6.BAS
REM ABCQ6.BAS
REM Porownywanie 2 liczb, wynik odejmowania dodatni lub 0
CLS
INPUT "Podaj 2 liczby "; a, b
IF a > b THEN
  wynik = a - b
  PRINT "a-b="; wynik
END IF
IF a < b THEN
  wynik = b - a
  PRINT "b-a="; wynik
  END IF
IF a = b THEN
  wynik = a - b
  PRINT "a-b=b-a="; wynik
END IF


 IF warunek THEN ... ELSE END IF

 Przyklad
 CLS
 INPUT "Podaj liczbe z przedzialu 1 do 20 "; liczba
 IF liczba >= 1 AND liczba <= 20 THEN
   PRINT "Prawidlowo"
 ELSE
   PRINT "Liczba spoza przedzialu"
 END IF
 PRINT "Koniec programu"


 Inne przyklady:

REM ABCQ7.BAS
REM Porownywanie liter
CLS
INPUT "Wpisz litere "; lit1$
INPUT "Wpisz litere "; lit2$
  IF lit1$ < lit2$ THEN
    PRINT lit1$, lit2$
  ELSE
    PRINT lit2$, lit1$
  END IF


' ABCQ8.BAS
REM ABCQ8.bas
REM Wprowadzone liczby maja byc z zakresu (0,1)
CLS
INPUT "Podaj 2 dodatnie liczby < 1 "; a, b
  IF a < 1 AND b < 1 AND a > 0 AND b > 0 THEN
    PRINT "Dobrze"
  ELSE
    PRINT "Zle"
  END IF


 IF warunek THEN EXIT - opuszczenie petli

 Czasem zachodzi koniecznosc opuszczenia petli przed jej zakonczeniem.

Mozna to zrealizowac instrukcja:
 IF warunek THEN EXIT {FOR | DO | LOOP}
ktora powoduje przejscie wykonywania programu do pierwszej instrukcji znajdujacej sie poza petla.

' Przyklad ABCQ8A.BAS
REM ABCQ8a.BAS
REM Petla DOO..LOOP
CLS
k = 0
INPUT "Ile przebiegow petli "; n
DO
  k = k + 1
  IF k = n THEN EXIT DO
LOOP
PRINT "Wykonano "; k, "przebiegow petli LOOP"

 lub

 INPUT "Ile petli "; n
 FOR m = 1 TO 10000
  IF m = n THEN EXIT FOR
 NEXT m
 PRINT "Wykonano "; m, "przebiegow petli FOR"

 Help z QBasic:
Executes a statement or statement block depending on specified conditions.

IF condition1 THEN
    [statementblock-1]
[ELSEIF condition2 THEN
    [statementblock-2]]...
[ELSE
    [statementblock-n]]
END IF


IF condition THEN statements [ELSE statements]

     condition1          Any expression that can be evaluated as
      condition2          true (nonzero) or false (zero).
     statementblock-1    One or more statements on one or more lines.
      statementblock-2
      statementblock-n
     statements          One or more statements, separated by colons.

Example:
    INPUT "1 or 2? ", i%
    IF i% = 1 OR i% = 2 THEN
        PRINT "OK"
    ELSE
        PRINT "Out of range"
    END IF



 Przyklady programow


' ABCQ11.BAS - znajdowanie maksymalnej i minimalnej

REM abcq11.bas
REM znajdowanie najwiekszej i najmniejszej liczby
 CLS
DIM liczba(50)
 INPUT "Ile liczb "; n
FOR i = 1 TO n
 PRINT "liczba nr "; i;
 INPUT liczba(i)
NEXT i
REM znajdowanie liczby najwiekszej
max = liczba(1) '1

FOR i = 1 TO n
 IF liczba(i) > max THEN max = liczba(i) '2
NEXT i

REM znajdowanie liczby najmniejszej '3
min = liczba(1)
FOR i = 1 TO n
IF liczba(i) < min THEN min = liczba(i) '4
NEXT i

REM wydruk liczby max i minim.
PRINT PRINT "Liczba najwieksza = "; max, "Liczba najmniejsza="; min

END



'ABCQ9.BAS  - porzadkowanie liczb
REM ABCQ9.BAS
REM Program wczytuje n liczb i porzadkuje
REM je od najwiekszej do najmniejszej

CLS
DIM liczba(50)

INPUT "Ile liczb "; n

FOR i = 1 TO n
PRINT "Liczba nr "; i
INPUT liczba(i)
NEXT i

REM porzadkowanie liczb
FOR i = 1 TO n - 1
  FOR j = i + 1 TO n
   IF liczba(i) < liczba(j) THEN SWAP liczba(i), liczba(j)
  NEXT j
NEXT i

REM Wydruk uporzadkowanych liczb
PRINT PRINT "Liczby w porzadku malejacym "
PRINT FOR i = 1 TO n
 PRINT , liczba(i)
NEXT i

END



'ABCQ10.BAS - porzadkowanie nazwisk wedlug alfabetu
REM ABCQ10.BAS
REM Program wczytuje n liczb i porzadkuje
REM je od najwiekszej do najmniejszej
CLS
DIM nazw(50) AS STRING

REM wprowadzenie nazwisk
INPUT "Ile nazwisk "; n
FOR i = 1 TO n
 PRINT "Nazwisko nr "; i
 INPUT nazw(i)
NEXT i

REM porzadkowanie nazwisk
FOR i = 1 TO n - 1
    FOR j = i + 1 TO n
      IF nazw(i) > nazw(j) THEN SWAP nazw(i), nazw(j) ' zamiana
    NEXT j
NEXT i

REM Wydruk uporzadkowanych nazwisk
PRINT
PRINT "Nazwiska w kolejnosci alfabetycznej "
PRINT

FOR i = 1 TO n
 PRINT , nazw(i)
NEXT i

END



 GOTO Etykieta

 Jest poleceniem skoku do wiersza programu rozpoczynajacego sie etykieta (ang. label) identyczna z rozpoczynajaca sie po slowie kluczowym GOTO.
Etykieta moze byc dowolna kombinacja znakow rozpoczynajacych sie litera, moze tez byc liczba.
Bardzo praktycznym rozwiazaniem jest uzywanie etykiet sugerujacych funkcje fragmentu programu, do ktorego ma nastapic skok.
Prawidlowe nazwy etykiet to np. obraz, wynik23, druk, 10, 200.
 Przyklad
  CLS
  REM GOTO
  INPUT "1/drukuj, 2/test lub 3/koniec ";k
    IF k = 1 GOTO drukuj
    IK k = 2 goto 200
    IF k = 3 GOTO koniec
   drujuj:
    PRINT "wybrales ";K
     END
   200 print "Jestem w wierszu 200"
     END
   koniec:
     PRINT "Koniec"

 Etykieta, rozpoczynajaca fragment programu, do ktorego bastepuje przeskok, musi spelniac warunki:

Etykieta moze znajdowac sie w wierszu z instrukcja, ale moze poprzedac te instrukcje, tworzac osobny wiersz.
 Przyklady etykiet:
  200
  PRINT a, b, c

  200 PRINT a,b,c

  drukuj:
  PRINT a,b,c

  drukuj: PRINT a, b, c

 UWAGA!  Numery wierszy umieszczane w programie napisanym w jezyku QBasic nie decyduja o kolejnosci ich ulozenia w pamieci,
         a tym samym o kolejnosci ich wykonywania, jak to ma miejsce          w prostszych wersjach jezyka BASIC.

 W przypadku instrukcji IF zawierajacej GOTO nie musimy uzywac slowa kluczowego THEN.
 IF a<=0.001 THEN a=0.001   'konieczne jest THEN
 IF b^2>16 GOTO licz       'THEN moze, ale nie musi byc uzyte
 IF b^2>16 THEN GOTO licz  ' -"-

 Zasada- nie uzywac instrukcji GOTO, jezeli potrafimy zastapic ja innym rozwiazaniem.
Program z duza iloscia skokow staje sie skomplikowany i nieczytelny!.
Ponadto wszelkie modyfikacje takiego programu sa bardzo  utrudnione i prowadza do bledow.
Zmiana etykiety w GOTO wymaga bowiem takiej samej zmiany w programie, w miejscu oznaczonym ta etykieta.
 Mozna wykorzystac instrukcje GOTO etykieta do wykonania skoku bezwarunkowego, jak w ponizszym przykladzie.

 10 INPUT "Podaj rok urodzenia "; rok
    wiek = 1994 - rok
    PRINT "Masz juz ";wiek, "lat"
    GOTO 10

 Program ten, raz uruchomiony, bedzie wykonywany "w nieskonczonosc", az do nacisniecia Ctrl+Pause (Ctrl+Break).



Funkcje operujące na znakach

CHR$ i ASC

Są to funkcje pozwalające na zamianę kodów ASII - CHR$ na odpowiadajace im znaki oraz na znajdowanie kodów ASCII podanych znaków - ASC.

CHR$(Numer_kodu)

 Zwraca literę (łańcuch jednoznakowy) odpowiadajacą danemu numerowi kodu ASCII.
Argumentem funkcji moze być dowolny kod ASCII, liczba od 0 do 255. Wynikiem jest znak odpowiadajacy kodowi (liczbie).

Description:
This function returns a one-character-long string, consisting of the character represented on the ASCII table by the value n (0 - 255).

Przykład 1;

[start] ' lub start: - zależnie od wersji
input "kod "; i
print chr$(i)
goto [start]    ' lub goto start

Przykład 2;

 print chr$(77)
 print chr$(34)
 print chr$(155)

Wynik:
M
"


ASC(wyrazenie_lancuchowe)
Zwraca nr kodu ASCII pierwszej litery w wyrazeniu łańcuchowym

Przykład 1:
start:    ' lub [start] 
iNPUT "znak"; zn$
PRINT ASC(zn4)
GOTO start


Przyklad 2
' Wydruk wszystkich znaków ASCII
CLS
PRINT "Kody ASCII i znaki "
FOR i = 0 TO 255
 PRINT "kod: ", i, "  znak ", CHR$(i)
NEXT i


Description:
This function returns the ASCII value of the first character of string s$.  s$ can be a string variable, or text enclosed in quotes.
Text and formatting characters have ASCII values from 0 to 255.  See also CHR$( n )

Usage:

'Example 1:
  print asc( "A" )              produces:  65
  let name$ = "Tim"
  firstLetter = asc(name$)
  print firstLetter             produces:  84
  print asc( "" )               produces:  0


'Example 2:
    ' This program ask for a string and then
    ' displays a list of ASCII codes for each
    ' character in the entered string
    input "Please enter a string >"; entry$
    for index = 1 to len(entry$)
        result$ = result$ + str$(asc(mid$(entry$,index,1))) + chr$(13)
    next index
    print result$

Wynik:
Please enter a string >Nowak
78
111
119
97
107


Funkcje LEFT$, RIGHT$, MID$, LEN

Są to funkcje umożliwiające działania na zmiennych znakowych czyli stałych znakowych przypisanych do nich.

LEFT$(wyrazenie_lancuchowe, n)
Zwraca n pierwszych znaków wyrażenia łańcuchowego
Przykład:
a$=:KOT TO NIE PIES"
B$="NIE"
C$="PIES"
PRINT LEFT4(A4, 6) + B$ + C$

Wynik: "KOT TO NIE PIES"

RIFHT$(wyrazenie_lancuchowe, n)
Zwraca n ostatnich znaków wyrażenia łańcuchowego
np.
a$="dzien dobry"
print right$(as$, 5)

Na ekranie będzie dobry

MID$(wyrazenie_lancuchowe, start, [dlugosc])
Funkcja zwraca łańcuch wycięty z wnętrza łańcucha
np.
print mid$("Ala ma kota", 1, 3)
Wynik: Ala
lub
MID$(wyrazenie_lancuchowe, start, [dlugosc]) = wyrazenie_lancuchowe
Instrukcja zastepuje całosć lub część zmiennej łańcuchowej wyrazeniem łańcuchowym (zmiana zmiennej)
np.
A$="TO TAK ŁATWO"
MID$(a$, 4, 3) = "NIE"
PRINT A$

Wynik: TO NIE ŁATWO

MID$(string, index, [number])

Description:
This function permits the extraction of a sequence of characters from the string, string variable, or string expression string starting at index.  [number] is optional.  If number is not specified, then all the characters from index to the end of the string are returned.  If number is specified, then only as many characters as number specifies will be returned, starting from index.

Usage:
 print mid$("greeting Earth creature", 10, 5)
Produces:   Earth

And:

  string$ = "The quick brown fox jumped over the lazy dog"
  for i = 1 to len(string$) step 5
    print mid$(string$, i, 5)
  next i


Produces:

  The_q
  uick_
  brown
  _fox_
  jumpe_
  d_ove
  r_the
  _lazy
  _dog


LEN(wyrazenie_lancuchowe)
Zwraca ilość znaków w wyrazeniu łańcuchowym,
np.
a$="Warszawa"
print len(a$)

Na ekranie pojawi się liczba 8

LEN(zmienna)

np.
Zwraca ilość bajtów zajmowanych przez zmienną
DIM a AS LONG
PRINT LEN(a)

W Just Basic
LEN( string )
LEN( structName.struct )
Description:
This function returns the length in characters of string, which can be any valid string expression. It also returns the size of a struct.

Usage:
' przykład w Just Basic
  prompt "What is your name?"; yourName$
  print "Your name is "; len(yourName$); " letters long"

'  struct person, name$ as ptr, age as long
' print len(person.struct)


Przykład 1:

clsDIM a AS LONG
PRINT LEN(a)

slowo$="abcdefghijklmn"
n=len(slowo$)

for i=1 to n
 print left$(slowo$,i)
next i

print
for i=1 to n
 print right$(slowo$,i)
next i

Wynik:
a
ab
abc
abcd
abcde
abcdef
abcdefg
abcdefgh
abcdefghi
abcdefghij
abcdefghijk
abcdefghijkl
abcdefghijklm
abcdefghijklmn

n
mn
lmn
klmn
jklmn
ijklmn
hijklmn
ghijklmn
fghijklmn
efghijklmn
defghijklmn
cdefghijklmn
bcdefghijklmn
abcdefghijklmn

Przykład 2:
Wykorzystanie funkcji LEN
CLS
INPUT "WPISZ ZDANIE "; zd$
PRINT
PRINT 'zdanie zawiera ", len(zd$); "znakow"
PRINT "Liczba calkowita zjmuje ", LEN(a%); " bajty"
PRINT "Liczba rzecz. zajmuje "; LEN(r); " bajtow"
PRINT "Liczba podwojnej prezycji zajmuje "; LEN(p#); " bajtow"

Funkcje STR$, VAL, LTRIM$

STR$(wyrazenie_liczbowe)
Zwraca wyrażenie liczbowe przekształcone w łańcuch znaków
Np.
x=43
x$=str$(x)
print x, x$
print 3*x
' print 3 * x$  - Błąd!


STR$(numericExpression)
Description: This function returns a string expressing the result of numericExpression. 
Usage:
age = 23
age$ = str$(age)
price = 2.99
price$ = str$(price)
totalApples = 37
print "Total number of apples is " + str$(totalApples)


VAL(wyrazenie_lancuchowe)
Zwraca wartość liczbową wyrażenia łańcuchowego, gdy  może ono byc interpretowane jako liczba
Np.
wart$ = "1245.01"
l = val(wart$)
print "Wartosc lancuchowa:  "; wart$, "Liczba = ";l
Wynik:

Wartosc lancuchowa:  1245.01              Liczba = 1245.01

VAL( s$ )
VAL(stringExpression)
Description:
This function returns a numeric value for stringExpression if stringExpression represents a valid numeric value or if it begins with a valid numeric value. 
If not, then zero is returned. 
(Jeśli wyrazenie łańcuchowe nie reprezentuje liczby lub nie zaczyna się od liczby to zwracana jest wartosc 0)
Usage:
 print 2 * val("3.14")         ' Produces:       6.28
 print val("hello")            ' Produces:       0
 print val("3 blind mice")    ' Produces:       3


LTRIM$(wyrazenie_lancuchowe)
Zwraca kopię wyrazenia łańcuchowego pozbawioną spacji wiodących
np.
A$ = "             ***TYTUL KSIAZKI**8'
B$=LTRIM(A$)

Wynik: łańcuch B$ będzie zaczynał sie od gwiazdki (*).


Przykład

    ' Dziala w QBasic
    CLS
    PRINT "Dziesiatkowa liczba 65 jest w postaci 16-wej reprezentowana jako: ";
    PRINT "&H" + LTRIM$(STR$(41))
    PRINT VAL(RIGHT$("Microsoft 1990", 4))


Funkcje INSTR, STRING$ i PACE$

INSTR([start],]wyrazenie_lancuchowe1, wyrazenie_lancuchowe2)
Poszukuje  łańcucha znaków wyrazenie_lancuchwe2 w łańcuchu wyrazenie_lancuchowe1  i zwraca numer kolejny znaku w wyrazenie_lancuchowe2, od którego rozpoczyna się znalezione w nim wyrazenie_lancuchowe1.
Parametry:
start - określa nr znaku, od którego ma się zaczać przeszukiwanie wyrażenia_łańcuchowego2 (gdy nie podano to od 1-go)
wyrazenie_lancuchowe1 - przeszukiwany łańcuch znaków
wyrazenie_lancuchowe2 - poszukiwany łańcuch znaków

Przykłady:

' 1
x$="ABCDEFUVXYZABCDEF"
y$="B"
na1 = INSTR(x$, y$)
na2 = INSTR(3, x$, y$)
PRINT na1, na2


' 2
zmienna$ = "ABCAABCABCD"
posz$="ABCD"
PRINT INSTR(zmienna$, posz$)

Wynik: 8

' 3
UZYTKOWNICY$="KOWALSKIMALINOWSKI"  ' Lista dopuszczalnych uzytkownikow: KOWALSKI, MALINOWSKI
INPUT "PODAJ SWOJE NAZWISKO ", NAZWISKO$
IF INSTR(UZYTKOWNICY$, NAZWISKO$) = 0 THEN     ' Jesli podane nazwisko nie jest
KOWALSKI lub MALINOWSKI
   PRINT "ODMOWIONO DOSTEPU"                   ' Drukuje ODMOWIONO DOSTEPU
END IF


' 3a
UZYTKOWNICY$="KOWALSKIMALINOWSKI"
INPUT "PODAJ SWOJE NAZWISKO "; NAZWISKO$
IF INSTR(UZYTKOWNICY$, NAZWISKO$) = 0 THEN
   PRINT "ODMOWIONO DOSTEPU"  

ELSE
 print "Mozna pracowac! OK"       
' Jesli podane nazwisko jest KOWALSKI lub MALINOWSKI
END IF

STRING$(m, {n | stringexpression$})
Składnia 1:
STRING$(m, n)
Zwraca łańcuch składający się z m powtórzeń znaku określonego w kodzie ASCII jako n
Np.
PRINT STRING$(5, 100)      ' drukuj 5 znaków o kodzie ASCII 100
Wynik: ddddd  ' 5 razy literka d jako znak ASCII znaku o kodzie 100

Składnia 2:
STRING$(m, wyrażenie_łańcuchowe)
Zwraca wyrażenie łańcuchowe, skłdajace się z m powtórzeń pierwszego znaku, wystepującego w wyrazeniu_łańcuchowym
Np.
PRINT STRING$(5, "Ala")
Wynik: AAAAA


QBasic (z Helpu)

STRING$(length%,{ascii-code% | stringexpression$})
Returns a string of a specified length made up of a repeating character.

    ţ length%              The length of the string.
    ţ ascii-code%          The ASCII code of the repeating character.
    ţ stringexpression$    Any string expression. STRING$ fills the string
                           with the first character in stringexpression$.

Example:
    PRINT STRING$(5, "-");  '  wyswietlenie: 5 x  -, czyli -----
    PRINT "Hello";                    ' wyswietlenie: Hello
    PRINT STRING$(5, "-")  ' '  wyswietlenie: 5 x  -, czyli -----


Wynik:
-----Hello-----


W JustBasic

INSTR(string1, string2, starting)


Description:

This function returns the position of string2 within string1.  If string2 occurs more than once in string1, then only the position of the leftmost occurance will be returned.  If the starting parameter is included, then the search for string2 will begin at the position specified by starting.

Usage:

  print instr("hello there", "lo")  '  produces:    4

  print instr("greetings and meetings", "eetin")  '   produces:    3

  print instr("greetings and meetings", "eetin", 5)  '   produces:    16

If string2 is not found in string1, or if string2 is not found after starting, then INSTR( ) will return 0.

  print instr("hello", "el", 3) '   produces:    0

and so does:
  print instr("hello", "bye")


SPACE$(n)
Zwraca ciąg złożony z n spacji (pustych miejsc)
Funkcja wymaga jednego parametru i generuje liczbę spacji, określoną parametrem n.

Przykłady:
'1
PRINT SPACE$(40); "x"  ' Znak x bedzie w 41 kolumnie, po 40 spacjach


' 2
for x = 1 to 10
        print space$(x); "*"
    next x

Wynik
*
  *
   *
    *
     *
      *
       *
        *
         *
          *

Przykład wykorzystujący powyższe funkcje (QBasic):

CLS
PRINT STRING$(80, "$")
FOR i = 1 TO 20 STEP 2
  PRINT STRING$(i, "*")
NEXT i
PRINT
FOR i = 0 TO 40 STEP 4
 PRINT SPACE$(i); STRING$(20, "&")
NEXT i

Pułapki - ON ERROR

Pułapka to instrukcja, która wyłapuje pewne zdarzenia w trakcie wykonywania programu, np. błędy, czy naciśnięcie okreslonego klawisza.

REM ABCQ12.BAS
REM Sprawdzanie rodzaju bledu: brak gotowosci drukarki, dzielenie przez zero, inny
CLS

ON ERROR GOTO label1
DEFINT A-D
INPUT "Podaj promien "; r
  obw = 2 * 3.14 * r
  pole = 3.14 * r ^ 2
  LPRINT "Promien="; r, " obwod = "; obw, "; pole = "; pole; ""
  w = pole / (r - r)
END

label1:
PRINT "Blad nr "; ERR
  SELECT CASE ERR
    CASE 25
     PRINT "Drukarka nie jest gotowa.  Wlacz ja i Enter"
     INPUT d$
    RESUME
  CASE 11
   PRINT "Dzielenie przez zero - Enter by zakonczyc"
   INPUT d$
  CASE ELSE
   PRINT "Nieznany blad - Enter by zakonczyc"
   INPUT d$
  END SELECT

W przypadku błędu nastąpi przeskok do etykiety label1, gdzie są przewidziane różne komunikaty w zależności od błędów.
Blok instrukcji
Select case err
 case 1
 case 2
...
end select
spełnia rolę podobną do bloku IF.
Funkcja ERR przyjmuje wwartość numeru błędu, który wystapił w programie i w zależności od tego nastąpi wykonanie odpowiedniego fragmentu bloku SELECT CASE.



PODPROGRAMY I FUNKCJE

Każdy prawidłowo zbudowany program powinien byc zbudowany z podprogramów. Kazdy podprogram powinien realizować jedno, możliwie krótkie zadanie.
Struktura programu z podprogramami  moze wyglądać następujaco;

PROGRAM GŁÓWNY

DEKLARACJE PODPROGRAMÓW
DEKLARACJE ZMIENNYCH
DEKLARACJE TABLIC

instrukcje
WYWOŁANIE PODPROGRAMU P1
instrukcje

WYWOŁANIE PODPROGRAMU P2
instrukcje

WYWOŁANIE PODPROGRAMU P2
instrukcje

WYWOŁANIE PODPROGRAMU P1
instrukcje

KONIEC PROGRAMU GŁÓWNEGO

PODPROGRAM P1
PODPROGRAM P2

W przykładzie program główny zawiera 2 podprogramy - P1 i P2. Kazdy z nich może być wywoływany z programu głównego dowolnie wiele razy.
Podprogramy mogą byc również wywoływane z innych podprogramów.
Instrukcji deklarowania programów nie może poprzedzać żadna instrukcja wykonywalna, np. pRINT, CLS, instrukcje przypisania itd.

Podprogram SUB

Instrukcja SUB

Składnia:
SUB nazwa_ogolna[(lista_parametrow)[STATIC]
...
[EXIT SUB]
END SUB

Opis
Instrukcja SUB służy do oznaczenia bloku podprogramu. Nazwa, parametry i treśc tworzą tzw. ciało procedury SUB.
nazwa_ogplna - dopuszczalna nazwa o dlugości do 40 znaków
lista_parametrów - lista parametrów przekazywanych do SUB
Parametry przekazywane są w poniższej formie (muszą być typu: INTERGER, LONG, DOUBLE, SINGLE, STRING lub własnej definicji)
zmianna[()] AS typ[, zmienna[()][AS typ]]


Wywołanie i powrót z podprogramu - CALL i END SUB

Wywołanie podprogramu - przejście do wykonywania instrukcji zawartych w podprogramie.
Instrukcje w wielu językach programowania mają postać:
 CALL  nazwa_podprogramu (parametry)
natomiast podprogram nazywany jest SUBROUTINE lub SUB
Powrót z podprogramu odbywa się po dojśiu do END SUB (w wielu językach używane jest słowo kluczowe RETURN).

Schemat reguł wykonywania podprogramu w większości języków programowania

MAIN PROGRAM

instr1m
CALL PDPR1(a,b)        ---------> SUBROUTINE PDPR1(x,y)
instr2m                            <------- powrót z    SUBROUTINE PDPR1
instr3m
instr4m
CALL PDPR1(r,s)
instr5m
instr6m
CALL PDPR2(z,w) ------------> SUBROUTINE PDPR2(p,r)
instr7m                    <------------ powrót z SUBROUTINE PDPR2
END

SUBROUTINE PDPR1(x,y)
instr1s1
CALL  PDPR2(c,d)     --> SUBROUTINE PDPR2(p,r)
instr2s1                        <--- powrót z  SUBROUTINE PDPR2
instr3s1
instr4s1
END SUB ------> instr2m

SUBROUTINE PDPR2(p,r)
instr1s2
instr2s2
END SUB         ---> instr2s1,  ---> instr7m

Kazdy podptogram moze byc wywoływany wielokrotnie.
Obowiązuja jednak pewne zasady. Jeśli podprogram PDPR2 został wywołany z podprogramu PDPR1, to nie moze on wywołac podprogramu PDPR1,  z którego został sam wywołany.

Przekazywanie wartości zmiennych między podprogramami

Podprogram musi byc wywołany z odpowiednimi argumentami.
np. instrukcja wywołania
CALL podpr1(a, b)
powoduje przejście do wykonywania podprogramu
SUB poppr1(x,y)
.Wartosci zmiennych a, b (argumenty) w chwili przejścia do instrukcji wywołania, sa przekazane do zmiennych x i y w poprogramie.
Zmiana wartosci x, y, w wyniku obliczeń wykonywanych w podprogramie, nie powoduje jednoczesnych zmian wartosci zmiennych a i b w programie wywołującym.
Dopiero powrót do programu wywołującego powoduje, ze zmienne a, b przyjmuja wartości, jakie w momencie opuszczania podprogramu miały w nim zmienne x i y.

Zmienne o tych samych nazwaach występujace w programie i podprogramach, jeśli nie są umieszczone jako argumenty w instrukcji wywołania, są zupełnie od siebie niezależne,
chyba, że umieścimy w podprogramie specjalne deklaracje  SHARED.

Reguły te mozna sprawdzić z przebiegu wykonania poniższego programu.

REM abcq13.bas
REM Podprogram drukuj – 2 wywolania
DECLARE SUB drukuj (x!)   ' ! oznacza single precision - real
CLS
a = 7
b = 15
CALL drukuj(a)
PRINT "Pierwszy powrot do Main"
CALL drukuj(b)
PRINT "Drugi powrot do Main"
PRINT "w programie MAIN a="; a, "b="; b, "x="; x
END

SUB drukuj (x)
PRINT "Jestem w podprogramie DRUKUJ ";
PRINT "x="; x, "a="; a, "b="; b
END SUB


Wydruk wyników wykonania programu:
Jestem w podprogramie DRUKUJ x=7          a=0           b=0
Pierwszy powrot do Main
Jestem w podprogramie DRUKUJ x=15         a=0           b=0
Drugi powrot do Main
w programie MAIN a=7        b=15          x=0

REM abcq13jb.bas  - wersja programu w Just Basic
REM Podprogram drukuj – 2 wywolania
' DECLARE SUB drukuj x   ' ! oznacza single precision - real
CLS
a = 7
b = 15
CALL drukuj a
PRINT "Pierwszy powrot do Main"
CALL drukuj b
PRINT "Drugi powrot do Main"
PRINT "w programie MAIN a="; a, "b="; b, "x="; x
END

SUB drukuj x
PRINT "Jestem w podprogramie DRUKUJ ";
PRINT "x="; x, "a="; a, "b="; b
END SUB

Deklaracja COMMON SHARED, SHARED

COMMON SHARED

Składnia;
COMMON [SHARED][/blok/] zmienna [({rozmiar])] [AS typ] [ , ...]
Opis: Definiuje zmienne globalne wspólne dla różnych modułów tego samego programu lub różnych programów powiązanych ze sobą.
Parametry:
SHARED - określa, że zmienne tego modułu będą dostępne w całym programie
blok - nazwa identyfikująca grupę zmiennych; maks. 40 znaków
zmienna - nazwy zmiennych
rozmiar - dowolna stała podająca liczbę wymiarów dla zmiennych tablicowych
AS typ - deklaruje zmienne jako typu: INTERGER, LONG, SINGLE, DOUBLE, STRING lub wg własnej definicji.

Przykład:

REM ABCQ14.BAS
REM 2 podprogramy: druk1 i druk2
DECLARE SUB druk1 ()
DECLARE SUB druk2 ()

COMMON SHARED ws

CLS

ws = 23

PRINT "W programie glownym ws="; ws
 CALL druk1   
' wywołanie podprogramu druk1 bez podawania argumentów
 CALL druk2   
' wywołanie podprogramu druk2 bez podawania argumentów
END

SUB druk1    
PRINT "w SUBroutine druk1 ws="; ws
END SUB

SUB druk2
PRINT "Tu takze (w subroutine druk2)  ws="; ws
END SUB


Wyniki

abcq14.bas - wyniki

Zmienna ws zadeklarowana w instrukcji COMMON SHARED jest zmienna wspólną dla wszystkich podprogramów (i programu głównego).
We wszystkich modułach programu ma ona wartość 23, przypisaną w programie głównym.
Deklaracja COMMON SHARED zmienna, umieszczona jest w programie głównym.
Wywolanie podprogramu odbywa się w ty przypadku bez podawania argumentów, jedynie przez podanie nazwy podprogramu.

Jest to wygodna metoda korzystania z wartości zadeklarowanych zmiennych we wszystkich podprogramach.
Niesie jednak niebezpieczeństwo przypadkowej, nie zamierzonej,  zmiany wartości zmiennych.
Zmiana wartosci zmiennej w którym kolwiek podprogramie powoduje zmianę jej wartości we wszystkich modułach.

Przykład:

REM abcq15.bas
REM Zmienne wspolne/wspoldzielone, podprogram (SUB) licz
DECLARE SUB licz ()
COMMON SHARED a, b, c, w
CLS
a = 1
b = 2
c = 3
PRINT "Przed wejsciem do procedury LICZ wartosci a, b, c oraz w (suma w licz): "
PRINT a, b, c, w
CALL licz
PRINT "Po wyjscu z proc LICZ wartosci a, b, c oraz w (suma przed zmiana w licz): "
PRINT a, b, c, w
PRINT "Poniewaz a, b, c byly zadeklarowane jako COMMON SHARED"
END

SUB licz
w = a + b + c
a = 10
b = 20
c = 30
END SUB


Wyniki:
ABCQ15-wyniki



Inną metodą udostępniania podprogramom wartości zmiennych, występujacych w programie głównym, jest deklaracja

SHARED
:

Składnia1
SHARED
zmienna1 [AS typ] [, zmienna2 AS typ ,[zmienna3]..]
Instrukcja ta może występowac jedynie w procedurach SUB i FUNCTION.
Instrukcja SHARED umożliwia korzystanie ze zmiennych będących w podprogramie z poziomu programu głównego, bez określania ich jako parametrów podprogramu
podczas wywoływania procedury.
Parametry:
zmienna - dowolna dopuszczalna przez Basic
typ - dowolny typ spośród wymienionych typów:
INTEGER, LONG, SINGLE, DOUBLE, STRING
lub wg. własnej definicji

Składnia 2
[RE] DIM | SHARED | zmienna [(indeksy)] [ AS typ], ...]
COMMON [SHARED] [/nazwa-bloku/] zmienna[()] AS typ [,...]
Opcja 2: Jako opcjonalny atrybut COMMON, DIM i REDIM umozliwia dostep innych modułów programowych do zmiennych zadeklarowanych w podprogramie.


Z helpu Qbasica'
SHARED gives procedures access to module-level variables.
STATIC makes a variable local to a function or procedure and preserves its value between calls.

SHARED variable[()] [AS type] [,variable[()] [AS type]]...
STATIC variable[()] [AS type] [,variable[()] [AS type]]...

     variable    The name of the module-level variable to share or variable
                  to make static. Variable names can consist of up to 40
                  characters and must begin with a letter. Valid characters
                  are A-Z, 0-9, and period (.).
     AS type     Declares the data type of the variable (INTEGER, LONG,
                  SINGLE, DOUBLE, STRING, or a user-defined type).

Example:
    The program REMLINE.BAS illustrates using the SHARED and STATIC  statements.
To view or run this program, load REMLINE.BAS using the Open  command from the File menu.

See Also    COMMON    DIM, REDIM

Przykłady wykorzystania deklaracji SHARED

REM abcq16.bas
REM zmienne shared i zwykle, 2 podprogramy
DECLARE SUB ekran ()
DECLARE SUB pisz ()

CLS
a = 12
b = 20
PRINT "MAIN (glowny) : a,b", a, b
CALL ekran
CALL pisz

SUB ekran
PRINT "ekran: a, b (zupelnie inne zmienne bo nie shared) "; a, b
END SUB

SUB pisz
SHARED a, b
PRINT "pisz: shared a, b", a, b
END SUB


Wyniki programu

Wyniki programu

Zmienne a i b maja w programie głównym wartosci 12 i 20.
W popdprogramie ekran, zmienne o tych samych nazwach są zupełnie innymi zmiennymi - na wydruku 0 i 0.
W popdprogramie pisz, w wyniku umieszczeina deklaracji SHARED a, b, zmienne te są tymi samymi zmiennymi co a i b w programie głównym.


FUNKCJE

Deklarowanie funkcji - DECLARE FUNCTION

QBasic umozliwia definiowanie funkcji, których rola jest podobna do podprogramów.
Funkcja jest oddzielnym modułem programu, w którym mogą byc wykonywane rózne operacje, a ich wynik przekazywany do programu głównego poprzez nazwę funkcji.

Składnia:
FUNCTION nazwa[(zmienna[()] [AS typ][, zmienna]()[AS typ]...)]
[STATIC]
...
nazwa = wyrazenie
END FUNCTION

Opis: Określa nazwę, parametry i wielkość zwracana przez procedurę
Parametry:
nazwa - nazwa procedury
FUNCTION zmienna - dowolna zmienna dopuszczona przez Basic
typ: INTEGER, LONG, SINGLE, DOUBLE, STRING lub zdefiniowany przez użytkownika
STATIC - przechowuje zmienne lokalne pośredniczące w wywołaniu FUNCTION
wyrażenie - wartość zwracana przez procedurę FUNCTION
END FUNCTION - oznacza koniec definicji procedury FUNCTION


Przykład: obliczenie sumy długośi przekątnych prostopadłoscianu o danych krwędziach, z wykorzystaniem funkcji.

REM p27.bas
REM Zastosowanie funkcji – FUNCTION nazwa (parametry)

DECLARE FUNCTION sumprz (a, b, c)

CLS
INPUT "Podaj 3 liczby "; a, b, c
PRINT "Suma dlug. przek prostop a,b,c= "; sumprz(a, b, c)

END

FUNCTION sumprz (a, b, c)
 p1 = SQR(a ^ 2 + b ^ 2)
 p2 = SQR(b ^ 2 + c ^ 2)
 p3 = SQR(a ^ 2 + c ^ 2)
 sumprz = 2 * (p1 + p2 + p3)
END FUNCTION



Deklaracja  funkcji musi poprzedzać instrukcje wykonywalne.
Musi zawierac 2 słowa kluczowe (DECLARE FUNCTION) oraz nazwę funkcji i ewentualnie argumenty formalne (powyżej a, b, c).
Nazwa funckcji musi byc zbudowana zgodnie z regułami tworzenia nazw zmiennych.
Występująca w przykladzie nazwa sumprz jest funkcją, której wynik działania musi być liczbą rzeczywistą (bo nazwa jest bez znaków specjalnych).
Jakaś inna funkcja, o nazwie oblicz%(a, b), musi dawać wynik w postaci liczby całkowitej.

Moduł programu będący funckcją musi zaczynać się słowem kluczowym FUNCTION, po którym umieszcza się nazwę identycną z nazwą użytą w deklaracji funkcji.
Dalej występują instrukcje wykonujące odpowiednie obliczenia lub inne operacje a jako przedostatnia musi byc instrukcja przypisania wyniku działania funkcji do jej nazwy.
Ostatnią instrukcją funkcji musi byc  END FUNCTION, która powoduje powrót do programu głównego i przekazanie wartości funkcji.

Chcąc w programie skorzystać z wartosci obliczonej przez zdefiniowaną funkcję, posługujemy sie nazwa funkcji.
Instrukcja
PRINT sumprz(a, b, c)
powoduje wydrukowanie wartości funkcji. Najpierw jest przejście do modułu podprogramu zadekalrowanego jako funkcja, z argumentami a, b, c.
Następnie wielkość obliczona przez funkcję jest przenoszona do programu głównego przez nazwę funkcji.
Umieszczenie w programie głównym instrukcji
wynikobliczen = sumprz (1, 2, 5)
Spowoduje przypisanie do zmiennej wynikobliczen obliczonej przez funkcję sumprz z wrtościami argumentów 1, 2, 5.


W wersji angielskiej

A subroutine (also called a "module") is a "mini-program" inside your program.
In other words, it is a collection of commands--and can be executed anywhere in your program.
To create a subroutine:
Go to the "Edit" menu Select "New Sub" Enter a name for the subroutine Type a list of commands between SUB and END SUB
To use the subroutine: Press F2 Select "Untitled" Press Enter to return to the "main module" Use CALL to execute the subroutine.

Parameters
Parameters Parameters are numbers and strings that you pass to a subroutine, much like a QBasic command

This passes 16 as a parameter:

CALL OutputNumber(16)
' Notice the parentheses around the parameter "num." ' Any variables placed inside the parentheses are set as ' the subroutine's parameters.

SUB OutputNumber (num)
PRINT num
END SUB
Output: 16

Functions

Function is the same as a subroutine, except it returns a value. Also, you must leave out the CALL command.
To return a value, set a variable with the same name as the function.
PRINT Add(10, 7 )

FUNCTION
Add (num1, num2) Add = num1 + num2
END FUNCTION
Output: 17
Since a function can return a value, the name of the function can end with special characters.


Przykłady

1) Liczenie wyrazów w zdaniu

'count the words
input "Type a sentence>"; sentence$

print "There are "; wordCount(sentence$); " words in the sentence."
end

function wordCount(aString$)
  index = 1
  while word$(aString$, index) <> ""
    index = index + 1
  wend
  wordCount = index - 1
end function

Przykład wyniku:
Type a sentence> Dzień dobry
There are 2 words in the sentence.

2) Zamiana liter małych na duże

DECLARE FUNCTION znaki$ (a$)

CLS

INPUT "Podaj imie i nazwisko: "; a$
PRINT
PRINT "Wczytalem "; a$
a$ = znaki$(a$) 'funkcja znaki$ zamienia litery male na duze
PRINT
PRINT "Po wykonaniu zamiany liter ", a$
END

FUNCTION znaki$ (a$)
nl = LEN(a$)
FOR i = 1 TO nl
b$ = MID$(a$, i)
nb = ASC(b$)
IF nb >= 97 AND nb <= 122 THEN
  MID$(a$, i) = CHR$(nb - 32)
END IF
100 NEXT i
znaki$ = a$
END FUNCTION


Nazwa funkcji kończy się znakiem dolara, bo wyznaczana wartość funkcji to stała znakowa.

Interpreter języka QBasic ma zaprogramowanych wiele funkcji o ogólnym zastosowaniu. Nie wymagają one deklarowania na początku programu.

Przykłady funkcji:
ABS
ATN


W przypadku zdefiniowania własnych funkcji przez programistę moze on korzystać z deklaracji
SHARED i STATIC
podobnie jak w przypadku podprogramów.
Czasem w programie chcemy korzystać z wielkości pośrednich obliczonych w trakcie wykonywania funkcji.
Przedstawia to poniższy przykład.

' Sumprz1
REM Zastosowanie funkcji – FUNCTION nazwa (parametry)

DECLARE FUNCTION sumprz (a, b, c)

CLS
INPUT "Podaj 3 liczby "; a, b, c
sumaprzek = sumprz(a, b, c)
PRINT
PRINT "W programie glownym"

PRINT "Suma dlug. przek prostop a,b,c= "; sumaprzek
PRINT "W programie glownym"
PRINT "p1 = "; p1, " p2 = "; p2, " p3="; p3

END

FUNCTION sumprz (a, b, c)
 SHARED p1, p2, p3
 p1 = SQR(a ^ 2 + b ^ 2)
 p2 = SQR(b ^ 2 + c ^ 2)
 p3 = SQR(a ^ 2 + c ^ 2)
 PRINT
 PRINT "W funkcji: "
 PRINT "p1="; p1, " p2="; p2, " p3="; p3
 sumprz = 2 * (p1 + p2 + p3)
END FUNCTION

Instrukcja
SHARED p1, p2, p3
umieszczona w module funkcji powoduje, żę wartosci zmiennych p1, p2 i p3 są dostępne w programie głównym.

W przypadku funkcji korzystanie z nich moze być wielopoziomowe jak w przypadku podprogramów.
Obliczenie wartości funkcji moze się odbywać poprzez wywołanie innych funkcji.
W obrębie funkcji nie wolno jednak posługiwac się funkcją, która właśnie jest wykonywana.

Argumentami funckji mogą być nazwy zmiennych o określonej uprzednio wartosci a takze stałe liczbowe czy znakowe.
Dozwolone są też wyrazenia algebraiczne i logiczne, których wartości zostaja wyliczone i przekazane do modułu tworzącego funkcję jako aktualne argumenty, dla których ma byc obliczona wartość funkcji.

Ilustruje to poniższy przykład:

' p237c.bas
DECLARE FUNCTION iloraz (a, b)
CLS
INPUT "Podaj 2 liczby: "; x, y
rez1 = iloraz(x, y)
rez2 = iloraz(33, 11)
rez3 = iloraz(x * y, x + y)
rez4 = ilorz(3 + x, y / 7)
PRINT rez1, rez2, rez3, rez4
END

FUNCTION iloraz (p, q)
 iloraz = p / q
END FUNCTION

Wersja do Just Basic

' p237cjb.bas
' DECLARE FUNCTION iloraz (a, b)
CLS
Print "Podaj 2 liczby: x, y  "
input "Podaj x: ";x
input "Podaj y: "; y
rez1 = iloraz(x, y)
rez2 = iloraz(33, 11)
rez3 = iloraz(x * y, x + y)
'rez4 = ilorz(3 + x, y / 7)
PRINT rez1, rez2, rez3, ' rez4
END


FUNCTION iloraz(p, q)
iloraz = p / q

END FUNCTION

Wyniki:
Podaj 2 liczby: x, y
Podaj x: 2
Podaj y: 3
0.66666667    3             1.2

Druga metoda definiowania funkcji w QBasicu  - DEF FNnazwa

Składnia 1:
DEF FNnazwa[(zmienna [AS typ]], zmienna [AS typ]] ...] = wyrazenie

składnia 2:
DEF FNnazwa[(zmienna [AS typ]], zmienna [AS typ]]...]
....
FNnazwa = wyrazenie
[EXIT DEF]
...
END DEF

Opis: Definiuje i okreśa nazwę funkcji
Parametry:
nazwa - nazwa definiowanej funkcji. Długośc do 40 znaków
zmienna - dowolna dopuszczona w BASIC'u nazwa zmiennej
typ INTEFER, LONG, DOUBLE lub STRING
wyrazenie - przekształaca zmienne, określa wartosć zwracaną przez funkcję
 END DEF - koniec definicji funkcji zbudowanej z wielu linii
EXIT DEF - dodatkowa możliowść opuszczenia definicji funkcji, w  wariancie instrukcji wieloliniowej, przed jej zakonczeniem.
W jednej DEF FN można umieścić wiele EXIT DEF.

Przykład
Definicja funkcji cotangens (x w radianach)
DEF FNcot (x) = 1 / TAN(x)

Definicję funckji DEF FNnazwa mozna umieścić w dowolnym miejscu programu głównego.

Przykład:

CLS
PRINT "Poczatek programu"
c = 12
d = 32
e = c * d
' ************* Definicja funkcji
 DEF FNiloczyn (a, b) = (a + b) * (a ^ 2 + b ^ 2) * (a63 + b ^ 3)
' ************* Koniec definicji funkcji
a = 3
b = 4
PRINT "FNiloczyn("; a; ","; b; ") = "; FNiloczyn(a, b)

END

Wiersz definiujący funkcję musi zaczynać się słowem DEF, po którym umieszcza sie nazwę funkcji. Nazwa musi się zaczynac od FN.

Jesli operacje wewnątrz funkcji  są długie to można je zapisać w kilku wierszach.

Przykład:
CLS

REM **** Definicja funkcji
DEF FNiloczyn (a, b)
 p1 = a + b
 p2 = a ^ 2 + b ^ 2
 p3 = a ^ 3 + b ^ 3
 FNiloczyn = p1 * p2 * p3
END DEF
REM **** Koniec definicji funkcji

 a = 3
 b = 4
 PRINT FNiloczyn(a, b)
END

Opisana definicja DEF FNnazwa pozwala na umieszczenie tej definicji w dowolnym punkcie programu głównego.
Korzystanie ze zdefiniowanej funkcji jest mozliwe tylko w części programu znajdującej się za tą definicja.
Metoda ta nie jest polecana. Instrukcje definiujące funkcję metoda DEF FN są jakby przemieszane z innymi instrukcjami, co nie daje przejrzystosci programu.

Różnice miedzy funkcją a podprogramem


Każde zadanie wykonywane przez program wielokrotnie należy zapisac w postaci podprogramu lub funkcji.

Zadanie, którego wynikiem ma byc jedna wartość programujemy jako funkcję,
natomiast zadanie, którego realizacja daje kilka wartosci należy zapisywac jako podprogram.



METODY NUMERYCZNE ROZWIAZYWANIA ZAGADNIEŃ


Metody numeryczne to metody dające rozwiązanie w postaci liczb, a nie wzorów.
Istotę metod numerycznych można przedtawic na przykładach zadań, które nie mają dokładnego rozwiazania analitycznego.

Przykładem jest równanie:
cos(x) - x = 0
Z wykresu funkcji y = cos(x) - x
wynika, że przecina ona oś X (wtedy y=0) tylko raz dla wartosci x ok. 0.8 radiana. W miarę oddalania się w lewo lub prawo, odległosć wykresu od linii y=0 wzrasta.
Oznaczając tę odleglość przez r możemy zapisać:
r = ABS(cos(x)-x)

Algorytm rozwiązania polega na obliczaniu kolejnych wartości r dla x zmieniającego się od 0,5 do 1, z ustalonym przyrostem dx do wartości x.
Wartość r początkowo będzie maleć a po przekroczeniu punktu przecięcia rosnąć.
Przybliżonym rozwiązaniem równania będzie wartość x, dla której kolejne r będzie większe od poprzedniego.
Im mniejszy zastosujemy przyrost dx, tym dokładniejsze będzie znalezione x.

REM p261
REM Rozwiazanie rownania cos(x)-x=0
CLS
PRINT "Rozwiazanie rownania cos(x)-x=0"
x = .5
dx = .01
r = ABS(COS(x) - x)
licznik% = 0
t1 = TIMER
 DO WHILE x < 1
  str = r
  r = ABS(COS(x) - x)
    IF r > str THEN EXIT DO
   x = x + dx
   licznik% = licznik% + 1
 LOOP
t2 = TIMER
czas = t2 - t1
PRINT "Licznik, czas, x, r "
PRINT licznik%; czas; x, r

Rozwiazanie:
Licznik: 25, czas 0. x 0.,749998, r =1.831073E-02


Optymalizacja obliczeń.

Jednym z lepszych rozwiązań jest zmienianie wartosci przyrostu dx w trakcie obliczeń.
Zaczynamy z przyrostem 0,1. Po pierwszym przekroczeniu punktu przecięcia (r zaczęłorosnąć) zmieniamy dx na dx/2 i zmieniamy znak (cofamy się).
Po ponownym przejściu powtarzamy procedurę, przyjmując dx=-dx/2 i kontynuujemy obliczenia. W ten sposób oscylujemy wokół punktu przeciecia z coraz to mniejszym krokiem

REM p262
REM Rozwiazanie rownania cos(x)-x=0
CLS
PRINT "Rozwiazanie rownania cos(x)-x=0"

dokl# = .0000001#

x = .5
dx = .1
r = ABS(COS(x) - x)
licznik% = 0

10  DO WHILE x < 1
  str = r
  r = ABS(COS(x) - x)
    IF r > str THEN EXIT DO
   x = x + dx
   licznik% = licznik% + 1
 LOOP

 IF ABS(r - str) <= dokl# GOTO 20
  dx = -dx / 2
   GOTO 10

20 PRINT licznik%; x, r

Rozwiązanie:
Licznik: 69,  x = 0.7390851, r =9.20E-08

Ostateczna postać programu
Program do rozwiązania danego zagadnienia moze być napisany wieloma sposobami. Przygotowując program należy, m.in. wiedzieć, dla jakich celów jest on przeznaczony:
1) Czy chcemy rozwiązać jednorazowo jakieś zagadnienie
2) Czy ma byc to program, z którego będzie korzystało więcej użytkowników

Przykład roziązania równań kwadratowych.
1) Najprostszy program w jezyku BASIC

INPUT "a, b, c "; a, b, c
del = b^2-4*a*c
IF del < 0 THEN END
PRINT (-b - SQR(del))/2/a, (-b+SQR(del))/2/a


2)  Program rozbudowany, dla celów uzytkowych
REM p263
REM Program rozwiazuje rownanie kwadratowe
REM  a x^2 + b x  + c  =  0
REM del   wyznacznik rownania
REM  x1, x2  pierwiastki
REM  PODPROGRAMY
REM  dane()  czytania danych
REM  delta()  liczy del
REM  pierw()  oblicza x1, x2
REM  wyniki()  druk wynikow

REM PROGRAM GLOWNY
  DECLARE SUB dane (a, b, c)
  DECLARE SUB delta (a, b, c, del)
  DECLARE SUB pierw (a, b, sqrdel, x1, x2)
  DECLARE SUB wyniki (a, b, c, x1, x2)
start:
 CLS
 LOCATE 12, 20
 PRINT "Program rozwiazuje rownanie kwadratowe"
  LOCATE 14, 30
  PRINT "a*x^2+b*x+c=0"
  INPUT "START - Enter "; st$
  CALL dane(a, b, c)
  CALL delta(a, b, c, del)
    IF del < 0 THEN
       CLS
       LOCATE 10, 20
       PRINT "delta < 0,  nie ma rozwiazania "
       GOTO koniec
    END IF
  sqrdel = SQR(del)
  CALL pierw(a, b, sqrdel, x1, x2)
  CALL wyniki(a, b, c, x1, x2)
koniec:
  LOCATE 22, 50
  INPUT "Nastepne rownanie ?  T / N "; tn$
  IF tb$ = "T" OR tn$ = "t" THEN GOTO start
  END

 SUB dane (a, b, c)
   INPUT "a = "; a
   INPUT "b = "; b
   INPUT "c = "; c
END SUB

SUB delta (a, b, c, del)
  del = b ^ 2 - 4 * a * c
END SUB

SUB pierw (a, b, sqrdel, x1, x2)
  mian = 2 * a
  x1 = (-b - sqrdel) / mian
  x2 = (-b + sqrdel) / mian
END SUB

SUB wyniki (a, b, c, x1, x2)
  CLS
  LOCATE 6, 20
  PRINT "Rownanie "; a; "x^2 + "; b; "x + "; c; " =  0"
  LOCATE 8, 22
  PRINT " x1="; x1, "x2="; x2
END SUB

Dobrze napisany program powinien byc odporny na różne reakcje użytkownika.
Napisanie takiego programu wymaga wielokrotnie więcej czasu

Funkcja RND i RANDOMIZE


RND(n)
Funkcja zwraca pseudolosową liczbę pojedynczej precyzji z zakresu 0 do 1
Gdy n < 0 to funkcja generuje tę samą liczbę przy każdym wywołaniu.
gdy n> 0 lub pomineto n - generuje przy kazdym kolejnym wywołaniu liczbę z ciągu wywołanego poprzednim razem

RANDOMIZE (wyrazenie)
Inicjuje pracę generatora liczb pseudolosowych. Wyrazenie jest liczbą z przedziału -32768, 32767, która określa stan poczatkowy generatora.

Przykłady programów:

' Totolotek
INPUT "Podaj liczbę mniejsza niz 32000 "; A
RANDOMIZE A
PRINT "Oto numery TOTOLOTKA na ten tydzien"
FOR i =1 TO 6
 PRINT INT(RND*50)
NEXT i


Symulacja rzutu kostką

' Losowanie liczb
REM P268
' LOSOWANIE LICZB
DEFLNG A-Z
CLS
RANDOMIZE TIMER
INPUT "Ile rzutow "; n
l1 = 1
l2 = 2
l3 = 3
l4 = 4
l5 = 5
l6 = 6
  w1 = 0
  w2 = 0
  w3 = 0
  w4 = 0
  w5 = 0
  w6 = 0
FOR k = 1 TO n
  w = INT(RND * 6) + 1
  IF w = 1 THEN w1 = w1 + 1
  IF w = 2 THEN w2 = w2 + 1
  IF w = 3 THEN w3 = w3 + 1
  IF w = 4 THEN w4 = w4 + 1
  IF w = 5 THEN w5 = w5 + 1
  IF w = 6 THEN w6 = w6 + 1
NEXT k
PRINT n; " rzutow"
PRINT "Liczby wylosowane ";
PRINT USING "########"; l1; l2; l3; l4; l5; l6
PRINT "Ilosc liczb       ";
PRINT USING "########"; w1; w2; w3; w4; w5; w6



Liczby pierwsze

REM P271
REM Program znajduje liczby pierwsze z przedzialu 1 do 1000
REM meoda prymitywna
CLS
PRINT "Liczby pierwsze 1..1000"
INPUT "Ile liczb przeszukiwac "; n
FOR lb = 2 TO n
  FOR k = 2 TO lb - 1
   IF lb \ k = lb / k THEN GOTO 10'sprawdza podzielnosc
  NEXT k
  PRINT lb;
10 NEXT lb



Instrukcja
lb \ k = lb/k
sprawdza czy liczba dzieli się bez reszty przez kolejne liczby całkowite
Operator \  jest operatorem dzielenia całkowitego, czyli daje część całkowitą dzielenia.
Jest on równowazny zapisowi  INT(lb/k)



OPERACJE DYSKOWE

OPEN, PRINT #, INPUT #, CLOSE
są to podstawowe instrukcje jezyka Basic pozwalajace założyc zbiór (plik), połączyc się z nim, zapisać informacje lub odczytać i odłączyć się od zbioru.

Przykłady programów

REM P278
REM Program do robienia spisu nazwisk, zapisu ich na dysk do zbioru
REM i odczytu ze zbioru
CLS
INPUT "Podaj przewidywana ilosc osob do wczytywania (>=fakt) "; ilosc
' Np ilosc = 40   'ilosc nazwisk
DIM tablnazw$(ilosc) ' deklaracja tablicy na dane
FOR i = 1 TO ilosc
INPUT "Imie i nazwisko ( Xxx - koniec) "; imnazw$  'wczytywanie danych
IF imnazw$ = "Xxx" GOTO 50
tablnazw$(i) = imnazw$
NEXT i
50 lbn = i - 1  'ilosc danych wczytanych
PRINT
 INPUT "Podaj nazwe zbioru 1 "; nazwzb1$
 OPEN nazwzb1$ FOR OUTPUT AS #1    ' Otwarcie zbioru do zapisu
 FOR i = 1 TO lbn
 PRINT #1, tablnazw$(i)            ' Drukowanie do zbioru
 NEXT i
 CLOSE #1                          ' Zamknięcie zbioru 
REM Odczytanie tresci zbioru
 OPEN nazwzb1$ FOR INPUT AS 3       ' Otwarcie zbioru do odczytu
 FOR i = 1 TO lbn
  INPUT #3, tablnazw$(i)            ' odczytywanie zawartosci zbioru
  NEXT i
  CLOSE #3
REM wydruk zbioru
  FOR i = 1 TO lbn
  PRINT tablnazw$(i)
  NEXT i
  END



REM P280
REM zakladanie zbioru
CLS
PRINT "Zakladanie zbioru, przegladanie zbiorow, zmiana nazwy zbioru"
PRINT
INPUT "Nazwa zbioru do zalozenia :"; zb1$
OPEN zb1$ FOR OUTPUT AS #1
PRINT #1, "Tresc tego zbioru nie ma znaczenia"
CLOSE #1
CLS
PRINT "Listowanie katalogu biezacego - FILES - odpowiednik DIR "
PRINT
FILES
PRINT
INPUT "Ktory naped obejrzec <Enter> - katalog biezacy "; nap$
FILES nap$
INPUT "nazwa zbioru po przemianowaniu "; zb2$
NAME zb1$ AS zb2$
PRINT
PRINT SPACE$(20); "Po zmianie nazwy zbioru "
FILES
INPUT "Nacisnij Enter "; e$
CLS



REM P281
CLS
PRINT "Sprawdzenia dzialania instrukcji APPEND - dopisywanie do zbioru"
PRINT
CLS
OPEN "zb1.tst" FOR OUTPUT AS #1
  PRINT "Otwierzylem do zapisu zbior 'zb1.tst'"
  PRINT
  INPUT "Podaj slowo1 do zapisu w zbiorze "; a$
  PRINT #1, a$
  PRINT "Zapisalem do zbioru 'zb1.tst' napis :  "; a$
CLOSE #1
PRINT
 PRINT "Zamknalem zbior"

 PRINT
OPEN "zb1.tst" FOR APPEND AS #1
  PRINT "Otworzylem zbior zb1.tst w trybie APPEND - mozna dopisywac "
  PRINT
  INPUT "Podaj slowo2 do dodania do zbioru"; b$
  PRINT #1, b$
  PRINT "Zapisalem do zbioru <zb1.tst>  slowo:  "; b$
CLOSE #1
 PRINT
 PRINT "Zamknalem zbior "
PRINT
 
 PRINT "Otwieram zbior do czytania i czytam z niego"
OPEN "zb1.tst" FOR INPUT AS #1
 INPUT #1, c$, d$
 PRINT c$, d$
CLOSE #1
PRINT
PRINT "Zamknalem zbior"
PRINT
INPUT "Nacisnij Enter "; a$
CLS



REM P282
REM Zapis i odczyt ze zbioru
CLS
OPEN "zb2.tst" FOR OUTPUT AS #1
  zn1$ = "abcdefghij"
  zn2$ = "12345"
  zn3$ = "A"
   PRINT #1, zn1$
   PRINT #1, zn2$
   PRINT #1, zn3$
CLOSE #1

OPEN "zb2.tst" FOR INPUT AS #7
 INPUT #7, a$, b$, c$
 CLOSE #7
PRINT "a$= "; a$, "b$= "; b$, "c$="; c$




Programy operujace na stałych i zmiennych znakowych

Przykłady programów

REM P284
REM Zamiana malych liter na duze
CLS
PRINT "Program zamienia male litery na duze"
PRINT
INPUT "Podaj zdanie lub slowo "; a$
ni = LEN(a$)

FOR i = 1 TO ni
 b$ = MID$(a$, i)
 nb = ASC(b$)
 IF nb >= 97 AND nb < 122 THEN
 MID$(a$, i) = CHR$(nb - 32)
 ' PRINT a$
 END IF
100 NEXT i

PRINT a$


REM P285
REM Zamiana malych liter na duze – plik danych i wynikow
CLS
PRINT "Program zamienia male litery na duze"
PRINT
INPUT "Nazwa pliku danych  "; f1$
INPUT "Nazwa pliku wynikow "; f2$
OPEN f1$ FOR INPUT AS #1
OPEN f2$ FOR OUTPUT AS #2
WHILE NOT EOF(1)
LINE INPUT #1, a$
ni = LEN(a$)

FOR i = 1 TO ni
 b$ = MID$(a$, i)
 nb = ASC(b$)
 IF nb >= 97 AND nb < 122 THEN
 MID$(a$, i) = CHR$(nb - 32)
 ' PRINT a$
 END IF
100 NEXT i
PRINT #2, a$
PRINT a$
WEND
CLOSE #1
CLOSE #2