Παρασκευή 15 Μαΐου 2009

Προγράμματα & Ανάπτυξη

Τώρα τελευταία, όλο και συχνότερα αντιμετωπίζω την απορεία ανθρώπων για το τί είναι πληροφορική? Τί είναι ο προγραμματιστής? Τί γράφει? Γιατί το γράφει τί σημαίνει πρόγραμμα και τα λοιπά ...

Σκέφτηκα λοιπόν, να δώσω μια μικρή ακτίδα φωτός μέσα στο χάος των προγραμμάτων, της λογικής του προγραμματισμού, της τέχνης του σχεδιασμού και στις δυνατότητες της πληροφορικής, μέσα από ένα άρθρο που μπορεί να είναι λίγο εκτενές αλλά πιστέψτε με,, στο τέλος η εικόνα θα είναι αρκετά πιο ελκυστική :-)

Τί είναι ο υπολογιστής? Μια συσκευή. Λίγο διαφορετική από το πλυντήριο στο σπίτι σας, αλλά με την ίδια σύνθεση περίπου. Δυστυχώς δεν έχει κάδο βέβαια αλλά έχει κυκλώματα και περιφερειακά τσιπάκια και τέτοιες ιστορίες όπως και το πλυντήριο. Λίγο αποτυχία ο συσχετισμός, αλλά, σοβαρά τώρα, σαν μηχανημα δεν έχει και πολλές δυνατότητες. Τουλάχιστον το πλυντήριο πλένει τα ρούχα μας. Σκοπός του είναι η διαχείριση της πληροφορίας, η αποθήκευση της και ο συνδυασμός της με άλλες ήδη υπάρχουσες πληροφορίες. Πως το κάνει αυτό?

Η όλη λειτουργία του βασίζεται στην ανάλυση ηλεκτρικών σημάτων στα επιμέρους κυκλώματα του. Δεν θα εμβαθύνω περισσότερο μιας και δεν μας ενδιαφέρει τόσο. Αυτό που μας ενδιαφέρει είναι οτι ο υπολογιστής μας απαρτίζεται από διάφορα κομμάτια που στο σύνολό τους προβάλλουν ένα αποτέλεσμα και το καθένα ξεχωριστά είναι υπεύθυνο για μια η περισσότερες εργασίες. Πχ η οθόνη είναι υπεύθυνη για την προβολή και την αλληλεπίδραση με το χρήστη. Ο σκληρός δίσκος για την αποθήκευση πληροφοριών, η μνήμη για τη προσωρινή κράτηση πληροφοριών και αποτελεσμάτων, το πληκτρολόγιο και το ποντίκι για την εισαγωγή και την κατάδειξη πληροφοριων κοκ.

Η καρδιά του υπολογιστή σας είναι ο επεξεργαστής (CPU = Central Processing Unit η ΚΜΕ = Κεντρική Μονάδα Επεξεργασίας). Η CPU είναι υπεύθυνη για την διαχείριση και επεξεργασία όλων των πληροφοριών του σύστήματος. Τα πάντα περνάνε απο εκείνη (εκτός από συγκεκριμένες προϋποθέσεις που δεν μας ενδιαφέρουν αυτή τη στιγμή). Πως είναι οι πληροφορίες αυτές?

10010101010101111000000111010111. Είναι ένας αριθμός. Ουσιαστικά είναι η μοναδική μορφή πληροφοριών που μπορεί να καταλάβει ο υπολογιστής σας. Στη πραγματικότητα είναι ο αριθμός 2.505.540.055 στο δεκαδικό σύστημα αριθμησης που ξέρουμε να μετράμε όλοι. Φυσικά δεν είναι το μοναδικό σύστημα αρίθμησης που υπάρχει. Συγκεκριμένα ο αριθμός 10010101010101111000000111010111 είναι το 2.505.540.055 στο δυαδικό σύστημα (βάση αριθμησης το 2) και το 955781D7 στο δεκαεξαδικό (βάση αρίθμησης το 16). Εύλογα θα ρωτήσει κανείς... Γιατί τόσες μορφές αρίθμησης? Σε τι ωφελούν όλα αυτά? Η απάντηση είναι πολύ απλή: Χώρος!! Ας πάρουμε ένα παράδειγμα: Κάθε αριθμός - γράμμα - σύμβολο εχει μήκος 1 byte (συνήθως, γιατί μπορεί να έχει και 2 ανάλογα κάποιες προϋποθέσεις. Εμείς υποθέτουμε οτι οι χαρακτήρες που εξετάζουμε έχουν μήκος 1 byte). Αυτό σημαίνει 1 byte = 8 bits. Το bit είναι η μικρότερη μονάδα πληροφορίας που μπορεί να οριστεί, να διαχειριστεί και να αποθηκευτεί από τον υπολογιστή σας. Δηλαδή το byte 255 (αριθμητικά) είναι 11111111 στο δυαδικό άρα FF στο δεκαεξαδικό. (απο δω και στο εξής: Δεκαεξαδικό = Hex, Δυαδικό = bin, Δεκαδικό = dec). Βάζοντάς τα κάτω έχουμε:

Dec Bin Hex
255 11111111 FF

Τί πιάνει περισσότερο χώρο και τί λιγότερο? To Hex, όπως βλέπουμε ... ;-) Ουσιαστικά αυτή είναι και η σκοπιμότητά του. Η αριθμητική σύμπτηξη. Λιγότερο μέγεθος, λιγότερη χρησιμοποιούμενη μνήμη.

Μνήμη,, τι εννοούμε μνήμη? Κατ'αρχήν ας πάρουμε τους εαυτούς μας. Όλοι μας έχουμε εμπειρίες που θυμόμαστε, παιδικά χρόνια, καλές στιγμές, κακές στιγμές. Πράγματα που θυμόμαστε πάντα και πράγματα που ξεχνάμε. Μιλάμε δηλαδή για το διαχωρισμό της ανθρώπινης μνήμης σε συνειδητό - ασυνείδητο. Έτσι και οι υπολογιστές χρησιμοποιούν μια λιγο διαφορετική μορφή αρχιτεκτονικής που ορίζουν τις ικανότητες να θυμάται και να αποθηκεύει. Βραχυπρόθεσμα και μακροπρόθεσμα. Ο διαχωρισμός τους είναι ως εξής:

ROM : Read Only Memory : Μνήμη μόνο για ανάγνωση. Περιέχει βοηθητικά προγράμματα ελέγχου των συσκευών του συστήματος, δίσκους, δισκέττες, CD-ROM, DVD κλπ. Συνήθως αρκετά μικρή μνήμη σε μέγεθος.
RAM : Random Access Memory: Μνήμη τυχαίας προσπέλασης. Αυτή θεωρείται ως η κύρια μνήμη οπου χρησιμοποιείται από τα προγράμματα του συστήματός σας για προσωρινή αποθήκευση δεδομένων. Μετά το πέρας της λειτουργίας του προγράμματος η μνήμη απελευθερώνεται για να αποδοθεί σε κάποιο άλλο πρόγραμμα.

Πως "παίζουμε" τώρα με όλα αυτά? Πως καθορίζουμε τη λογική των προγραμμάτων μας? Με ένα περιβάλλον ανάπτυξης (ένα άλλο πρόγραμμα δηλαδή) που σκοπό έχει να φτιάχνει προγράμματα μέσω συμβολικής "γλώσσας προγραμματισμού". Υπάρχουν πολλές στο εμπόριο, από μεγάλες εταιρείες. Άλλες τζαμπέ άλλες επί πληρωμή ... Πολύ γνωστές είναι η Microsoft Visual Basic .NET, C#, C++, Delphi, Cobol, Clipper, Java και άλλες πολλές μικρότερες και μεγαλύτερες από αυτές. Η επιλογή είναι θέμα του καθενός μας. Του τί θέλει να κάνει, πως να το κάνει, τα πλεονεκτήματα και τα μειονεκτήματα της κάθε γλώσσας κλπ. Υπάρχουν Projects που είναι φτιαγμένα και σε περισσότερες από μια γλώσσες συνδυαστικά. Κοινώς? Τα πάντα μπορούν να γίνουν με οποιοδήποτε τρόπο. Αρκεί να έχουμε φαντασία - όραμα - υπομονή - επιμονή και όρεξη για γράψιμο!!

Πως φαίνεται ένα πρόγραμμα? Ένα μέρος ενός προγράμματος φαίνεται παρακάτω:

procedure TfrmMain.btTestClick(Sender: TObject);
var
LocalArray : TByteDynArray;
Counter : Integer;
Res : AnsiString;
begin
SetLength(LocalArray, 1);
For Counter := $0 to $FF do
begin
LocalArray[Counter-1] := Counter;
SetLength(LocalArray, Length(LocalArray)+1);
end;
SetLength(LocalArray, Length(LocalArray)-1);
Res := '';

For Counter := $0 to $FF do Res := Res + AnsiChar(LocalArray[Counter]);
mmLog.Lines.Add( Res );
end;

Το τί κάνει αυτό το πραμα? Λίγη σημασία έχει ... Αυτό που έχει σημασία είναι οτι καταλαβαίνουμε τις λέξεις και μπορούμε να διαχωρίσουμε τη σύνταξη. Πχ. For <Μεταβλητή> := to do begin .... end; Η πρόταση αυτή είναι μια συγκεκριμένη σύνταξη που αναμένεται από το περιβάλλον ανάπτυξης. Ειδάλλως είναι λάθος, άρα δε τρέχει το πρόγραμμα! Αυτή η σύνταξη προέρχεται από τη γλώσσα Delphi. Ας δούμε μια άλλη γλώσσα, πχ C++:

int __Execute( const TStrings * Params, const TStrings * Vars,
const TStrings * TempVars, AnsiString * Response)
{
AnsiString datetime;
try
{
Query->SQL->Clear();
Query->SQL->Add("select getdate() 'datetime'");
Query->Open();
if(Query->Eof)
return 2;
datetime = Query->FieldByName("datetime")->AsString;

if(Params->Values["Append_Date"] == "Y")
Response->printf("%s, %s", Params->Values["Data"], datetime);
else
Response->printf("%s", Params->Values["Data"]);
}
__finally
{ Query->Close();

}
return 0;
}

Συγκεκριμένα προέρχεται από μια έκδοση της C++ που λέγεται Borland C++. Θα μπορούσα να συνεχίσω να παραθέτω τμήματα κώδικα από δεκάδες γλώσσες προγραμματισμού που υπάρχουν στο κόσμο της πληροφορικής. Το θεωρώ ανούσιο. Το να μάθει κανείς μια γλώσσα είναι το εύκολο της υπόθεσης. Το δύσκολο είναι να μπορέσει κανείς να απλουστεύσει το τρόπο σκέψης του τόσο ώστε να περιγράψει σε απλά βήματα τη λογική του τι θέλουμε ένα πρόγραμμα να κάνει περιγράφοντάς τη σκέψη μας κάνοντας χρήση της σύνταξης και των εντολών των γλωσσών προγραμματισμού.

Για να φτάσουμε όμως μέχρι εδώ, δηλαδή, την αποτύπωση της λογικής με απτές φράσεις και εντολές κατανοητές από τον άνθρωπο περάσαμε από τρικυμίες και μποφόρια, καινοτομίες και αποτυχίες. Οι υπολογιστές εξελίχθηκαν τεχνολογικά αλλά παρέμειναν τόσο ηλίθιοι όσο στα πρώτα χρόνια τους. Και εξηγούμαι: Δε καταλαβαίνουν τίποτα παραπάνω από τερααάστιες ακολουθίες από 0 και 1. Δηλαδή μεταφράσεις ψηφιακών σημάτων (όροι & κοιλάδες) σε 0 για κοιλάδες και 1 για όρη. (Τετραγωνισμένη μορφή της ημιτονοειδούς καμπύλης).Με αυτά ορίζονται τα κλεισίματα και τα ανοίγματα "διακοπτών" ωστε το 'α' να οριστεί σαν άλφα. Επειδή πλέον όλα γίνονται μέσω τρανζίστορς το άνοιγμα και το κλείσιμο των διακοπτών διαφέρει λιγάκι σε μορφή. Εσείς έχετε στο μυαλό σας οτι 1 = άνοιγμα διακόπτη, 0 = το κλείσιμό του.

Η βάση των πάντων? Μια γλώσσα που θεωρείται ως γλώσσα άμεσα κατανοητή από τον υπολογιστή,, η Assembly. Τα τσιπ των υπολογιστών, ο "επεξεργαστής" ως λεγόμενος, διαθέτει μια σειρά από εσωτερικές εντολές. Αυτές προδιαθέτουν και τις "χαμηλού επιπέδου" εντολές. Πως ορίζεται η Assembly? Δείτε,, κι αμα καταλάβετε σφυρίχτε μου κλέφτικα!!

.MODEL SMALL
.STACK 100h
.DATA
HelloWorldStr DB "Hello World$", 0Dh, 0Ah
.CODE
pusha ;Αποθήκευση καταχωρητών κατά την είσοδο (AX,BX,CX,DX,SI,BP)
mov dx, offset HelloWorldStr ;Φόρτωση μηνύματος
mov ah, 09h ;Εξυπηρέτηση 09h για εμφάνιση μηνύματος στην οθόνη
Int 21h ;Εμφάνιση
popa ;Επαναφορά καταχωρητών πριν την έξοδο
mov ah, 4Ch ;Εξυπηρέτηση 4Ch για έξοδο από το πρόγραμμα
Int 21h ;Εκτέλεση εξόδου

Καλούλιιι??! Αναμφισβήτητα! Το θέμα είναι οτι αν μέχρι σήμερα,, γράφαμε έτσι θα βρισκόμασταν ακόμα στο 1985,, τεχνολογικά πάντα. Άσε που κώδικα θα έγραφαν το 1/100 των ήδη υπάρχοντων προγραμματιστών στο πλανήτη. Χάλια ... Στη προκειμένη περίπτωση το συγκεκριμένο προγραμματάκι εμφανίζει στην οθόνη απλώς ένα μήνυμα: "Hello World".

Για να γίνει κανείς προγραμματιστής,,, δε χρειάζεται πολλά πράγματα. Διάβασμα, ενασχόληση, μεράκι και σκληρή δουλειά. Ότι δηλαδή θα χρειαζόταν σε οτιδήποτε άλλο με το οποίο θα θέλαμε να καταπιαστούμε. Το κακό είναι οτι η τεχνολογία προχωράει,, και μαζί πρέπει να προχωράμε και όλοι εμείς που δραστηριοποιούμαστε σε αυτό το τομέα. Κατα τα άλλα,, τα Bachelors, Masters και λοιπά κωλό-χαρτα δεν κάνουν το προγραμματιστή. Αλλά η σκληρή δουλειά και η αγάπη για το αντικείμενο. Στα χρόνια που έχω μέσα σε αυτό το αντικείμενο, είδα καλούς επαγγελματίες χωρίς ουτε κάν χαρτί πανεπιστημιακού επιπέδου, (ΙΙΕΚ δηλαδή), να βάζουν κάτω Πολυτεχνειάδες με πουλάδες και αστέρια που φυσικά κώδικα γράψανε μόνο στη σχολή και την είδανε Bill Gates μέσα σε μια νύχτα αφού πήραν το πτυχίο τους. Όπως φυσικά και πραγματικούς επαγγελματίες και επιστήμονες να ξαναεφεύρουν το τροχό επειδή και μόνο ο τροχός που υπήρχε στο εμπόριο δεν τους άρεσε! Με ένα laptop και λίγο καφέ, δηλαδή, να φτιάχνουν τεχνολογικά διαμάντια!!

Πως αποθηκεύονται οι πληροφορίες? Σε αρχεία, καταλόγους, μέσα σε άλλους καταλόγους και πάει λέγοντας!! Η έννοια της πληροφορίες μέσα στα αρχεία διαχωρίζεται σε κείμενο (text) και δυαδικά δεδομένα (binary data). Τα αρχεία κειμένου συνήθως περιέχουν δεδομένα που μπορούν να διαβαστούν από τον άνθρωπο άμεσα. Τα δυαδικά αρχεία περιέχουν, συνήθως, μεγάλες σειρές από περίεργα σύμβολα, που φυσικά νόημα δε βγαίνει με τίποτα!! Κι όμως!! ;-)

Ας πάρουμε 2 περιπτώσεις. Ας υποθέσουμε οτι θέλουμε να φτιάξουμε ένα πρόγραμμα που να διαβάζει ένα αρχείο κειμένου που ονομάζεται TestImport.txt και να το εμφανίζει στην οθόνη. Κάθε γραμμή περιέχει συγκεκριμένα στοιχειά: Πχ

000001$ΘΕΟΔΩΡΟΣ ΚΟΛΟΚΟΤΡΩΝΗΣ$210 9999999$ΤΡΟΠΟΛΙΤΣΑΣ 44-100$ΚΑΤΩΧΩΡΙ

Διακρίνουμε 5 πεδία με διάφορες πληροφορίες που διαχωρίζονται με το χαρακτήρα '$'. Πάμε να το σπάσουμε και να εμφανίσουμε τα δεδομένα σε μια οθόνη:

Procedure ReadLine();
var
InputFile : TextFile;
Line : String;
Broker : TStringList;
Counter : Integer;
begin
Assign(InputFile, 'c:\TestImport.txt'); //Προετοιμασία δείκτη αρχείου
Reset(InputFile); //Ανοιγμα αρχείου
Broker := TStringList.Create; //Δημιουργία λίστα σπασίματος πεδίων '$'
While Not Eof(InputFile) do //Για κάθε γραμμή μέχρι τέλος του αρχείου
begin
ReadLn(Line, InputFile); //Διάβασμα γραμμής αρχείου
Broker.Text := AnsiReplaceStr(Line, '$', #10); //Σπάσιμο πεδίων
For Counter := 0 to Broker.Count -1 do //Εμφάνιση στην οθόνη όλων των πεδίων
WriteLn(Broker[Counter]);
end;
CloseFile(InputFile); //Κλείσιμο αρχείου
End; //Τελος διαδικασίας

Το αποτέλεσμα φαίνεται παρακάτω όπως θα φαίνεται στην οθόνη:

000001
ΘΕΟΔΩΡΟΣ ΚΟΛΟΚΟΤΡΩΝΗΣ
210 9999999
ΤΡΟΠΟΛΙΤΣΑΣ 44-100
ΚΑΤΩΧΩΡΙ

Αυτού του τύπου τα αρχεία λέγονται CSV (Comma Separated Values). Οι τιμές δηλαδή χωρίζονται με comma ή κάποιον αντίστοιχο χαρακτήρα που έχει το ρόλο του νοητού διαχωρισμού των τιμών κάθε γραμμής του αρχείου. Υπάρχουν και τα λεγόμενα Fixed Width όπου το μέγεθος είναι δεδομένο για κάθε πεδίο και σταθερό ότι και να γίνει. Το αρχείο θα γινόταν ως εξής:

000001ΘΕΟΔΩΡΟΣ ΚΟΛΟΚΟΤΡΩΝΗΣ210 9999999ΤΡΟΠΟΛΙΤΣΑΣ 44-100ΚΑΤΩΧΩΡΙ

Για να το διαβάσουμε θα μας έδιναν προδιαγραφές ανάγνωσης. Δηλαδή ποιό πεδίο ξεκινά από ποιά θέση και για τι μέγεθος. πχ:

Πεδίο εκκίνηση μήκος
-----------------------------------------------------
Κωδικός 1 6
Ονοματεπώνυμο 7 21
Τηλέφωνο 22 11
Διεύθυνση 39 18
Περιοχή/Πόλη 57 8

Τροποποιώντας τον κώδικα λίγο παραπάνω, θα λάβουμε ακριβώς τα ίδια πράγματα.

Αντίστοιχα για τα αρχεία δυαδικών δεδομένων (binary files), συμβαίνει περίπου το ίδιο με μια μικρή διαφοροποίηση: Οτι έχουμε ήδη έτοιμη μια δομή που οριοθετεί την ανάγνωση και το γράψιμο της κάθε εγγραφής μέσα στο αρχείο. Και εξηγούμαι: Γνωρίζουμε από το πινακάκι πιο πάνω τα μεγέθη των δεδομένων προς διάβασμα. Πόσο μήκος σε χαρακτήρες έχει ο κωδικός, το ονοματεπώνυμο κλπ. Έτσι αποτυπώνουμε το πινακάκι αυτό σε μια μορφή "σφραγίδας" και παίζουμε επάνω της:

Type
RecordStruct = Record
Code : String[06];
FullName : String[21];
Phone : String[11];
Address : String[18];
Area : String[08];
End;

Ωραία πράματα!! Τί έχουμε εδώ? Μια χαρτογράφηση της εγγραφής με αυτά τα στοιχεία που γνωρίζουμε οτι περιέχονται ανα εγγραφή. Δηλαδή σε κάθε γραμμή του αρχείου. Αυτό βοηθάει τα πράγματα αρκετά. Γιατί? Γιατί δεν είμαστε υποχρεωμένοι να υπολογίσουμε το μήκος διαβάσματος από κάθε νοητή γραμμή του αρχείου (γιατί ουσιαστικά δεν υπάρχει πλέον γραμμή μιας και είναι δυαδικά δεδομένα). Πάμε να τα τσιμπήσουμε:

Type
RecordStruct = Record
Code : String[06];
FullName : String[21];
Phone : String[11];
Address : String[18];
Area : String[08];
End;

Procedure ReadBinaryData()
var
RecordItem : RecordStruct;
DataFile : File Of RecordStruct;
begin
AssignFile(DataFile, 'c:\TestImport.dat');
Reset(DataFile);
.
.
.
CloseFile(DataFile);
end;

Διαβάσαμε δηλαδή τα περιεχόμενα του αρχείου ως αυτά έχουν αποθηκευτεί στο αρχείο με βάση το αποτύπωμα που ορίσαμε RecordStruct = Record ...

Ωραία όλα αυτά,, και μπράβο τους που υπάρχουν. Αλλά σε τί ωφελούν τόσοι διαχωρισμοί? Γιατί μπλέξαμε τα αρχεία κειμένου και τα δυαδικά αρχεία σε ένα αχταρμά? Η εξήγηση είναι απλή: Υπο κανονικές συνθήκες ένα αρχείο πρέπει να περιέχει μόνο μίας μορφής δεδομένα. Δηλαδή κείμενο, ή αριθμούς έτσι ώστε τα πράγματα που διαβάζονται να διαβάζονται με συγκεκριμένη τυποποίηση. Αργότερα φυσικά, αυτό άλλαξε αλλά κρατήθηκε η προς τα πίσω συμβατότητα. Έτσι πλέον στα δυαδικά αρχεία και με την τυπολογία που ορίσαμε στο τελευταίο παράδειγμα μπορούμε να μπλέξουμε τα πράγματα και να έχουμε αριθμούς και κείμενο και αριθμούς κινητής υποδιαστολής και λοιπά.

Μιας και μιλάμε για κείμενα, αριθμούς και τέτοια,, ας δουμε τί εννοούμε κείμενο και αριθμοί.. Κείμενο είναι το κείμενο που ξέρουμε όλοι. Αποτελείται από γράμματα της αλφαβήτου, σημεία στίξης, αριθμούς υπο μορφή κειμένου κλπ. Συνήθως μια τέτοια γραμμή κειμένου ονομάζεται "συμβολοσειρά" ή "αλφαριθμητική τιμή" δηλαδή τιμή που αποτελείται από γράμματα και αριθμούς. Διαχωρίζω τους αριθμούς σε αριθμούς και αριθμούς κειμένου γιατί υπάρχει σοβαρός λόγος!! Αν πάρουμε τον αριθμό 65 πχ. σε μορφή κειμένου τότε έχουμε 2 χαρακτήρες: το 6 και το 5. Αν πάρουμε όμως την αριθμητική τιμή του 65 και προσπαθήσουμε να δείξουμε το χαρακτήρα 65 από τον πίνακα χαρακτήρων που κρατείται εσωτερικά στον υπολογιστή σας θα δούμε οτι είναι το γράμμα 'Α'. Τί σημαίνει αυτό? Το σύστημα αναγνωρίζει τους χαρακτήρες που γράφονται σε ένα αρχείο με βάση την κωδική τους αντιστοιχία. Δηλ 'Α' = 65, 'Β' = 66, 'C' = 67 κοκ. Αυτός ο πίνακας ονομάζεται πίνακας ASCII (προφέρεται 'άσκι'). Επειδή τώρα οι τιμές είτε αλφαριθμητικές, είτε αμειγώς αριθμητικές κρατούνται σε προσωρινές θέσης μνήμης πρέπει ο υπολογιστής σας να γνωρίζει τί τιμές θα κρατηθούν ώστε να δεσμεύσει το κατάλληλο μέγεθος μνήμης σε bytes προκειμένου να κρατηθεί η εκάστοτε τιμή. Πχ ας δούμε το παρακάτω παραδειγματάκι σε C++:

#include
#include

int main(void)
{
signed int iNumber = 12345;
char* AlphaNumericValue = "Hello World!";

return 0;
}

Το προγραμματάκι δε κάνει τίποτα περισσότερο παρά να ορίζει μεταβλητές (θέσεις μνήμης προσωρινής αποθήκευσης) για να κρατήσει τον αριθμό 12345 και τη φράση "Hello World!". Προσέξτε τη δήλωση "signed int". Η "signed int" ορίζει μια μεταβλητή τύπου integer (ακέραιου αριθμού) o οποίος πρέπει να είναι >= 0 και <= 65535. Δηλαδή αν προσπαθήσουμε να την εξισώσουμε με 70123 το πρόγραμμα θα βγάλει σφάλμα. Γιατί? Πολύ απλά: Για να κρατήσουμε έναν αριθμό τύπου signed int πρέπει να χρησιμοποιήσουμε 2 bytes. Αρα ξέρει με τη δήλωση αυτη ο υπολογιστής οτι θα πρέπει να δεσμεύσει 2 bytes στη μνήμη για να αποτυπώσει τον αριθμό 12345. Δηλαδή θα γίνει 30 & 39 hex. Το 70123 όμως στο hex γίνεται 1 11ΕΒ hex. 1 byte δηλαδή παραπάνω απ'ότι μπορούμε να κρατήσουμε. Οπότε αντί να κάνουμε χρήση 2bytes πάμε να χρησιμοποιήσουμε 3bytes. Κάτι που φυσικά θα μπορούσε να είναι καταστροφικό αν δεν μας πληροφορούσε η C++ οτι ο τύπος της μεταβλητής είναι εσφαλμένος.

Πάμε τώρα να δούμε το δεύτερο τύπο char* να δούμε κάτι καλό!! Το "char" βγαίνει από τα 4 αρχικά γράμματα της λέξης "character" που σημαίνει χαρακτήρας. Όλα καλά μέχρι εδώ!! Έλα μου όμως που η C++ ξέρει μόνο αυτό!! Δηλαδή δε γνωρίζει τι σημαίνει φράση ή πρόταση ή αλφαριθμητικό?! Το οτι βέβαια δε το ξέρει, υπάρχει λόγος που γίνεται. Ο αστερίσκος δίπλα στο char,, char* λέει στη C++ ότι πρόκειται να κρατηθεί μεταβλητό μήκος χαρακτήρων ξεκινώντας από τη θέση στη μνήμη που υπάρχει ο πρώτος χαρακτήρας. Λίγο τρελούτσικο,, αλλά θα το ξεδιαλύνουμε .. Ας πάρουμε το "Hello World!". Με βάση τα όσα είπαμε, για το char η AlphaNumericValue θα πρέπει να ξέρει μόνο το "H". Και σωστά. ΌΜΩΣ! Το αστεράκι "*" μετατρέπει το AlphaNumericValue σε ένα δείκτη σε πίνακα χαρακτήρων που οριοθετείται από το χαρακτήρα 0.?! Προκειμένου δηλαδή να γνωρίζει η C++ οτι τελειώνει μια αλφαριθμητική τιμή προσθέτει στο τέλος κάθε αλφαριθμητικής τιμής το χαρακτήρα \0. Οπότε το παραπάνω στη μνήμη γίνεται:

char* AlphaNumericValue = ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0']

Το παραπάνω ορίζεται ως δείκτης σε πίνακα χαρακτήρων (pointer to character array) η (pointer to characters). Γιατί διάλεξα αυτό το τρόπο να σας δείξω τις αλφαριθμητικές τιμές? Τη C++ δηλαδή? Γιατί μπορεί να μη φαίνεται στις περισσότερες γλώσσες αλλά μέσες άκρες τα πράγματα είναι ακριβώς ίδια σε όλους. Ο τύπος δεδομένων "String" που χρησιμοποιείται σε άλλες γλώσσες και στη C++ κατ'επέκταση δουλεύει με τον ίδιο τρόπο για όλα. Γνωρίζει δηλαδή πίνακα χαρακτήρων. Τίποτα άλλο. Γι'αυτό όταν ρωτάστε: Πόσο πρόκειται να φτάσει το μέγεθος του επωνύμου, πχ αναμένεται να απαντήσετε με ένα λογικό μέγεθος του μεγαλύτερου επωνύμου που μπορείτε να σκεφτείτε. 20 - 30 ή ακόμα και 50 χαρακτήρες για τα σύνθετα επώνυμα πχ.

Πάμε να χαλαρώσουμε λιγάκι .. πολλές οι πληροφορίες και πως να τις διαχειρισούμε!! Ας δούμε λίγες πράξεις με αριθμους ... Έστω έχουμε τις μεταβλητές iInt τύπου integer, fFloat τύπου double, sText τύπου String (ίδιο με char*). Τότε ισχύουν τα εξής:

#include
#include

int main(void)
{
int iInt = 0; // ---> δήλωση μεταβλητής & αρχικοποίηση με 0.

iInt = 5 + 3; // ---> iInt = 8
iInt = iInt - 3 // ---> iInt = 5
iInt = (5+3)-2+1 // ---> iInt = 7

double fFLoat = 0.0; // ---> δήλωση μεταβλητής & αρχικοποίηση με 0.0.
fFloat = 0.123; // ---> fFloat = 0.123;
fFloat *= 15; // ---> Πολ/σμός και ανάθεση τιμής στον fFloat. Ισοδύναμα: fFloat = 0.123 * 15 => 1.845

String sText = "Hello World!"; // ---> sText = "Hello World!"
sText += " of Greece!"; // ---> πρόσθεση και άλλου κειμένου sText = "Hello World! of Greece!"

return 0;
}

Ουσιαστικά αυτό που κάναμε είναι αριθμητικές πράξεις και ανάθεση των τιμών σε μεταβλητές ιδίου τύπου. Εδώ λοιπον έχουμε ένα θεματάκι: Κάναμε χρήση ενός ακέραιου αριθμού (4 bytes μέγεθος) και ενός αριθμού κινητής υποδιαστολής double (8 bytes μέγεθος). Αφού τα αποτελέσματα και των δύο τύπων πράξεων, (ακέραιοι & κινητής υποδιαστολής) είναι μικρότερα από τα μέγιστα όρια αντοχής των τύπων γιατί δε διαλέξαμε να κάνουμε τις πράξεις μόνο στη πρώτη μεταβλητή? Η απάντηση επίσης είναι απλή! Ο ορισμός υποδιαστολής δεν είναι ανεκτή από τους ακέραιους. Όπως και στα μαθηματικά. Με λίγα λόγια μπορεί να γίνει ακέραιος και κινητής υποδιαστολής υπολογισμός σε double μεταβλητή αυτό δεν ισχύει και για ακέραια μεταβλητή. Και ερχόμαστε στο επομενο ερώτημα: Γιατί τότε δε χρησιμοποιούμε μόνο μεταβλητές τύπου double να τελειώνουμε? Γιατί πολύ απλά όπως αναφέραμε πιο πάνω το μήκος σε bytes του double είναι 8. Άρα 2, 3 ή περισσότερες μεταβλητές αν δηλωθούν προς χρήση αυτόματα ανεβαίνει η μνήμη που δεσμεύεται κατά 8 * (1, 2, 3 .... ν) bytes, ανεξάρτητα από το τις τιμές που κρατάμε σε αυτες τις δεσμευμένες περιοχές μνήμης. Σκοπός είναι η χρήση της μνήμης που πραγματικά χρειαζόμαστε μιας και η μνήμη του υπολογιστή δεν είναι ανεξάντλητη, όπως επίσης τα προγράμματά μας δεσμεύουν μνήμη σε ένα σύστημα κατά την εκτέλεσή τους, το ίδιο γίνεται και με 10δες άλλα που τρέχουν την ίδια ακριβώς στιγμή στο ίδιο σύστημα. Άρα η μνήμη επιβαρύνεται με αρκετά πράγματα που ουσιαστικά δεν χρειάζονται.

Ωραία ολα αυτά .. λίγο πολύπλοκα αλλά ίσως είναι η μοναδική πολυπλοκότητα που αξίζει να υπάρχει. Γιατί προφανώς,, δε γίνεται αλλιώς. Το να φτιάξουμε ένα προγραμματάκι που να κάνει 5 πράγματάκια για προσωπική μας χρήση, δεν είναι δύσκολη υπόθεση. Τί γίνεται όμως όταν μπαίνουμε στα άδυτα των εταιρειών και τον οργανισμών που παράγουν προγράμματα για τους χρήστες της αγοράς? Η φάση της ανάπτυξης ή αλλιώς του γραψίματος του κώδικα του προγράμματος, θεωρείται οτι είναι η λιγότερη δουλειά απο όλες τις άλλες που πρέπει να γίνουν:

1. Ανάλυση
Η φάση της ανάλυσης προϋποθέτει τη συγκέντρωση των πληροφοριών που χρειαζόμαστε έτσι ώστε να γνωρίζουμε επ'ακριβώς τι είναι αυτό που θέλουμε να φτιάξουμε. Τί πρέπει να κάνει, πως να το κάνει, που να το κάνει και για ποιόν. Εμπλουτίζουμε δηλαδή το βασικό μοντέλο Input - Processing - Output όπως σχηματικά κάτω:

|------------|
INPUT ----------->| PROCESSING |-----------> OUTPUT
|------------|

Ορίζουμε δηλαδή, τί είναι το input και τι περιλαμβάνει, τι είναι το OUTPUT και τί περιλαμβάνει και τέλος τι είναι το OUTPUT και φυσικά τί περιλαμβάνει και αυτό απο τη πλευρά του.

Εφόσων έχουμε καταγράψει λεπτομερώς και έχουμε περιγράψει τις συνθήκες λειτουργίας του προγράμματος μαζί με τις διαδικασίες και έχουμε ήδη δημιουργήσει όλες εικόνες που χρειαζόμαστε, περνάμε στη φάση του σχεδιασμού.

2. Σχεδιασμός
Η φάση του σχεδιασμού προϋποθέτει την συγκέντρωση του team που θα λάβει μέρος στην ανάπτυξη του προγράμματος. Αναλυτές για την επεξήγηση των πληροφοριών που έχουν συγκεντρώσει από τη φάση της ανάλυσης, τους προγραμματιστές που θα αναλάβουν την συγγραφή και την ανάπτυξη της εφαρμογής, τεχνικούς για τυγχόν επιπρόσθετο εξοπλισμό που μπορεί να χρειαστεί κατά τη φάση της ανάπτυξης ή του testing κλπ. Η κατάληξη, μετά από διαβουλεύσεις, ιδέες που πέφτουν στο τραπέζι και λοιπά είναι η σχηματική αποτύπωση της ροής των πληροφοριών. Αυτό το σχεδιάγραμμα ονομάζεται FLOW CHART και αποτυπώνει σχηματικά μεν, λεπτομερώς δε, τη "ροή της πληροφορίας". Επίσης αποφασίζονται τα εργαλεία που θα χρησιμοποιηθούν, (γλώσσες προγραμματισμού, βιβλιοθήκες, μηχανήματα κλπ).

3. Ανάπτυξη
Η φάση της ανάπτυξης είναι η φάση στην οποία η ομάδα των προγραμματιστών ξεκινάει την συγγραφή του κώδικα που απαρτίζει το πρόγραμμα που περιέγραψαν οι αναλυτές στη φάση της Ανάλυσης και του Σχεδιασμού. Πλέον είναι ξεκάθαρος ο στόχος, η εικόνα της εφαρμογής, καθώς και ο τρόπος που θα φτάσουμε στην επίτευξη του στόχου μας. Δηλαδή την ολοκλήρωση μιας εφαρμογής που κάνει ακριβώς ότι περιγράφεται από τα σχέδια της εταιρείας.

4. Testing
Πρίν την ολοκλήρωση της ανάπτυξης, μια ομάδα ατόμων, ανεξάρτητη από την ομάδα ανάπτυξης, αναλαμβάνει να περάσει την εφαρμογή από "κόσκινο"!! Δηλαδή να βρει πιθανά λάθη που μπορεί να κάνει η εφαρμογή βάσει των προδιαγραφών που έχουν στα χέρια τους. Μηνύματα λάθους που δεν είναι σωστά, αποτελέσματα που επίσης μπορεί να μην είναι σωστά, και λάθος υπολογισμοί κλπ. Όλα αυτά καταγράφονται και δίνονται πίσω στο τμήμα ανάπτυξης για διόρθωση των επίμαχων σημείων της εφαρμογής. Συνήθως αυτό το στάδιο διαρκεί αρκετά μιας και οι συνδιασμοί και ο σχολαστικός έλεγχος είναι επίπονη διαδικασία για ανθρώπους και συστήματα.

5. Πιλοτική εκτέλεση
Μετά το testing, η εφαρμογή μπαίνει σε πιλοτική εκτέλεση. Δηλαδή εγκαθίσταται από το τεχνικό προσωπικό (προγραμματιστές, αναλυτές, τεχνικούς) σε ένα περιβάλλον παρόμοιο με αυτό που θα εκτελείται μόλις βγεί στην αγορά. Αυτό γίνεται για να ελεγθεί σε πραγματικές συνθήκες και οι πιθανες αρνητικές αντιδράσεις της εφαρμογής που δεν έχουν αναγνωριστεί κατά τη φάση του testing. Συνήθως η πιλοτική φάση, διαρκεί από εβδομάδα μέχρι και αρκετούς μήνες ανάλογα με το μέγεθος της εφαρμογής και της σπουδαιότητας των διαχειριζόμενων πληροφοριών. Τυγχόν σφάλματα που βρίσκονται, αναγνωρίζονται και είτε διορθώνονται επι τόπου ή αναθέτεται στο team ανάπτυξης να διορθώσουν το πρόβλημα.

6. Live
Τελειώνοντας το κύκλο ανάπτυξης, επέρχεται η φυσική κατάληξη της εφαρμογής. Η εγκατάσταση στο πελάτη ή το λανσάρισμα στην αγορά. Σε αυτή τη φάση έχουμε το πέρας των εργασιών και της πώλησης πλέον ως ένα ολοκληρωμένο προϊόν στην αγορά! Ο στόχος μας δηλαδή έχει επιτευχθεί. Έχουμε φτάσει να κάνουμε πραγματικότητα μια ιδέα γραμμένη στο χαρτί, πράξη βλεποντάς το να εκτελείται μέσα σε έναν υπολογιστή μας!! Φανταστικό συναίσθημα! Πιστέψτε με! Το νιώθεις παιδί σου ... :-)

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου