Introduzione al c

Post on 07-Mar-2016

243 views 0 download

description

introduzione al linguaggio c programmazione 2 slides

Transcript of 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

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;+, -, *, /, %,

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)

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

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

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

7

CygWin

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?

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

}

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

}

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

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

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

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…

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

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

}

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

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?

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

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’

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]

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;

return p;}

Dichiarazione funzione power

Definizione funzione main

Definizione funzione power

Call graph

main()

power()

printf()

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

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

\0OAIC

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