<- PW: Intro - Indice Generale - Copertina - PW: AVI -> |
PlutoWare
di Rudi Giacomini Pilon, con Diego Fernando Parruccia
L'articolo...Una breve introduzione al C e al C++, per chi non ha ancora avuto modo di apprezzare questi linguaggi... |
[ Quando ho iniziato a scrivere questo articolo, raccogliendo l'invito di Germano Rizzo, avevo molti dubbi; soprattutto sulla necessità, e l'opportunità, di scrivere l'ennesimo articolo sul C e C++. Una volta dissipati tali dubbi mi sono reso conto che creare un qualcosa per persone a digiuno dell' argomento era impresa più difficile di quanto avevo previsto. Soprattutto per la tendenza, propria di qualsiasi programmatore, a dare molte cose per scontate. Ho quindi deciso di chiedere l'aiuto di un caro amico: l'ing. Diego Parruccia, programmatore professionista e profondo conoscitore di C e C++. Ciò che leggerete ha superato la sua revisione e spero sia per voi una lettura utile e/o gradevole... ]
Il C è un linguaggio di programmazione sviluppato da Dennis Ritchie,
ai Bell Labs, a metà anni 70. Venne chiamato C
in quanto era un evoluzione del linguaggio B che, a sua volta,
derivava dal BCPL. Data la sua diffusione, il linguaggio
è stato sottoposto ad un processo di standardizzazione
che ha condotto all'approvazione dello standard da parte dell' ANSI
nel 1989 (ANSI: X3.159-1989 / ISO: JTC1 SC22 WG14 e successive
revisioni).
Il C, originariamente, era stato progettato come linguaggio di
sistema e tale natura è ancora presente in molte delle sue
capacità. Esso C viene definito un linguaggio di
programmazione ad alto livello ma è, per sua origine,
più vicino al codice assembly, e quindi al linguaggio
macchina, di qualsiasi altro linguaggio ad alto livello. Ad oggi,
probabilmente, il più grosso programma scritto in C
è stato il sistema operativo UNIX e per molti anni il C
è stato così strettamente legato a UNIX che le
persone accomunavano i due termini.
Il nucleo del C è costituito da un insieme
relativamente limitato di istruzioni: non comprende ad esempio
funzioni per l'accesso alla memoria, per l'input/output o per il
trattamento delle stringhe.
Tali funzioni aggiuntive sono fornite dalle librerie, ed in
particolare dalle librerie standard del C. Per poter usufruire di
tali librerie (e quindi di tali funzioni) è necessario
"includerle" nel programma principale. Un vantaggio di
tale organizzazione è la possibilità di includere
solo le librerie che servono ottenendo programmi molto più
snelli e leggibili. E' inoltre possibile sfruttare questo metodo
di lavoro per creare le proprie librerie personalizzate e
sostituire o integrare quelle standard.
Le funzioni vengono "dichiarate" o "definite" attraverso dei
file detti header (letteralmente intestazione), che
hanno estensione .h, dai quali vengono richiamati i file
contenenti il "corpo" delle funzioni vere e proprie.
Gli header vengono poi inclusi nel programma principale tramite
un'apposita istruzione (#include) che esamineremo in
seguito.
Un programma non banale è quindi formato da più file, con estensioni .c e .h, connessi tra loro da apposite chiamate. La sua struttura generica è la seguente:
A questo punto, prima di addentrarci ulteriormente nei meandri del C, è opportuno almeno un esempio di base.
Premetto che l'esempio che segue non brilla per
originalità, ma serve in ogni caso a rendere un po' meno
astratte alcune spiegazioni.
Con un editor di testo scrivete quanto segue in un file e
salvatelo con il nome miofile.c
|
Vi faccio notare i commenti, che vengono racchiusi fra due
coppie di simboli ( /* e */ ), e l'istruzione
#include
che carica l'header della libreria
stdio.h (ovvero la libreria standard con le funzioni di I/O).
Tale libreria è stata inclusa in quanto per stampare il
messaggio abbiamo utilizzato la funzione printf() che
è, appunto, compresa all'interno della libreria stdio.h.
Tale istruzione non è un comando C ma una direttiva al
preprocessore che indica di caricare il file aggiuntivo. In
generale, all'interno dell' header, vi saranno le dichiarazioni
delle funzioni della libreria e/o l'istruzione di caricamento di
ulteriori file componenti la libreria.
Dopo quest' ulteriore digressione passiamo alla compilazione del programma. Dando per scontato che il compilatore sia lo GNU C Compiler (gcc), certamente IL compilatore free per eccellenza, scrivete la riga seguente al prompt dei comandi (la seconda riga mostra l'output del compilatore):
$ gcc -Wall -o mioC mioC.c |
notate l'opzione -o con la quale assegno un nome, di mia scelta, al file eseguibile che viene compilato. Il nome di default è a.out e personalmente preferisco specificare sempre il nome. Avendo attivato la funzione -Wall, inoltre, il compilatore segnalerà tutti i warning, cioè gli avvertimenti (sugli errori), pertanto la riga di output ci segnala che la funzione main non ritorna un valore intero, ma vuoto. Essendo questa una mia esplicita scelta, per dimostrare la funzionalità descritta, ignoriamo l'avviso e proviamo ad eseguire il programma.
$ ./mioC |
Orribile vero?
Andiamo comunque ad esaminare come funziona, a grandi linee, la
compilazione: finora ho dato per scontato che
tutti sapessero che il C è un linguaggio compilato, e che
tutti fossero a conoscenza della differenza tra un linguaggio
compilato ed uno interpretato. Innanzitutto un programma scritto
in un linguaggio interpretato, al momento dell'esecuzione, viene
letto da un interprete, ovvero un programma in grado di comprendere
le istruzioni del sorgente ed eseguirle. Un linguaggio compilato
viene, invece, trasformato dalla sua forma nativa ad una forma
direttamente eseguibile. Risulta ovvio che un linguaggio
compilato permette di ottenere programmi più veloci di un
equivalente codice interpretato in quanto, durante l'esecuzione,
viene saltato il processo di interpretazione . Le fasi della
compilazione sono le seguenti:
#include
)
Spenderò due parole per accennare alla differenza fra librerie statiche e
librerie dinamiche:
Le librerie statiche hanno la caratteristica di contenere
del codice che, al momento del link, viene incorporato nel file eseguibile che
viene generato. Il programma pertanto è completo in tutte le sue parti e
può venire eseguito su un qualsiasi sistema.
Le librerie dinamiche contengono del codice che non è incorporato nell'
eseguibile ma viene caricato dinamicamente nel momento in cui il programma lo
richiama. I pro sono che il codice in questione può venire condiviso da n
programmi eseguibili con una minore occupazione di memoria da parte del codice
della libreria (che in alternativa si ripeterebbe per ogni programma che lo usa).
Inoltre la scoperta di un bug nel programma o nella libreria richiede la
modifica della sola parte incriminata senza richiedere la modifica dell'altra.
L'altra faccia della medaglia è la necessità di avere a disposizione
anche la libreria oltre al programma per potere utilizzare quest'ultimo in un
nuovo sistema.
Su suggerimento del mio supervisore preferito vorrei spendere due righe sui vari tipi di file che vi trovate fra i piedi lavorando con il C:
A questo punto evito di ricreare l'ennesimo corso sul C e vi rimando alla sezione, dedicata a tale argomento, degli Appunti di informatica libera di Daniele Giacomini [ No, non siamo parenti :-) ]. Una lettura che ho trovato fondamentale in molte occasioni.
Riporto solamente una nota curiosa:
Sembra che, in assoluto, l'errore più frequente commesso
programmando in C sia dimenticare un segno di uguale
(=) all'interno delle operazioni di confronto. Vediamo un
esempio: l'istruzione
if (i==3)
esegue il confronto fra la variabile i ed il numero 3. Scrivendo
invece
if (i=3)
si assegna ad i il valore 3, ed il test risulta sempre vero. Per
evitare quest' errore, banale ma frequentissimo, i guru della
programmazione suggeriscono di utilizzare nei test la forma
seguente:
if (3==i)
anteponendo il valore costante alla variabile. Infatti se in tale
forma si omette un segno =, il compilatore genererà una segnalazione
di errore, in quanto stiamo tentando di assegnare ad un numero
costante una variabile.
Per ulteriori approfondimenti sul C vi rimando nuovamente ai riferimenti bibliografici [servono a questo :-) vero?] e sposto l'attenzione sul C++
Il C++ nasce all'inizio degli anni ottanta, anch'esso nei laboratori Bell, grazie all'opera del matematico Bjarne Stroustrup, che era stato incaricato di sviluppare un software per simulare il funzionamento di alcuni centralini di commutazione telefonica. L'applicazione richiedeva un linguaggio con alte prestazioni, ed il C era considerato il più adatto ma, dall'analisi, risultava la necessità di un approccio ad oggetti. Fu quindi creato un superset del linguaggio C chiamato inizialmente "C with classes", che soddisfaceva le necessità del caso.
Dal 1986 il linguaggio iniziò a diffondersi e ad essere utilizzato in maniera sempre maggiore anche al di fuori del gruppo di programmatori cui faceva capo Stroustrup. Il linguaggio C++ fu poi sottoposto al processo di standardizzazione del comitato ANSI (American National Standard Institute), a partire dal 1989, con il numero di protocollo X3J16, e divenne standard da settembre 1994.
Uno degli scopi principali del C++ era quello di mantenere piena compatibilità con il C. L'idea era quella di conservare l'integrità di molte librerie C e l'uso degli strumenti sviluppati per il C.
Il miglioramento più rilevante introdotto dal linguaggio C++ è il supporto della programmazione orientata agli oggetti (Object Oriented Programming, OOP). Tale metodo permette di ottenere un codice facile da mantenere e riutilizzare. Per sfruttare tutti i benefici introdotti dal C++ occorre quindi passare da una programmazione strutturata ad un approccio ad oggetti.
Tentiamo, quindi, di definire che cosa si intende per oggetto.
Innanzitutto non si deve cadere nell'equivoco che si possa
definire oggetto solo un qualcosa di solido. In programmazione
tale termine può definire tanto un qualcosa di tangibile
quanto un concetto. Per rendere le cose più
chiare potrei definire un oggetto come una variabile nella quale
vengono immagazzinati i dati. Rispetto ad altre variabili
l'oggetto ha la caratteristica di essere dotato di
proprietà e di interfacce.
La proprietà, detta anche attributo, rappresenta uno stato/valore che la
variabile può assumere.
L'interfaccia, detta anche metodo, è una funzione, che viene resa
disponibile al resto del programma, il cui scopo è di fornire un mezzo tramite
il quale manipolare il valore di una o più proprietà. Il rendere disponibile una
funzione viene detto "esportare" l'interfaccia.
Un esempio di oggetto (come presentato da Bruce Eckel:)
può essere la lampadina. Essa ha delle proprieta come il
suo stato (in un dato momento può essere accesa o spenta),
il colore, la tensione di funzionamento, ecc. Possiede anche
delle interfacce in quanto può venire accesa o spenta.
In un programma C++ l'oggetto è rappresentato dalla
classe, le proprietà dalle variabili private
della classe e le interfacce dalle funzioni pubbliche.
Tutto ciò verrà ulteriormente chiarito da quanto
verrà esposto di seguito.
La programmazione orientata agli oggetti (OOP) si basa su tre
concetti fondamentali: incapsulamento, ereditarietà e
polimorfismo.
L’incapsulamento è la capacita di raccogliere dati e
funzioni nelle classi per nascondere il funzionamento e
l'eleborazione, interna alla classe stessa, ed esportare solo un'
interfaccia che permetta la comunicazione con il resto
del programma.
L’ereditarietà è la capacità di
acquisire le strutture dati e funzioni di altre classi di oggetti
(classi base) in modo da riutilizzarli in nuovi classi di oggetti
(classi derivate).
Per ultima la capacità forse più importante, il
polimorfismo, che è la capacità di alcune funzioni
(chiamate virtuali) di svolgere a run-time funzioni diverse a
seconda della classe cui fanno riferimento. Per non appesantirlo
troppo, in questo articolo non approfondiremo questi concetti.
Potete comunque fare riferimento alla bibliografia per ulteriori
informazioni.
Pur non essendo un concetto tipico dei linguaggi dei linguaggi ad oggetti, vorrei accennare ad un’altra miglioria introdotta dal C++ nella programmazione: l’overloading degli operatori o delle funzioni. Questa tecnica di programmazione supportata dal C++ permette al programmatore di modificare o estendere gli operatori standard del linguaggio sostituendo la loro funzionalità nativa con una nuova implementazione. Nel caso delle funzioni è possibile definire più versioni della stessa funzione con nome uguale ma numero e/o tipo di parametri diverso. L’implementazione interna della funzione può anche differire notevolmente da una versione all’altra e la funzione corretta verrà scelta al volo in base ai parametri passati quando essa viene richiamata.
Cercherò di dare alcuni esempi di codice che illustrano i concetti finora riportati:
Tentiamo di realizzare qualcosa di più rispetto al
solito "Ciao mondo" (anche se il tema rimarrà lo
stesso).
Il programma che segue è scritto in C++ ma in forma
strutturata anziché ad oggetti. Produce due scritte sullo
schermo (in modalità testo). Chiaramente la
semplicità di quest'esempio non richiederebbe alcuna
implementazione ad oggetti, ma ci servirà per confrontare le
due forme di scrittura.
Con un editor di testo scrivete quanto segue in un file chiamato
primo.C
//primo.C -questo è un commento con il nome del programma //includiamo la libreria per l'IO #include <iostream> //iniziamo con il programma principale (si chiama sempre main) void main (int argc,char *argv) { char *soggetto; char *saluto; //un saluto dall'autore soggetto="L'autore dice"; saluto=" - Ciao mondo - "; cout << soggetto << saluto << endl; //un saluto dal pc soggetto="Il pc dice"; cout << soggetto << saluto << endl; } |
Come prima cosa, faccio notare che l'estensione del file
è .C (e non .c) in quanto tale estensione è quella
attribuita di default ai file C++ (a seconda del compilatore
altre estensioni valide sono .cc e .cpp). Vorrei poi mettere in
evidenza che ora i commenti sono delimitati da una doppia barra
// all'inizio della riga (anche se la forma di commento
del C è ancora utile per commentare blocchi di codice).
Inoltre l'output del programma non è più affidato
alla funzione printf() ma all'operatore di stream (flusso)
<<, che è incluso nella libreria iostream.h. A questo
punto compiliamo il programma. Dò per scontato che stiate usando
Linux con installato il compilatore g++, il tool di gcc per il c++, e
che vi siate già portati nella directory contenente il file sorgente.
$ ./g++ -g -o primo primo.C |
eseguite il programma digitando il nome:
$ ./primo |
il risultato sarà qualcosa di simile
L'autore dice - Ciao mondo - |
Ora trasformiamo il tutto in un programma ad oggetti cercando di introdurre alcune nozioni
In C++ gli oggetti vengono "realizzati" tramite le classi: una classe viene dichiarata tramite la parola chiave class seguita dal nome della classe scelto dal programmatore. Segue una coppia di parentesi graffe al cui interno vengono definite delle variabili che rappresentano le proprietà dell'oggetto e delle funzioni che rappresentano le interfacce dell'oggetto. Tali funzioni vengono dette anche "funzioni membro" quando sono definite internamente alla classe, mentre vengono chiamate "funzioni esterne" se esse sono definite, al di fuori della classe (pur venendo utilizzate al suo interno).
Ci sono alcune regole che sarebbe bene seguire:
Generalizzando di solito per una classe C++ si ha la seguente struttura:
Classe Area privata: variabili funzioni di servizio Area pubblica: metodi (funzioni pubbliche) overloading di operatori variabili pubbliche (ovvero variabili manipolabili direttamente dal resto del programma senza avere un accesso filtrato dall'interfaccia:meglio evitarle in quanto sono una cattiva abitudine di programmazione)vediamo quindi la re-implementazione del programma precedente:
//secondo.C -questo è un commento con il nome del programma //includiamo la libreria per l'IO #include <iostream> #include <string> //dichiariamo la classe saluto class saluto { private: char *soggetto; char *messaggio; //una funzione per inizializzare le stringhe void init_saluto(const char *sogg,const char *mess){ soggetto = new char [strlen(sogg)+1]; strcpy(soggetto,sogg); messaggio = new char [strlen(mess)+1]; strcpy(messaggio,mess); } public: //il costruttore della classe saluto(const char *sogg, const char *mess){ init_saluto (sogg,mess); } //il distruttore della classe ~saluto(){ delete (soggetto); delete (messaggio); } //la funzione pubblica di visualizzazione void visualizza () const { cout << soggetto << messaggio << endl; } }; //iniziamo con il programma principale (si chiama sempre main) void main (int argc,char *argv) { saluto sal1 ("L'autore dice"," - Ciao mondo - "); saluto sal2 ("Il PC dice" ," - Ciao mondo - "); sal1.visualizza(); sal2.visualizza(); } |
dopo la compilazione e l'esecuzione, naturalmente, il
risultato è identico a quello dell'esempio precedente. Il
primo programma contiene 10 righe di codice, esclusi i commenti,
il secondo 29 ovvero quasi tre volte tante.
Fra i vari motivi causa dell'aumento di dimensione vi sono le
funzioni costruttore e distruttore della classe: Il costruttore
è una funzione con lo stesso nome della classe, ed è
la prima funzione membro chiamata da un oggetto quando viene
creato in memoria. Può essere usata per inizializzare i
dati membro dell' oggetto stesso.
Il distruttore è l’ultima funzione membro chiamata
da un oggetto. Questa funzione viene chiamata prima della
rimozione del oggetto dalla memoria. Generalmente viene
utilizzata per liberare le risorse occupate dall' oggetto
(memoria, file, risorse di sistema, ecc.). Sostanzialmente
è una funzione con lo stesso nome della classe preceduto
da una tilde [~]. Nel esempio precedente possiamo vedere
l’uso del costruttore saluto(const char *sogg, const
char *mess) e del distruttore ~saluto().
Vi è un ovvia considerazione da fare: nei programmini
così piccoli l'overhead creato dallo scrivere codice a
oggetti sembrerebbe rendere pesante, se non addirittura
sconsigliabile, questo tipo di approccio.
Confutiamo subito tale affermazione partendo da un esempio pratico anche se banale: Il vostro cliente vi ha appena telefonato e annuncia che vuole invertire l'ordine delle scritte in uscita ovvero il risultato dovrà essere:
- Ciao mondo - L'autore dice
cout << soggetto << saluto << endl; |
cout << saluto << soggetto << endl; |
nel caso della programmazione ad oggetti tale modifica viene operata una volta sola, all'interno della funzione visualizza().
In realtà anche il primo esempio poteva essere scritto in maniera migliore, in modo da richiedere un unica modifica. Ho voluto banalizzare l'esempio per far comprendere come un codice ad oggetti può rivelarsi molto più facile da mantenere.
Di fronte a queste osservazioni, sembra che il C++ abbia solo connotazioni negative. In realtà queste premesse sono necessarie per avere un quadro globale della situazione. Sono dell'opinione, infatti, che non esista un linguaggio di programmazione migliore di altri, ed ognuno ha vantaggi e svantaggi che lo rendono più o meno utile a seconda del tipo di applicativo che si deve realizzare. Ad esempio, il C è insuperabile per la programmazione di basso livello come i Sistemi Operativi [sì, anche Linux :-) ] ed i device driver benché nulla vieti di utilizzarlo per sviluppare applicazioni più complesse come è dimostrato dal gran numero di applicazioni scritte in C all'interno di Linux.
Il C++ consente lo sviluppo di software su larga scala. Grazie a un maggiore rigore sul controllo dei tipi, molti degli effetti collaterali tipici del C (e molti errori) divengono impossibili in C++, e grazie agli oggetti il codice C++ è (se scritto bene) sufficientemente portatile e facile da mantenere da permettere lo sviluppo di grosse applicazioni.
Una delle principali "guerre di religione dei linguaggi" dei nostri giorni mette a confronto il C++ con Java. Pur non volendo prendere una posizione a favore dell'uno o dell'altro, cercherò di riportare alcune notizie fra quelle più diffuse:
Il C++ genera programmi estremamente veloci ed è da 10 a 20 volte più veloce di JAVA non solo quando Java viene interpretato, ma anche quando Java viene compilato da un JIT (just in time compiler).Il C++ è un sovrainsieme del C, quindi mantiene anche le caratteristiche peggiori del C. Prima fra tutte l'allocazione di memoria manuale che oltre a essere noiosa da gestire è una delle principali fonti di errori. In questo senso Java è imbattibile, a meno di non avere sottomano delle ottime librerie di gestione della memoria (vedere in merito quanto esposto nel C++ Programming How-To di Alavoor Vasudevan).
Se ciò di cui si necessita è invece un linguaggio di scripting allora si può puntare sul PHP che ha il vantaggio di avere una sintassi molto simile a quella del C++.
Quello che segue è poco più di un elenco di una serie di
strumenti che utilizzo per il mio lavoro (o comunque ho trovato degni di nota).
Ognuno di Voi mi perdoni, se non ho citato il suo editor o compilatore
preferito, ma ho preferito descrivere solo strumenti che ho
provato almeno una volta...
Come avevo già sottolineato esistono numerose librerie che risolvono i limiti di quelle standard del C e del C++. Alcune di queste sono corredate di ambienti di sviluppo più o meno integrati. Accenno di seguito alle più usate:
Iniziando dalla mia preferita: FLTK (si pronuncia "fulltick")
è un toolkit (ovvero un insieme composto da ambiente
grafico di sviluppo, libreria ed editor) per il C++ multi
piattaforma. Ad oggi lavora con X (praticamente tutti gli UNIX),
MacOS, e MS Windows. Supporta la grafica 3D tramite le librerie
OpenGL.
Lo considero veramente portabile come ambiente di sviluppo, anche
se va integrato con un editor aggiuntivo in quanto quello in
dotazione è ancora scarno. Il suo vantaggio principale
è quello di portare a generare eseguibili di dimensioni
ridotte e alta velocità.
Un'altra libreria da me molto usata in passato e che ora ho abbandonato è la XForms un toolkit basato sulla xlib (e quindi su X-window) con un editor di interfaccia in grado di generare il relativo codice C. Soffre del problema della scarsa portabilità ma il codice generato è molto snello.
La libreria GTK+ è un
toolkit multi piattaforma orientato allo sviluppo in C anche se
esistono le implementazioni delle interfacce per il suo utilizzo
tramite C++.
Inizialmente era solo la libreria tramite la quale è stato
sviluppato il noto software di grafica Gimp poi è stata
adottata per lo sviluppo del Window Manager Gnome e si è
estesa alle altre applicazioni Gnome. Fra le varie applicazioni
vi è anche un editor per l'interfaccia grafica Glade che semplifica notevolmente
il lavoro di costruzione della stessa producendo il codice C
relativo.
Per quanto riguarda tale libreria Vi posso consigliare l'ottimo tutorial di
Nicola Fragale apparso nei numeri
34,
35 e
36
del Pluto Journal.
La libreria Qt è
una libreria, orientata al C++, multi piattaforma, che supporta
MS/Windows, Unix/X11 (Linux, Sun Solaris, HP-UX, Digital Unix,
IBM AIX, SGI IRIX e altre varianti di Unix), Macintosh (compreso
Mac OS X) e piattaforme Embedded. Tale libreria è diffusa
in quanto è alla base dello sviluppo del window manager KDE che oggi assieme a Gnome è uno
dei Wm preferiti degli utenti Linux.
La libreria è accompagnata da un IDE (Integrated
Development Enviroment) per UNIX, KDevelop, che possiede delle buone
caratteristiche e che, come il resto dell'ambiente, ha rilasci
frequentissimi con notevoli migliorie.
La Qt non gode, comunque, di buona fama presso la Open Community
in quanto inizialmente era stata rilasciata con una licenza
non libera, e quindi era considerata "sporca".
Xwpe è un editor per UNIX con una interfaccia compatibile con quella dei vecchi editor del Borland C e Borland Pascal per DOS. Da xwpe potete editare il programma, avviare la compilazione e il debug dei programmi. L'estetica è sicuramente un po' datata, anche perché lo sviluppo del programma aveva subito una battuta d'arresto, ma le varie funzionalità di cui è dotato lo rendono insuperabile (a mio parere chiaramente).
Chiamare editor Emacs è estremamente riduttivo. Questo programma scritto da R. Stallman è un ambiente di lavoro in cui si può fare di tutto, da leggere la posta a compilare un programma. Nella sua home page viene definito come editor realtime estensibile, personalizzabile e autodocumentante. Troverete centinaia (se non migliaia) di utilizzatori di Emacs pronti a giurare che è il miglior editor per qualsiasi linguaggio di programmazione.
Se, invece, avete la necessità di usare lo stesso
editor qualsiasi sia la piattaforma su cui sviluppate, sappiate
che VI o meglio la sua versione migliorata VIM gira su AmigaOS, AtariMiNT, BeOS,
DOS, MacOS,MachTen, OS/2, RiscOS, VMS, e Windows
(95/98/NT4/NT5/2000/XP/.NET/64-Bit/Embedded)e, naturalmente,
tutte le versioni di UNIX come affermato nella home page del
programma.
Personalmente lo utilizzo spesso per amministrare i sistemi UNIX
di cui sono responsabile, ma non lo trovo funzionale come xwpe
come ambiente di programmazione.
Vorrei chiudere con una considerazione. Tutti i programmatori, me compreso, hanno la tendenza a riscrivere codice da zero. Questo serve, nella fase iniziale, per crearsi un insieme di esperienze dirette (si impara molto dai propri errori). Ma come dice, giustamente, Eric Raymond nel suo "La cattedrale e il bazar" ogni programmatore ha il dovere di evitare di reinventare la ruota e, quindi, di riutilizzare il codice già scritto da altri sviluppatori e testato dalla comunità. Questo immenso patrimonio di codice già scritto che l'Open Source porta con sè dovrebbe quindi diventare la Vostra risorsa principale e la principale fonte di istruzione. Nel caso del C e ancor più nel caso del C++ il riutilizzo delle librerie e dei sorgenti è facilitato dalla natura stessa del linguaggio. Fatene buon uso e che la forza... :-)
Gli autoriRudi Giacomini Pilon, programmatore dall'età di 14 anni, ex progettista elettronico, ex hardwarista e sistemista presso un Microsoft Solution Provider, ex esperto di reti e programmatore in una concessionaria IBM, incontra Linux nel 1994 e da allora vede pinguini ovunque. Dal 1999 è responsabile EDP in una SpA ove affronta l'informatica a 538 gradi (360 erano pochi).Diego Fernando Parruccia Ingegnere elettronico e programmatore. Inizia a 15 anni con il BASIC e assembler per Z80. Col passare degli anni scopre C e C++ trovando la base per sviluppare applicazioni che vanno da device driver a gestionali con esperienze anche su sistemi embedded. |
<- PW: Intro - Indice Generale - Copertina - PW: AVI -> |