Introduzione al c

36
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

description

introduzione al linguaggio c programmazione 2 slides

Transcript of Introduzione al c

Page 1: Introduzione al c

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

Page 2: Introduzione al c

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

Page 3: Introduzione al c

3

Principali similitudini con JavaOperatori

Aritmeticiint i = i+1; i++; i--; i *= 2;+, -, *, /, %,

Relazionali e logici<, >, <=, >=, ==, !=&&, ||, &, |, !

Sintassi, strutture di controlloif ( ) { } else { }while ( ) { }do { } while ( );for(i=1; i <= 100; i++) { }switch ( ) {case 1: … }continue; break;

Cenni storici - I

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:

Algol 60 1960 (Comitato Int.)CPL 1963 (Cambridge)BCPL 1967 (Cambridge)B 1970 (Thompson)C 1972 (Ritchie)

Page 4: Introduzione al c

4

Cenni storici

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

Page 5: Introduzione al c

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”);}

Page 6: Introduzione al c

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

http://developer.apple.com/technologies/tools/xcode.html

Page 7: Introduzione al c

7

CygWin

Suite di utility Unix per sistema operativoWindows

Inclusa una shell UnixIncluso il compilatore GCC

Download all’indirizzohttp://www.cygwin.com/

Cygwin - Download

Page 8: Introduzione al c

8

Cygwin - Download

Cygwin - Download

Page 9: Introduzione al c

9

Cygwin - Download

Cygwin - Download

Page 10: Introduzione al c

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

Page 11: Introduzione al c

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

Page 12: Introduzione al c

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

Page 13: Introduzione al c

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?

main(){printf(“ciao”);printf(“mondo”);printf(“\n”);

}

main(){printf(“ciao mondo \n”);

}

Page 14: Introduzione al c

14

Un programma (un po’) piu’ complesso…

Conversione da °C a °F°C = (5/9)(°F-32)

Output

1 -1720 -640 460 1580 26100 37120 48140 60160 71180 82200 93220 104240 115260 126280 137300 148

Page 15: Introduzione al c

15

Dichiarazione di variabili

int fahr, celsius;int lower, upper, step;

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

Page 16: Introduzione al c

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

Tipicamente a 32 bit

Page 17: Introduzione al c

17

Programma rivisitato

#include <stdio.h>main(){

float fahr, celsius;float lower, upper, step;

lower = 0; /* lower limit of temperatuire scale */upper = 300; /* upper limit */step = 20; /* step size */fahr = lower;while (fahr <= upper) {

celsius = (5.0/9.0) * (fahr-32.0);printf("%3.0f %6.1f\n", fahr, celsius);

fahr = fahr + step;}

}

Cosa notiamo di diverso?

float fahr, celsius;float lower, upper, step;

Dichiarazione di variabili di tipo float

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…

Page 18: Introduzione al c

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“%”

Page 19: Introduzione al c

19

Il costrutto FOR

#include <stdio.h>

main(){int fahr;for (fahr = 0; fahr <= 300; fahr = fahr + 20)

printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

}

Come funziona la struttura iterativa FOR?Ricordate da Java…

Dichiarazione di costanti

Utilizzo della direttiva di preprocessore #define

#define nome testo_da_sostituire

Il preprocessore analizza il programma e rimpazza ogni occorrenza dinome con testo_da_sostituire

#include <stdio.h>

#define LOWER 0 /* lower limit of table */#define UPPER 300 /* upper limit */#define STEP 20 /* step size */

/* print Fahrenheit-Celsius table */

main(){int fahr;for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

}

Page 20: Introduzione al c

20

Output preprocessore

gcc -E fahr4.c –o fahr4.iEsegue solo lo step di preprocessore del compilatore(ricordate?) e produce il file fahr4.i

Output (la parte superiore contiene stdio.h)…main(){int fahr;for (fahr = 0; fahr <= 300; fahr = fahr + 20)printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

}

Lettura e scrittura di caratteri

Impariamo a realizzare semplici “filtri”Programmi che leggono una sequenza dicaratteri e producono in output unasequenza di caratteri

c=getchar() Legge un carattere dal canale standard di input

putchar(c)Scrive il carattere c sul canala standard di output

Page 21: Introduzione al c

21

Copia di un file

leggo un carattere;while(il carattere letto non è il carattere di fine file)

{stampo il carattere;leggo il carattere successivo;

}

In C (libreria stdio.h) il carattere di fine file è rappresentato mediante EOF

Copia di un file - Implementazione

#include <stdio.h>

main(){int c;c = getchar();while (c != EOF) {putchar(c);c = getchar();

}}

Notate qualcosa di strano?

Page 22: Introduzione al c

22

int c?

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

Page 23: Introduzione al c

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

Page 24: Introduzione al c

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…

Page 25: Introduzione al c

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);

}}

Page 26: Introduzione al c

26

Esercizio

Contiamo le righe di un fileCome?

Ogni riga termina col carattere di ritorno a capo ‘\n’

Vettori (array) in C

Dichiarazione array:tipo identificatore[dimensione]

Esempio:int ndigit[10]

Come in Java l’accesso agli elementi del vettore avviene mediante indici interindigit[0], ndigit[1], … , ndigit[9]

Page 27: Introduzione al c

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);

}

Page 28: Introduzione al c

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]++?

Page 29: Introduzione al c

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

Page 30: Introduzione al c

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()

Page 31: Introduzione al c

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;

return p;}

Dichiarazione funzione power

Definizione funzione main

Definizione funzione power

Call graph

main()

power()

printf()

Page 32: Introduzione al c

32

Definizione funzione

tipo_ritorno nome_funzione(parametro1, parametro2,…){statement…

}

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

Page 33: Introduzione al c

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

Page 34: Introduzione al c

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!

Page 35: Introduzione al c

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

\0OAIC

Page 36: Introduzione al c

36

Stampa di una stringa…

#include<stdio.h>

main(){char str[] = "Ciao Mondo!";printf("%s\n",str);

}

Esercizio

Scriviamo un programma che calcoli la lunghezza di una stringa