Trochę historii.

Clipper powstał w 1985 roku jako język programowania na podstawie systemu zarządzania bazą danych dBase firmy Ashton-Tate. Poczatkowo Clipper'a rozwijała firma Nantucket. Pod jej kontrolą powstały kolejne wersje:

* Clipper'85 Winter
* Clipper'86 Autumn - 31.09.1986
* Clipper'87 Summer - 21.12.1987

W roku 1990 powstała nowa (zupełnie) wersja Clipper'a. Wersja ta była zgodna (funkcjonalnie) z Clipper'87 natomiast pod względem wewnętrznej architektury był to już zupełnie nowy produkt.

* Clipper 5.00
* Clipper 5.01 - 15.04.1991

Wersja 5.01 była ostatnią (i niezbyt udaną) wersją firmy Nantucket. Wkrótce po jej wypuszczeniu Clipper'a przejął jeden z największych producentów software w ameryce - Computer Associates, który w krótkim czasie wypuscił poprawioną wersje:

* CA-Clipper 5.01a

Następnie po dwuletnim milczeniu powstała nowa, już całkowicie wyprodukowana przez CA wersja. Wersja 5.2 była wielokrotnie poprawiana. Powszechnie uważa się że wersja 5.2d jest najlepszą (najstabilniejszą) wersją Clipper'a

* CA-Clipper 5.20 - 15.12.1993
* CA-Clipper 5.2a
* CA-Clipper 5.2b - 25.07.1993
* CA-Clipper 5.2c
* CA-Clipper 5.2d - 25.03.1994
* CA-Clipper 5.2e - 07.12.1995

Ostatnia wersja Clipper'a pokazała się w 1995 roku.

* CA-Clipper 5.30 - 26.07.1995
* CA-Clipper 5.3a - 20.05.1996
* CA-Clipper 5.3b - 21.05.1997

Wszystko wskazuje na to, że to już koniec. CA nie planuje nowych wersji (ani poprawek). Oficjalnym ciągiem dalszym jest CA-Visual Object.


Podstawy języka Clipper.

Program utworzony przez programistę jest nazywany programem źródłowym i jest on po prostu tekstem. Po przetłumaczeniu przez translator uzyskuje się program wynikowy (binarny).

Przy pisaniu programu należy zwracań uwagę na poprawność składni. W języku Clipper relacje (tablice) pamiętane są w postaci plików bazy danych. Każdy wiersz tablicy odpowiada rekordowi, a każda kolumna tablicy odpowiada polu. Pliki bazy danych mają rozrzeszenia .dbf. Inne podstawowe pliki wykorzystywane w języku Clipper to pliki zawierające pola typu MEMO danego pliku bazy danych o rozszerzeniu .dbt, pliki zawierające informacje o uporządkowaniu rekordów pliku bazy danych o rozszerzeniu .ntx oraz pliki .mem przechowujące nazwy zmiennych i ich wartości, które zostały zapamiętane w pliku podczas wykonywania programu.

Pola w pliku bazy danych mogą być typu tekstowego (character), numerycznego (numeric), typu daty (data), logicznego (logical) oraz typu notatnika (memo).

Pliki bazy danych można utworzyć przy pomocy pomocniczego systemu o nazwie dbu.exe dostarczanego wraz z kompilatorem Clipper, lub wykorzystując funkcję DBCREATE(). Do otworzenia istniejącego pliku bazy danych służy instrukcja USE, np
USE nazwa
Powyższa instrukcja powoduje otwarcie pliku o nazwie nazwa

Język Clipper umożliwia zaindeksowanie plików bazy danych tzn. przechowywanie
w dodatkowym pliku o rozszeszeniu .ntx żądanej kolejności danych.
Zaindeksowanie pliku umożliwia bardzo szybki dostęp do przechowywanych danych. Indeksowanie plików dokonuje się przy pomocy instrukcji INDEX ON. Poniżej przedstawiono przykład indeksowania pliku o nazwie Baza według pola nazwisko.

INDEX ON nazwisko TO Baza

Język Clipper definiuje 255 obszarów roboczych. W celu przejścia do określonego obszaru roboczego należy wykonać instrukcję SELECT z określonym parametrem definiującym numer obszaru roboczego (od 0 do 255)

Do przejścia do wybranego rekordu wykorzystuje się instrukcję SKIP, np
SKIP 1 //przejście do następnego rekordu
SKIP //przejście do następnego rekordu
SKIP -1 //przejście do poprzedniego rekordu
SKIP 20 //przejście o 20 rekordów do przodu

Podstawową instrukcją służącą do wprowadzania i wyprowadzania danych jest instrukcja @... SAY...GET
Oto przykład wykorzystania tej instrukcji:

@ 10, 30 SAY "Pewien tekst"
//na ekranie w miejscu o współrzędnych 10, 30
// wyprowadzony zostanie komunikat: Pewien tekst
x := 0
@ 14, 20 SAY "Podaj nową liczbę" GET x
READ

Na ekranie w miejscu o współrzędnych 14, 20 wyprowadzony zostanie komunikat:
podaj nową liczbę, a następnie zostanie wyświetlone pole do wprowadzania wartości zmiennej x.
Wprowadzenie wartości zmiennej x następuje po wykomuaniu instrukcji READ

W celu przypisania wartości wyrażenia wskazanemu elementowi języka np. zmiennej
używamy instrukcji przypisania. Instrukcja ta ma postać:
v:=wyrażenie
gdzie:
v - zmienna,
wyrażenie - wyrażenie odpowiedniego typu.
Przykład:
x := 10 // zmienna x przyjmuje wartość 10
y := x + 20 // zmienna y przyjmuje wartość 30
z := 5 // zmienna z przyjmuje wartość 5
t := z + 3 // zmienna t przyjmuje wartość 8

W języku Clipper istnieją następujące rodzaje zmiennych:
- LOCAL
- STATIC
- PRIVATE
- PUBLIC

Zmienne lokalne dostępne są wyłącznie wewnątrz danej procedury.
Tworzone są przy rozpoczęciu pracy procedury lub funkcji i likwidowane
po zakończeniu jej pracy.

Zmienne statyczne natomiast dostępne wewnątrz procedury w której
zostały zadeklarowane, po wykonaniu danej procedury zachowują swoje
wartości i po ponownym wywołaniu procedury zmienne te posiadają poprzednią wartość.

Zmienne PRIVATE są dostępne wewnątrz procedury, w której zostały utworzone oraz we wszystkich procedurach wywoływanych bezpośrednio lub pośrednio z danej procedury. Zmienne nie zadeklarowane w tekście traktowane są jako PRIVATE.

Zmienna PUBLIC dostępna jest we wszystkich procedurach programu, chyba że istnieje zmienna PRIVATE, LOCAL lub STATIC o takiej samej nazwie jak zmienna PUBLIC.

Składnia deklaracji PUBLIC jest następująca:
PUBLIC identyfikator [[ := wartość], ...]
Przykład:

Test()
// zmienna x jest globalna i jej wartość nie może zostać
// wyświetlona
? x
// zmienna y jest niedostępna w programie
RETURN
PROCEDURE Test
PUBLIC x
x := 10
y := 20
RETURN

Jeżeli odwołujemy się do pola bliku bazy danych, wówczas nazwę zmiennej
należy poprzedzić instrukcją: FIELD.

Przykład:
FIELD imie, wiek
Use Plik // otwarcie bazy o nazwie Plik
APPEND BLANK // przyłączenie pustego rekordu.
REPLACE nazwisko WITH "Kowalski" // zamiana wartości w polu nazwisko na "Kowalski"
imie := "Jan"
wiek := "35"
? imie // wyświetlenie wartości pola imie
? wiek // wyświetlenie wartości pola wiek
LIST nazwisko, imie, wiek //wyświetlenie pól: nazwisko, imie, wiek


Zmienne sterujące.

Podstawową instrukcją decyzyjną jest instrukcja IF o następującej strukturze:
IF warunek
instrukcja
ENDIF

Mogą to być również instrukcje zagnieżdżone:

IF warunek1
instrukcja1 ELSEIF warunek2
instrukcja2
ELSE
instrukcja3
ENDIF

Następną instrukcją sterującą jest: DO WHILE

DO WHILE warunek
instrukcje
EXIT
instrukcje
LOOP
instrukcje
ENDDO

Instrukcja DO WHILE powoduje wykonanie bloku instrukcji tak długo,
jak długo spełniony jest warunek.
Użycie instrukcji EXIT powoduje natychmiastowe zakończenie wykonywania DO WHILE i przeniesienie sterowania do instrukcji umieszczonej po ENDDO. Zastosowanie instrukcji LOOP powoduje przeniesienie sterowania do ENDDO (pomijane są instrukcje zawarte między LOOP i ENDDO)

Instrukcja FOR:
FOR zmienna = wyrażenie1 TO wyrażenie2 STEP wyrażenie3
instrukcje
EXIT
instrukcje
LOOP
NEXT

Instrukcja FOR powoduje wykonanie instrukcji umieszczonych pomiędzy słowem kluczowym FOR a NEXT określoną liczbę razy.
wyrażenie1 jest wartością początkową zmiennej sterującej, wyrażenie2 jest wartością końcową zmiennej sterującej, a wyrażenie3 jest nazywane krokiem pętli.
Zakresem instrukcji FOR są wszystkie instrukcje poczynając od następnej po FOR, a kończąc na NEXT. Wykonanie instrukcji FOR polega na ściśle określonym wielokrotnym wykonaniu instrukcji wchodzących w skład zakresu instrukcji FOR. Liczba powtórzeń wynika z wartości wyrażeń: wyrażenie1, wyrażenie2, wyrażenie3.

Przykład:
FOR i = 5.5 TO 10.4 STEP 1.6
? "Wykonano jeden cykl dla i = " ,i"
NEXT

Wyniki wykonania programu:

Wykonano jeden cykl dla i= 5.5
Wykonano jeden cykl dla i= 7.1
Wykonano jeden cykl dla i= 8.7
Wykonano jeden cykl dla i= 10.3

Następny program wczytuje 10 liczb i sprawdza czy są one większe od 1000

CLEAR
FOR i = 1 TO 10
x := 0
@ 10, 10 SAY "Podaj kolejną liczbę " GET x
READ
IF ( x > 1000 )
@ 24,0
@ 24,0 SAY "Wczytana liczba jest większa od tysiąca"
ELSE
@ 24,0
@ 24,0 SAY "Wczytana liczba jest mniejsza lub równa tysiąc"
ENDIF
NEXT
RETURN

Instrukcja DO CASE

DO CASE
CASE warunek
instrukcje
CASE warunek
instrukcje
OTHERWISE
instrukcje
ENDCASE

Instrukcja DO CASE powoduje wykonanie fragmentu programu umieszczonego wewnątrz instrukcji DO CASE dla pierwszego napotkanego warunku, który jest spełniony. Jeżeli żaden z podanych warunków nie jest spełniony, wykonywane są instrukcje podane po słowie kluczowym OTHERWISE.

Przykład:

DO CASE
CASE nr == 1
Prog_1()
CASE nr == 2
Prog_2()
CASE nr == 3
Prog_3()
OTHERWISE
Blad()
ENDCASE


Tablice.


Tablica jest to uporządkowany zbiór wartości, które posiadają taką samą nazwę. Każdą wartość w tablicy nazywamy jej elementem. Element tablicy może być dowolnego typu z wyjątkiem typu MEMO. W tej samej tablicy elementami mogą być łańcuchy tekstowe, liczby, daty, a nawet inne tablice, obiekty oraz bloki kodu. Fakt, że elementem tablicy może być inna tablica, jest bardzo istotny, ponieważ umożliwia tworzenie tablic zagnieżdżonych, które są rozszerzeniem tablic wielowymiarowych.

Tablicę przyporządkowuje się zmiennej, która zawiera odwołanie do tablicy (wskazanie na tablicę). Inaczej pisząc zmienna jest deklarowana jako tablica. Tablicę można tworzyć wykorzystując jedną z następujących instrukcji: PRIVATE, PUBLIC, LOCAL, STATIC.

Przykład:
LOCAL a[20,30], b[20] [30]
// zadeklarowano dwie tablice a i b
// każda z nich składa się z dwudziestu tablic o trzydziestu
// elementach
Do poszczególnych elementów tablicy odwołujemy się podając nazwę tablicy i następnie w nawiasach prostokątnych liczby lub zmienne definiujące numery kolejnych tablic wewnętrznych oraz numer danego elementu, np. polecenie: ? a [1, 1] wyświetli nam wartość elementu 1 -go w 1 -ej wewnętrzej tablicy (inaczej jest to wartość pierwszego wiersza i pierwszej kolumny tej tablicy).
Tablicę można również tworzyć przy pomocy funkcji ARRAY() o składni:

y := ARRAY(7,8)
// zadeklarowano tablicę y zawierającą siedem podtablic,
// z których każda zawiera osiem elementów


Procedury i funkcje.


Procedura posiada następującą strukturę:
PROCEDURE nazwa_procedury
instrukcje
RETURN

Funkcja posiada następującą strukturę:
FUNCTION nazwa_funkcji
instrukcje
RETURN wyrażenie

Procedura od funkcji różni się tym, że procedura nie może zwracać wartości. Procedura lub funkcja mogą być umieszczone w dowolnym miejscu w programie lub w oddzielnym pliku (chyba, że jest zadeklarowana z opcją STATIC - wówczas może być wywoływana wyłącznie przez podprogramy umieszczone w tym samym pliku, w którym znajduje się jej definicja).

Przykład ilustrujący wywoływanie podprogramów:

z := 3 * Wyr(5) // wywołanie funkcji Wyr
Tablica() // wywołanie funkcji Tablica
Test() // wywołanie procedury Test
RETURN

PROCEDURE Test
? "Wykonana została procedura test"
RETURN

FUNCTION Wyr(x)
y := 4 * x * x + 5 * x - 8
RETURN y

FUNCTION Tablica
PUBLIC z := { {} , {} } // utworzenie pustej tablicy z
// złożonej z dwóch podtablic
RETURN NIL

(c) LAnFORM 09-06-2003 r.