• Non ci sono risultati.

C librerie standard

N/A
N/A
Protected

Academic year: 2021

Condividi "C librerie standard"

Copied!
32
0
0

Testo completo

(1)

C librerie standard

Il C è un linguaggio ricco di librerie che possono essere opportunamente caricate con la direttiva <include> del compilatore.

La libreria standard C (RunTIme Library) contiene centinaia di funzioni ed è suddivisa in sezioni

Il linker accede, in genere, automaticamente ai codici binari della libreria

Il compilatore, invece,

richiede che tutte le funzioni usate nel programma siano espressamente dichiarate tramite inclusione dei

corrispondenti header-files

Header file Descrizione

ctype.h Funzioni che verificano proprietà dei caratteri

string.h Funzioni di elaborazione di stringhe

stdio.h Funzioni per operazioni di input/output

stdlib.h Funzioni di conversione numeri in stringhe e viceversa, generatori causali, altre utilità

time.h Funzioni manipolazione date e valori temporali

... ...

(2)

C libreria ctype.h

La libreria ctype (ctype.h) contiene funzioni che verificano proprietà dei caratteri.

Ritornano un intero e non un booleano (anche se resta inteso che un valore nullo sta per false ed un valore diverso da zero sta per true).

Prototipo Descrizione

int isalnum (int c); Controlla se c è una cifra o una lettera int isalpha (int c); Controlla se c è una cifra o una lettera int isdigit (int c); Controlla se c è una cifra

int iscntrl (int c); Controlla se c è un carattere di controllo int isspace (int c); Controlla se c è un separatore

int isxdigit (int c); Controlla se c è una cifra esadecimale

int tolower (int c); Se c è una lettera, restituisce la sua versione minuscola, altrimenti restituisce c inalterato

int toupper (int c); Se c è una lettera, restituisce la sua versione maiuscola, altrimenti restituisce c inalterato

...

(3)

C libreria ctype.h

Manipolazione di caratteri

int isdigit(int c) {

return ((c>=‘0’)&&(c<=‘9’));

}

int isalpha(int c) {

return (((c>=‘a’)&&(c<=‘z’)) || ((c>=‘A’)&&(c<=‘Z’)));

}

int tolower(int c) {

if isupper( c )

c=c-’A’+’a’;

return c;

}

(4)

C libreria stdlib.h

La libreria stdlib (stdlib.h) contiene funzioni di conversione di numeri in stringhe e viceversa, generatori causali, altre utilità

Prototipo Descrizione

int atoi(const char s[]); Converte la stringa C contenuta nell’array s in un intero void itoa(int n, char sn[], int b); Converte il numero intero n in una stringa C, copiata

nell’array sn

double atof(const char s []); Converte la stringa C contenuta nell’array s in un

double. La funzione restituisce 0 se la C non contiene un numero reale valido

int rand (); Genera un numero pseudocasuale

void srand(unsigned int seme); Genera un punto di partenza per la funzione rand().

void exit(int CodiceDiUscita); Provoca l’immediata terminazione del programma e fornisce il CodiceDiUscita al sistema operativo.

int system (const char cmd []); Invia la stringa cmd all’interprete dei comandi del sistema operativo

...

(5)

C libreria stdlib.h

La funzione rand() genera in maniera casuale un numero intero compreso tra 0 e 32767

32767 è il massimo intero rappresentabile con 2 byte

Casuale significa che valore tra 0 e 32767 ha la stessa probabiltà di essere generato

Esempio: simulare il lancio di un dado

n = rand() % 6 + 1;

(6)

C libreria stdlib.h

Problema dell’estrazione del lotto: simulare una sequenza casuale di n numeri senza ripetizioni nell’intervallo [0 nr] (n≤nr)

• La sequenza ordinata di valori [0, 1, 2, …, nr] viene “mischiata”:

scorrendo dal primo all’ultimo valore, il valore i-esimo viene scambiato con un altro valore (anche sé stesso) selezionato casualmente

for i from 0 to nr-1:

numeri[i] ß i for i from 0 to nr-1:

indice ß random(0,nr);

temp ß numeri[indice];

numeri[indice] ß numeri[i];

numeri[i] ß temp;

for i from 0 to n-1:

randnumeri[i] ß numeri[i];

Algoritmo

2

numeri

...

indice (casuale) i

1

0

scambia

3 4 5 6 89

4 27

33 43 0

randnumeri

75 12 ... 65

(7)

C libreria stdlib.h

Se eseguiamo più volte un programma contenente l’istruzione rand() si vede che i valori generati sono sempre gli stessi.

La procedura srand(seme) ha lo scopo di cambiare il valore iniziale e quindi tutta la serie secondo il valore introdotto nella variabile seme.

all’inizio di ogni programma invocando la funzione:

srand(time(0))

si fa sì che le successive invocazioni della funzione rand() generino

unasuccessione diversa di valori casuali ad ogni esecuzione del programma

(8)

C libreria time.h

La libreria time (time.h) contiene funzioni di manipolazione date e valori temporali

Prototipo Descrizione

double time(); Restituisce il tempo assoluto in secondi double

localtime(); Converte il tempo assoluto nella rappresentazione suddivisa double asctime(); Converte in stringa il tempo memorizzato in una struttura tm double ciftime(); Calcola intervalli di tempo

double clock(); Restituisce il tempo trascorso dall’inizio dell’esecuzione del programma (in ticks)

...

struct tm

{int tm_sec; //secondi 0..59 int tm_min; //minuti 0..59 int tm_hour; //ora 0..23 int tm_mday; //giorno 1..31 int tm_mon; //mese 0..11

int tm_year; //anno 0..anno-1900 int tm_wday; //secondi 0..6

int tm_yday; //secondi 0..365 ...

(9)

C libreria string.h

La libreria string (string.h) contiene funzioni di manipolazione di stringhe

Prototipo Descrizione

char *strcpy(char *s, char *cs); copia cs in s e ritorna s char *strcat(char *s, char *cs); concatena cs ad s e ritorna s

int strcmp(char *cs1, char *cs2); confronta cs1 e cs2; se cs1 < cs2 il valore di ritorno è < 0; se cs1 > cs2 il valore di ritorno è > 0;

se le due stringhe sono uguali il valore di ritorno è 0 char *strstr(char *cs1, char *cs2); restituisce un puntatore alla prima occorrenza in

cs1 della stringa cs2

size_t strlen(char *cs); restituisce la lunghezza di cs

...

(10)

C librerie personali

Nella scrittura di programmi accade spesso di dover utilizzare le stesse operazioni: un tipico esempio è dato dalle istruzioni di input/output. A questo scopo conviene progettare una sola volta le funzioni che ci

servono per poi tenerle pronte per un possibile riutilizzo.

Costruiamo una funzione per l’inserimento dei numeri interi.

Il file, che chiameremo InsertNumero.h potrà essere richiamato da qualsiasi programma.

(11)

C librerie personali

Per costruire una funzione che restituisca solo numeri interi osserviamo che:

1. conviene accettare l’input sotto forma di stringa per poi trasformarlo in numero intero con la funzione di sistema atoi(stringa) contenuta nell’header

<stdlib>;

2. la funzione atoi(stringa) si comporta in questo modo:

a- se il primo carattere non è né una cifra, né il segno + o – allora restituisce il valore 0;

per esempio se digitiamo aa321 restituisce zero; per evitare che ogni digitazione errata corrisponda al valore zero dobbiamo controllare se il primo carattere inserito è 0;

b- se il primo carattere è una cifra oppure è un segno + o – allora restituisce solo il numero corrispondente alle prime cifre digitate; per esempio:

atoi("aa321") à 0 atoi("124-33") à 124

3. considerare la possibilità che il numero inserito sia incluso tra due valori assegnati (per default supporremo che questi valori siano compresi tra –2 miliardi e +2 miliardi).

(12)

C libreria inserimento dati

Scriviamo una libreria per l’inserimento di numeri interi

supponiamo l’input come stringa per poi trasformarlo in numero intero con la funzione di sistema atoi(stringa) (includi il file stdlib.h)

il numero inserito è nell’intervallo consentito [-2miliardi, +2miliardi]

function NumeroIntero(limiteinf, limitesup) ok ß ‘falso’

do:

leggi(stringaint)

Numero ß atoi(stringaint)

if ((Numero ≥ limiteinf) and (Numero £ limitesup)):

ok ß ‘vero’

if (Numero=0 and primocarattere(stringaint) ¹ ‘0’) ok ß ‘falso’

while (ok = ‘falso’):

return Numero:

(13)

C libreria inserimento dati

Se includiamo il codice nelle nostre librerie per richiamarlo basterà scrivere

#include “InsertNumero.h”

Se il nome del file header viene posto tra “ ” allora il

compilatore si aspetta di trovarlo nella stessa directory del file chiamante, mentre se viene posto tra parentesi angolari

<> lo cerca nella libreria include (in genere settabile come parametro di variabile d’ambiente nel compilatore).

(14)

C libreria inserimento dati

Se il file viene richiamato più volte nel corso di un programma, per evitare problemi è possibile utilizzare la direttiva condizionale del compilatore #ifndef.

Scrivere ad esempio

#ifndef INSERT_NUMERO_H

#define INSERT_NUMERO_H

……istruzioni

#endif

significa segnalare al compilatore che in questo programma, con l’istruzione

#define INSERT_NUMERO_H

viene definita la costante INSERT_NUMERO_H; la direttiva

#ifndef

avverte il preprocessore di controllare se è già stata definita la costante INSERT_NUMERO_H

se tale costante non è stata ancora definita, allora devono essere compilate tutte le istruzioni comprese tra #ifndef e #endif, altrimenti quella stessa parte di codice non deve essere presa in considerazione.

(15)

#ifdef INSERT_NUMERO_H

#define INSERT_NUMERO_H

#include <stdio.h>

#include <stdlib>

using namespace std;

// PROTOTIPO

int NumeroIntero(const char[], float=-2e9, float=2e9);

// DEFINIZIONE

int NumeroIntero(const char INTEST[],float inf, float sup) {

char INT1[12];

int i,m;

bool OKint=false;

do {

printf(INTEST);

scanf("%d", &INT1);

m=atoi(INT1);

if (m>=inf && m<=sup) OKint=true;

if (INT1[0]!='0' && m==0) OKint=false;

} while(!(OKint));

return m;

}

#endif

C libreria inserimento dati

#include <stdio.h>

#include "InsertNumero.h"

using namespace std;

int main () { int n;

n=NumeroIntero ("Inserire un numero intero:");

printf("%d\n",n);

}

(16)

C libreria utilità vettori

Scriviamo una libreria di funzioni di utilità per vettori:

LeggeVettore() - legge un vettore generico di dimensione n Parametri:

• int [] Vet è Vet è il vettore restituito (per un vettore non è necessario introdurre l’operatore & )

• const int n è n rappresenta la lunghezza del vettore assegnato come parametro in input

• char nome è nome è un carattere che rappresenta il nome del vettore

• bool Acaso èAcaso è un valore booleano che, se vale true, assegna a caso i valori del vettore, se false aspetta che siano immessi da tastiera; notiamo che esso è un parametro di default, bool=true nel prototipo

(dichiarazione), per cui se non viene inserito si sottintende true.

• int nr è tutti i valori generati dal computer sono compresi nell’intervallo (- nr; nr) estremi esclusi

(17)

C libreria utilità vettori

Scriviamo una libreria di funzioni di utilità per vettori:

StampaVettore() stampa il vettore sul monitor;

i parametri formali sono:

const int[] a è a è il vettore da stampare (che può anche essere un vettore costante)

const int n è rappresenta la lunghezza del vettore assegnato come parametro in input

char nome è un carattere che rappresenta il nome del vettore

(18)

C libreria utilità vettori

Scriviamo una libreria di funzioni di utilità per vettori:

La libreria la organizziamo in un unico (header) file // InsertArray.h

#ifndef INSERT_ARRAY_H

#define INSERT_ARRAY_H

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <time.h>

using namespace std;

//PROTOTIPI

void LeggeVettore (int [],const int, char, bool=true, int=100);

void StampaVettore (const int [], const int, char);

//DEFINIZIONI ...

(19)

C libreria utilità vettori

Scriviamo una libreria di funzioni di utilità per vettori:

...

void LeggeVettore (int vet[],const int n, char nome, bool Acaso, int nr) {

int i;

if (Acaso){

srand(time(0));

for (i=0; i<n; i++) {

vet[i]=rand() % nr - nr/2;

printf("%c[%d]=%d", nome, i, vet[i]);

} }

else {

for (i=0; i<n; i++) {

printf("%c[%d]=%d", nome, i);

scanf("%d", &vet[i]);

} } }

...

(20)

C libreria utilità vettori

Scriviamo una libreria di funzioni di utilità per vettori:

...

void StampaVettore (const int a[], const int n, char nome) { int i;

for (i=0; i<n; i++) {

printf("%c[%d]=%d\n", nome, i, vet[i]);

} }

#endif

(21)

C libreria utilità stringhe

Scriviamo una libreria di funzioni di utilità per stringhe:

Confronta se due stringhe sono uguali (paragona)

Confronta due stringhe e ritorna un valore booleano, true se le stringhe sono uguali, false altrimenti.

Calcola la lunghezza di una stringa

Restituisce la lunghezza della stringa.

Concatena due stringhe

Restituisce il risultato nella terza.

#ifndef stringhe_array_h

#define stringhe_array_h

#include <stdio.h>

using namespace std;

// PROTOTIPI

bool paragona (const char[], const char[]);

int lung(const char[]);

void concat(const char[], const char[], char[]);

// DEFINIZIONI

//qui vanno inserite le implementazioni delle funzioni

#endif

(22)

C libreria utilità stringhe

Utilizziamo la parola chiave const per tutte le variabili di input nella lista dei parametri formali: in questo modo anche una stringa costante può essere passata come parametro.

La prima funzione paragona confronta due stringhe; per verificarne l’uguaglianza è necessario confrontarle carattere per carattere: se due caratteri sono distinti allora le stringhe non sono uguali e la funzione deve restituire false, true altrimenti.

22

22

Finché i due caratteri i-esimi sono uguali

Se la stringa è terminata restituisci TRUE Incrementa l’indice i

Se esce dal ciclo allora i due caratteri sono diversi e quindi

restituisci FALSE

bool paragona (const char s1[], const char s2[]) { int i=0;

while (s1[i]==s2[i]) { if (s1[i]=='\0')

return true;

i++;

}

return false;

}

(23)

C libreria utilità stringhe

La seconda funzione lung calcola il numero di caratteri racchiusi in una stringa: è sufficiente scandire la stringa inserendo un contatore nel ciclo (per eliminare il tipico errore off by one viene restituito un valore

decrementato di una unità).

int lung(const char s1[]) { int i=0;

while (s1[++i]!='\0');

return i--;

}

(24)

C libreria utilità stringhe

L’ultima funzione concat concatena due stringhe S1 ed S2 in S3.

A questo scopo, si copiano in S3 prima tutti i caratteri di S1, successivamente tutti quelli di S2 ed, infine, si aggiunge il carattere di fine stringa ‘\0’.

void concat(const char s1[], const char s2[], char s3[]) { int i=0,j=0;

while (s1[i]!='\0') { s3[i]=s1[i];

i++;

}

while (s2[j]!='\0') { s3[i++]=s2[j++];

}

s3[i]='\0'; // inserisce il simbolo di fine stringa }

(25)

C libreria utilità stringhe

Scriviamo un programma che usa la libreria di funzioni di utilità per stringhe

#include <stdio.h>

#include <stdlib.h>

#include "stringhearray.h"

using namespace std;

int main () {

char t[10],s[10],z[20];

printf("stringa s =");

scanf("%s", s);

printf("stringa t =");

scanf("%s", t);

printf("Lunghezze\ns = %d\nt = %d\n", lung(s), lung(t));

concat(s,t,z);

printf("stringa s concatenata a t = %s\n", z);

if (paragona(s,t))

printf("Le due stringhe sono uguali\n");

else

printf("Le due stringhe NON sono uguali\n");

return 0;

}

(26)

C libreria utilità stringhe

Problema: Data una stringa qualsiasi verificare se è palindroma

Una stringa è palindroma quando ha uguali i caratteri che hanno la stessa distanza dal centro della stringa. Per esempio

Palindromi NON palindromi

ANNA AMARA

ADA AROMA

DEOED ODE

baccdccab abcab

detta n la lunghezza della stringa, se è palindroma sarà:

s[i]=s[n-1-i] per ogni i=0,…,n-1

(27)

Esercizi su funzioni e array

Esercizi: usare le funzioni di utilità per vettori e per stringhe

1. Generato in modo random un vettore contenente N interi relativi compresi tra –M ed M mediante una procedura, risolvere i seguenti problemi :

scrivere un programma che stampi tutti i numeri positivi e la loro posizione scrivere un programma che stampi tutti i numeri minori o uguali a zero scrivere un programma che stampi il più grande ed il più piccolo e le loro

posizioni

scrivere un programma che stampi tutti i numeri maggiori di un valore dato e le posizioni

scrivere una procedura che restituisca tutte le posizioni dei numeri negativi 2. Definire una funzione Uguali2 che prenda in input un vettore V di interi di

lunghezza n, e restituisca:

true se il vettore contiene almeno due numeri uguali, false altrimenti Esempi: Se V=[1,22,13,24,5] allora Uguali2(V) à false

Se invece V=[1,2,6,24,2] è Uguali2(V) à true

(28)

Esercizi su funzioni e array

3. Definire una procedura PrecSegueX che abbia in input un vettore V di interi di lunghezza n, ed un numero X, e:

inserisca all’inizio di V i valori di V minori o uguali ad X (preservandone l’ordine);

inserisca in seguito tutti i valori di V maggiori di X (preservandone l’ordine).

Esempio: Sia V= [56,35,4,2,22]. L’output di PrecSegueX(V,40) deve essere: V=[35,4,2,22,56]

4. Definire una funzione ContaCifre che prenda in input un vettore V di interi di lunghezza n, ed un numero X e conti quante volte tutte le cifre di X siano contenute negli elementi che compongono il vettore

Esempio: Siano V=[484,325,12,8489,48,12487,1284] e X=48;

ContaCifre(V,7,48) à 4

(sono evidenziati i numeri che contengono al loro “interno” il numero 48).

5. Definire una procedura GoDestra, che, assegnato un vettore V di n elementi ed un intero m, 0£ m £ n, sposti verso destra di m passi tutti gli elementi del vettore V

Esempio: Sia V=[7,8,9,0] ed n=4 otteniamo GoDestra(V,3) fa diventare V=[8,9,0,7]

(29)

Esercizi su funzioni e array

6. Scrivere una procedura Comuni, che assegnati due vettori V1, V2 di

dimensioni rispettivamente n1 ed n2, ponga in un altro vettore V3 tutti e soli gli elementi di V1 che compaiono anche in V2, conservando l’ordine con cui compaiono in V1

Esempio: Siano V1=[1,2,3,4,5], V2=[5,0,3,0,1], V3 qualunque.

Eseguiamo Comuni(V1, V2,V3). Allora V3 diventa [1,3,5]

7. Definire una procedura PariDispari che dato un vettore V di interi di lunghezza n:

ponga all’inizio di V i valori di V pari, nello stesso ordine in cui si trovavano in V;

li faccia seguire dai valori di V dispari, di nuovo nello stesso ordine in cui si trovano in V.

Esempio: Sia V= [5,3,4,2,1]. Eseguiamo PariDispari si deve avere: V = [4,2,5,3,1]

8. Scrivere una funzione che dato un array V di interi di dimensione n

restituisce true se nell’array V c’è un valore che è uguale alla somma di tutti i valori che lo precedono, false altrimenti

Esempio. V=[1, 4, 4, 9, 3] la funzione restituisce true perché V[3]=9=1+4+4

V=[1,3,5,8,3] la funzione restituisce false

(30)

Esercizi su funzioni e array

9. Scrivere una procedura che dati 2 array di interi V1 e V2 di dimensione n restituisce nell’array V3 gli elementi che appartengono a V1 ma non a V2 non ripetuti e in N3 il numero di tali elementi

Esempio: V1= [2, 4, 4, 5, 3] e V2= [7, 3 ,10 ,6 ,7] si deve ottenere V3= [ 2, 4, 5] con N3 =3

10. Scrivere una funzione che data una stringa s ed un carattere car restituisce il numero massimo di caratteri car consecutivi presenti nell’array

Esempio: s = ‘abcaacaaabaa', car=’a’ la funzione deve restituire 3 11. Scrivere una procedura che dato un array a ordinato di dimensione N

inserisce nell’array il valore x in modo tale che l’array dopo l’inserimento sia ancora ordinato

Esempio: Siano a = [2, 3, 7, 11, 24] e x =5 si deve ottenere a = [2, 3, 5, 7, 11,24 ]

(31)

Esercizi su funzioni e array

12. Scrivere un programma che, dati due vettori di interi di dimensione N, ne costruisca un terzo di dimensione 2N i cui elementi di posizione pari siano gli elementi del primo vettore e gli elementi di posizione dispari siano gli

elementi del secondo vettore. Strutturare il programma in procedure e funzioni

13. Scrivere un programma che, dato un vettore V1 di reali di dimensione N, ne generi un altro V2 così definito: il primo elemento di V2 è dato dal prodotto degli elementi 1 e 2 di V1, il secondo elemento di V2 è dato dal prodotto degli elementi 3 e 4 di V1, e così via

(32)

Esercizi su funzioni e array

14.Scrivere una procedura che genera un vettore V di numeri reali di dimensioni N (N£100). Con tale procedura scrivere un programma che

stampi prima tutti gli elementi di posto dispari e poi quelli di posto pari,

letto un indice h stampi l’indice ed il valore del più piccolo fra i numeri maggiori di V[h];

stampi l’indice ed il valore dei numeri di valore dispari massimo e minimo;

si costruisca e quindi si stampi un secondo array di N elementi tali che il primo

elemento contenga la somma di tutti gli N numeri, il secondo la somma dei numeri dal secondo in poi, il terzo la somma dal terzo in poi e così via;

si stampi l’indice ed il valore dell’elemento massimo fra gli elementi di posto dispari, quindi l’indice ed il valore del minimo fra gli elementi di posto pari;

letto un indice h, si costruisca e quindi si stampi un array di N elementi tali che il

primo sia quello specificato dall’indice, il secondo sia quello precedente e così fino al primo, poi proseguendo dall’ultimo retrocedendo fino a completare l’array.

15.Scrivere un programma che prenda in input un vettore già ordinato di interi e stampi in output l’istogramma delle occorrenze di ogni elemento del vettore.

Esempio. dato il vettore V=[1,1,1,3,5,5,7,7,7,7,10,10], deve stampare:

1 ***

3 *5 **

7 ****

10 **

Riferimenti

Documenti correlati

Possiamo pensare che la retta r t sia la retta per il punto O ed il punto P t che si muove di moto uniforme sulla circonferenza di centro O e raggio 1, percorrendo in senso

Valore assoluto Per parlare di vicinanza fra punti della retta reale conviene pas- sare attraverso la nozione di distanza fra due punti, e per descrivere la distanza fra due

Mariano Giaquinta Professore Emerito Scuola Normale Superiore Piazza dei Cavalieri, 7 I-56100

NeU.e ipotui pO.6te, peJt ogrU dato irUuale (.6, b) amrrU.M-i..bile peJt i l pdJt ui.6te almeno una /~o.f.uzione de.f. pdJL in n c.on

In questo modo l’istruzione: srand (time(NULL)); inizializza il generatore ad ogni esecuzione con un valore (seme) diverso e le successive istruzioni rand()

U numero della settimana dell'anno (Domenica viene considerato primo giorno della settimana) [00-53]. W numero della settimana dell'anno (Lunedì viene considerato primo giorno

strncpy() Copia i primi n caratteri di una stringa in un’altra stringa strcat() Concatena due stringhe. strncat() Concatena i primi n caratteri di una stringa ad un’altra

Esercizio: adesso provate a fare il send e receive di una matrice tra due processi usando i diversi