Nessun titolo diapositiva - PowerPoint PPT Presentation

About This Presentation
Title:

Nessun titolo diapositiva

Description:

Title: Nessun titolo diapositiva Last modified by: Valued Acer Customer Document presentation format: Presentazione su schermo (4:3) Other titles – PowerPoint PPT presentation

Number of Views:53
Avg rating:3.0/5.0
Slides: 57
Provided by: diiUnisi9
Category:

less

Transcript and Presenter's Notes

Title: Nessun titolo diapositiva


1
Array e puntatori in C
2
Sommario
  • Gli array ed i puntatori
  • Dichiarazione e memorizzazione di array
  • Linizializzazione di array
  • Laritmetica dei puntatori
  • Il passaggio di puntatori come argomenti di
    funzione
  • Gli algoritmi di ordinamento
  • Le stringhe

2
3
Gli array ed i puntatori
3
4
Gli array
  • Nel linguaggio C, un array è un insieme di
    variabili dello stesso tipo memorizzate
    consecutivamente
  • Ogni variabile dellarray, detta elemento, può
    essere acceduta mediante il nome dellarray ed un
    indice (un espressione), con il primo elemento
    individuato dallindice di valore 0
  • Esempio Memorizzare la temperatura media
    registrata per ogni giorno dellanno
  • Si dichiara un array di 365 elementi (piuttosto
    che 365 variabili!), identificati con un solo
    nome, e che occupano posizioni di memoria
    consecutive
  • Nota Gli array contengono informazione correlata
    (le temperature di un anno, i voti di esame di
    uno studente, etc.)

4
5
La dichiarazione di array ? 1
  • La sintassi della dichiarazione di array è
  • La dichiarazione viene effettuata inserendo una
    coppia di parentesi quadre dopo il nome
    dellarray
  • La dimensione dellarray viene specificata
    inserendo il numero di elementi allinterno delle
    parentesi quadre

5
6
La dichiarazione di array ? 2
  • Il riferimento ad un elemento dellarray è invece
    loperazione di accesso al dato elemento ed
    avviene utilizzando il nome dellarray seguito
    dallindice dellelemento (racchiuso fra
    parentesi quadre)
  • Le istruzioni di dichiarazione di un array e di
    riferimento ad un elemento dellarray sono molto
    simili nella forma, ma molto diverse nel
    significato

/ I seguenti sono riferimenti a elementi
dellarray i valori 0,1,2, specificano gli
elementi cui accedere / daily_temp0 ?
2 daily_temp1 ? 5 daily_temp2 ? 3
/ La seguente è una dichiarazione il
valore 365 specifica il numero di elementi
dellarray / int daily_temp365
6
7
La dichiarazione di array ? 3
  • Esempio Calcolo della temperatura media annua

?include ltstdio.hgt ?include ltstdlib.hgt ?define
DAYS_IN_YEAR 365 main() int j, sum?0
int daily_tempDAYS_IN_YEAR / si
assegnano i valori a daily_temp / for
(j?0 jltDAYS_IN_YEAR j??) sum ??
daily_tempj printf(La temperatura media
dellanno è d.\n, sum/DAYS_IN_YEAR)
exit(0)
7
8
La memorizzazione di array
  • Esempio
  • ar2 e ar4 sono indefiniti il contenuto delle
    posizioni di memoria è quello rimasto da
    esecuzioni precedenti (garbage)

int ar5 / dichiarazione / ar0 ? 15 ar1
? 17 ar3 ? 3
8
9
Linizializzazione di array ? 1
  • La presenza di valori indefiniti in alcuni
    elementi dellarray può provocare errori
    difficili da rilevare
  • ? Occorre inizializzare lintero vettore
  • Dichiarare larray static (vettore a durata
    fissa) gli elementi del vettore, non
    inizializzati esplicitamente, vengono posti a
    zero
  • Valori diversi possono essere specificati,
    facendoli seguire alla dichiarazione dellarray,
    racchiusi fra parentesi graffe tali valori
    devono essere espressioni costanti che possano
    essere convertite automaticamente nel tipo
    dellarray

9
10
Linizializzazione di array ? 2
  • Esempio
  • Nota il valore floating?point 3.5 viene
    convertito nel valore intero 3

static int ar5 static int
br5?1,2,3.5,4,5
10
11
Linizializzazione di array ? 3
  • Specificare un numero maggiore di valori di
    inizializzazione, rispetto agli elementi
    dellarray, costituisce un errore segnalato dal
    compilatore
  • Se vengono specificati meno valori rispetto alla
    dimensione, gli elementi rimanenti vengono
    inizializzati a zero
  • Esempio La dichiarazione
  • static int cr5 ? 1,2,3
  • produce linizializzazione
  • cr0 ? 1
  • cr1 ? 2
  • cr2 ? 3
  • cr3 ? 0
  • cr4 ? 0

11
12
Linizializzazione di array ? 4
  • Se vengono specificati i valori iniziali, può
    essere omessa la dimensione dellarray il
    compilatore calcola automatica-mente il numero
    degli elementi sulla base del numero dei valori
    iniziali specificati
  • Esempio
  • static char dr ? a,b,c,d
  • comporta la creazione di un array di quattro
    elementi, di tipo char, caratterizzati dai valori
    iniziali
  • dr0 ? a
  • dr1 ? b
  • dr2 ? c
  • dr3 ? d

12
13
Crittografia ? 1
  • Poiché in formato elettronico viene memorizzato e
    trasmesso ogni tipo di informazione (anche
    personale, quindi coperta da privacy), viene
    posta attenzione alla sicurezza rispetto ad
    accessi indesiderati
  • I file, nei sistemi multiutente, sono provvisti
    di vari livelli di protezione, il primo dei quali
    è costituito dallautenticazione al sistema
    tramite password
  • Oltre ai tipi di protezione standard, il
    contenuto di un file riservato può essere
    codificato, utilizzando tecniche crittografiche
    che producono, a partire dal testo in chiaro, il
    cosiddetto crittogramma, o testo cifrato
  • Il legittimo proprietario del file (e chi da lui
    autorizzato) è lunico depositario della chiave
    di decodifica ed è lunico in grado di operare
    linversione da testo cifrato a testo in chiaro

13
14
Crittografia ? 2
  • Inoltre, negli attuali sistemi informativi
    distribuiti, e più in generale nel settore delle
    telecomunicazioni, la crittografia ha assunto
    rilievo ed interesse crescenti nelle
    infrastrutture di sicurezza

14
15
Crittografia ? 3
  • Se il sistema di cifra, o cifrario, è ben
    congegnato, loperazione di decifrazione o
    decifratura deve risultare semplice al legittimo
    proprietario (o al destinatario del messaggio),
    ma di complessità proibitiva alla spia
  • ? possibile in quanto gli utenti legittimi
    possiedono uninformazione che deve rimanere
    inaccessibile alla spia, la chiave del cifrario
  • Occorre notare la distinzione tra decifrazione e
    decrittazione, loperazione illegittima in cui
    non ci si può avvalere della chiave

15
16
Crittografia ? 4
/ Dato un carattere, ne fornisce un valore
codificato / ?define ILLEGAL_VAL ?1 char
encode(ch) char ch static unsigned char
encoder128 ? 127,124,121,118,115,112,
109,106,103,100,97,94,91,88,85,82,79,76,73,70,67,6
4,61, 58,55,52,49,46,43,40,37,34,31,28,25,22,
19,16,13,10,7,4, 1,126,123,120,117,114,111,10
8,105,102,99,96,93,90,87,84,
81,78,75,72,69,66,63,60,57,54,51,48,45,42,39,36,33
,30, 27,24,21,18,15,12,9,6,3,0,125,122,119,11
6,113,110,107, 104,101,98,95,92,89,86,83,80,7
7,74,71,68,65,62,59,56,53,
50,47,44,41,38,35,32,29,26,23,20,17,14,11,8,5,2
/ Controlla la presenza di caratteri
illeciti / if (ch gt 127)
return ILLEGAL_VAL else return
encoderch / Fornisce il carattere codificato
/
480 ? 111o
16
17
Crittografia ? 5
  • Il codice Shift Cypher con K?3 era utilizzato da
    Giulio Cesare
  • Esercizio Con K?11, si somma 11 al valore
    corrispondente alla lettera e, nel caso che la
    somma superi 25, si divide il numero per 26 e si
    considera il resto della divisione intera
  • we will meet at midnight
  • 22 4 22 8 11 11 12 4 4 19 0 19 12 8 3 13 8 6 7
    19
  • ?
  • 7 15 7 19 22 22 23 15 15 4 11 4 23 19 14 24 19 17
    18 4
  • hphtwwxppelextoytrse

17
18
Esempio ? 1
/ Dato un vettore, stabilisce se vi sono
almeno due elementi uguali tra loro / define
MAX_DIM 256 typedef intMAX_DIM VECTOR int
TwinSearch (v) / ricerca degli elementi gemelli
/ VECTOR v int c ? 0 int k ? 0
int found ? ?1 / ricerca senza successo ritorna
?1 / for(c ? 0 ((c lt (MAX_DIM?1))
(found ?? ?1)) c??) for(k ? (c?1)
((k lt MAX_DIM) (found ?? ?1)) k??)
if (vc ?? vk)
found ? 1 / ricerca con successo /
return found
18
19
Esempio ? 2
/ Inverte gli elementi di un vettore
/ include ltstdio.hgt int main()
/dichiarazioni/ int a10, b10 int i,
dim?10 /input elementi/
for(i?0iltdimi??) printf(inserire
lelemento ad ,i) scanf(d, ai)
/stampa vettore/ printf(\nIl
vettore è\n\n) for(i?0iltdimi??)
printf(ad ? d\n, i, ai) printf(\n)

/inversione vettore/ for(i?0iltdimi??)
bi?adim?1?i /stampa vettore
invertito/ printf(Il vettore invertito
è\n\n) for(i?0iltdimi??)
printf(bd ? d\n, i, bi) return 0

19
20
Laritmetica dei puntatori ? 1
  • Il C permette lutilizzo degli operatori additivi
    in concomitanza con i puntatori
  • Se p è un puntatore, lespressione p?3 è lecita
    ed individua il terzo oggetto che segue quello
    puntato da p
  • Poiché p contiene un indirizzo, operazioni
    aritmetiche su p forniscono nuovi indirizzi
  • Il compilatore non opera semplicemente una somma
    tra 3 e p, ma moltiplica 3 per la dimensione
    delloggetto puntato da p effettua cioè uno
    scaling
  • Esempio Se lindirizzo contenuto in p è 1000 e p
    è un puntatore a long int, allora p?3 identifica
    lindirizzo 1018 (8 byte per gli interi lunghi)
    se p è un puntatore a char, p?3 rappresenta
    lindirizzo 1003

20
21
Laritmetica dei puntatori ? 2
  • Nellipotesi di puntatori che si riferiscono allo
    stesso tipo di dato, è lecito sottrarre il valore
    di un puntatore da un altro loperazione
    fornisce un valore intero che rappresenta il
    numero di oggetti compresi fra i due puntatori
  • Se il primo puntatore è relativo a un indirizzo
    inferiore al secondo, il risultato è un intero
    negativo
  • È lecito anche sottrarre un valore intero da un
    puntatore il risultato è un puntatore

21
22

Laritmetica dei puntatori ? 3
  • Esempio

long p1, p2, k int j char p3
p1?k p2?p1? 4 / OK / j?p2?p1 / OK a j
viene assegnato 4 / j?p1?p2 / OK a j viene
assegnato ?4 / p1?p2?2 / OK tipi dei
puntatori compatibili / p3?p1?1 / NO tipi
diversi di puntatori / j?p1?p3 / NO tipi
diversi di puntatori /
22
23
Laritmetica dei puntatori ? 4
  • Il linguaggio C prevede la definizione di
    puntatori nulli, ovvero di puntatori che non
    puntano ad alcun oggetto valido
  • Un puntatore nullo è un qualsiasi puntatore a cui
    sia assegnato il valore zero
  • char p
  • p?0 / rende p un puntatore nullo /
  • In questo caso il compilatore non effettua la
    conversione esplicita dellespressione intera nel
    tipo del puntatore
  • La definizione del puntatore nullo è utile
    allinterno di istruzioni di controllo il
    puntatore nullo è lunico puntatore cui è
    associato il valore FALSE tutti i puntatori
    validi valgono TRUE

23
24
Il passaggio di puntatori come argomenti di
funzione ? 1
  • Il compilatore segnala i tentativi di utilizzo
    congiunto di puntatori di tipi diversi
  • Uneccezione alla regola è costituita dalluso di
    puntatori come argomenti di funzione in mancanza
    di un prototipo, il compilatore non effettua
    controlli per verificare la corrispondenza di
    tipo fra parametro attuale e parametro formale
  • ? si possono produrre risultati inconsistenti
    nel caso di parametri di tipo disomogeneo
  • Il prototipo di una funzione è una dichiarazione
    di funzione antecedente alla sua definizione
    permette al compilatore di compiere il controllo
    sui tipi degli argomenti che vengono passati alla
    funzione

24
25
Il passaggio di puntatori come argomenti di
funzione ? 2
s0?1 s1?2 s2?3
?include ltstdio.hgt ?include ltstdlib.hgt void
clr(p) int p p ? 0 / Memorizza 0 alla
locazione p / main() static short s3 ?
1,2,3 clr(s1) / Azzera lelemento 1
di s / printf(s0?d\ns1?d\ns2?d\n,
s0,s1,s2) exit(0)
p è un puntatore a int ? vengono azzerati 4 byte,
quindi sia s1 che s2
s0?1 s1?0 s2?0
25
26
Laccesso agli elementi di array mediante
puntatori ? 1
  • È possibile accedere agli elementi di un array
    attraverso
  • luso del nome dellarray con il relativo indice
  • luso dei puntatori
  • Infatti vale la regola che
  • Aggiungere un intero ad un puntatore allinizio
    di un array, ed accedere allindirizzo puntato
    dallespressione, equivale ad utilizzare lintero
    come indice dellarray
  • Inoltre, un nome di array non seguito da un
    indice viene interpretato come un puntatore
    allelemento iniziale dellarray

Se p?ar0 ? (p?e) è equivalente a are
ar è equivalente a ar0
26
27
Laccesso agli elementi di array mediante
puntatori ? 2
  • Combinando le due relazioni, si ottiene la regola
    generale
  • Un nome di array viene trasformato dal
    compilatore C in un puntatore allelemento
    iniziale dellarray e quindi gli indici vengono
    interpretati come spostamenti dalla posizione di
    indirizzo base
  • In considerazione del meccanismo di scaling, lo
    spostamento determina il numero di elementi da
    oltrepassare
  • Esempio

arn equivale a (ar?n)
Sono equivalenti in entrambi i casi, ar è un
puntatore allelemento iniziale dellarray e 2 è
un fattore di spostamento che richiede al
compilatore di aggiungere due al valore del
puntatore
ar2 (ar?2)
27
28
Laccesso agli elementi di array mediante
puntatori ? 3
  • Tuttavia
  • i valori delle variabili puntatore possono
    essere modificati
  • i nomi di array non sono variabili, ma
    riferimenti a indirizzi delle variabili array e,
    come tali, non possono essere modificati
  • Un nome di array non associato ad un indice o ad
    un operatore accesso allindirizzo di () non
    può apparire alla sinistra di un operatore di
    assegnamento

float ar7, p p?ar / OK equivale a
p?ar0 / ar?p / NO assegnamento su un
indirizzo di array / p?ar / NO assegnamento
su un indirizzo di puntatore / ar?? / NO
non è possibile incrementare un indirizzo di
array / ar1?(p?5) / OK ar1 è una
variabile / p?? / OK è possibile
incrementare una variabile puntatore /

28
29
Il passaggio di array come argomenti di funzione
? 1
  • In C, un nome di array, utilizzato come argomento
    di funzione, viene interpretato come indirizzo
    del primo elemento dellarray
  • Esempio
  • Nella funzione chiamata è necessario dichiarare
    largomento come un puntatore allelemento
    iniziale di un array

main() extern float func() float x static
float farray5 x ? func(farray) /
equivalente a func(farray0) /
29
30
Il passaggio di array come argomenti di funzione
? 2
  • Anche nel secondo caso, ciò che viene passato è
    un puntatore al primo elemento dellarray ed il
    compilatore è in grado di convertire
    automaticamente ar in un puntatore a float
  • In termini di leggibilità, la seconda versione è
    preferibile, poiché evidenzia che loggetto
    passato è lindirizzo di base di un array e non
    un generico puntatore a una variabile float
    (scalare o composta?)
  • La dichiarazione della dimensione dellarray
    nella definizione dellargomento è comunque
    corretta il compilatore può usare linformazione
    sulla dimensione per effettuare controlli sui
    valori limite

30
31
Il passaggio di array come argomenti di funzione
? 3
  • Non è possibile ottenere la dimensione di un
    array allinterno di una funzione cui viene
    passato come argomento, ma solo laddove larray è
    effettivamente dichiarato

?include ltstdio.hgt ?include ltstdlib.hgt void
print_size(arg) float arg printf(La
dimensione di arg è d\n,sizeof(arg)) main()
void print_size() static float
f_array10 printf(La dimensione di f_array
è d\n,sizeof(f_array)) print_size(f_array)
exit(0)
Sulla macchina di riferimento, lesecuzione del
programma fornisce
La dimensione di f_array è 40 La dimensione di
arg è 4
31
32
Uscita dal limite superiore di un array
  • Il compilatore, di solito, non controlla che
    laccesso agli elementi di un array venga
    effettuato rispettandone i limiti dimensionali
  • ? È possibile accedere per errore ad elementi
    per i quali non è stata allocata memoria (aree
    di memoria riservate ad altre variabili,
    riservate ad altri processi, etc.)
  • Esempio

Essendo ar un array di 10 elementi, quelli cui è
possibile accedere in modo corretto hanno indice
da 0 a 9 il ciclo for contiene un errore
off?by?one Probabilmente verrebbe azzerata la
variabile j ? il ciclo diventa infinito
main() int ar10, j for(j?0 jlt?10
j??) arj ? 0
32
33
Gli algoritmi di ordinamento ? 1
  • Lordinamento di una sequenza di informazioni
    consiste nel disporre le stesse informazioni in
    modo da rispettare una qualche relazione
    dordine ad esempio, una relazione dordine
    minore o uguale dispone le informazioni in modo
    non decrescente
  • Lordinamento è unoperazione molto importante
    perché permette di ridurre notevolmente i tempi
    di ricerca di uninformazione, nellambito di una
    sequenza di informazioni
  • Nel caso in cui tale sequenza risulta ordinata,
    secondo una qualche relazione dordine, è infatti
    possibile sfruttare la stessa relazione dordine
    per effettuare la ricerca

33
34
Gli algoritmi di ordinamento ? 2
  • Esistono due categorie di algoritmi di
    ordinamento la classificazione è fatta in base
    alla complessità di calcolo e alla semplicità
    algoritmica
  • La complessità di calcolo si riferisce al numero
    di operazioni necessarie allordinamento tali
    operazioni sono essenzialmente confronti e scambi
    tra gli elementi dellinsieme da ordinare
  • La semplicità algoritmica si riferisce alla
    lunghezza e alla comprensibilità del codice

34
35
Gli algoritmi di ordinamento ? 3
  • Algoritmi semplici di ordinamento
  • Algoritmi che presentano complessità O(n2), dove
    n è il numero di informazioni da ordinare sono
    caratterizzati da poche e semplici istruzioni,
    dunque si realizzano con poche linee di codice
  • Algoritmi evoluti di ordinamento
  • Algoritmi che presentano complessità
    computazionale O(n?log2n) sono più complessi,
    fanno spesso uso di ricorsione la convenienza
    del loro utilizzo si rileva quando il numero n di
    informazioni da ordinare è molto elevato

35
36
Bubblesort ? 1
  • La strategia Bubblesort (ordinamento a bolla)
    prevede il confronto dei primi due elementi di un
    array, e lo scambio, se il primo è maggiore del
    secondo
  • Dopo il primo confronto, si effettua un confronto
    fra il secondo ed il terzo elemento (con
    eventuale scambio), fra il terzo ed il quarto,
    etc.
  • Gli elementi pesanti (grandi) tendono a
    scendere verso il fondo del vettore, mentre
    quelli leggeri (più piccoli) salgono (come
    bolle) in superficie

36
37
Bubblesort ? 2
  • Il confronto fra tutte le coppie di elementi
    adiacenti viene detto passaggio
  • Se, durante il primo passaggio, è stato
    effettuato almeno uno scambio, occorre procedere
    ad un ulteriore passaggio
  • Ad ogni passaggio, almeno un elemento assume la
    sua posizione definitiva (lelemento più grande
    del sottoinsieme attualmente disordinato)
  • Devono essere effettuati al più n?1 passaggi
  • Al k?esimo passaggio vengono effettuati n?k
    confronti (con eventuali scambi) almeno k?1
    elementi sono già ordinati
  • Complessivamente, vengono effettuati n?(n?1)/2
    confronti
  • ? La complessità computazionale del Bubblesort è
    O(n2)

37
38
Bubblesort ? 3
?define FALSE 0 ?define TRUE 1 ?include
ltstdio.hgt void bubble_sort(list, list_size) int
list, list_size int j, temp,
sorted?FALSE while(!sorted)
sorted ? TRUE / assume che list sia ordinato
/ for(j?0 jltlist_size?1 j??)
if(listjgtlistj?1)
/ almeno un elemento non è in ordine /
sorted ? FALSE
temp ? listj listj ?
listj?1 listj?1 ? temp
/ fine del ciclo for
/ / fine del ciclo while /
Nota Nel caso migliore, quando il vettore è già
ordinato, si effettua un solo passaggio, con n?1
confronti e nessuno scambio ? La complessità
scende a O(n)
38
39
Le stringhe
39
40
Definizione
  • Una stringa è un array di caratteri terminato dal
    carattere nullo, corrispondente alla sequenza di
    escape \0 (con valore numerico associato zero)
  • Una stringa costante (o letterale) è una serie di
    caratteri racchiusi fra doppi apici tale stringa
    è di tipo array di caratteri, con ogni carattere
    che occupa un byte
  • Ad ogni stringa viene aggiunto automaticamente
    dal compilatore un carattere nullo, ad indicarne
    la fine

40
41
Dichiarazione e inizializzazione ? 1
  • Per memorizzare una stringa occorre dichiarare un
    array di char, che può essere inizializzato con
    una stringa costante
  • static char str?testo
  • Larray ha dimensione maggiore di uno rispetto
    alla lunghezza della stringa, per consentire la
    memorizzazione del carattere nullo di
    terminazione (str ha lunghezza 6 byte)
  • Il compilatore segnala un errore se si dichiara
    la lunghezza della stringa n, e si inizializza
    con una stringa costante di lunghezza gtn
  • static char str3?quattro / SCORRETTO /
  • static char str13?tre / CORRETTO /
  • I compilatori ANSI, generalmente, consentono di
    specificare una dimensione di array che non
    includa il carattere terminatore

41
42
Dichiarazione e inizializzazione ? 2
  • È possibile inizializzare un puntatore a char con
    una stringa costante
  • char ptr altro testo
  • si crea un array di caratteri, inizializzato ad
    altro testo, ri-servando però memoria anche per
    il puntatore
  • Nel caso dellarray, tutti i successivi accessi
    utilizzano il nome dellarray come riferimento
    per lindirizzo dellelemento iniziale
    dellarray tale indirizzo non può essere
    modificato
  • Il puntatore è una variabile e può essere
    modificato lindirizzo relativo alla prima
    inizializzazione viene perso

ptr
1006
2000
42
43
Gli assegnamenti a stringhe
  • Un puntatore a char può essere inizializzato con
    una stringa costante, perché una stringa è un
    array di char
  • Una stringa costante viene interpretata come un
    puntatore al primo carattere della stringa

?include ltstdlib.hgt main() char
array10 char ptr1 ? 10 spazi char
ptr2 array ? not OK / non è possibile
assegnare un indirizzo / array5 ? A
/ OK / (ptr1?5) ? B / OK / ptr1
? OK ptr15 ? C / opinabile a causa
dellassegnamento precedente / ptr2 ? not
OK/ conflitto di tipi / ptr2 ? OK
/ opinabile perché non cè inizializzazione /
exit(0)
43
44
Stringhe e caratteri ? 1
  • Occorre notare la differenza fra stringhe
    costanti e costanti di tipo carattere
  • È possibile assegnare una costante carattere
    allindirizzo contenuto in un puntatore a char è
    invece scorretto effettuare la stessa operazione
    relativamente ad una stringa

char ch ? a / Per a è riservato un byte /
/ Vengono riservati due byte per a, oltre
allo spazio necessario alla memorizzazione di
ps / char ps ? a
char p2 p2 ? a / not OK / p2 ? a / OK
/
char p1 p1 ? a / OK / p1 ? a / not
OK /
Le stringhe sono interpretate come puntatori a
carattere
44
45
Stringhe e caratteri ? 2
  • Le inizializzazioni e gli assegnamenti non sono
    simmetrici è infatti possibile scrivere
  • char p ? string
  • ma non
  • p ? string
  • Nota vale per inizializzazioni ed assegnamenti
    di tutti i tipi di dati
  • float f
  • float pf ? f /OK /
  • pf ? f / SCORRETTO /

Puntatore a carattere
Carattere
Puntatore a float
Float
45
46
Lettura e scrittura di stringhe ? 1
  • Le stringhe possono essere lette e scritte
    utilizzando le funzioni scanf() e printf(), con
    lo specificatore di formato s
  • Largomento della funzione scanf() deve essere un
    puntatore ad un array di caratteri di dimensioni
    sufficienti a contenere la stringa in ingresso,
    che si intende terminata da un qualsiasi
    carattere di spaziatura
  • La funzione scanf(), dopo aver letto il dato in
    ingresso, aggiunge automaticamente il carattere
    \0 in fondo alla stringa
  • Largomento della funzione printf() deve essere
    un puntatore ad un array di caratteri terminato
    dal carattere nullo (che non viene stampato)

46
47
Lettura e scrittura di stringhe ? 2
  • Esempio Scrivere un programma che legge una
    stringa dalla periferica dingresso di default e
    la stampa dieci volte

?include ltstdio.hgt ?include ltstdlib.hgt ?define
MAX_CHAR 80 main() char strMAX_CHAR
int i printf(Introdurre una stringa)
scanf(s, str) for (i?0 ilt10 i??)
printf(s\n, str) exit(0)
È possibile utilizzare il nome dellarray come
argomento per le funzioni di I/O, in quanto
puntatore allinizio dellarray
47
48
Le funzioni di libreria per le stringhe strlen()
  • La funzione strlen(), restituisce il numero di
    caratteri che compongono una stringa (escluso il
    carattere nullo)
  • Poiché nellespressione str?? i due operatori
    hanno la stessa precedenza ed associatività
    de-stra, lespressione viene analiz-zata dal
    compilatore nel modo seguente
  • Valutazione delloperatore di incre-mento
    postfisso il compilatore passa str alloperatore
    successivo e lo incrementa solo al termine della
    valutazione dellespressione

int strlen(str) char str int i for
(i?0 str?? i??) / istruzione vuota
/ return i
  • Valutazione delloperatore , applicato a str
  • Completamento dellespressione, con lincremento
    di str

48
49
Le funzioni di libreria per le stringhe strcpy()
  • La funzione strcpy() copia una stringa in unaltra
  • Il risultato dellassegnamento costituisce la
    condizione di test per il ciclo while
  • Se s2 vale zero (per il carattere di
    terminazione), si ha luscita dal ciclo

void strcpy(s1, s2) char s1, s2
while(s2?? ? s1??) /istruzione vuota /
  • Loperatore di incremento postfisso è
    obbligatorio un incremento prefisso non
    produrrebbe un risultato corretto, dato che il
    primo elemento non verrebbe copiato

49
50
Le funzioni di libreria per le stringhe strstr()?
1
  • La funzione strstr() effettua la ricerca di una
    sottostringa allinterno di una stringa,
    operazione detta comunemente pattern matching
  • La funzione prevede come argomenti due puntatori
    a stringhe di caratteri ed effettua la ricerca di
    unoccorrenza della seconda stringa nella prima
  • se esiste unoccorrenza, viene restituita la
    posizione dinizio nellarray
  • altrimenti, viene restituito ?1
  • Nota la maggior parte delle funzioni della
    libreria di run?time restituisce 0 o ?1, come
    valore di errore (per strstr(), 0 corrisponde
    alloccorrenza della seconda stringa allinizio
    della prima)

50
51
Le funzioni di libreria per le stringhe strstr()?
2
/ Restituisce la posizione di str2 in str1
restituisce ?1 se non esiste occorrenza / int
strstr(str1, str2) char str1, str2
char p, q, substr / Itera su ogni
carattere di str1 / for(substr?str1
substr substr??) p ? substr
q ? str2 / Controlla se loccorrenza
di str2 corrisponde alla posizione corrente /
while(q) if(q?? !? p??)
goto no_match / serve per
uscire dal while, ma restare nel for / /
Si giunge qui solo se si è trovata unoccorrenza
di str2 / return substr?str1 /
Si giunge qui se non è stata riscontrata
unoccorrenza di str2 (nel ciclo while) /
no_match / Si giunge qui se
non vi sono occorrenze di str2 in str1 /
return ?1
51
52
Le funzioni di libreria in string.h
strcpy() Copia una stringa in un array
strncpy() Copia una parte di una stringa in un array
strcat() Concatena due stringhe
strncat() Concatena parte di una stringa ad unaltra
strcmp() Confronta due stringhe
strncmp() Confronta due stringhe per una lunghezza data
strchr() Cerca la prima occorrenza di un carattere specificato in una stringa
strcoll() Confronta due stringhe sulla base di una sequenza di confronto definita
strcspn() Calcola la lunghezza di una stringa che non contiene i caratteri specificati
strerror() Fa corrispondere ad un numero di errore un messaggio di errore testuale
strlen() Calcola la lunghezza di una stringa
strpbrk() Cerca la prima occorrenza di uno tra i caratteri specificati allinterno di una stringa
strrchr() Cerca lultima occorrenza di un carattere in una stringa
strspn() Calcola la lunghezza di una stringa che contenga caratteri specificati
strstr() Cerca la prima occorrenza di una stringa in unaltra
strtok() Divide una stringa in una sequenza di simboli
strxfrm() Trasforma una stringa in modo che sia utilizzabile come argomento per strcmp()
52
53
Esempio Calcolo delletà
/ Esempio di conversione da stringa ad intero
/ ?include ltstdio.hgt ?include
ltstdlib.hgt main() char anno_nascita5,
anno_corrente5 int anni
printf(Inserire lanno di nascita )
scanf(s, anno_nascita) printf(Inserire
lanno corrente ) scanf(s,
anno_corrente) / atoi() converte una
stringa in un intero / anni ?
atoi(anno_corrente) ? atoi(anno_nascita)
printf(Età d\n, anni) exit(0)
53
54
Esempio Parole nella stringa
/ Conta il numero di parole in una stringa
/ ?include ltctype.hgt int word_count(s) char
s int count?0 while(s !?\0)
while(isspace(s)) / salta
la spaziatura / ??s
if(s !?\0) / trovata una parola /
??count
while(!isspace(s) s !?\0)
??s / salta la parola /
return count
54
55
Esempio Parole palindrome
/ Letta in input una stringa, verifica se è
palindroma / ?include ltstdio.hgt ?include
ltstdlib.hgt ?include ltstring.hgt main()
char parola32, i?0, n printf(Inserisci
una parola (lunga al max 31 caratteri) )
scanf(s, parola) n ? strlen(parola)
while((i ?? n/2) (parolai ? ?
parolan?1?i)) i?? if(i ? n/2)
printf(La parola s è palindroma.\n, parola)
else printf(La parola s non è
palindroma.\n, parola) exit(0)
55
56
Esempio Da minuscole a maiuscole
/ Letta una stringa alfabetica, la riscrive
con solo lettere maiuscole/ ?include
ltstdlib.hgt ?include ltstdio.hgt ?include
ltstring.hgt main() char s100,
t100 int i
printf(Inserisci una stringa )
scanf(s, s) for (i?0 i?strlen(s)
i??) if (si ?? 97
si ?? 122) ti ? si ?
32 else ti ?
si printf(Stringa
maiuscola s\n, t) exit(0)
56
Write a Comment
User Comments (0)
About PowerShow.com