Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Introduzione alla Programmazione in C: Esercizi e Concetti Fondamentali, Appunti di Programmazione C

Tutto il linguaggio C, riassunto

Tipologia: Appunti

2022/2023

Caricato il 20/09/2023

Utente sconosciuto
Utente sconosciuto 🇮🇹

5

(1)

1 documento

1 / 37

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
PROGRAMMAZIONE:
INTRODUZIONE:
1) editor: qualsiasi programma in grado di creare e modificare file di testo per qualsiasi
linguaggio di programmazione
#include <stdio.h>
main(){
printf(“Hello World!\n”);
}
2) compilatore: trasforma un programma in un file di formato eseguibile in linguaggio
macchina
a) GCC -H (guida in linea), MAN GCC (man pages), INFO GCC (info pages)
b) SI SCRIVE:
i) gcc helloworld.c compila il file sorgente C e genera il file eseguibile
a.out
ii) gcc-o helloworld helloworld.c
c) se non compila è perché abbiamo violato delle regole della grammatica del
linguaggio C e riporta due messaggi di errore:
i) warning: non impedisce la compilazione, ma segnala un potenziale
problema
ii) error: indica un errore di sintassi che compromette la compilazione
SINTASSI:
1) i linguaggi di programmazione sono formali
2) EXTENDED BACKUS-NAUR FORM: linguaggio formale per esprimere delle
grammatiche
a) una produzione (::=) è composta da, per esempio:
i) <simbolo nonterminale>::= simbolo terminale |<simbolo nonterminale>
[<simbolo non terminale>]
ii) <simbolo nonterminale>::= simbolo terminale | simbolo terminale |
iii) <cifra> ::= simbolo terminale | <cifra non nulla>
per esempio: 0 e 23 sono riconosciute; 023, ventitre e 3.0 non sono
riconosciute dalla grammatica
<programma>::=
[<direttiva>]* #include <<header>>stdio.h
main(){
[<istruzione>]* <istruzionesemplice>::=<espressione>;
}
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25

Anteprima parziale del testo

Scarica Introduzione alla Programmazione in C: Esercizi e Concetti Fondamentali e più Appunti in PDF di Programmazione C solo su Docsity!

PROGRAMMAZIONE:

INTRODUZIONE:

  1. editor : qualsiasi programma in grado di creare e modificare file di testo per qualsiasi linguaggio di programmazione #include <stdio.h> main(){ printf(“Hello World!\n”); }
  2. compilatore : trasforma un programma in un file di formato eseguibile in linguaggio macchina a) GCC -H (guida in linea), MAN GCC (man pages), INFO GCC (info pages) b) SI SCRIVE: i) gcc helloworld.c → compila il file sorgente C e genera il file eseguibile a.out ii) gcc-o helloworld helloworld.c c) se non compila è perché abbiamo violato delle regole della grammatica del linguaggio C e riporta due messaggi di errore: i) warning : non impedisce la compilazione, ma segnala un potenziale problema ii) error : indica un errore di sintassi che compromette la compilazione

SINTASSI:

  1. i linguaggi di programmazione sono formali
  2. EXTENDED BACKUS-NAUR FORM: linguaggio formale per esprimere delle grammatiche a) una produzione (::=) è composta da, per esempio: i) ::= simbolo terminale | [] ii) ::= simbolo terminale | simbolo terminale | … iii) ::= simbolo terminale | per esempio: 0 e 23 sono riconosciute; 023, ventitre e 3.0 non sono riconosciute dalla grammatica ::= []* → #include <
    > stdio.h main(){ []* → ::= ; }

SEMANTICA:

  1. definisce il significato di un programma: che cosa succede quando si esegue un programma?
  2. sbagliando la semantica,il programma non farà quello che voglio che faccia
  3. una delle cose che fa il C è la risoluzione di espressioni: sequenze di simboli che seguono delle norme e producono a) un valore b) un effetto (cambia qualcosa in memoria o in I/O) e possono essere a) intere b) di output
  4. un’altra capacità del C è valutare istruzioni semplici (si trova tra le parentesi graffe del programma) #include <stdio.h> main(){ printf(“...”); → ESPRESSIONE SEMPLICE } ESPRESSIONE DI OUTPUT: printf(“Hello”); → COSTANTE STRINGA DI FORMATO
  5. bisogna utilizzare la direttiva #include <stdio.h> per stampare a video ● EFFETTO: stampa a video l’espressione tra virgolette ● VALORE: il numero di caratteri stampati
  6. \n → manda a capo dopo la stringa stampata

ESPRESSIONI INTERE:

  1. rappresenta espressioni su numeri interi a) espressioni unarie : che hanno un solo operando → -(+(-(-(+(-2)))))= b) espressioni binarie : che ha più operandi → 2+(3*(-(4-5))= 5
  2. se mettiamo un’espressione tra parentesi, possiamo creare espressioni più complesse: ((13+12)*(5-6)) ● EFFETTO: nessuno → non causano O/I o cambiamenti di memoria ● VALORE: come quello delle espressioni aritmetiche
  3. in linguaggio C la divisione intera scarta i decimali (/) → 7/3=
  4. il resto della divisione intera è un’espressione a parte (%) → 7%3=
  5. specificatore di conversione %d: converte i valori dell’espressione, bisogna mettere tanti %d quante sono le espressioni da convertire → printf(“%d%d%d”, 2, 3, 5, 7); = 3, 5, 7

assegnamento assegnamento compatto

14 dx concatenazione , 15 sx

  1. viene determinato dalle regole di associatività e priorità e indica quali espressioni vengono valutate ( raggruppamento )
  2. non influisce sul risultato finale se le espressioni non hanno effetto ( ordine di valutazione)

FLUSSO:

  1. è l’ ordine in cui vengono eseguite le istruzioni ( flusso predefinito )
  2. seguire il flusso predefinito è una nuova capacità del C #include <stdio.h> main(){ printf(“%d\n”, 5+2); printf(“%d\n”, 5-2); printf(“%d\n”, 5*2); printf(“%d\n”, 5/2); }

VARIABILI:

  1. astrazione di un’ area di memoria e rappresenta una di queste aeree a cui si da un nome e contengono i valori binari che hanno un significato
  2. più semplice: un’ associazione di un nome ad un valore

ASSEGNAMENTO DI VARIABILI:

  1. si da un nome alla variabile e un tipo, dopodichè si assegna un valore ad essa; useremo, quindi, quel nome al posto del valore int dividendo; dividendo=22; printf(“Quoziente: %d\n”, dividendo/7);
  2. utilizzando le variabili abbiamo una sola modifica da fare
  3. assegnare = scrivere quel valore in una cella di memoria
  4. i nomi delle variabili devono iniziare con una lettera maiuscola o minuscola e continuare con underscore, numeri o altre lettere
  1. altre due tipologie di espressioni sono: a) espressione variabileEFFETTO : nessuno ● VALORE : il valore dell’area di memoria identificata dall'identificatore b) espressione assegnamentoEFFETTO : il valore dell’espressione viene scritto nell’area identificata dal nome della variabile ● VALORE : il nuovo valore dell’area identificata dal nome della variabile (dividendo=22)*2 → 44 #include <stdio.h> main(){ int v; v=4; printf(“%d\n”, _v2_* ); }
  2. l’assegnamento è distruttivo, poichè si può sovrascrivere il valore precedente
  3. le variabili non devono essere usate prima di essere inizializzate, poiché prima del primo assegnamento il valore della variabile è imprevedibile
  4. l’assegnamento è associativo a dx a=b=c=1 = a=(b=(c=1))

STATO DELLA MACCHINA ASTRATTA:

  1. descrizione di una condizione in cui si trova la macchina astratta, che è sufficiente a prevedere tutte le condizioni successive man mano che il programma va avanti con le istruzioni

INPUT:

  1. ricevono dati dall’ esterno (utente) e li elaborano ESPRESSIONE DI INPUT: int a; scanf (“%d”, &a);
  2. scrive il valore aggiunto dall’utente dentro alla variabile chiamata in precedenza e seguita da & dentro scanf #include <stdio.h> main(){ int dividendo; printf(“Inserisci un numero intero\n”);
  1. se la condizione tra parentesi è vera, fai l’istruzione; altrimenti non viene eseguita
  2. in C un’espressione di valore 0 è falsa, se diversa è vera
  3. istruzione di controllo di flusso : modifica il flusso rispetto a quello predefinito, infatti può causare la mancata esecuzione di un’istruzione DIAGRAMMA DI FLUSSO:
  4. diagramma di flusso : rappresentazione grafica del programma, formato da blocchi e frecce
  5. i blocchi : a) rettangolo: un'istruzione qualsiasi con una freccia in I/O b) rombo: un’istruzione condizionale con due frecce di T/F OPERATORI RELAZIONALI ESPRESSIONE VALE 1 SE E SOLO SE VALE 0 SE E SOLO SE a == b a e b sono uguali a e b sono diversi a != b a e b sono diversi a e b sono uguali a < b a minori di b a maggiore di b a<= b a minore uguale di b a maggiore uguale di b a > b a maggiore di b a minore di b a >= b a maggiore uguale di b a minore uguale di b ISTRUZIONE IF-ELSE: if (){...} else
  6. se la condizione di if è vera esegui l’istruzione, altrimenti esegui quello dopo else
  7. il PRINCIPIO DRY (don’t repeat yourself) viene usato dall’istruzione if-else, che consente di non ripetere due volte if e non dimenticare nulla in caso di modifica della variabile
  8. CONNETTIVI LOGICI : operatori che consentono di combinare espressioni logiche componendone i valori secondo la logica; definiti da tabelle di verità a) unari (negazione) i) corrisponde al “non” e si indica con “!” ii) V se p è F, F se p è V TABELLA DI VERITA’ p !p 0 1 non 0 0 b) binari (congiunzione)

i) congiunzione (and) && ii) disgiunzione (or) || TABELLA DI VERITA’ p q p&&q p||q 0 0 0 0 0 non 0 0 1 non 0 0 0 1 non 0 non 0 1 1

  1. i connettivi logici vengono valutati in cortocircuito : la macchina valuta la 2condizione solo se 1condizione è vera; oppure valuta la 2 solo se la 1 è falsa

SALTI:

  1. istruzioni che alterano il flusso senza limitazioni ISTRUZIONE GOTO: goto …;
  2. comporta il salto del flusso all’istruzione immediatamente successiva all’etichetta

BLOCCHI:

  1. sequenze di istruzioni raggruppate in modo tale che dal flusso di controllo vengano eseguite o tutte o nessuna
  2. racchiuso fra {...}
  3. un blocco può essere vuoto {}

ITERAZIONI:

  1. ogni istruzione viene eseguita: a) 1 volta b) 0 volte c) più volte → iterare
  2. pattern: soluzione generale a un problema ricorrente a) il pattern ciclo risolve il problema di dover ripetere l’esecuzione di certe istruzioni, è caratterizzato da: i) corpo (istruzione da eseguire più volte) ii) condizione di permanenza (se falsa esce dal ciclo)

for(i=2; i<=10; i++) printf(“%d\n”, i);

CONTROLLO DI VERSIONE:

  1. consente di archiviare e recuperare tutte le versioni significative della cartella di un repository e permette: a) confrontare con versioni precedenti b) ripristinare una versione precedente (rollback)
  2. i sistemi di controllo di versione si dividono in: a) locali : repository sul computer di lavoro (RCS) b) centralizzati : repository su server (CVS, SUBVERSION) c) distribuiti : repository su più computer (GIT, MERCURIAL)
  3. il sistema di controllo di versione dominante è GIT , creato da Linus Torvalds COMANDI GITHUB COMANDO DESCRIZIONE git init nuovo repository nella cartella corrente git status mostra info sul suo stato git clone … crea in locale un clone del repository git pull aggiorna dal remoto al locale git push aggiorna dal locale al remoto git add aggiungo file dal workspace a index commit aggiungo dall’index al repository locale (eternità) git log mostra l’elenco di tutti i commit git checkout … riporta la cartella di lavoro allo stato corrispondente a quel commit git checkout master esegue il checkout del commit più recente del master git merge mettere insieme le modifiche di più branch
  4. branching : un commit può avere anche un successore a) master = main b) hottix: quando devo modificare un errore c) develop: aggiungere modifiche che quando mi soddisferanno posso riportarle nel master

d) …

SEQUENZE:

  1. elenco finito o infinito di elementi dello stesso tipo
  2. si possono dividere in: a) valori di variabile, espressione, input, output b) array c) file di record d) lista collegata
  3. attraverso le sequenze si possono prendere i suoi elementi uno alla volta, attraverso le operazioni di: a) map : data una sequenza, ne crea un’altra che si ottiene dalla prima applicando la stessa operazione a tutti gli elementi i) map(o, S1) #include <stdio.h> main(){ int i=1; for(i=1; i<=10; i++){ printf(“%d\n”, 2*i); } } b) filter : data una sequenza, prende gli elementi della sequenza che hanno una certa proprietà i) filter(o, S1) #include <stdio.h> main(){ int i=1; for(i=1; i<=10; i++){ if(i%2==0){ printf(“%d\n”, i); } } } c) reduce : applica la stessa operazione a tutti gli elementi della sequenza (detto anche folde o aggregate) i) reduce(o, v0, s1) #include <stdio.h> main(){ int p=1; →accumulatore int a; →assume i valori int i; →contatore for(i=0; i<5; i++){ scanf(“%d”, &a); p=p*a; }

delete breakpoint n elimina il breakpoint n continue riprende l’esecuzione step esegue una singola istruzione (eventualmente entrando nel codice) next esegue una singola istruzione (completando in un passo unico la chiamata della funzione) info locals elenca tutte le variabili locali watch … interrompe l’esecuzione ogni volta che … cambia valore

  1. il debugger su VSC si attiva: a) CTRL+SHIFT+D o nell’icona a sinistra con l’insetto b) creare il file launch.json c) run and debug d) C++ (GDB/LLDB) e) default configuration f) in “program” eliminare tutta la parte prima del $

ESPRESSIONI:

NUMERI NATURALI:

  1. i calcolatori utilizzano solamente due cifre (0 1)
  2. numero di configurazioni 2 𝑛
  3. il massimo numero rappresentabile è 2 𝑛 − 1 INTERI NATURALI SENZA SEGNO NOME NUMERO BIT unsigned char 0…255 8 unsigned short 0…65535 16 unsigned int ??? 16/ unsigned long 0…4294967295 32 unsigned long long 0…18446744073709551615 64
  4. dipende dall’architettura che sto utilizzando e che voglio utilizzare
  1. overflow : errore quando si supera la cifra massima o si diminuisce la cifra minima

NUMERI RELATIVI:

  1. si utilizza il complemento alla base per creare numeri negativi: a) metà delle configurazioni negative e metà positive b) ma con overflow se si sommano due numeri con lo stesso segno INTERI NATURALI CON SEGNO NOME NUMERO BIT char -128…127 8 short (int) -32768…32767 16 int ??? 16/ long (int) -2147483648… 2147483647

long long (int) -9223372036854775808… 9223372036854775807

  1. la dimensione di alcuni tipi dipende dal compilatore
  2. short<=int<=long<=long long

NUMERI IN VIRGOLA MOBILE:

  1. per rappresentare i floating point si utilizza la notazione scientifica: a) la mantissa definisce la precisione del numero b) le cifre riservate all’esponente definisce la dimensione massima del numero
  1. 87 × 10 − NUMERI REALI NOME PRECISIONE BIT float singola 32 double doppia 64 long double lungo doppia 80
  1. la sintassi dei numeri reali: a) 24. b) 2.4E c) 240.0E-
  2. nelle stringhe formato si utilizza il %f (float) e %lf (double e long double)

(2) int → long (3) float → double (4) double → long double ii) si perdono dati : (1) gli estremi del tipo da convertire sono esterni al nuovo tipo (2) ci sono troppe cifre decimali nel tipo da convertire #include <stdio.h> main(){ int a=5; float f=6.6; char c=4; c- -; f=a+f; a=a%c; a=f*c; }

TYPE CASTING:

()

  1. type casting : conversione esplicita attraverso l’operatore
  2. in questo caso il compilatore non mi da Warning #include <stdio.h> main(){ int i; float f; f=10.3/2; i=(int) f+2; }

ASSEGNAMENTO CONCATENATO:

  1. l’operatore di concatenazione è la virgola
  2. tutte le espressioni vengono valutate
  3. viene assegnato l’ ultimo valore della concatenazione 4) var=espressione

ESPRESSIONE CONDIZIONALE:

condizione? espressioneVera : espressioneFalsa

  1. l’espressione condizionale produce un valore a differenza di un’istruzione condizionale
  2. l’istruzione non può essere inserita in un’espressione condizionale

FUNZIONI:

  1. astrazione procedurale : procedimento in cui si prendono una sequenza di istruzioni con un nome e poi ci si riferisce a quella sequenza richiamando la funzione senza riscrivere tutte le istruzioni

SUBROUTINE:

  1. sottoprocedura o subroutine : saltare al codice, eseguirlo e ritornare al punto di chiamata identificato in qualche modo
  2. è possibile scrivere il codice una volta e chiamarlo due
  3. () → definizione di funzione
  4. () → chiamata di funzione #include <stdio.h> _star(){ int i; for(i=0; i<20; i++) printf(“”); }_* main(){ int j; for(j=0; j<5; j++) star(); }

PARAMETRI:

  1. parametri : variabili utilizzate per influenzare il comportamento della subroutine
  2. la sintassi dei parametri è: a) per la definizione : i) () ii) ::= void [, ]* iii) oppure b) per la chiamata : i) () ii) ::= [, ]* ::= {[]* []*}
  3. i parametri formali funzionano come variabili inizializzate
  4. ogni chiamata di funzione è indipendente da qualsiasi altra
  5. parametri ben identificati e localizzati
  6. le variabili locali non “sporcano” il resto del programma
  7. la macchina astratta gestisce automaticamente l’assegnamento dei parametri
  1. le variabili possono essere definite in qualsiasi parte del blocco
  2. vietato usare variabili con lo stesso nome e lo stesso scope, ma si possono definire variabili con lo stesso nome ma in scope uno interno all’altro #include <stdio.h> int i=0; int main(){ int i=1; { int i=2; printf(“%d\n”, i); } printf(“%d\n”, i); return 0; }
  3. l’identificatore si riferisce alla variabile con lo scope con numero minimo (cioè quello più interno)
  4. nessuna funzione ha mai accesso alle variabili locali di altre funzioni: le variabili locali con lo stesso nome ma di funzioni diverse, sono variabili diverse

ALGORITMI E PROGRAMMI:

ALGORITMI:

  1. risolvere un problema —> risolvere la sua funzione caratteristica
  2. MACCHINA DI TURING: modello astratto delle capacità di calcolo di un computer, calcolatore di funzioni a) alfabeto di simboli 𝐴 b) insieme 𝑆 di stati di cui uno iniziale (s0) e alcuni finali ( 𝐹) c) funzione di transazione → δ: 𝑆 × 𝐴 → 𝑆 × 𝐴 × {𝑑, 0, 𝑠 }
  3. TESI DI CHURCH-TURING: tutte le funzioni calcolabili dal calcolatore possono essere calcolate da una macchina di Turing
  4. algoritmo : la soluzione al problema, una sequenza di istruzioni (non ambigue e finite) per un determinato esecutore (o macchina astratta) esempio → dati: “a” e ”b”, numeri naturali A. se “a=b” vai al passo 4 B. se “a < b” allora assegna a “b” il valore “b-a”, altrimenti assegna ad “a” il valore “a-b” C. vai al passo 1 D. il risultato è “a”
  5. un algoritmo è in grado di: a) fare confronti

b) fare operazioni aritmetiche c) fare salti condizionati o incondizionati d) fare assegnamenti (cambiare valore di una variabile)

  1. due algoritmi si dicono equivalenti quando accettano gli stessi input e restituiscono lo stesso output per ogni input
  2. complessità : il numero di passi che richiede la sua esecuzione in funzione della dimensione dell’input a) trovare un algoritmo che sia abbastanza veloce e che utilizzi uno spazio piccolo di memoria (compromesso spazio/tempo)

LINGUAGGI DI PROGRAMMAZIONE:

  1. i linguaggi di programmazione sono linguaggi formali
  2. sintassi : insieme di regole che definiscono se una sequenza di simboli è un programma o no
  3. semantica : definisce il significato di un programma e un esecutore a) operazionale b) denotazionale c) assiomatica
  4. programma : algoritmo per l’esecutore definito dalla semantica del linguaggio di programmazione
  5. TURING COMPLETE: quando un linguaggio di programmazione ha una semantica in grado di implementare una qualsiasi macchina di Turing a) HALTING PROBLEM: è impossibile scrivere un algoritmo che determini se un programma in linguaggio di programmazione Turing Complete terminerà
  6. processo : sequenza delle operazioni eseguite da una macchina per eseguire un programma a) ad un programma possono esserci più processi b) processo ≠ processo del sistema operativo
  7. livello : un linguaggio di programmazione è di un livello alto quando si avvicina al linguaggio di dominio dell’applicazione
  8. in base a cosa si classificano i linguaggi: a) tipizzazione statica o dinamica : se statica si associa un tipo alla variabile ed essa potrà contenere solo quel tipo; se dinamica non associa alle variabile un tipo predefinito b) gestione della memoria automatica o manuale c) assegnamento distruttivo : si possono assegnare ad una variabile valori diversi, sovrascrivendo i valori precedenti d) impostazione procedurale o dichiarativa : se procedurale la semantica è definita in modo “che cosa fa il programma”, se dichiarativa si basa sulla logica e) organizzazione dei programmi orientata agli oggetti : paradigma di programmazione che permette di definire oggetti software in grado di interagire gli uni con gli altri attraverso lo scambio di messaggi
  9. come viene trasformato il codice sorgente in linguaggio macchina: a) interpretazione : copiare in RAM il programma e prendere ogni singola istruzione ed eseguirla