Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(appunti): Aggiunto esempio modalità esame fax simile Santini #77

Merged
merged 2 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Meht-evaS marked this conversation as resolved.
Show resolved Hide resolved

## :mortar_board: Studente
Cristian Cerami

## :ticket: Matricola
362384
Meht-evaS marked this conversation as resolved.
Show resolved Hide resolved

## :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).
Meht-evaS marked this conversation as resolved.
Show resolved Hide resolved
* 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).
Meht-evaS marked this conversation as resolved.
Show resolved Hide resolved

## :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
Meht-evaS marked this conversation as resolved.
Show resolved Hide resolved

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
Meht-evaS marked this conversation as resolved.
Show resolved Hide resolved

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
Loading