1 Introduzione al Linguaggio C Overview Linguaggio general purpose Procedurale (a differenza di Java che e’ object- oriented) C++ è l’estensione OO del C Applicazioni: compilatori, sistemi operativi, grafica, giochi, sistemi embedded Cosa hanno in comune queste applicazioni? Limitato set di keyword (32) Da un lato, linguaggio di alto livello Costrutti di controllo del flusso (simile a Java) Funzionalità di basso livello Gestione diretta della memoria Manipolazione di indirizzi
introduzione al linguaggio c programmazione 2 slides
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
1
Introduzione al Linguaggio C
Overview
Linguaggio general purposeProcedurale (a differenza di Java che e’ object-oriented)
C++ è l’estensione OO del CApplicazioni: compilatori, sistemi operativi, grafica, giochi, sistemi embedded
Cosa hanno in comune queste applicazioni?Limitato set di keyword (32) Da un lato, linguaggio di alto livello
Costrutti di controllo del flusso (simile a Java)Funzionalità di basso livello
Gestione diretta della memoriaManipolazione di indirizzi
2
Linguaggio di per se’ limitato
Utilizzo di funzioni di libreriaAssenza di operatori predefiniti per oggetticomplessi (stinghe, strutture dati)Utilizzo di funzioni di libreria per l’I/O
Le funzioni piu’ comuni sono contenute in una libreria standard (circa 150 funzioni)
Buona portabilità a livello di codice sorgenteMa questo dipende dalle librerie che usiamo… e dall’uso di dialetti
Perche’ studiare il C (dopo Java)?
Linguaggio al tempo stesso di alto e basso livelloMaggior controllo degli aspetti di basso livelloIn generale, migliori performance rispetto a Java
Anche se Java e’ migliorato tantissimo negli ultimi anni
Pero’:Saremo responsabili della gestione della memoriaIl linguaggio ci lascera’ fare molte cose che Java ciproibiva (e.g. conversioni implicite tra tipi)Maggiori possibilita’ di errori
3
Principali similitudini con JavaOperatori
Aritmeticiint i = i+1; i++; i--; i *= 2;+, -, *, /, %,
Il linguaggio C è stato sviluppatointorno al 1972 nei Bell Laboratories AT&T americani, Dennis Ritchie.E’ nato come linguaggio di sviluppo del Sistema Operativo UNIX.Gli antenati del C possono essere riunitiin linea genealogica:
AlgolLinguaggio modulare e con sintassi regolareAbbastanza complesso
CPL (Combined Programming Language) e BCPLMigliorano le caratteristiche di AlgolAncora pero’ molto complessi
BLinguaggio vicino alla macchinaSviluppato per lo UNIX del DEC PDP-7Non tipato
CInclude le migliori caratteristiche dei linguaggi sopra citati
Cenni Storici - III
1983: l’American National Standards Institute(ANSI) ha iniziato i lavori per la definizione dell’ANSI C1983: Bjarne Stroustrup (Bell Labs) sviluppa il C++ a partire da C e Smalltalk
Paradigma di programmazione a oggettiNato come preprocessore per il C
1988: nasce l’ANSI C1999: Versione corrente dell’ANSI C (ANSI C 99)
Alcune modifiche sostanziali rispetto alle versioniprecedentiE.g. dichiarazione variabili in qualsiasi statementTipi boolean, complexDichiarazione variabili nelle strutture di controllo
5
Perché programmare in C
Portabilità del codice e del compilatoreCodice generato molto efficienteFacilità di accesso al livello “macchina”Interfacciamento completo al S.O. UNIXNon complesso
Struttura dei Programmi
- Un programma è formato da uno o piùblocchi chiamati funzioni
- Una funzione è formata da un insieme diuna o più istruzioni
Esempio:#include<stdio.h>main() /* esempio di programma C */{
printf(“Hello World!\n”);}
6
Commenti
#include<stdio.h> Direttiva di preprocessore (include file .h)/* */ Apertura e chiusura di un commento
main() Nome di funzioneMain e’ la funzione chiamata quandosi invoca un programma
{ Inizio corpo funzioneprintf(“Hello World\n”); Invocazione funzione printf
} Fine corpo funzione
Strumenti
Quello che vi occorre è Un compilatore C (ANSI C compatibile!!)Un editor di testo
Io uso Emacs….http://www.gnu.org/software/emacs/http://www.xemacs.org/Download/win32/Altro editor: VI http://www.vim.org/
GCC – GNU C CompilerDistribuito con tutte le distribuzioni di LinuxSe avete una macchina con Linux il gioco è fatto…
Alcune distribuzioni consentono il boot da USB stick…MAC OS – XCode
Suite di utility Unix per sistema operativoWindows
Inclusa una shell UnixIncluso il compilatore GCC
Download all’indirizzohttp://www.cygwin.com/
Cygwin - Download
8
Cygwin - Download
Cygwin - Download
9
Cygwin - Download
Cygwin - Download
10
Eclipse CDT
http://www.eclipse.org/cdt/Ambiente integratoSyntax highlighting, debugger integratonell’editor…Appropriato se siete gia’ abituati a lavorare con Eclipse (JDT)
Sovrapponibile.. scaricate versioni compatibili (Helios) dientrambi e scompattateli nella stessa dir…
Abituatevi anche e soprattutto ad usarecompilatore e altri strumenti da riga dicomando!!!
Eclipse CDT
11
Programmare in C in <120 min.
Viewer discretion is advised
Compilazione di un programma C
Il codice sorgente puòessere altamenteportabileLa compilazioneproduce un eseguibile
In linguaggiomacchina, quindieseguito direttamentedalla macchinaDipendentedall’architettura e dalS.O.
Invece, Java produce bytecode
Eseguito dalla Java Virtual MachineIndipendentedall’architettura e dalS.O.
Source codeHello.c
Preprocessed codeHello.i
Object moduleHello.o
ExecutableHello / Hello.exe
Librerie
Informazioni dirilocazione
Altriobject module
Preprocessore
Compilatore
Linker
Assembly codeHello.s
Assemblatore
12
Il preprocessore
Trasforma il file sorgente inizialeprocessando direttive del preprocessoreIniziano con “#”, eg.
#define definizione di costanti/macro#include inclusione di altri sorgenti#if #else #endif compilazione condizionale
Compilazione ed esecuzione
cc ciao.cO anche gcc ciao.cSpesso cc e’ un link simbolico (alias) di gcc
Produrra’ il file eseguibile a.outa.exe con Cygwin
Per eseguirlo:./a.out
Hello World
13
Alcune opzioni GCC
gcc –Wall –pedantic –ansi ciao.c –o ciao.out
-Wall produce tutti I possibili warning (usatelo!)-ansi evita che usiate codice non-ANSI
e.g. parte del dialetto GCC-pedantic visualizza tutti i warning circa la compliance ISO C-o file_output specifica il nome del file eseguibile
Ritorno a capo
La funzione printf non genera un carattere diritorno a capo al termine della stringa
Come System.out.print, non come System.out.printlnOccorre stampare esplicitamente un caratterespeciale ‘\n’Qual’e’ la differenza tra questi due programmi?
Nome del tipo seguito da lista di nomi divariabili (identificatori)Tipo int: intero
Numero di bit machine dependent, spesso 16 bit [-32768, +32767]Che tipo di rappresentazione numerica è usata?
printf..
printf("%d\t%d\n", fahr, celsius)
Stampa il valore della variable fahrStampa un carattere \t (tabulazione)Stampa il valore della variable celsiusStampa un ritorno a capo \n
"%d\t%d\n“ e’ una stringa di formattazione%d in posizione i-esima indica che va prodottol’output (come decimale intero) della i-esimavariabile nella lista dopo la stringa diformattazione
16
Giustificazione numeri…
L’output prodotto in precedenza contenevaprintf("%3d %6d\n", fahr, celsius);
Riserva 3 cifre per fahr e 6 per celsius
Problema
Le temperature °F sono interi a intervalli di 20Le conversioni °C sono troncate all’interoinferiore → non molto preciseDobbiamo utilizzare variabili floating pointfloat fahr, celsius
celsius = (5.0/9.0) * (fahr-32.0);Perche’ 5.0 9.0 32.0?Come vedremo, il C effettua una conversione implicita5 e 9 sarebbero trattate come costanti intere
Il risultato di 5/9 sarebbe troncato all’intero inferiore (0)
Se scrivevamo fahr-32?fahr e’ float32 interoIn questo caso il C avrebbe convertito tutto al tipo float (+ preciso di int)Quindi andava bene, ma meglio far vedere esplicitamente che 32 e’ float
Questo problema sarà affrontato in dettaglio piu’ avanti nelcorso…
18
printf: stringhe di formattazione per numeri
printf("%3.0f %6.1f\n", fahr, celsius);
%3.0f fahr e’ stampato utilizzando spazio x 3 caratteri di ampiezza senza decimali%6.1f celsius e’ stampato utilizzando spazio x 6 caratteri di ampiezza, incluso 1 decimale
printf: riepilogando…
%d Intero in notazione decimale%4d Intero in notazione decimale, 4 caratteri%f Float%.2f Float, 2 caratteri dopo il punto decimale%6.2f Float 6 caratteri di cui 2 dopo il punto decimale
Ve ne sono altre (%o ottale, %x esadecimale, %ccarattere, %s stringa)Usate printf(“%%”) per stampare un carattere“%”
Assegniamo un carattere a una variabile int?In realtà, in C esiste il tipo char
tipicamente 8 bitdi fatto è trattato come intero
Il C consente assegnazioni tra tipi eterogeneiCosa accade?
int c=‘a’;
char c=‘a’;
(Le costanti char si sono rappresentate da caratteri tra singoli apici)printf(“%d”,’a’) stampa il valore 97Come vedete.. è possibile fare di tutto… a vostro rischio e pericolo
1000011000000000
10000110
Il codiceASCII di ‘a’ è 97
Il codiceASCII di ‘a’ è 97
Quindi…
Quindi meglio dichiarare char c?Beh… il fatto è che EOF è una costante intche indica la fine del file
In alcune architetture la dimensione dell’intpotrebbe essere >255Quindi è safer utilizzare intAnche se nella maggior parte dei casi char vabene
23
Versione compatta!
#include <stdio.h>main(){
int c;while ((c = getchar()) != EOF)
putchar(c);
}
Come lo usiamo?
In una shell Unix, se invochiamo un comando seguito da <filename→ il comando considera come canale diinput standard il fileSe invochiamo un comando seguito da>filename→ il comando produce l’output su file
./copyfile <file1 >file2
24
Confronto (!=) ha precedenzasu assegnazione (=)
#include <stdio.h>main(){
int c;while (c = getchar() != EOF)
putchar(c);}
Cosa accade?c = getchar() != EOF equivale a c = (getchar() != EOF)Il risultato di un’ espressione booleana è 0 se falso, 1 se vero…Quale sarà l’output del programma?
Ora provate voi…
Scrivete un programma per il conteggio deicaratteri contenuti in un file…
25
Altro esercizio…
Stampiamo i codici ASCII di tutti i carattericontenuti in un file…
Stampiamo tutte le ‘a’ contenute in un file
#include <stdio.h>main(){
int c;while ((c = getchar()) != EOF){if(c==‘a’)putchar(c);
}}
26
Esercizio
Contiamo le righe di un fileCome?
Ogni riga termina col carattere di ritorno a capo ‘\n’
Come in Java l’accesso agli elementi del vettore avviene mediante indici interindigit[0], ndigit[1], … , ndigit[9]
27
Esempio
Contiamo cifre, spazi bianchi e altri caratteriin un testoCi occorrono:
Una variabile per contare gli spazi bianchiint nwhite;
Una per contare gli altri caratteriint nother;
10 variabili per contare 0, 1,…9,Beh, un vettore di 10 interi…int ndigit[10];
Codice…#include <stdio.h>main(){
int c, i, nwhite, nother;int ndigit[10];
nwhite = nother = 0;for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar()) != EOF)if (c >= '0' && c <= '9')
++ndigit[c-'0'];else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;else
++nother;
printf("digits =");for (i = 0; i < 10; ++i)
printf(" %d", ndigit[i]);printf(", white space = %d, other = %d\n",nwhite, nother);
}
28
Inizializziamo le variabili
nwhite = nother = 0;for (i = 0; i < 10; ++i)
ndigit[i] = 0;
L’inizializzazione è fondamentale in CA differenza di Java, l’inizializzazione a zero non è garantita!
Leggiamo I caratteri fino alla fine del file
while ((c = getchar()) != EOF)if (c >= '0' && c <= '9')++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t')++nwhite;
else++nother;
if (c >= '0' && c <= '9') restituisce true se ilcarattere è compreso tra 0 e 9C-’0’ vale 0 se c==‘0’, 1 se c==‘1’, etc.Quindi ndigit[c-’0’] punta all’elemento del vettorecorrispondente alla cifra++ndigit[c’-0’] incrementa il numero di cifre…
Che differenza c’e’ tra ++ndigit[c-’0] e ndigit[c-’0]++?
29
Infine..
Stampiamo il risultato:printf("digits =");for (i = 0; i < 10; ++i)printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n",nwhite, nother);
Object-oriented programming…
Avete studiato JavaLinguaggio OOIl funzionamento di un programma avvenivamediante scambio di messaggi tra oggetti
obj
obj
obj obj
obj
op
op
op
op
op
op
op
30
Linguaggio procedurale…
C è un linguaggio proceduraleIl programma è costituito da un insieme di unitàfunzionali dette funzioniFunzioni in Fortran, procedure in Pascal
Una funzione:riceve zero o piu’ parametri in ingressoEsegue un task specificato da una sequenza distatement (come nel caso di un metodo)
Eventualmente invocando altre funzioniInfine, termina
Eventualmente, ritornando un risultato in uscitaEventualmente, modificando i parametri in ingresso
Programmazione procedurale
main()
foo()
bar()
fun()
ff()
31
Esempio#include <stdio.h>
int power(int m, int n);
main(){
int i;for (i = 0; i < 10; ++i)printf("%d %d %d\n", i, power(2,i), power(-3,i));
return 0;}
int power(int base, int n){
int i, p;p = 1;for (i = 1; i <= n; ++i)p = p * base;
Se ometto tipo_ritorno, si assume che sia intInfatti main ritorna int…
Una funzione potrebbe non avere tipo di ritornoIn tal caso come dovrei dichiarare la funzione?
Posso omettere i parametritipo_ritorno funzione(){}
Dichiarazione funzione
In C le funzioni devono essere dichiarate prima dipoter essere usateSiccome power è definita dopo main, ilcompilatore non l’avrebbe trovata durante la compilazione di main
Anche se tale dichiarazione è opzionale nei compilatoriANSI 99Warning visibili solo con -Wall
Quindi, è necessaria una dichiarazionetipo_ritorno nome_funzione(lista_parametri);Nota anche come prototipo della funzione
33
Prototipo funzione
Lista parametri può esseretipo1 nome1, tipo2 nome2…..oppure è lecito anche scriveretipo1, tipo2..e.g. int power(int, int)Ma è meno comprensibile
Return
Sintassireturn espressione;return;
Non ritorna nulla…
Anche la funzione main può ritornare un valoreInfatti è definita come funzione con tipo di ritorno intValore usato dal sistema operativoDiverso da zero → codice di errore
34
Passaggio parametri per valore
Parametri passati alle funzioni tramite variabiliprovvisoriePossono essere usate come variabili locali nellafunzione
E quindi modificate
Ma la variabile passata nella funzione chiamanteresta inalterataVi sono eccezioni
Quando passo un vettore, passo l’indirizzo del primo elementoLe vedremo in seguito
Passaggio parametri - esempio
#include <stdio.h>
int fact(int n);
main(){
int i;for (i = 0; i < 5; ++i)
printf("%d e' il fattoriale di %d\n", fact(i),i);return 0;
}
int fact(int n){
int result=1;while(n>0)
{result*=n;n--;
}return result;
}
i viene stampato dopo aver invocato factMa il parametro n è decrementato dentro factNo problem, il valore di inon cambia in main!
35
Vettori di caratteri
A differenza di Java il C non ha un tipo stringaLe stringhe sono trattate come array di caratterichar msg[10]; /*array di caratteri, lunghezza 10*/
char [] = “Ciao Mondo”/* Inizializzazione con una stringa costante */
Notare l’assenza di dimensione
OAIC
Carattere di fine stringa
Molte funzioni richiedono stringhe (array di caratteri) come inputProblema: come facciamo a conoscere la lunghezza dellastringa?Non esiste una funzione che ci dica la lunghezza di un array (come length in Java!)Inoltre, quando accedo ai singoli elementi, C non mi proibisce diandare oltre il limite!
→ Per convenzione, quando creiamo una stringa in C aggiungiamo un carattere di terminazione ‘\0’ al terminedell’array
Quando assegniamo una costante stringa a un array ciòavviene automaticamente