LINGUAGGIO C Parte 1 (v1.1) Premessa: Con questa serie di documenti non ho la pretesa di mettermi in cattedra, sia ben chiaro. Non sono un esperto programmatore, anzi, non mi ritengo ancora nemmeno un programmatore. Un amatore, se vogliamo. Lo scopo di questa serie (che spero altri vengano ad arricchire) di piccole infarinature sul linguaggio C dovrebbe essere quello di invogliare o dare il via a chi non ha mai sentito parlare (o quasi) di C o di programmazione in generale a metterci sopra le mani. Ripeto: quello che scriverò sarà senza dubbio incompleto (spero non errato, almeno per quel poco!) e non equiparabile alle informazioni che potreste trovare su un manuale, ma, al contrario di quest'ultimo, sarà gratis. Ho pensato di farlo perchè, ad esempio, se qualcuno mettesse delle lezioni base di Assembler o anche solo di Pascal o Java, mi farebbe un grosso favore! (Eh, già, adesso capite perchè non posso ritenermi un programmatore!). Il C, oltre ad essere praticamente l'unico linguaggio da me conosciuto con un minimo di ampiezza, è obiettivamente importante e potente, e spero che a qualcuno servano veramente questi appunti. Colgo l'occasione per invitare chi ne sapesse di più a correggermi e postare a sua volta! ******OOO****** La Primissima riga: Questo manualetto è di stampo pratico: non si parla di programmazione in senso lato o di stili di programmazione, si parla di C. Quando scriverete il vostro primo programma C avrete subito a che fare con una strana riga, fatta piu' o meno così: #include dove il contenuto (stdio.h) potrebbe anche variare, ma la forma sarà la stessa. Si tratta di quel che viene chiamato come "direttiva al pre-processore", un nome difficile e burocratico che potrebbe invogliare i più pigri a chiudere l'editor. Non bisogna averne paura. E' un'amica. La direttiva al pre-processore (in questo caso la #include, ma ce ne possono essere altre) ci fa risparmiare tempo e fatica. In realtà il suo significato, al di là della definizione formale, è molto intuitivo, una volta che si sa cosa è un .h . Con l'estensione .h si identificano le librerie, ovvero listati di codice precompilati, scritti da altri, contenenti funzioni di uso piu' o meno comune. Nel nostro caso, la stdio.h sta per "standard input output", e contiene tutte le funzioni di base per fare dell'input e dell'output (ricevere dati e mostrarli a schermo, insomma). Già con la prima riga, quindi, abbiamo "incluso", appunto, molte informazioni, che aspettano solo di essere usate da noi. Un programma, e nello specifico il nostro, può necessitare anche solo della stdio.h per funzionare, in quanto contiene già un bel po' di funzioni. Puo' quindi iniziare il programma vero e proprio, e di nuovo ci serve una parola chiave, un formalismo, per far capire al compilatore (l'interprete del nostro codice, colui cioè che visiona quanto abbiamo scritto, ne accerta la correttezza sintattica e ne passa il significato alla macchina per l'esecuzione) che da qui inizia il flusso di informazioni da trattare. La riga è questa: main(){ dove main è il nome della funzione, le due parentesi tonde ne definiscono lo spazio per le dichiarazioni di input (vedremo in seguito queste cose, quando parleremo di funzioni. Per ora è vuoto, ma bisogna indicarlo comunque con le due parentesi) e la parentesi graffa aperta ne contiene il corpo, che sarà chiuso a fine programma. Non c'è modo migliore di capire un linguaggio che non leggerlo: quindi ora riporterò il programma per intero e il suo significato, poi ne vedremo le singole parti per cercare di togliere i dubbi. Il programma è molto semplice ed elementare e ci farà fare conoscenza con un paio di importanti funzioni di input/output (IO), printf e scanf. In pratica il programma è una calcolatrice in grado di eseguire somme di numeri immessi dall'utente, visualizzando il risultato. Ecco il codice: #include main(){ int a, b, somma; // dichiarazione variabili printf("Inserire primo numero: "); scanf("%d", &a); printf("Inserire secondo numero: "); scanf("%d", &b); somma = a+b; printf("La somma è: %d\n", somma); printf("Fine programma"); } Tutto chiaro? Passiamo alla spiegazione. L'include e il main ormai li conosciamo. La riga int a, b, somma; contiene la dichiarazione delle variabili, come indicato dal commento a lato (le due barre // indicano un commento, ovvero tutto quello che le segue fino a fine riga viene ignorato dal programma e servono solo al lettore umano). Le variabili sono il pepe del programma. Sono i contenitori che via via si riempiono dei dati necessari per il funzionamento. Dichiararle è fondamentale, e questa operazione va fatta subito all'inizio del listato. Il tipo di variabile, int, identifica a, b e somma come interi, ovvero numeri naturali col segno. Ci sono altri tipi di variabili, ma per ora vedremo solo gli interi. Da notare, importantissimo, il ';' che chiude ogni riga del programma. In realtà esso serve per definire la fine del comando ed è obbligatorio. Lo troveremo al termine di ogni comando, sia assegnamento, sia operazione, sia chiamata a funzione. E arriviamo alla prima funzione, printf. La printf serve per produrre output su schermo, ovvero stampare a schermo a tempo d'esecuzione tutto quello che ha tra virgolette " ". La prima printf produrrà quindi a schemo il seguente output: Inserire primo numero: La scanf è invece una funzione atta all'input, ovvero a ricevere dati da tastiera e memorizzarli nei "contenitori", le variabili. Il dato ricevuto deve essere conforme al tipo di dato ricevibile dalla variabile, altrimenti il compilatore segnala un errore. La sintassi della scanf può sembrare più ostica di quella della printf. Ci troviamo subito difronte ad un simbolo strano, %d. Questo simbolo è chiamato segnaposto, ed è proprio quello che fa. %d identifica un digit, cioè un intero. In pratica dice: aspettati di ricevere un intero, e mettilo in a. Davanti ad a c'è &. Altra cosa strana. Il simbolo & indica che della variabile a, in questo caso, ci interessa l'indirizzo, ovvero la cella di memoria fisica in cui è stata allocata. Sono informazioni che all'utente non interessano, in quanto gestite dal computer. E' la sintassi a volerlo, e come soluzione rimane effettivamente un po' indietro coi tempi. I linguaggi ad alto livello normalmente non necessitano di queste cose, e anche nel C esistono funzioni di input che non hanno bisogno di specificare l'indirizzo anzichè il nome della variabile per andarla a riempire. Qui abbiamo usato la scanf proprio perchè ha questa particolarità e anche perchè è molto utilizzata, percui è bene ricordarsi di questa regola. La maggior parte di errori su scanf si riassumono proprio nella dimenticanza del &! Le altre due righe hanno lo stesso significato delle prime due. Dopo i due inserimenti, vi è un'operazione che l'utente non vede a tempo d'esecuzione, in quanto eseguita senza interazione. Il suo significato è molto intuitivo: fai la somma di a e b e mettila nella variabile somma. Intervengono qui due operatori: quello di assegnamento e di addizione, rispettivamente = e +. NB: non confondere l'assegnamento, =, con l'uguaglianza, che ha altra sintassi, e la vedremo poi. L'ultima riga del programma è una printf che stampa a schermo il risultato dell'operazione. Ha però qualcosa di diverso dalle altre printf viste, poichè contiene un segnaposto e il nome della variabile somma fuori stringa (ovvero fuori le virgolette). Dopo il discorso sulla scanf e i segnaposto, dovrebbe essere abbastanza intuitivo il significato di questa variazione. Il programma stampa a schermo tutto il contenuto della stringa, ma quando arriva al %d sa che dovrà stampare un numero, e precisamente quello che si trova nella variabile indicata subito dopo, somma. Altra cosa strana è il \n, che indica semplicemente la new line, ovvero di andare a capo al termine della stringa. Da notare, a fine programma, la parentesi graffa chiusa, in corrispondenza a quella aperta subito dopo main(). Attenzione a non dimenticare mai di chiudere le parentesi aperte! Anche su questo discorso, molto importante, ci torneremo a tempo debito. Per ora sappiate che tra parentesi graffe è contenuto il corpo della funzione. Quindi, l'output del programma, immaginando un input da parte dell'utente dei numeri 6 e 98, sarà: Inserire primo numero: 6 Inserire secondo numero: 98 La somma è: 104 Fine programma Riassunto: Abbiamo visto, per quanto riguarda la sintassi iniziale: #include per l'inclusione di librerie di sistema stdio.h unica libreria che conosciamo per ora. Contiene le funzioni base di IO main(){ inizio del programma int keyword (parola chiave) per l'inizializzazione di variabili di tipo intero comandi (dalla stdio.h): printf() output formattato a schermo. Può contenere segnaposto e simboli di formattazione, come \n, newline scanf() input da tastiera. Deve contenere i segnaposto e i nomi delle variabili da riempire, preceduti da & operatori e formattatori: = operatore di assegnamento. Assegna il valore a destra alla variabile a sinistra + esegue la somma degli operandi %d segnaposto per gli interi \n newline, manda a capo " " definitori di stringa ; fine del comando // commento. Il compilatore ignora tutto quello che vi è alla sinistra, fino a fine riga Possibili esercizi: 1) aggiungere la funzionalità di sottrazione alla calcolatrice e visualizzare entrambi i risultati, uno a seguito dell'altro, con gli stessi operandi. 2) per gli sperimentatori nati, provare a modificare il codice del programma somma eliminando la variabile 'somma' e lasciando inalterate le funzionalità. /******************************************************************************** Tutte le informazioni contenute in questo file non sono state prese da alcun * manuale o libro presente sul mercato e non si è quindi violato alcun copyright. * Questo è il frutto della mia esperienza e dei miei studi ufficiali e privati. * *********************************************************************************/