uniroma1
.*_main.c
.cognome.nome
. Sulle postazioni del laboratorio sarà /home/studente/Desktop/cognome.nome/
.cognome.nome.zip
(zip -r cognome.nome.zip cognome.nome/
).cognome.nome.zip
.rm -rf cognome.nome
).Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.
Si vuole scrivere nel file E1-find-person/e1.c
due funzioni che lavorano su array di strutture che rappresentano persone come definito di seguito:
typedef struct person_t person_t;
struct person_t {
char *name;
int age;
};
La prima funzione ha il seguente prototipo:
void sort_people(person_t p[], size_t n);
e deve ordinare per nome le persone nell’array p
di dimensione n
. La seconda funzione ha il seguente prototipo:
person_t *find_person(char *key, person_t sorted[], size_t n);
e, assumendo che sorted
sia un array di n
persone ordinate per nome e key
è un nome da cercare, restituisce il puntatore a una persona nell’array che ha quel nome, oppure NULL
se nessuna persona ha quel nome. Se vi sono più persone con il nome cercato, restituisce una qualunque.
NOTA: Si ricorda che per operazioni di ordinamento e ricerca è possibile utilizzare le funzioni qsort
e bsearch
.
Si consideri un software per la gestione delle prenotazioni in un ristorante. L’elenco dei prenotati è salvato in un buffer, composto dalla concatenazione di record di 37 byte ciascuno. Ogni record è suddiviso nei seguenti campi:
Tutti questi campi sono rappresentati da stringhe senza terminatore. Non esiste separatore tra i campi e tra i record. I bytes in eccesso sono costituiti da padding rappresentato con il carattere _
. Il campo dell’orario ha il formato hh:mm
.
Ad esempio, il record:
Rossi_________________________0419:50
descrive una prenotazione a nome Rossi, per 4 posti, alle ore 19:50.
Si scriva in e2.c
una funzione getBookingsAfterTime
con il seguente prototipo:
void getBookingsAfterTime(struct booking ** list, const char * data, int size, const char * time);
che, dato in ingresso un buffer data
(di dimensione size
byte) con tutti i record dei tavoli prenotati e un orario time
espresso in formato hh:mm
, restituisce in list
la lista di tutti i tavoli prenotati
per un orario uguale o successivo a time
. Si noti che list
deve essere una lista collegata costituita da elementi rappresentati dalla struct booking
(definita nel file e2.h
):
struct booking {
char * surname;
int places;
char * time;
struct booking * next;
};
L’ordine delle prenotazioni in list
deve essere coerente con l’ordine che le stesse hanno nel buffer data
.
Usare il main di prova nella directory di lavoro E2
compilando con gcc e2_main.c e2.c -o e2
.
NOTA: Si ricorda che per convertire una stringa in un numero intero è possibile utilizzare la funzione atoi
.
Tradurre in IA32 in un file e3.s
la seguente funzione, tenendo presente che i codici ASCII dei caratteri ‘0’ e ‘9’ sono 48 e 57, rispettivamente.
e3.c
int count_digits(const char *s) {
int cnt = 0;
while (*s) {
if (*s >= '0' && *s <= '9') cnt++;
s++;
}
return cnt;
}
Usare il main di prova nella directory di lavoro E3 compilando con gcc -m32 e3_main.c e3.s -o e3
.
Rispondi alle seguenti domande, tenendo conto che una risposta corretta vale 1 punti, mentre una risposta errata vale 0 punti.
Domanda 1. Siano %eax=20 (decimale), %edx=0 (decimale) e %ecx=8 (decimale). Con riguardo alle due istruzioni “idivl %ecx” e “sarl $3, %eax”, quale delle seguenti affermazioni risulta vera:
Domanda 2. Assumendo %eax=0xFF000000, %ecx=1 (decimale) e %edx=10 (decimale), dopo aver eseguito l’istruzione “testl %eax, %eax” quale delle seguenti affermazioni risulta vera:
Domanda 3. Assumendo %eax=10 (decimale), %ecx=7 (decimale) e %edx=2 (decimale), quale delle seguenti affermazioni risulta vera:
Domanda 4. Quale delle seguenti è un’istruzione valida:
e1.c
#include "../../T08/E1-find-person/e1.h"
#include <string.h>
#include <stdlib.h>
int cmp(const void *ap, const void *bp){
person_t a = *(person_t*)ap;
person_t b = *(person_t*)bp;
return strcmp(a.name, b.name);
}
void sort_people(person_t p[], size_t nel) {
qsort(p, nel, sizeof(person_t), cmp);
}
person_t *find_person(char *key, person_t sorted[], size_t nel) {
person_t key_person;
key_person.name = key;
return bsearch(&key_person, sorted, nel, sizeof(person_t), cmp);
}
e2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../T08/E2/e2.h"
int get_timestamp(const char * A){
char Ah[3] = {A[0], A[1], '\0'};
char Am[3] = {A[3], A[4], '\0'};
return atoi(Ah) * 60 + atoi(Am);
}
void getBookingsAfterTime(struct booking ** list, const char * data, int size, const char * time){
*list = NULL;
struct booking * last = NULL;
struct booking * elem;
int start = get_timestamp(time);
// Leggo dal buffer fino a quando riesco a trovare ulteriori prenotazioni
int pos = 0;
while(pos < size) {
// Leggo la prossima prenotazione dal buffer
const char* buf = &data[pos];
pos += 37;
// Estraggo l'ora di prenotazione
int i=32;
char time_tmp [6];
while (i<37) {
time_tmp[i-32] = buf[i];
i++;
}
time_tmp[i-32]='\0';
// Se l'ora di prenotazione è successiva a time
if (get_timestamp(time_tmp) >= start) {
// Alloco memoria per un nuovo elemento della lista
elem = malloc(sizeof(struct booking));
// Aggiungo all'elemento l'orario di prenotazione
elem->time = malloc((strlen(time_tmp) + 1) * sizeof(char));
strcpy(elem->time, time_tmp);
// Estraggo ed aggiungo all'elemento il numero di posti prenotati
char seats_tmp [3];
seats_tmp[0] = buf[30];
seats_tmp[1] = buf[31];
seats_tmp[2] = '\0';
elem->places = atoi(seats_tmp);
// Estraggo ed aggiungo all'elemento il cognome di chi ha prenotato
i=0;
char surname_tmp [31];
while (i<30 && buf[i]!='_') {
surname_tmp[i] = buf[i];
i++;
}
surname_tmp[i]='\0';
elem->surname = malloc((strlen(surname_tmp) + 1) * sizeof(char));
strcpy(elem->surname, surname_tmp);
// Aggiungo l'elemento in coda alla lista
elem->next=NULL;
if (*list == NULL)
*list = elem;
else
last->next = elem;
last = elem;
}
}
return;
}
e3_eq.c
int count_digits(const char *s) {
int a = 0;
const char* c = s;
L:
char dl = *c;
if (dl == 0) goto E;
if (dl < '0') goto F;
if (dl > '9') goto F;
a += 1;
F:
c++;
goto L;
E:
return a;
}
e3.s
.globl count_digits
count_digits: # int count_digits(const char *s) {
xorl %eax, %eax # int a = 0;
movl 4(%esp), %ecx # const char* c = s;
L:
movb (%ecx), %dl # char dl = *c;
testb %dl, %dl # if (dl == 0) goto E;
je E
cmpb $48, %dl # if (dl < '0') goto F;
jl F
cmpb $57, %dl # if (dl > '9') goto F;
jg F
incl %eax # a += 1;
F:
incl %ecx # c++;
jmp L # goto L;
E:
ret # return a;