Skip to content

Commit

Permalink
Aggiunta esempio esame Santini
Browse files Browse the repository at this point in the history
  • Loading branch information
Meht-evaS committed Dec 15, 2023
1 parent 5757ae3 commit b865031
Show file tree
Hide file tree
Showing 19 changed files with 1,026 additions and 4 deletions.
32 changes: 32 additions & 0 deletions magistrale/Anno 1/Didattica/Santini/FaxSimileEsame/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Didattica dell'Informatica
## Esame di Programmazione Procedurale con Laboratorio
Eaborato con gli esercizi, e relative soluzioni, per l'esame di Programmazione Procedurale con Laboratorio.

## :mortar_board: Studente
Cristian Cerami

## :ticket: Matricola
362384

## :pencil: Caratteristiche
Il progetto rispetta le seguenti specifiche:

* Composto da 5 esercizi (versione corta) che coprono più argomenti possibili del corso.
* Ispirato agli esami degli anni passati (a.a. 2021 in poi) visibili sulla [pagina del corso](https://francescosantini.sites.dmi.unipg.it/progI23.html) di Programmazione procedurale con Laboratorio.
* Sritto in Latex sfruttando il package [exam](https://ctan.org/pkg/exam?lang=en).
* Contiene le soluzioni e i codici sorgente di tutti gli esercizi proposti.

## :page_facing_up: Elaborato PDF
Come anticipato sopra, sono stati creati due documenti PDF:

* [Compito d'esame](pdf/didattica_inf_esame_prog1_cerami.pdf): contiene il compito d'esame vero e proprio da assegnare agli studenti. Va solo cambiata l'intestazione che per ora contiene il mio nome. Per farlo si può modificare il [seguente file LaTeX](latex_sources/Esame/esercizi.tex).
* [Compito d'esame con correzioni](pdf/didattica_inf_esame_prog1_con_soluzioni_cerami.pdf): identico al precedente file ma al suo interno contiene la risposte (correzioni) degli esercizi. Anche qui va cambiata l'intestazione del documento con il [relativo file LaTeX](latex_sources/Esame/esercizi.tex).

## :computer: Codice sorgente esercizi
Per ogni esercizio assegnato in questo compito d'esame è stato creato un file contenente il codice sorgente e la relativa spiegazione di risoluzione dell'esercizio.

* [Esercizio 1](c_sources/esercizio%201/Es_1.c)
* [Esercizio 2](c_sources/esercizio%202/Es_2.c)
* [Esercizio 3](c_sources/esercizio%203/Es_3.c)
* [Esercizio 4](c_sources/esercizio%204)
* [Esercizio 5](c_sources/esercizio%205/Es_5.c)
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//***********************************************************//
// 5 punti. Cosa stampa il seguente frammento di codice? //
//***********************************************************//

#include <stdio.h>

int main() {

int a = 0123 ^ 0x056 ; //3+2*8+8*8 = 83 , 6+5*16 = 86

/*
83 = 64 + 16 + 2 + 1 = 01010011
86 = 64 + 16 + 4 + 2 = 01010110
01010011 = 83
01010110 = 86
-------- ^ XOR BIT A BIT
00000101 = 1 + 4 = 5
*/

double b = 2.59;

printf ("%d\n", a); //5

while ((++a || a++) ? a-=1 : 0) {
if (!(a-- && --a ))
break;
else
printf("%d\n", a);
}

/**
Step dentro ciclo while:
inizio con a==5 -> ++a == 6 -> (a-=1) == 5
if !(5 && 3) -> Falso , a == 3
stampo 3
inizio con a==3 -> ++a == 4 -> (a-=1) == 3
if !(3 && 1) -> Falso , a == 1
stampo 1
inizio con a==1 -> ++a == 2 -> (a-=1) == 1
if !(1 && -1) -> Falso , a == -1
stampo -1
inizio con a==-1 -> ++a == 0 || a++ == valuto 0 e poi incremento a 1 -> 0 || 0 quindi esco dal while con a==1
**/

a<=a, a+=b, a++;

/**
La prima espressione non ha nessun side effect quindi può essere ignorata in questo caso.
Nella seconda invece si somma ad "a" il float "b" ma, come da regole, si prende solo la parte intera quindi a=1+2 -> a==3
Nella terza si incrementa nuovamente a -> a==4
**/
printf("a: %d\n", a); //4

return 0;
}

/**
Stampa:
5
3
1
-1
a: 4
---------------------------------------
Usati argomenti:
- Logical operator
- Bitwise operator
- Conditional operator
- Compound assignment operator
- Expressions and comma operator
- Precedence and associativity
- Order of evaluation, Short circuit
- Side effects
**/
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//**************************************************************************//
// 6 punti. //
// Elencare le conversioni di tipo implicite (... da ... a). //
// Scrivere cosa viene stampato a schermo sapendo che: //
// UCHAR_MAX = 255 , 'a' = 97 //
// //
//**************************************************************************//

#include <stdio.h>

double fun (float a) {
char b = ('x' * 3) - 'g'; // = 1
return (a / b);
}

int main (void) {
unsigned int a = 'g' - 3UL; // = 100
float b = fun(a) ; // = 100.0
unsigned char c = -(int) (b+53); // = (UCHAR_MAX + 1) - 153 = 256-153 = 103
printf("c: %c, %d\n", c, c); // c: g, 103
return 0;
}


/*
linea 7: 'g' convertito da int a unsigned long int
linea 7: il valore dopo l'uguale è convertito da unsigned long int ad unsigned int
linea 8: il parametro "a" di fun() è convertito da unsigned int a float
linea 2: il valore dopo l'uguale è convertito da int a char
linea 3: "b" è convertito da char a float per la divisione
linea 3: il risultato della divisione è convertito da float a double
linea 8: il valore di ritorno è convertito da double a float
linea 9: 53 è convertito da int a float
linea 9: il valore dopo l'uguale è converito da int (dopo la conversione esplicita) a unsigned char
A schermo viene stampato "c: g, 103" perchè c = (UCHAR_MAX + 1) - 153 = 103 = 'g' in ASCII
*/

/*
Per sapere cosa stampa il seguente programma è bene prima scrivere da una parte tutti i valori int ASCII così da non doverli
calcolare ogni volta (si risparmia molto tempo e si riducono gli errori):
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
a b c d e f g h i j k l m n o p q r s t u v w x y z
printf("%d\n", 'x'); // 'x' = 120
printf("%d\n", 'g'); // 'g' = 103
printf("%d\n", ('x' * 3) - 'g'); // 'x' * 3 - 'g' = 120*3 - 103 = 257
char a = ('x' * 3) - 'g';
printf("%d\n", a); // = 1 perchè:
-------------------------------------------
char a = 257, UCHAR_MAX = 255
Per troncamento si ha (rappresentazione little endian):
INT (4 byte) 10000000 10000000 00000000 00000000 = 257
CHAR (1 byte) 10000000 xxxxxxxx xxxxxxxx xxxxxxxx = 1
==============================================================================
==============================================================================
Quando si arriva qua si ha "b"==100.0
Aggiungendogli 53 si arriva a 153.0 che poi per il cast esplicito e il
segno meno diventa -153 causando un wraparound che può essere così calcolato:
unsigned char c = -(int) (b+53); // -153 -> (UCHAR_MAX + 1) - 153 = (255 + 1) -153 = 103 = 'g' in ASCII
==============================================================================
==============================================================================
Per vedere direttamente a schermo i valori ottenuti a ogni passaggio si può usare il seguente codice:
double fun (float a) {
char b = ('x' * 3) - 'g'; // // 'x' * 3 - 'g' = 120*3 - 103 = 257 = 1
printf("b: %d\n", b);
printf("a/b: %f\n", a/b);
return (a / b);
}
int main (void) {
unsigned int a = 'g' - 3UL; // = 100
printf("a: %u\n", a);
float b = fun(a) ; // = 100.0
printf("b: %f\n", b);
printf("b cast int: %d\n", -(int) (b+53)); // = -153
unsigned char c = -(int) (b+53); // = 256-153 = 103
printf("c: %c, %d\n", c, c); // = 'g', 103
return 0;
}
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
Data la seguente struct, scrivere la definizione di una funzione di nome ritorna_dispari che prende come parametro una
lista (lista_input) e ritorna un'altra lista (lista_output, creata nella funzione) che contiene, nello stesso ordine della
lista passata, solamente gli elementi in posizione dispari (se presenti).
Se la lista originale è 5-2-9, la lista ritornata sarà 5-9.
typedef struct node Node;
struct node {
int info;
struct node* pNext;
};
*/

/*
Del seguente codice era richiesta solo la funzione "ritorna_dispari" ma per farne vedere il corretto funzionamento
sono state create delle funzioni aggiuntive.
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct node Node;

struct node {
int info;
struct node* pNext;
};

void print_list(Node* pFirst) {
if(pFirst == NULL) {
printf("Lista vuota!\n");
}
else {
Node* pScan = pFirst;
do {
printf("Info: %d\n", pScan->info);
pScan = pScan->pNext;
} while(pScan!= NULL);
}
return;
}


Node* ritorna_dispari(Node* lista_input) {

if (lista_input == NULL) {
//Se lista_input è vuota allora non ritorno alcuna lista
return NULL;
} else {
//Se lista_input contiene almeno un elemento allora procedo a creare la lista di elementi dispari
//Ricordiamo che dobbiamo mantenere lo stesso ordine degli elementi di input quindi INSERIMENTO IN CODA!
int counter = 0;
Node* pScan = lista_input;

Node* lista_output = NULL; //Puntatore al primo elemento della nuova lista
Node* lista_output_pLast = NULL; //Per inserire in coda all'ultimo elemento

while (pScan != NULL) {
if (counter % 2 == 0) {
Node* pNew = (Node*) malloc(sizeof(Node));
pNew -> info = pScan -> info;
pNew -> pNext = NULL;

//Se lista_output non contiene neanche un elemento
if (lista_output == NULL) {
lista_output = pNew;
lista_output_pLast = pNew;
} else {
//Se lista_output contiene almeno un elemento allora lo inseriamo in coda
lista_output_pLast -> pNext = pNew;
lista_output_pLast = pNew;
}
}

pScan = pScan -> pNext;
counter++;
}

return lista_output;
}
}


int main() {

Node *pFirst = NULL;
Node *pLast = NULL;

//Creo una linked list con campi info da 1 a 5
for (int i = 1; i < 6; i++) {
Node* pNew = (Node*) malloc(sizeof(Node));
pNew -> info = i;
pNew -> pNext = NULL;

if (pFirst == NULL) {
pFirst = pNew;
pLast = pNew;
} else {
pLast -> pNext = pNew;
pLast = pNew;
}
}

//Stampo il contenuto della lista ritornata da "ritorna_dispari" e che contiene solo gli elementi in posizione dispari
print_list(ritorna_dispari(pFirst));

/*
Viene stampato:
Info: 1
Info: 3
Info: 5
*/

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Dire quali compilazioni provocano errore a causa del linker (e perchè):
1) gcc -o write write.c
2) gcc -c main.c
3) gcc -o main main.c
4) gcc -o execute main.c write.c
In caso il punto 4) ritorni un errore, descrivere come può essere corretto. Infine, dopo la correzione
eventualmente applicata, elencare tutte le definizioni, dichiarazioni e tipologie di linkage, presenti
in ogni file, per count, i, a, e mywrite. Cosa stampa il programma?
*/

/*
Le correzioni sono presenti nel file "write.c"
*/

extern void mywrite(int *count);
extern int count;
int i;
int i = 1;

int main(void) {
do {
mywrite(&count);
} while(count <= 0);
}
Loading

0 comments on commit b865031

Please sign in to comment.