Università degli Studi di Bari Corso di Laurea in ...lops/linguaggi/1-IntroC.pdf · 4 Struttura di...

28
1 Introduzione al linguaggio C Pasquale Lops Stefano Ferilli Corrado Mencar Università degli Studi di Bari Corso di Laurea in Informatica Corso di Linguaggi di Programmazione Corso C, sedi Brindisi e Corigliano Obiettivi del corso Fornire le conoscenze di base per la programmazione nel linguaggio C Confrontare i costrutti del linguaggio C con quelli del linguaggio Pascal Fornire gli elementi per sviluppare in C mediante l’ambiente di sviluppo DEV-C++ Prerequisito: Conoscenza del Pascal

Transcript of Università degli Studi di Bari Corso di Laurea in ...lops/linguaggi/1-IntroC.pdf · 4 Struttura di...

1

Introduzione al linguaggio C

Pasquale LopsStefano FerilliCorrado Mencar

Università degli Studi di BariCorso di Laurea in InformaticaCorso di Linguaggi di Programmazione Corso C, sedi Brindisi e Corigliano

Obiettivi del corso

Fornire le conoscenze di base per la programmazione nel linguaggio CConfrontare i costrutti del linguaggio C con quelli del linguaggio PascalFornire gli elementi per sviluppare in C mediante l’ambiente di sviluppo DEV-C++

Prerequisito: Conoscenza del Pascal

2

Testi consigliati

Linguaggio C (ANSI C) – II ed.B.W. Kernighan, D.M. Ritchie (Jackson)

C Corso Completo di ProgrammazioneH.M. Deitel, P.J. Deitel (Apogeo)

Caratteristiche fondamentali del C

Linguaggio imperativoTra basso livello e alto livello

Costrutti di alto livello tipo Pascal• Cicli, selezioni, funzioni, etc.• Leggibilità e manutenibilità dei programmi

Costrutti di basso livello tipo Assembly• Aritmetica degli indirizzi, enfasi sui puntatori,

corrispondenza con le istruzioni macchina• Efficienza dei programmi

3

Caratteristiche fondamentali del C

Tipizzazione deboleControlli di tipo poco rigorosi

• Utile per la programmazione di basso livelloPossibili effetti indesiderati

• Scarsa manutenibilitàPortabilità

Assicurata dallo standard ANSIPossibilità di sviluppare programmi non portabili

Nutrito insieme di librerie standardIl C è case-sensitive

Parole chiave in minuscolo

Struttura di un programma

PascalMain program

Procedure• Procedure

• …• Funzioni

• …

Funzioni• Procedure

• …• Funzioni

• …

CFunzione mainFunzione…Funzione

4

Struttura di un programma

Pascalprogram nome-progdich-tipidich-variabilidich-procedure-e-funzioni

beginistruzioni

end.

Cmain() {

istruzioni}funzione-1funzione-2…funzione-n

Struttura di un programma

PascalStruttura nidificata

• Astrazione funzionale

Apposita sezione dichiarativa

• Visibilità: l’intera procedura/funzione

• Leggibilità, controllo

CStruttura appiattita

• Funzioni paritarie

Dichiarazioni sparse• Visibilità: il blocco in cui

sono dichiarate• Efficienza in spazio

5

Il più semplice programma C

main () {}

abbreviazione per:

int main (void) {}

Le funzioni restituiscono per default un intero

voidParola chiave per specificare l’assenza di parametri o di risultato

Funzioni

Pascalfunction nome([var]

arg: tipo,…, [var] arg: tipo): tipo;

dichiarazionibegin … end;

Passaggio parametririferimento o valore

Valore di ritornonome := valore

Ctipo nome(tipo arg,

…, tipo arg)

/* dichiarazioni nel corpo */

{ … }

Passaggio parametrivalore

Valore di ritornoreturn valore;

6

Tipi semplici

--Boolean

charChar

float, doubleReal

intInteger

CPascal

Modificatori di tipo

Ampiezzachar (8 bit) < short (16 bit) < int < long (32 bit)float < double < long double

• Possono coincidere con 1, 2 o 3 ampiezze diverse

Segnosigned/unsigned

• Applicabili a char e int• Estensione del segno

7

Il pre-processore

Direttive#include “nomefile”#include <nomeheader.h>

Inclusione di file esterni• I file di intestazione raccolgono dichiarazioni di costanti e

funzioni definite in altri moduli#define NOME espansione

Definizione di costanti simboliche• Prima della compilazione tutte le occorrenze di NOME

vengono sostituite da espansione

Variabili - Costanti

Pascalvar id: tipo;

Dichiarazione obbligatoriaGlobali se dichiarate nel programma principaleSolo dichiarazione e non inizializzazione

const id = valore;

Ctipo id [= valore];

Dichiarazione obbligatoriaGlobali se dichiarate fuori dalle funzioniPossibile inizializzazione

const tipo id = valore;Costanti matematiche:<float.h>Costanti di piattaforma:<limits.h>

8

Costanti enumerative

enum nome { ID [= valore], …, ID [= valore] };

Valori non necessariamente distintiValori progressivi dall’ultimo specificatoSe non specificato, il primo valore è 0

Nomi diversi in enumerazioni distinteEsempio

enum mesi {GEN=1, FEB, MAR…}

Istruzioni

Pascal; separatoreFunzioni elementari predefinite

• I/O di base• matematiche

(* … *), { … }

C; terminatoreNessuna funzione predefinita#include <stdio.h>#include <math.h>

/* … */

9

AssegnamentoOperatori aritmetici

Pascal:=var := var op esprvar := var + 1var := var - 1

+, -, */, divmod

C=var = var op esprvar op = esprvar++ ++varvar-- --var

+, -, */%

Operatori relazionaliOperatori logici

Pascal=<><, <=, >, >=

notandor

C==!=<, <=, >, >=

!&&||

10

Puntatori

&variabile

Indirizzo in memoria di variabile• Utilizzabile per il passaggio di parametri per riferimento

*puntatore

Valore contenuto all’indirizzo di memoria puntatore• * operatore di “indirezione”

tipo *puntatore

*puntatore è di tipo tipo, ossia puntatore è l’indirizzo di un valore di tipo tipo

Puntatori - Esempio

int x = 1, y = 2, z[10];int *ip; /* ip puntatore ad un intero */ip = &x; /* ip punta ad x */y = *ip; /* y vale 1 */*ip = 0; /* x vale 0 */ip = &z[0] /* ip punta a z[0] */

Esempi di costrutti validi:*ip = *ip + 10; y = *ip + 1;*ip += 1;++*ip; (*ip)++

11

Procedura di scambio di valori

void swap(int *x, int *y) {int temp;

temp = *x;*x = *y;*y = temp;}

Viene chiamata con i riferimenti: swap(&a, &b);

I/O base

Pascalwrite(…)• writeln(…)

read(…)

Cprintf(“…”, …)• printf(“…\n”, …)

scanf(“…”, …)

12

Funzioni di I/O base

printf(“formato”, parametro, …, parametro)scanf(“formato”, &parametro, …, &parametro)

formato è la stringa da stampare/leggerePossibilità di inserire caratteri specialiSegnaposto per i parametri da stampare/leggere

• Corrispondenza fra numero e tipo dei segnaposto e sequenza dei parametri

Numero di spaziature ignorato in lettura

Caratteri speciali

Sequenze di escape\n a capo\t tab orizzontale\v tab verticale\b cancellazione\” doppi apici\’ apice singolo\? punto interrogativo\\ barra rovesciata

Segnaposto parametri%d decimale%i intero%f virgola mobile%e esponenziale%c carattere%s stringa%% stampa ‘%’

13

Programma di benvenuto

#include <stdio.h>main () {printf(“Salve, mondo\n”);}

#include <stdio.h>main () {

printf(“Salve, ”); printf(“mondo”);printf(“\n”);}

Somma e media di due valori

#include <stdio.h>main() {

int a,b,s;

printf(“Inserisci due numeri interi:\n”);scanf(“%d %d”,&a,&b);s = a + b;printf(“Somma = %d\tMedia = %f\n”,s,s/2.0);}

14

Sequenza

Pascalbegin …

end[;]

C{ … }

Località delle variabili

Selezione binaria

Pascalif condizione thenistruzione/sequenza

[elseistruzione/sequenza

]

condizione è una espressione booleana

Cif (condizione) istruzione/sequenza

[elseistruzione/sequenza

]

condizione èun’espressione che restituisce un numero intero

Se il risultato è zero, la condizione è falsa, altrimenti è vera

15

Parità di un intero

#include <stdio.h>

main() {int n;

printf("Inserisci un intero: ");scanf("%d",&n);if (n % 2 == 0)

printf("%d e' pari\n",n);else

printf("%d e' dispari\n",n);}

Selezione multipla

Pascal

case espressione ofvalori: istruzione;…valori: istruzione[;otherwise istruzione]end;

C

switch (espressione){case costante:

istruzione[break;]…case costante:

istruzione[break;]default: istruzione}

16

Stampa numeri

#include <stdio.h>main() {

char n;printf("Inserisci il numero 1 o 2: ");scanf("%d",&n);switch (n) {

case 1: printf(“Uno\n");break;case 2: printf(“Due\n");break;default: printf(“Numero non riconosciuto\n",n);}

}

Segno di un intero

#include <stdio.h>

main() {signed int n;

printf("Inserisci un intero: ");scanf("%d",&n);if (n > 0)

printf("Positivo\n");else if (n < 0)

printf("Negativo\n");else

printf("Nullo\n");}

17

Iterazione

Pascalwhile condizione do

istruzione

repeatistruzione

until condizione-falsa

Cwhile (condizione)

istruzione

do { istruzione

}while condizione-vera

Conto alla rovescia

#include <stdio.h>

main() {int n = 10;

while (n != 0){printf("%d\n",n);n--;}

printf(“GO!\n");}

18

Inserimento di valori negativi

#include <stdio.h>

main() {signed int n;

do {printf("Inserisci un intero negativo: ");scanf("%d",&n);}

while (n >= 0);}

Iterazione

Pascalfor ind := inf to sup

doistruzione;

≡ind := inf;while ind <= sup do

beginistruzione;ind := ind + 1

end;

Cfor (espr1; espr2; espr3)

istruzione

≡espr1;while espr2

{istruzione;espr3;

}

19

Calcolo dei primi n numeri dispari

#include <stdio.h>main() {int n;

printf(“Quanti numeri devo generare?\n”);scanf(“%d”,&n);for(int i=0; i<n; i++)

printf(“%6d.%10d\n”,i+1,2*i+1);}

Vettori

Pascalvar:

array[dim] of tipo;

Indici enumerativiIntervallo a piacere

Accesso:variabile[ind]

Ctipo var[[dim]]

[= {val, …, val}];

Indici interiPartono sempre da 0

In C var ≡ &var[0]

Accesso:variabile[ind]

20

Vettori multidimensionali

Pascalvar:

array[dim,…,dim]of tipo

Accesso:var[ind,…,ind]

Ctipo

var[[dim]]…[[dim]][= {{val, …, val},…, {val, …, val}}]

Accesso:var[ind]…[ind]

Strutture

Pascalvariabile: recordid: tipo;…id: tipo;end;

Accesso:variabile.id

Cstruct [nome] {tipo id;…tipo id;} [variabile = {val,

…, val}];

Accesso:variabile.id

21

Strutture

p

Puntatore a struttura*p

Contenuto della struttura(*p).el abbreviato in p->el

Elemento della struttura

Definizione di nuovi tipi

typedef tipo Nome;

Semplici sinonimi di tipi esistentiPossibilità di dare un nome a tipi complessi

Interpretata dal compilatore (a differenza della #define)

Parametrizzazione di programmi (portabilità)Significatività dei nomi (documentabilità)

22

Forzatura di tipi

(tipo) espressione

Operatore di “Cast”Forzatura di un valore ad un tipo

Il tipo deve essere compatibile col valore

Input & Output (I/O)

Gestione dell’I/O tramite funzioni delle librerie standardInput e Output realizzato attraverso flussi

Flusso (stream) = sequenza ordinata di byteFILE = sorgente o destinazione di un flussoUn FILE in C può essere:

• Un file del sistema operativo• Una periferica (tastiera, monitor, stampante, etc.)

23

Flussi standard

stdin (standard input)Flusso di dati proveniente dalla tastieraLettura del flusso con la funzione scanf(…)

stdout (standard output)Flusso di dati verso lo schermoScrittura del flusso mediante printf(…)

stderr (standard error)Flusso di dati verso una periferica per la notifica di erroriSpesso stdout = stderr

Libreria per l’uso dei flussi standard: stdio.h

I formati di file

TestualeFile definito da linee di caratteri stampabili, separate da ‘newline’ (‘\n’)Esempi: documenti di testo (txt), codice sorgente

BinarioFile definito da qualunque sequenza di byteEsempi: immagini, file eseguibili, etc.

24

La gestione dei flussi

Struttura dati FILEDefinita nella libreria stdio.hContiene le informazioni necessarie all’accesso (lettura e/o scrittura) ad un flussoDi norma, non si accede direttamente alle informazioni contenute nella struttura, ma essa viene passata come parametro nelle funzioni per l’I/O

Apertura e chiusura di file

Aprire un file = abilitare un flusso di datiEsempio in C:

FILE* fp;fp = fopen(nomefile, mode);

Modalità di apertura (mode)“r”: lettura da file testuale“w”: scrittura di nuovo file testuale“a”: scrittura (append) su file testuale esistente“r+”: lettura/scrittura su file testuale esistente“rw”: lettura/scrittura su nuovo filemode+”b” (es. “wb”): accesso a file binario

Chiusura di un file = disabilitare un flusso di datifclose(fp);

25

Lettura e scrittura per caratteri

char fgetc(FILE*)

Legge un carattere da un flussofputc(char, FILE*)

Scrive un carattere in un flussofeof(FILE*)

Verifica se un flusso è terminato o noVale per tutti i tipi di flusso

Lettura e scrittura per linee di testo

char* fgets(char* s, int n, FILE*stream)

Legge una linea di testo (cioè fino alla prossima newline) e la memorizza in s. Il numero massimo di caratteri che possono essere letti è stabilito da n

fputs(char* s, FILE* stream)

Scrive una linea in un testo

26

Lettura e scrittura formattata

fscanf(FILE* f, char* format, vars)Legge dal file testuale f e valorizza le variabili in varssecondo il formato specificato in formatEsempio: fscanf(f,”%d %c”, &v1,&v2) legge da f un decimale (%d) che memorizza in v1 e un carattere (%c) che memorizza in v2

fprintf(FILE* f, char* format, vars)Scrive nel file f la stringa specificata nel formato con i valori delle variabili specificateEsempio: fprintf(f,”%d %c”, v1, v2) scrive in f i valori di v1 e v2 separati da uno spazio.

Altre modalità di lettura e scrittura

Per blocchi (file testuali)fread / fwriteUtili per la lettura/scrittura di record

Accesso direttofseek / ftell

27

La libreria standard

assert.hGestione delle asserzioni. Utile per verificare la correttezza semantica dei programmi

ctype.hGestione dei caratteri

• Riconoscimento di categorie di caratteri (p.e. maiuscole, minuscole, cifre, punteggiatura, etc.)

• Trasformazioni di caratteri (p.e. minuscolo maiuscolo)

La libreria standard

limits.hDimensioni dei tipi di dati dipendenti dall’implementazione

math.hFunzioni matematiche complesse

stdio.hFunzioni per l’input e l’output

28

La libreria standard

stdlib.hFunzioni di utilità generale (p.e. generazione di numeri pseudo-casuali, conversione da testo a numeri, etc.)

string.hGestione delle stringhe di testo (copia, concatenazione, confronto, etc.)

time.hGestione delle informazioni temporali