vuoi
o PayPal
tutte le volte che vuoi
Touch: C, permette di creare un file nella directory corrente
Tree: C, visualizza albero directory dalla directory corrente.
Quit: C, serve per tornare al prompt.
WHICH: C, dice il nome del file che viene eseguito per eseguire il comando da me impartito. In soldoni stampa il percorso
assoluto del file stesso.
WILDCARD: “*” = nessuno o più caratteri “?” = uno e un solo carattere. Sono operatori della shell, utile, con ls, per
individuare nomi di file con determinate caratteristiche.
>, operatore di redirezione.
Costrutti di controllo
Istruzioni composte: le pongo tra parentesi graffe {istr1 istr2}, ogni istr avrà il proprio punto e virgola.
Costrutto if: if (espr) / { 1 o più istruzioni}
Costrutto if else: if (espr) / { 1 o più istruzioni} / else {1 o più istruzioni}
-Condizioni complesse con operatori logici: if ((a%2=0) && (a/2=0) || !(a%2=1))
Costrutto for: for (espr1 (inizializzazione, si ripete solo all’inizio del ciclo); espr2 (condizione) ; espr3
(incremento/decremento contatore)) istr (eseguita se condizione è positiva)
Costrutto While: while (espr (condizione)) istr , se la condizione è vera esegue l’istruzione.
Costrutto do-while: do istr while (espr), viene eseguita un’istruzione, ed in base alla condizione si
decide se continuare o no ad eseguirla.
Costrutto Switch: switch (sel), parentesi graffe obbligatorie, case 1, case 2 … case n. Ogni case termina con un break. Ogni
case ha istruzioni. Se non viene selezionato nessun caso si va al default.
Controllo del flusso di esecuzione: fattibile grazie a break (termina il ciclo più interno) e continue (passa immediatamente
all’iterazione successiva; in for viene fatto l’incremento e poi valutata la condizione).
Salto incondizionato: fattibile grazie a “goto etichetta”, e reindirizza ad etichetta. Non posso saltare tra funzioni diverse ed
è utile per non dover usare n break in una funzione con diversi cicli nidificati. Etichetta: printf.
Identificatori
%0nx, numero esadecimale con almeno n cifre, e sostituisce, eventualmente, con 0.
%ni, intero con almeno n cifre, sostituirebbe spazio.
%c, stampa il carattere ASCII corrispondente al numero.
%s, stampa stringa.
%lf, double
Differenza tra singoli e doppi apici
Singoli: costante di tipo char
Doppi: stringa, con relativo terminatore
Tipi di dati
Il C è un linguaggio tipizzato, ovvero ad ogni variabile deve essere assegnato un tipo, in modo da – verificare che
l’assegnamento avvenga correttamente (semi aspetto un numero intero non accetterà un testo) – riserva una parte
di memoria (fissa, per ogni tipo) per la variabile. Calcolatore deve conoscere indirizzo, dimensione e tipo di dato
(per capire come tradurre il binario).
Tipi interi: la dimensione di ognuno di essi dipende dal processore e dal compilatore. (char, short, int, long, long
long). Esistono i signed e gli unsigned (con 8 bit, Sign -128 +127, UnS 0 +255). Costanti intere, abbiamo la possibilità
di rappresentarle in base 10, 8 e 16 (aggiungendo uno 0 [8], 0x [16]). Col tipo char posso rappresentare tra singoli
apici il numero del carattere ASCII corrispondente. S E
Tipi a virgola mobile: rappresentati secondo lo standard IEEE, come (-1) M 2 . Includendo math.h posso fare calcoli
matematici basati sul double, compilandolo inserendo -lm. Bisogna utilizzare angoli in radianti (π = m_pi). Costanti
in float, double se non specifico. Posso dotare il numero di esponente (e/E).
Puntatori: sono variabili che rappresentano un indirizzo di memoria. Serve il tipo a cui si punta, asterisco e il nome.
E’ int il valore puntato da p. E’ una variabile contenente un indirizzo, nel quale sono presenti dei bit da interpretare
come un numero di tipo intero. Ogni puntatore, sulla stessa macchina, ha la stessa dimensione.
Tramite l’operatore & posso ottenere l’indirizzo di una variabile, ed assegnarlo poi, eventualmente, al mio
puntatore.
Tramite l’operatore * posso accedere al valore contenuto in un determinato indirizzo di memoria. “*p=3” significa
quindi: assegna il valore 3 alla cella corrispondente all’indirizzo situato in p. Accedendo ad un’area di memoria in
questo modo tramite un puntatore, si definisce Deferenziare un puntatore.
Esiste il puntatore nullo, p=0, e 0 è un indirizzo di memoria non accessibile.
Array: aree contigue di memoria in cui sono memorizzati elementi di tipo omogeneo. In base alla loro dimensione
prendono nomi diversi. Vettori: sintassi, int vett[n° elem] (N.B. vett = nome vettore) . Ogni elemento del vettore è
esprimibile come vett[0]… vett [N-1], dati N elementi. I dati sono memorizzati in indirizzi di memoria contigui, in
questo modo posso sempre trovare l’indirizzo dell’ i-esimo elemento con: base + i * dim (base = indirizzo 1°
elemento, dimensione del tipo di dato). Il vettore può essere visto come un puntatore costante, che punta al primo
elemento del vettore (vett fornisce indirizzo del primo elemento del vettore), quindi scrivere vet[0] o *vet è la
stessa cosa (*(vet+1) = vet[1]). N.B. è possibile sbagliare il numero di indicizzazione del vettore errato, e ciò può o
portare ad un segmentation fault (non poterci accedere) o, peggio, accedere ad una locazione di memoria a cui il
programma può accedere e modificare altri dati, di cui non conosciamo l’entità e la funzione.
Inizializzazione: - int vett[] = {1, 2, 5} non specificando il numero. – int vett[10] = {2, 3} inizializzazione parziale, i
primi due a 2 e 3 mentre gli altri 8 a 0. N.B. sizeof(vett)=dimens vettore.
Sizeof: operatore che ritorna la dimensione in byte dell’oggetto indicato.
Stringhe: costanti, sequenza di 0 o più caratteri tra doppi apici, concatenabili con spazio. Variabili, dichiarata come
vettore di tipo char con N elementi, più un carattere di terminazione, lo ZERO (0 o ‘\0’). Quindi la dimensione di una
stringa comprende anche il carattere di terminazione. Visualizzo stringa con puts. N.B. stringa ha SEMPRE N
caratteri, anche se gli ho copiato dentro solo 10 caratteri, gli altri sono aleatori (tranne lo 0 dopo i 10 caratteri).
Funzioni su stringhe: strcpy(s, “stringa”)= copia nella stringa s un’altra stringa. Strcat(stringa1, stringa2)= accoda
stringa2 a stringa1. Strlen(s), individua lunghezza totale della stringa. Strstr(s, “in”) cerca la stringa “in” da sx
all’interno di s, per poi stampare la stringa (con puts) ed il continuo della stringa principale. Strchr(s, ‘e’) cerca il
carattere e fa come Strstr. Strrchr(s, ‘e’), come la precedente, solo che partendo da dx. Strcmp(stringa 1, stringa
2), funzione che compara due stringhe, dice se sono uguali o se la prima viene prima in ordine alfabetico rispetto
all’altro (restituisce valore <0) oppure (>0) nell’altro caso.
Interi di dimensione prefissata: come sappiamo gli interi non hanno una dimensione fissa, ma essa dipende
dall’architettura sulla quale stiamo lavorando. Dal ’99 sono stati introdotti tipi di dimensione e segno noto.
Conversione ti tipo: automatica, il tipo del risultato è pari a quello dell’operando più ricco di informazioni.
Assegnamento, il valore assegnato viene convertito nel tipo dell’espressione a sx dell’uguale, se voglio assegnare ad
una variabile int un numero double mi perderò la parte decimale. Esplicita, viene fatta applicando esplicitamente
l’operatore di cast all’espressione da convertire. Forzo la conversione del valore nel tipo che io specifico. x/
(double)y =/= (double) (x/y). Tuttavia non cambio il tipo di dato associato alla mia variabile, ma soltanto del valore
in essa contenuto, “vedo il valore come double”.
PreProcessore
E’ un programma che elabora il contenuto di un sorgente prima della compilazione vera e propria. Esso opera
sostituzioni tipografiche sul codice prima che venga compilato. Vengono sostituite parti del codice con altro testo,
senza considerare il significato sintattico di ciò che si va a sostituire. Le direttive per il preprocessore sono
precedute dal # e permettono di: - includere altri file nel sorgente – ridefinire il significato degli identificatori -
disabilitare parti di codice per la compilazione.
#Define: usata per creare le macrodefinizioni, che fanno delle sostituzioni tipografiche. Ex. “#define H ciao” nel
testo ogni volta che il preprocessore incontra H gli sostituisce “ciao”. Le macro possono ricevere dei parametri, per
questo possono realizzare delle speudo-funzioni.
Funzioni
In C una funzione è una porzione di codice, che può essere richiamata in un programma. Ogni funzione ritorna un
valore e riceve opzionalmente una serie di parametri. Le funzioni possono essere dichiarate una volta sola in un
programma oppure si possono reperire in librerie di codice.
Dichiarazione: in essa viene specificato il prototipo della funzione., ed include: -tipo di dato restituito dalla funzione
-nome della funzione -tipi degli argomenti. int secondi (int h, int m, int s). Funzioni accettano tipi void e possono
restituire void come ritorno = funzione non richiede alcun parametro e non restituisce alcun parametro. Funzione
exti termina istantaneamente il programma.
Definizione: formata da -Dichiarazione -Corpo della funzione (tra graffe).
Chiamata: operazione con la quale si richiama l’esecuzione della funzione. int a; a = funzione( int b, int c);. Quando
una funzione termina (con return) il programma riprende dal punto in cui la funzione è stata richiamata. N.B.
richiamando una funzione devo stare attento ad inserire nei parametri dei dati dello stesso tipo, altrimenti avrei
risultati (ex. troncamenti) errati.
Passaggio dei parametri: i parametri sono necessari alla funzione per funzionare. Essi vengono passati dalla
funzione chiamante alla funzione chiamata, ciò si dice passaggio per valore. La funzione chiamata utilizza una copia
locale della variabile passata come parametro (la funzione potrà modificare soltanto la copia locale, in quanto le 2
variabili sono allocate in porzioni di memoria diverse). N.B. le variabili locali allocano spazio in memoria soltanto nel
momento in cui la funzione viene chiamata, e liberata quando la funzione termina.
Passaggio per riferimento: in questo modo è possibile modificare il valore delle variabili passate dalla funzione
chiamante. In questo modo posso ritornare più di un valore e non perdo tempo nella copia di variabili. Questo
passaggio avviene tramite il passaggio per valore del puntatore alla variabile, così che la funzione chiamata
conosca l’indirizzo in cui è memorizzata la variabile della funzione chiamante.
Calcolo di un istogramma: vedi pag. 113
Passaggio di parametri al programma principale: un modo per passare dei dati in ingresso ad un programma è il
passaggio di parametri tramite linea di comando, nella parte dedicata agli argomenti