Sei sulla pagina 1di 112

Esercizio 1 (punteggio 7)

Dato un file di testo denominato interi.txt contenente in ogni riga due numeri interi positivi.
Scrivere un programma C (Pascal) che per ogni coppia di interi X ed Y appartenenti alla
stessa riga del file interi.txt scrive sul file coprimi.txt il numero X se X e Y hanno almeno un
divisore comune diversi da 1, Y altrimenti.
Ad esempio:

interi.txt coprimi.txt
5 15 5
21 7 21
4 15 15
25 16 16

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

int coprimi(int x, int y)


{
int flag=1, i;

for(i=x; i>1; i--)


if((y%i == 0) && (x%i == 0))
flag=0;
return flag;
}

int main()
{
FILE *fi, *fo;
int x, y;

fi = fopen("interi.txt","r");
fo = fopen("coprimi.txt","w");

if(fi==NULL || fo==NULL)
exit(-1);

while(fscanf(fi,"%d%d",&x,&y) != EOF)
{
if(coprimi(x,y)==0)
fprintf(fo,"%d\n",x);
else
fprintf(fo,"%d\n",y);
}

fclose(fi); fclose(fo);
return 0;
}

Esercizio 2 (punteggio 7)
Definire un tipo di dato struct (record per Pascal) di nome INTERNO con due campi A e B di tipo int
(integer per Pascal). Definire un tipo di dato struct (record per Pascal) di nome ESTERNO con due
campi C e D di tipo INTERNO.
Scrivere una funzione C (procedura per Pascal) che ha in ingresso un parametro X di tipo ESTERNO
che restituisce 1 se il campi A delle componenti C e D di X sono rispettivamente uguali ai campi B
delle componenti C e D di X, 0 altrimenti.

#include <stdio.h>
#include <stdlib.h>
typedef struct {int A, B;} INTERNO;
typedef struct {INTERNO C,D;} ESTERNO;

int funz(ESTERNO X)
{
if(X.C.A == X.D.A && X.C.B == X.D.B)
return 1;
else
return 0;
}

int main() //NON RICHIESTO DAL TESTO


{
ESTERNO Y={{2,23}, {2 ,23}};
ESTERNO Z={{6 ,13},{5, 35}};

printf("%d\t%d\n",funz(Y),funz(Z));

return 0;
}

Esercizio 3 (punteggio 6)
Sintetizzare con il minor numero di bit in binario la funzione f(x)= x2, dove x è un numero in
complemento a 2 di 2 bit.

X1 X2 X |X| U2 U1 U0
0 0 0 0 0 0 0
0 1 1 1 0 0 1
1 0 -2 4 1 0 0
1 1 -1 1 0 0 1
U2 = X1-X2
U0 = X2
U1 = 0
Esercizio 1 (punteggio 7)
Dato un file di testo denominato interi.txt contenente in ogni riga un numero intero. Scrivere
un programma C (Pascal) che letto da standard input un intero positivo X e calcolata la media
M dei valori contenuti nel file interi.txt, scrive sul file maggiori.txt i valori di interi.txt che distano
meno di X da M. Utilizzare la funzione abs(y) per determinare il valore assoluto.
Ad esempio se X vale 2:

interi.txt maggiori.txt
8 8
11 7
6
7

#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fi, *fo;
int X, M, v;
double cont;

fi = fopen("interi.txt","r");
fo = fopen("maggiori.txt","w");

if(fi==NULL || fo==NULL)
exit(-1);

printf("dammi un intero: ");


scanf("%d",&X);

cont=0; M=0;
while(fscanf(fi,"%d",&v) != EOF)
{
cont++;
M = M + v;
}
M = M / cont;

fclose(fi);
fi = fopen("interi.txt","r");

while(fscanf(fi,"%d",&v) != EOF)
{
if(abs(v-M) < X)
fprintf(fo,"%d\n",v);
}
fclose(fi); fclose(fo);
return 0;

Esercizio 2 (punteggio 7)
Definire un tipo di dato struct (record per Pascal) di nome ORARIO con due campi ora e minuti di
tipo int (integer per Pascal). Definire un tipo di dato struct (record per Pascal) di nome TEMPI con
due campi primo e secondo di tipo ORARIO.
Scrivere una funzione C (procedura per Pascal) che ha in ingresso un parametro X di tipo TEMPI che
restituisce la differenza in minuti tra i campi primo e secondo di X.
Ad esempio, se il campo ora di primo contiene 2 ed il campo minuti di primo contiene 23, mentre il
campo ora di secondo contiene 5 ed il campo minuti di secondo contiene 35, la funzione deve
restituire -192. Oppure, se il campo ora di primo contiene 6 ed il campo minuti di primo contiene 13,
mentre il campo ora di secondo contiene 5 ed il campo minuti di secondo contiene 35, la funzione
deve restituire 38.

#include <stdio.h>
#include <stdlib.h>
typedef struct {int ora, minuti;} ORARIO;
typedef struct {ORARIO primo, secondo;} TEMPI;

int funz(TEMPI X)
{
int a;

a = X.primo.ora*60 - X.secondo.ora*60 + X.primo.minuti-


X.secondo.minuti;

return a;
}

int main() //NON RICHIESTO DAL TESTO


{
TEMPI Y={{2,23}, {5 ,35}};
TEMPI Z={{6 ,13},{5, 35}};

printf("%d\t%d\n",funz(Y),funz(Z));

return 0;
}

Esercizio 3 (punteggio 6)
Sintetizzare con il minor numero di bit in binario la funzione f(x)= |x| (valore assoluto o modulo di x),
dove x è un numero in complemento a 2 di 2 bit.

X1 X2 X |X| U1 U0
0 0 0 0 0 0
0 1 1 1 0 1
1 0 -2 2 1 0
1 1 -1 1 0 1
U1 = X1-X2
U0 = X2

Esercizio 1 (punteggio 7)
Scrivere un programma C che esegue le seguenti operazioni:
legge da standard input una sequenza di numeri interi inserendoli in un vettore A.
L’operazione di lettura deve terminare quando viene inserito un numero negativo o
viene inserito il millesimo valore,
inserisce in un vettore B opportunamente dimensionato i valori dispari contenuti nel
vettore A.

#include <stdio.h>
#include <stdlib.h>
#define DIM 100
int main()
{
int A[DIM], B[DIM];
int k,j,i=0, val;

scanf("%d",&val);
while ((val > 0) && (i<DIM))
{
A[i] = val;
i++;
scanf("%d",&val);
}

k=0;
for(j=0;j<i;j++)
if(A[j] % 2 != 0)
{
B[k] = A[j];
k++;
}

system("pause");
return 0;
}

Esercizio 2 (punteggio 7)
Definire un tipo di dato struct di nome INS composto da tre campi: V di tipo vettore di 100
elementi di tipo int, A di tipo int e B di tipo int.
Scrivere una funzione C con un parametro di nome ST di tipo INS che modifica ST
inserendo nelle posizioni pari del campo V di ST il valore del campo A di ST, mentre nelle
restanti posizioni del campo V di ST inserisce il valore del campo B di ST.
#include <stdio.h>
#include <stdlib.h>
#define DIM 100

typedef struct {int V[DIM], A, B;}INS;

void C (INS *ST){

int i;

for(i=0;i<DIM;i=i+2)
{
ST -> V[i] = ST -> A;
ST -> V[i+1] = ST -> B;
}
}

int main() //NON RICHIESTO DAL TESTO


{
INS s;
int i;

scanf("%d",&(s.A));
scanf("%d",&(s.B));
C(&s);

for(i=0;i<DIM;i++)
printf("%d %d\n",i,s.V[i]);
system("pause");
return 0;
}

Esercizio 3 (punteggio 6)
Una società che produce mobili in kit gestisce una base di dati per la produzione che
contiene tra le altre le seguenti relazioni:

Mobile (codice, descrizione, prezzo)


Componente (codice, descrizione)
Costruzione(codMobile, codComp, quantita)

dove nella relazione Mobile l’attributo codice è la chiave primaria. Nella relazione
Componente l’attributo codice è la chiave primaria. Nella relazione Costruzione gli attributi
codMobile e codComp sono la chiave primaria e sono chiavi esterne rispettivamente per le
relazioni Mobile e Componente.
Si chiede di:
definire in SQL le 3 relazioni

CREATE TABLE Mobile


(codice int, descrizione char(20), prezzo real,
PRIMARY KEY (codice));

CREATE TABLE Componente


(codice int, descrizione char(20),
PRIMARY KEY (codice));

CREATE TABLE Costruzione


(codMobile int, codComp int, quantita int,
PRIMARY KEY (codMobile, codComp));

scrivere l’interrogazione SQL che permette di visualizzare per ogni valore dell’attributo
codice della relazione Mobili il numero di componenti utilizzati per la costruzione,

SELECT codMobile, count(*) AS TotComp


FROM Costruzione
GROUP BY codMobile

scrivere l’interrogazione SQL che permette di visualizzare il valore di descrizione della


relazione Mobile, di descrizione della relazione Componente e di quantita della
relazione Costruzione dei mobili che hanno il valore dell’attributo prezzo più elevato,
ordinando il risultato per l’attributo codice della relazione Mobile.

SELECT Mobile.descrizione, Componente.descrizione, quantita


FROM Mobile, Componente, Costruzione
WHERE Costruzione.CodMobile = Mobile.codice
AND Costrizione.CodComp = Componente.codice
AND prezzo = (SELECT max(prezzo) FROM Mobile)

Esercizio 1 (punteggio 7)
Scrivere un programma C che esegue le seguenti operazioni:
legge da standard input 1000 numeri interi ed inserisce in un vettore A
opportunamente dimensionato solo i numeri compresi tra 1 e 100 estremi inclusi
scartando gli altri,
inserisce in un vettore B opportunamente dimensionato la frequenza assoluta di ogni
numero contenuto nel vettore A.

#include <stdio.h>
#include <stdlib.h>
#define DIM 1000
#define DIMFr 100
int main()
{
int A[DIM], B[DIMFr];
int j,i=0, val;

j=0;
for(i=0;i<DIM;i++)
{
scanf("%d",&val);
if((val >= 1) && (val <= DIMFr))
{
A[j] = val;
j++;
}
}

for(i=0; i<DIMFr; i++)


B[i] = 0;

for(i=0; i<j; i++)


B[A[i]-1]++;

system("pause");
return 0;
}

Esercizio 2 (punteggio 7)
Definire un tipo di dato struct INS composto da un campo A di tipo vettore di 100 elementi di
tipo int e da un campo B di tipo double. Definire un tipo di dato struct di nome OUT composto
da un campo T di tipo double.
Scrivere una funzione C con un parametro ST di tipo INS ed un parametro R di tipo OUT* che
inserisce nel campo T del parametro R il rapporto tra il valore massimo tra gli elementi del
campo A di ST diviso il valore contenuto nel campo B di ST.

#include <stdio.h>
#include <stdlib.h>
#define DIM 5

typedef struct {int V[DIM]; double B}INS;


typedef struct {double T;} OUT;

void C (INS ST, OUT *R)


{
int i, max;
max = ST.V[0];
for(i=1;i<DIM;i++)
if(max < ST.V[i])
max = ST.V[i];
R -> T = max / ST.B;
}

int main() //NON RICHIESTO DAL TESTO


{
INS s; OUT o;
int i;

scanf("%lf",&(s.B));
for(i=0;i<DIM;i++)
scanf("%d",&(s.V[i]));
C(s,&o);

printf("%f\n",o.T);
system("pause");
return 0;
}

Esercizio 3 (punteggio 6)
Uno studio medico multispecialistico per la gestione delle tariffe possiede fra le altre le
seguenti relazioni:

Medico (codice, cognome, nome, qualifica)


Specialita (codice, descrizione)
MediciSpecialita (codMedico, codSpec)

dove nella relazione Medico l’attributo codice è la chiave primaria. Nella relazione Specialita
l’attributo codice è la chiave primaria. Nella relazione Tariffa l’attributo qualifica è la chiave
primaria. Nella relazione MediciSpecialita gli attributi codMedico e codSpec sono la chiave
primaria e sono chiavi esterne rispettivamente per le relazioni Medico e Specialita. Si
suppone che non esistano due medici con lo stesso nome e cognome.
Si chiede di:
definire in SQL le 3 relazioni

CREATE TABLE Medico


(codice int, cognome char(20), nome char(20), qualifica char(10),
PRIMARY KEY (codice));

CREATE TABLE Specialita


(codice int, descrizione char(20),
PRIMARY KEY (codice));

CREATE TABLE MediciSpecialita


(codMedico int, codSpec int,
PRIMARY KEY (codMedico, codSpec));

scrivere l’interrogazione SQL che permette di visualizzare per ogni valore dell’attributo
codice della relazione Specialita il numero di medici specialisti divisi per i valori
dell’attributo qualifica della relazione Medico,

SELECT Specialita.codice, qualifica, COUNT(*) AS Specialisti


FROM Medico, Specialita, MediciSpecialita
WHERE MediciSpecialita.codMedico = Medico.codice
AND MediciSpecialita.codSpec = Specialita.codice
GROUP BY Specialita.codice, qualifica

scrivere l’interrogazione SQL che permette di visualizzare il cognome ed il nome di tutti


i medici che hanno un numero di specializzazioni maggiore di uno.

SELECT cognome, nome


FROM medico
WHERE codice IN (SELECT codMedico
FROM MediciSpecialita
GROUP BY codMedico
HAVING COUNT(*) > 1)

Esercizio 1 (7 punti)

I file dati1.txt e dati2.txt contengono uno per riga dei numeri decimali. Scrivere il
programma C che legge i numeri dai due file e produce un terzo file (dati3.txt) che contiene la
somma dei due valori letti. I file dat1.txt e dati2.txt non hanno la stessa lunghezza. Quando
uno dei due file è terminato sul file dati3.txt sono ricopiati i valori del file non ancora terminato.

Esempio

3.60 -3.00 0.60


-78.904 7.0 -71.904
23.0 23.0
-17.3 -17.3
dati1.txt dati2.txt dati3.txt

Esercizio 2 (7 punti)

Produrre le dichiarazioni C che permettono di


definire una struttura denominata DATI composta da due campi uno e due di tipo
int,
una struttura denominata STRUTDATI con un campo vt, vettore di 30 elementi di tipo
DATI, ed un campo, max di tipo int.
Scrivere quindi la funzione che ha in ingresso un elemento x di tipo STRUTDATI e che restituisce nel
campo max il valore più grande contenuto nel campo vt (essendo il campo composto da un vettore di
tipo DATI il valore massimo va ricercato su entrambi i campi uno e due).

Esercizio 3 (6 punti)
Un sistema per la gestione degli spettacoli teatrali contiene fra le altre due relazioni (in
grassetto sono indicati gli attributi che costituiscono la chiave)

Abbonati (IdAbb, Cognome, Nome, Indirizzo, telefono)


Cartellone (IdSpett, Titolo, dalGiorno, alGiorno)
SpettacoliVisti (IdAbb, IdSpett, data)

Si chiede di formulare le seguenti interrogazioni:


elencare il valore di Titolo, in ordine decrescente di spettatori abbonati che lo hanno
visto;
elencare Cognome e Nome e numero degli Spettacoli Visti da ciascun abbonato;
elencare Cognome e Nome degli abbonati che hanno visto più spettacoli in
assoluto.

Esercizio 1 (7 punti)
Il file uno.txt contiene su ogni riga due numeri decimali, mentre il file due.txt ne contiene uno
solo per riga. Scrivere il programma C che leggendo in parallelo i file uno.txt e due.txt scrive sul
file terzo.txt il valore 1 se il valore contenuto in due.txt è strettamente maggiore di entrambi i
valori contenuti in uno.txt, 0 altrimenti. I file uno.txt e due.txt non hanno lo stesso numero di
righe. Se il file due.txt termina prima del file uno.txt sul file terzo.txt si scrive il valore –1
per ogni riga di uno.txt che non ha corrispondenza in due.txt. Se il file uno.txt termina prima
del file due.txt si ricopia il contenuto residuo di due.txt su terzo.txt.

Esempio 1
12.7 23.6 56.89 1
-34.56 56.1 40.8 0
16.3 23.7 -23.01 0
14.0 236.7 -1
12.7 -23.67 -1
uno.txt due.txt terzo.txt

Esempio 2
12.7 23.6 56.89 1
-34.56 56.1 140.8 1
16.3 23.7 -23.01 0
14.0 236.7 24.9 0
12.7 -23.67 12.7 0
-56.8 -56.8
678.9 678.9
uno.txt due.txt terzo.txt

Esercizio 2 (7 punti)
Produrre le dichiarazioni C che permettono di
definire una struttura denominata DATI composta da due campi uno e due di tipo
double,
un vettore di 30 elementi di tipo DATI denominato VETDATI.
Scrivere quindi la funzione che ha in ingresso un vettore v di tipo VETDATI e che restituisce attraverso
il parametro par1 l’elemento di v con il valore massimo del campo uno e attraverso il parametro
par2 l’elemento di v con il valore minimo del campo due. In entrambi i casi se più di un elemento
rispondesse alla richiesta ne sceglierebbe uno qualunque.

Esercizio 3 (6 punti)
I dipendenti di una società fruiscono di un sistema di buoni mensa di diversi fornitori. La
società per gestire il servizio ha creato una base di dati che contiene fra le altre le seguenti
relazioni (in grassetto gli attributi che costituiscono la chiave):

Dipendente (idDip, Cognome, Nome, Incarico)


FornitoreBuoni (idForn, Nome, Indirizzo)
BuoniSpesi (idDip, idForn, data, CAPLuogoFruizione)

Si chiede di formulare le seguenti interrogazioni:


elenca per ogni Cognome e Nome in Dipendente il numero di buoni spesi e quanti
valori diversi ha CAPLuogoFruizione;
elenca per ogni fornitore quanti buoni sono stati spesi dai dipendenti;
elenca Cognome e Nome dei Dipendenti che hanno usato il minimo numero di
buoni mensa.

E1
Dato un file di testo chiamato dati.txt già esistente contenente uno per riga valori che
rappresentano numeri decimali, scrivere un programma in linguaggio C in cui si dichiarino
due vettori denominati rispettivamente VT1 e VT2 formati da 10 elementi di tipo double e che
svolga i seguenti compiti:

legge da dati.txt e pone i valori positivi in VT1 e quelli negativi in VT2; la lettura termina
quando il file è finito o entrambi i vettori sono stati riempiti (quando uno dei due vettori
è pieno si riempie solo l'altro vettore e scartando i valori che andrebbero inseriti nel
vettore pieno);
determina il valore massimo contenuto in ciascun vettore tenendo conto solo dei valori
effettivamente inseriti (ad esempio se VT1 è stato riempito dalla posizione 0 alla
posizione 4 calcola il valore massimo compreso nelle posizioni da 0 a 4);
divide tutti gli elementi di ogni vettore per il rispettivo valore massimo e riscrive i valori
calcolati nelle stesse posizioni.

#include <stdio.h>
#include <stdlib.h>
double maxVt (double v[], int dim)
{
double max = v[0];
int i;
for(i=1;i<dim;i++)
if (max < v[i])
max = v[i];
return max;
}

int main()
{
double vT1[10], vT2[10], v, maxVt1, maxVt2;
FILE *f;
int ivT1=0, ivT2=0, i;

if((f = fopen("dati.txt","r")) == NULL)


exit(-1);

while(fscanf(f,"%lf",&v) != EOF)
if (v > 0 && ivT1< 10)
{vT1[ivT1] = v;
ivT1++;}
else if (v <= 0 && ivT2< 10)
{vT2[ivT2] = v;
ivT2++;}
else if (ivT1 > 10 || ivT2 > 10)
break;
fclose(f);
maxVt1 = maxVt(vT1,ivT1);
maxVt2 = maxVt(vT2,ivT2);

for(i=0; i<ivT1; i++)


vT1[i] = vT1[i] / maxVt1;

for(i=0; i<ivT2; i++)


vT2[i] = vT2[i] / maxVt2;

system("pause"); return 0;
}

E2
Definire un nuovo tipo di dato chiamato ST formato da due campi A e B il primo di tipo double
ed il secondo di tipo vettore di 10 int. Scrivere la funzione ft che:
restituisce, attraverso un opportuno parametro, una struttura di tipo ST nella quale il
campo A contiene il rapporto fra il valore massimo ed il valore minimo del campo B.
restituisce il numero di elementi di B superiori al valore calcolato nel punto precedente
(Esempio se il campo B contiene [12, 3, -5, 7, 8, 120, 2, -1, -9, 1] in A andrà il valore -13,333,
la funzione restituirà inoltre il valore 10)

#include <stdio.h>
#include <stdlib.h>
typedef struct {double A; int B[10];} ST;
int fz(ST *par)
{ int num=0, i;
double m, M;

M=m=par->B[0];

for(i=1; i<10; i++)


if (m > par->B[i])
m = par -> B[i];
else if (M < par-> B[i])
M = par -> B[i];
par -> A = M/m;

for(i=0; i<10; i++)


if(par->B[i] > par->A)
num++;
return num;
}
int main() //NON RICHIESTO DAL TESTO
{ ST s={0.0,12, 3, -5, 7, 8, 120, 2, -1, -9, 1};
int t;
t = fz(&s); printf("%d %f\n",t,s.A);
system("pause"); return 0;
}

E3
Sintetizzare la funzione booleana f(x)=x*2 - 1 dove x è un numero binario senza segno di 2 bit
e l'uscita deve essere espressa in complemento a 2 con il minor numero di bit.

X1 X0 X X*2-1 U3 U2 U1 U0
0 0 0 -1 1 1 1 1
0 1 1 1 0 0 0 1
1 0 2 3 0 0 1 1
1 1 3 5 0 1 0 1

U0 = 1
U1 = -X0
U2 = -X1-X0 + X1X0
U3 = -X1-X0
E1
Scrivere un programma C che compie le seguenti operazioni:
inserisce in un vettore di nome VETT di 20 interi una sequenza di numeri letti da
tastiera. Il caricamento del vettore deve terminare o al raggiungimento del ventesimo
numero o quando è inserito il primo numero strettamente inferiore a 2.
memorizza in un secondo vettore di nome PRIMI quei numeri di VETT che sono primi;
tale vettore deve essere riempito progressivamente a partire dalla cella di indice 0 (non
deve contenere buchi);
memorizza in un terzo vettore di nome GRANDI quegli elementi di primi strettamente
maggiori di 50. Tale vettore deve essere riempito progressivamente a partire dalla
cella di indice 0 (non deve contenere buchi).

#include <stdio.h>
#include <stdlib.h>
typedef int VETTORE[20];
void stampa(int *v, int l, char *s)
{int i;
printf("%s: ",s);
for(i=0; i<l; i++)
printf("%3d\t",v[i]);
printf("\n");
}

int primo(int v)
{ int i;
for( i=2; i<v; i++)
if (v%i == 0)
return 0;
return 1;
}

int main()
{
VETTORE VETT={0}, PRIMI={0}, GRANDI={0};
int i,j,k,v;

scanf("%d",&v);
for(j=0,i=0;i<20 && v>=2; i++)
{
VETT[i] = v;
if(primo(VETT[i]))
{PRIMI[j]=VETT[i];
j++;}
scanf("%d",&v);
}
for(k=0, i=0; i<j; i++)
if(PRIMI[i] > 50)
{GRANDI[k] = PRIMI[i];
k++;}

stampa(VETT,20,"vettore iniziale");
stampa(PRIMI,j,"primi");
stampa(GRANDI,k,"maggiori 50");

system("pause"); return 0;
}

E2
Definire un nuovo tipo di dato di nome IMPIEGATO contenente i campi di nome ID e
STIPENDIO, entrambi di tipo int. Scrivere una funzione con un parametro formale di nome X
vettore composto da elementi di tipo IMPIEGATO ed un parametro formale di nome DIM di
tipo intero che rappresenta il numero di componenti di X. La funzione deve restituire:
attraverso un valore di ritorno la media dei valori contenuti nel campo STIPENDIO
attraverso il parametro formale TOT il numero di elementi di X che hanno un valore nel
campo STIPENDIO maggiore o uguale al valor medio.

#include <stdio.h>
#include <stdlib.h>
typedef struct {int ID, STIPENDIO;} IMPIEGATO;

double fz(IMPIEGATO X[], int DIM, int *TOT)


{
double media=0.0;
int i;
*TOT = 0;

for(i=0; i<DIM; i++)


media = media + X[i].STIPENDIO;
media = media/DIM;

for(i=0; i<DIM; i++)


if( X[i].STIPENDIO >= media)
(*TOT)++;
return media;
}

int main()
{
IMPIEGATO v[]={{1,45}, {2,67}, {3,16}};
int t; double m;
m= fz(v,3,&t);

printf("%f %d\n",m,t);
system("pause"); return 0;
}

E3
Sintetizzare la funzione booleana f(x)=2x-2, dove x è un numero binario assoluto di 2 bit. Il
risultato deve essere espresso in complemento a due con il minor numero possibile di bit.

X1 X0 X f(x) Y3 Y2 Y1 Y0
0 0 0 -2 1 1 1 0
0 1 1 0 0 0 0 0
1 0 2 2 0 0 1 0
1 1 3 4 0 1 0 0

Y0 = 0;
Y1 = -X0
Y2 = -X1-X0 + X1X0
Y3 = -X1-X0

E1.
Scrivere un programma C che compie le seguenti operazioni:
legge da tastiera una sequenza di numeri interi e la memorizza nel file di nome
dati.txt. La sequenza termina quando viene inserito un numero negativo o un
numero strettamente superiore a 20.
Di ogni numero N presente in dati.txt calcola il valore di 2N (senza usare la
funzione di libreria pow()) e memorizza il risultato nel file potenza.txt;
Di ogni numero intero compreso tra zero e dieci presente nel file dati.txt calcola la
frequenza e la visualizza.

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

int pot(int v)
{
int ret=1;
for( ; v>0; v--)
ret = ret * 2;
return ret;
}

int main()
{ FILE *f1, *f2;
int v, i, freq[11]={0};

f1 = fopen("dati.txt","w");
f2 = fopen("potenza.txt","w");
if( f1 == NULL || f2 == NULL)
exit(-1);

scanf("%d",&v);
while (v>=0 && v<=20)
{
fprintf(f1,"%d\n",v);
fprintf(f2,"%d\n",pot(v));
if(v<=10)
freq[v]++;
scanf("%d",&v);
}

//inizializzare vettore se modo diverso da testo


for(i=0;i<10;i++)
printf("%2d freq=%d\n",i,freq[i]);
system("pause"); return 0;
}

E2.
Definire un nuovo tipo di dato di nome RETTANGOLO contenente 2 campi di nome BASE e
ALTEZZA, entrambi di tipo int. Scrivere una funzione con un parametro formale X vettore di
elementi di tipo RETTANGOLO ed un parametro formale di nome DIM di tipo intero che
rappresenta il numero di componenti di X. La funzione fa quanto segue:
restituisce 1 se ogni campo di ogni componente di X è strettamente positivo, 0
altrimenti.
restituisce, attraverso un opportuno parametro formale, un elemento di X il cui
prodotto dei due campi è il massimo indipendentemente dal rispetto della condizione di
stretta positività di entrambe le componenti.

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

typedef struct{int BASE, ALTEZZA;}RETTANGOLO;

int fz(RETTANGOLO X[], int DIM, RETTANGOLO *maxSup)


{
int i, ret=1, max, s;
max = X[0].BASE * X[0].ALTEZZA;
for(i=0;i<DIM;i++)
{
if((s=X[i].BASE * X[i].ALTEZZA) < 0)
ret = 0;
if(s > max)
{ max = s;
*maxSup = X[i];
}
}
return 0;
}

int main()
{ RETTANGOLO x[]={{4,5},{-2,3},{8,9}}, sp;
int r;
r = fz(x,3,&sp);
printf("%d %d\n",r,sp.BASE*sp.ALTEZZA);
system("pause"); return 0;
}

Esercizio 3
Sintetizzare la funzione f(x,y)=x*y+3, dove x e y sono numeri rappresentati in complemento a
2 usando 1 bit. Il risultato deve essere espresso in forma di numero binario assoluto.

X0 Y0 X X f(x,y) U2 U1 U0
0 0 0 0 3 0 1 1
0 1 0 -1 3 0 1 1
1 0 -1 0 3 0 1 1
1 1 -1 -1 4 1 0 0

U2 = X0Y0
U1=U0 = -(X0Y0)= -X0 + -Y0

E1
Scrivere un programma C che:
ha in ingresso due file denominati rispettivamente A.txt e B.txt contenenti su ogni
riga un numero intero. Il numero di righe dei due file non è noto a priori ma è uguale
nei due file;
definisce una matrice di nome MATRI 2 X 10 di tipo opportuno;
riempie la prima riga di MATRI con gli elementi di A.txt fino al riempimento della riga
o all'esaurimento dei dati letti dal file;
riempie la seconda riga di MATRI con gli elementi di B.txt fino al riempimento della
riga o all'esaurimento dei dati letti dal file;
copia in un vettore VETT gli elementi presenti nella prima riga della matrice che
soddisfano i seguenti criteri:
il valore è copiato solo se è maggiore o uguale al valore corrispondente nella
seconda riga della matrice;
il vettore non deve presentare buchi, ovvero deve essere riempito senza
soluzione di continuità.
Il programma stampa i valori effettivamente inseriti in VETT.

#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fA, *fB;
int MATRI[2][10], VETT[10], el;
int indR, indV, j;

fA = fopen("A.txt","r");
fB = fopen("B.txt","r");

if(fA == NULL || fB== NULL)


exit(-1);

indR=0;
while(fscanf(fA,"%d",&el) != EOF && indR<10) {
MATRI[0][indR] = el;
indR++;
}

for(j=0;j<indR; j++)
fscanf(fB,"%d",&MATRI[1][j]);

indV=0;
for(j=0; j<indR; j++)
if(MATRI[0][j] >= MATRI[1][j]){
VETT[indV] = MATRI[0][j];
indV++;
}

for(j=0; j<indV; j++)


printf("%d\n",VETT[j]);

fclose(fA); fclose(fB);
system("pause"); return 0;
}

E2
Definire una struttura denominata PRIMO contenente due campi A e B di tipo rispettivamente
double e SECONDO dove SECONDO è una struttura composta da due campi denominati
rispettivamente X ed Y di tipo int.
Scrivere la funzione FZX che ha in ingresso un parametro passato per valore sec di tipo
SECONDO ed un parametro passato per indirizzo prim di tipo PRIMO e che inserisce nel
campo B di prim il contenuto di sec e nel campo A di prim il valore della divisione decimale
dei campi X ed Y di sec , se il campo Y è diverso da zero. La funzione restituisce 1 se il
campo Y di sec è diverso da zero, 0 altrimenti.

#include <stdio.h>
#include <stdlib.h>
typedef struct{int X,Y;} SECONDO;
typedef struct{double A; SECONDO B;} PRIMO;
int FZX(SECONDO sec, PRIMO *prim)
{ int ret=0;

prim -> B = sec;


if(sec.Y != 0)
{
prim->A = sec.X;
prim->A /= sec.Y;
ret=1;
}
return ret;
}

int main() //non richiesto dal testo


{
PRIMO p1, p2;
SECONDO s1={3.5, 8.9}, s2={45,0.0};
int r1, r2;

r1 = FZX(s1,&p1);
r2 = FZX(s2,&p2);

printf("%d %f\n",r1,p1.A);
printf("%d %f\n",r2,p2.A);
system("pause"); return 0;
}

E3
Una sistema di ordini on line si compone fra le altre delle seguenti relazioni (in neretto sono
indicati gli attributi che compongono la chiave primaria):
Utente (IDUtente, password, CAP)
Merce (IDMerce, descrizione, prezzoUnitario)
Ordine (NumeroOrdine, IDUtente, data, importoTotale)
VociOrdine(NumeroOrdine, IDMerce, importoVoce)

Per semplicità si supponga che il formato di data sia gg/mm/aaaa.


Formulare le seguenti interrogazioni:
Indicare per ogni valore di NumeroOrdine il numero di voci che compongono l'ordine.
Indicare il valore di descrizione per le merci che non compaiono in nessun ordine.
per valore di NumeroOrdine eguale a 432 calcola il valore di importoTotale ed aggiorna
l'attributo importoTotale nella relazione Ordine.

SELECT NumeroOrdine, count(*) AS TotaleVoci


FROM VociOrdine
GROUP BY NumeroOrdine

SELECT descrizione
FROM Merce
WHERE IDMerce NOT IN (SELECT IDMerce FROM VociOrdine)
UPDATE Ordine
SET importoTotale = (SELECT SUM(importoVoce)
FROM VociOrdine
WHERE NumeroOrdine =432)
WHERE NumeroOrdine = 432

E1
Un programma C:
ha in ingresso un file denominato rendimenti.txt contenente 10 righe dove ogni
riga indica il valore di un rendimento annuale espresso come percentuale,
legge un valore iniziale CAP indicante un capitale iniziale
legge un valore obiettivo, denominato TARGET, che indica il capitale finale desiderato.
Il programma calcola anno per anno il valore della somma capitale + rendimento annuale e
pone il risultato in un vettore TOT opportunamente dimensionato. Il calcolo si interrompe
quando il valore calcolato è maggiore o uguale a quello di TARGET o si superano i 10 anni.
Il programma produce in uscita la stampa dei valori presenti nel vettore TOT limitatamente alle
posizioni utilizzate; in caso non si sia raggiunto il valore di TARGET stampa valore non
raggiunto altrimenti stampa il numero di anni necessari a raggiungere il valore di TARGET.

Esempio
rendimenti.txt
5 quindi 0,05
2 quindi 0,02
2.5 quindi 0,025
:

CAP = 100.0
TARGET = 200.0
TOT
100 105 107.10 109.78 ...
5 2 2.5
#include <stdio.h>
#include <stdlib.h>
typedef struct{int G,H;} BETA;
typedef struct{int X; BETA Y[5];} ALFA;

int main()
{
FILE *fR;
double CAP, TARGET, TOT[11], rdA;
int anni=0, i;

if((fR=fopen("rendimenti.txt","r")) == NULL)
exit(-1);

printf("capitale: "); scanf("%lf",&CAP);


printf("target: "); scanf("%lf",&TARGET);
TOT[0] = CAP;

for(anni=0; anni<10 && TARGET>TOT[anni]; anni++)


{
fscanf(fR,"%lf",&rdA);
TOT[anni+1] = TOT[anni] * (1+rdA/100);
}

if(TARGET > TOT[anni])


printf("valore non raggiunto\n");
else
printf("occorrono %d anni\n",anni);

for(i=0; i<=anni; i++)


printf("%d %f\n",i, TOT[i]);
fclose(fR);

system("pause"); return 0;
}

E2
Definire una struttura chiamata ALFA contenente due campi X ed Y di tipo rispettivamente
int e vettore di 5 elementi di tipo BETA dove BETA è una struttura composta di due campi G
ed H di tipo int. Scrivere una funzione FGH che ha un parametro par1 di tipo vettore di 10
elementi di tipo int ed un parametro par2, passato per indirizzo, di tipo ALFA. La funzione
riempie gli elementi del campo Y di par2 con i valori contenuti in par1 e inserisce nel campo
X il numero di elementi di par1 positivi.

#include <stdio.h>
#include <stdlib.h>
typedef struct{int G,H;} BETA;
typedef struct{int X; BETA Y[5];} ALFA;

void FGH(int par1[10], ALFA *par2)


{
int i, j;

for(j=0, i=0;i<5;i++, j=j+2)


{
par2->Y[i].G = par1[j];
par2->Y[i].H = par1[j+1];
}
par2->X = 0;
for(j=0;j<10;j++)
if (par1[j] > 0)
par2->X = par2->X + 1;
}

int main() //non richiesto dal testo


{
ALFA p1;
int vt[10] = {3,5,-12,6,8,13,-2,-5,7,-123}, i;

FGH(vt, &p1);

for(i=0;i<5; i++)
printf("%2d %4d %4d\n",i,p1.Y[i].G,p1.Y[i].H);
printf("%d \n",p1.X);

system("pause"); return 0;
}

E3
Una base di dati per la gestione di centraline per la rilevazione dell'inquinamento ha fra le
altre le seguenti relazioni (in grassetto sono indicati gli attributi che formano la chiave):

Centralina (IdCentralina, Via, NumeroCivico)


Inquinanti (IdInquinante, Nome, ValMax)
Rilevazioni (Numero, Data, Ora, IdCentralina, IdInquinante, Valore)

Dove in Rilevazioni gli attributi IdCentralina ed IdInquinante sono chiavi esterne rispettivamente per le
relazioni Centalina ed Inquinanti. Inoltre, per semplicità si supponga che il formato di Data sia
gg/mm/aaaa e quello di Ora hh:mm.
Formulare le seguenti interrogazioni:
Eliminare tutte le rilevazioni quando IdInquinate è uguale a COx e Valore è superiore
a ValMax.
Indicare il numero di inquinanti diversi rilevato da ogni centralina.
Dato il giorno 02/06/2007 determinare quante centraline hanno avuto un valore di
IdInquinante PM10 strettamente superiore al valore medio dell'inquinante.

DELETE FROM Rilevazioni


WHERE Valore > (SELECT ValMax
FROM Inquinanti
WHERE IdInquinante = 'COx')
AND IdInquinante = 'COx'

SELECT IdCentralina,
count(DISTINCT IdInquinante) AS numeroInquinanti
FROM Rilevazioni
GROUP BY IdCentralina

SELECT COUNT(DISTINCT IdCentralina)


FROM Rilevazioni
WHERE Valore > ( SELECT AVG(Valore)
FROM Rilevazioni
WHERE DATA = 02/06/2007
AND IdInquinante = 'PM10')
AND DATA = 02/06/2007
AND IdInquinante = 'PM10'
Esercizio 1 (10 punti)
Le tuple delle relazione Impiegati(Matricola,Stipendio,AnnoNascita) e Laureati(Matricola,Voto)
i cui attributi sono tutti di tipo intero sono rispettivamente memorizzati nei file di nome
impiegati.txt e laureati.txt. Scrivere un programma che svolga le seguenti operazioni:
Memorizza in un file di nome Elevati.txt, quelle tuple di Impiegati il cui stipendio è
superiore alla media degli stipendi ed il cui anno di nascita è compreso tra il 1970 ed il
1975.
Memorizza in un file di nome Proiettato.txt il risultato dell’operazione di proiezione
dell’algebra relazionale di Impiegati sugli attributi Matricola e Nascita.
Memorizza in un file di nome Query.txt il risultato della seguente query SQL:
SELECT * FROM Impiegati,Laureati WHERE Impiegati.Matricola=Laureati.Matricola.

#include<stdio.h>
int main(void){
FILE *imp, *lau,*ele,*pro,*que;
double media;
int nroImp,x,y,z,mat,voto;
imp=fopen("impiegati.txt","r");
ele=fopen("elevati.txt","w");
if (imp==NULL || ele == NULL) return -1;

media=0; nroImp=0;
while(fscanf(imp,"%d%d%d",&x,&y,&z) != EOF){
media=media+y;
nroImp++;
}
media=media/nroImp;
rewind(imp);
while(fscanf(imp,"%d%d%d",&x,&y,&z) != EOF){
if (y> media && z>1970 && z<1975) fprintf(ele,"%d%d%d\n",x,y,z);
}
fclose(ele);

pro=fopen("proiettato.txt","w");
if (pro==NULL) return -1;

rewind(imp);
while(fscanf(imp,"%d%d%d",&x,&y,&z) != EOF){
fprintf(pro,"%d%d\n",x,z);
}
fclose(pro);

lau=fopen("laureati.txt","r");
que=fopen("query.txt","w");
if (lau==NULL || que == NULL) return -1;
rewind(imp);
while(fscanf(imp,"%d%d%d",&x,&y,&z)!=EOF){
while(fscanf(lau,"%d%d",&mat,&voto)!=EOF){
if(x==mat) fprintf(que,"%d%d%d%d%d\n",x,y,z,mat,voto);
}
}

fclose(que);
fclose(lau);
fclose(imp);
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato INFO struttura contenente un campo di nome MAT, matrice di
dimensione 10x10 di interi. Scrivere una funzione con due parametri formali X e Y entrambi di
tipo int e che restituisce attraverso un valore di ritorno una struttura di tipo INFO in cui il
campo MAT contiene il valore X nelle celle della prima e ultima riga e il valore Y nelle restanti
celle.

#include<stdio.h>
typedef struct{int MAT[10][10];} INFO;

INFO f(int x,int y){


INFO Q;
int i,j;
for(i=0;i< 10;i++){
Q.MAT[0][i]=x;
Q.MAT[9][i]=x;
}

for(i=1;i< 9;i++){
for(j=0;j<10;j++)
Q.MAT[i][j]=y;
}

return Q;
}
int main(){
return 0;
}

Esercizio 3 (4 punti)
Sintetizzare la funzione f(x)=2x+3, dove x è un numero in complemento a 2 di 2 bit. La
funzione deve essere rappresentata in complemento a due con il minimo numero di bit.

Esercizio 1 (10 punti)


Scrivere un programma che svolga le seguenti operazioni:
Definisce due matrici MAT e ADATTI entrambe di 2 righe e 20 colonne contenenti
numeri interi. Definisce un vettore COEFF contenente 20 numeri interi.
Inserisce nella matrice MAT una sequenza di numeri interi letti da tastiera. I numeri
positivi e dispari sono i soli numeri della sequenza che devono essere memorizzati
nella matrice. La lettura della sequenza di numeri termina al riempimento della
matrice.
Per ogni colonna di MAT verifica che il numero nella prima riga sia maggiore o uguale
a quello nella seconda ed in caso affermativo copia entrambi i numeri nella matrice
ADATTI. La coppia di numeri deve essere copiata così da rispettare le rispettive
posizioni di riga. Inoltre, la matrice ADATTI deve essere riempita progressivamente a
partire dalla prima colonna (non deve contenere buchi).
per ogni colonna di ADATTI calcola il coefficiente binomiale dei 2 numeri e memorizza
il risultato nel vettore COEFF.

#include<stdio.h>
int fatt(int X){
int ris;
ris=1;
while(X>1){
ris=ris*X;
X--;
}
}
int main(void){
int MAT[2][20], ADATTI[2][20],COEFF[20],x,i,j,k;
for(i=0;i<2;i++){
for(j=0;j<20;j++){
do{
printf("mat[%d][%d]:",i,j);
scanf("%d",&MAT[i][j]);
}while(MAT[i][j]<0 || MAT[i][j]%2==0);
}
}

k=0;
for(j=0;j<20;j++){
if (MAT[0][j]>=MAT[1][j]) {
ADATTI[0][k]=MAT[0][j];
ADATTI[1][k]=MAT[1][j];
k++;
}
for(i=0;i<k;i++){
COEFF[i]=fatt(ADATTI[0][i])/(fatt(ADATTI[0][i]-ADATTI[1]
[i])*fatt(ADATTI[1][i]));
}
}
return 0;
}
Esercizio 2 (6 punti)

Definire un tipo di dato RIGHE, struttura con due campi di nome prima e ultima entrambi di
tipo vettore di 10 int. Definire un tipo di dato MAT, matrice 10x10 di interi. Scrivere una
funzione con un parametro formale di nome X di tipo MAT che restituisce una struttura di tipo
RIGHE il cui campo prima contiene i dati della prima riga di X e il campo ultima contiene i
dati dell'ultima riga di X.

#include<stdio.h>
typedef struct{int prima[10],ultima[10];} RIGHE;
typedef int MAT[10][10];
RIGHE f(MAT X){
RIGHE Q;
int i;
for(i=0;i< 10;i++){
Q.prima[i]=X[0][i];
Q.ultima[i]=X[9][i];
}
return Q;
}

Esercizio 3 (4 punti)
Sintetizzare la funzione f(x)=2x+1, dove x è un numero binario positivo di 2 bit. La funzione
deve essere rappresentata in binario con il minimo numero di bit.

Esercizio 1 (8 punti)

Scrivere un programma C che faccia quanto segue:

1) Inizializza la prima riga di una matrice 50x50 di nome M con il


valore 1;

2) legge una sequenza di numeri interi e li mette nella prima riga di


della matrice M. La lettura della sequenza termina quando alla prima
riga della matrice M sono stati assegnati 50 interi oppure quando
viene
letto il secondo numero intero negativo;

3) copia il contenuto della prima riga in tutte le righe successive.

#include<stdio.h>
int main(void){
int M[50][50],i,j,neg;

for(i=0;i<50;i++) M[0][i]=1;

i=0;
neg=0;
do
{
scanf("%d",&M[0][i]);
if (M[0][i]<0) neg++;
i++;
}while (neg < 2 && i<50);

printf("FINE CARICAMENTO");

for(i=1;i<50;i++)
for(j=0;j<50;j++)
M[i][j]=M[0][j];

for(i=1;i<50;i++){
for(j=0;j<50;j++) {
M[i][j]=M[0][j];
printf("%d ",M[0][j]);
}
printf("\n");
}

Esercizio 2 (8 punti)

Definire un nuovo tipo di dato di nome REC, struttura con


due campi:
il primo campo, di nome b2, deve essse di tipo vettore di 10
componenti di tipo int;
il secondo campo, di nome b10, deve essere di tipo int.

Scrivere una funzione di nome F con un parametro formale di nome


X di tipo REC passato per indirizzo. La funzione deve assegnare al
campo b10 di X il risultato della conversione da base 2 a base 10 del
numero dato nel campo b2 di X.

typedef struct{int b2[10],b10;} REC;

f(REC *X){
int i,peso;
peso=1;
X->b10=0;
for(i=9;i>=0;i--){
X->b10=X->b10+X->b2[i]*peso;
peso=peso*2;
}
}

Esercizio 3 (4 punti)
Sintetizzare in binario e con il minor numero di bit la funzione
f(x)=x+7, dove x è
un numero rappresentabile in binario con un bit.

ESERCIZI

Esercizio 1 (8 punti)
Scrivere un programma C che faccia quanto segue:

1) Legge una sequenza di numeri interi e quei numeri compresi tra 0 e


1023
vengono memorizzati in un vettore di
nome V. La lettura termina quando nel vettore sono
stati inseriti 10 numeri.

2) Per ogni numero in V il programma esegue la conversione in


binario,
memorizza i resti ottenuti in un vettore R opportunamente
dimensionato e stampa il contenuto di R.

#include<stdio.h>
int main(void){
int i,j,V[10],R[10];

i=0;
do{
scanf("%d",&V[i]);
if (V[i]>=0 && V[i]<=1023) i++;
}while(i<10);

for(i=0;i<10;i++){
for(j=9;j>=0;j--){
R[j]=V[i]%2;
V[i]=V[i]/2;
}
for(j=0;j<10;j++) printf("%d ",R[j]);
printf("\n");
}

return 0;
}

Esercizio 2 (8 punti)

Definire un nuovo tipo di dato di nome NUMERI, struttura con due


campi di nome b2 e cpl2 entrambi di tipo vettore di 10 componenti di
tipo int;

Scrivere una funzione di nome F con un parametro formale di nome X di


tipo NUMERI passato per indirizzo. La funzione deve assegnare al
campo cpl2 di X il risultato del complemento a 2 del numero nel campo
b2 di
X. Nota: se il complemento a 2 di b2 non esiste, allora la funzione
puo' mettere in cpl2 quello che vuole.

typedef struct{int b2[10],cpl2[10];} NUMERI;

f(NUMERI *X){
int i;

i=10;
do{
i--;
X->cpl2[i]=X->b2[i];
}while(X->b2[i]!=1 && i>0);
i--;
while(i>=0){
X->cpl2[i]=1-X->b2[i];
i--;
}
}

Esercizio 3 (4 punti)
Sintetizzare con il minor numero di bit la funzione f(x)=(x+1)*8,
dove x è
un numero rappresentabile in complemento a 2 con un bit.

Esercizio 1 (punteggio 10)


Sia dato un file di testo denominato dati.txt contenete numeri interi positivi. Scrivere un
programma in linguaggio C che:
definisce un vettori V contenente 100 numeri interi;
legge gli interi di dati.txt e li memorizza in V. L’operazione di lettura termina
quando vengono inseriti 100 numeri in V oppure quando viene letto dal file un valore
che è una potenza di 7 oppure quando vengono esauriti gli elementi del file dati.txt.
Negli ultimi due casi le restanti posizioni di V sono inizializzate con il valore 0.
Visualizza su standard output i valori contenuti in V che sono divisibili per 3.

#include <stdio.h>
#include <stdlib.h>
int potenza (int x)
{
int ris, p;
ris=0; p=1;
while (p <= x)
{if(p==x) ris=1; p=p*7; }
return ris;
}
int main()
{
FILE *f;
int x[100], i=0,b,j;
f=fopen("C:/temp/dati.txt", "r"); /*suppongo dati.txt in C:/temp */
if (f==NULL) exit(-1);
while ((fscanf(f, "%d", &b)!= EOF) && (i<=99) && (!potenza(b)))
{x[i]=b; if ((x[i]%3)==0) printf("%d\n", x[i]);i++; }
fclose(f);
for (j=i; j<=99; j++)
x[j]=0;
system("PAUSE");
return 0;
}

Esercizio 2 (punteggio 6)
Definire un tipo di dato struct di nome ST con due campi A e B di tipo int. Quindi scrivere una
funzione con due parametri V di tipo vettore di 100 elementi di tipo ST e R di tipo ST La
funzione deve assegnare a tutti gli elementi di V la struct R con i campi A e B incrementati del
valore dell’indice di V.

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

typedef struct {int A; int B;} ST;

void f (ST v[100], ST R)


{int i;
for (i=0; i<=99; i++)
{v[i].A = R.A+i;
v[i].B = R.B+i;}
}

Il main è per provare f e non era richiesto nel compito

int main()
{ ST x;
ST y[100];
int j;
x.A=10;
x.B=20;
f(y,x);
for (j=0; j<=99; j++)
printf("%d %d\n", y[j].A, y[j].B);
system("PAUSE");
return 0;
}

Esercizio 3 (punteggio 4)
Si deve realizzare un circuito che calcoli la funzione f(x,y)=x y, dove x è un numero di due bit in
complemento a due mentre y è un numero binario positivo di un bit. Calcolare il minimo
numero di bit in uscita del circuito esibendo i calcoli, scrivere la tavola di verità del circuito e le
espressioni booleane che rappresentano la funzione. Si assume che la funzione f(0,0)=1.

x1 x0 y F(x,y) C1 C0
0 0 0 1 0 1
0 0 1 0 0 0
0 1 0 1 0 1
0 1 1 1 0 1
1 0 0 1 0 1
1 0 1 -2 1 0
1 1 0 1 0 1
1 1 1 -1 1 1

C1=x1y
C0=-x1-y + x1y + x0y + -x0-y

Esercizio 1 (8 punti)
Dato un file di testo denominato dati.txt e contenente solo numeri interi positivi, scrivere un
programma C che per ogni numero X contenuto in dati.txt visualizzi su standard output
l’elenco dei numeri primi che dividono X.

#include <stdio.h>
#include <stdlib.h>
int primo(int v)
{
int ret=1, i;
for(i=2; i<v; i++)
if(v%i == 0)
ret = 0;
return ret;
}
int main()
{
FILE *f;
int X, i;

f=fopen("dati.txt","r");
if (f==NULL)
exit(-1);

while(fscanf(f,"%d",&X) != EOF)
{
printf("divisori primi di %d: ",X);
for(i=1;i<=X;i++)
if(primo(i)==1 && X%i==0)
printf("%d ",i);
printf("\n");
}
system("pause");
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato T, struttura con due campi il primo di nome dati di tipo vettore di 10 int
ed il secondo di nome val tipo int. Scrivere una funzione con un parametro formale di nome X
di tipo T che restituisce 1 se il valore del campo val di X è contenuto in una qualche posizione
del campo dati di X, 0 altrimenti.

#include <stdio.h>
#include <stdlib.h>
typedef struct{int dati[10], val;} T;

int funz(T X)
{ int i;
for(i=0;i<10;i++)
if (X.dati[i] == X.val)
return 1;
return 0;
}
int main() //non richiesto dal testo
{
T Q={{1,8,9,-23, 156,90,234, -9, 12, 1560},-90};

printf("%d \n",funz(Q));

system("pause");
return 0;
}

Esercizio 3 (6 punti)
Sia dato il seguente schema di base di dati:

STUDENTI(Matricola, Nome, Cognome, Indirizzo, Telefono, Cod_CorsodiLaurea)


DOCENTI(Codice_Docente, Nome, Cognome)
CORSO_DI_LAUREA(Codice_CdL, Nome, Cod_Fac)
INSEGNAMENTO(Codice_Insegnamento, Nome, Cod_Docente, Codice_Corso_di_Laurea)
ESAMI(Matr, Voto, Data, Lode, Cod_Ins)
FACOLTA(Codice_Fac, Nome, Indirizzo_Sede, N_Telefonico)

Scrivere le query SQL per:

visualizzare la matricola degli studenti della facoltà di Economia che hanno sostenuto il
maggior numero di esami;
SELECT Matr, COUNT(*)
FROM Esami
WHERE Matr IN
(SELECT Matricola
FROM STUDENTI
WHERE
Cod_CorsodiLaurea IN
(SELECT Codice_CdL
FROM Corso_Di_Laurea, Facolta
WHERE
Cod_Fac = Codice_Fac
AND
Facolta.Nome = “ECONOMIA”)
)
GROUP BY Matr
HAVING COUNT(*) =
(
SELECT MAX(TotEx) M
FROM a
(SELECT Count(*) AS TotEx s
FROM Esami s
WHERE Matr IN i
(SELECT Matricola m
FROM STUDENTI o
WHERE n
Cod_CorsodiLaurea IN u
(SELECT Codice_CdL m
FROM Corso_Di_Laurea, e
Facolta r
WHERE o
Cod_Fac = d
Codice_Fac i
AND e
Facolta.Nome = s
“ECONOMIA”) a
) m
GROUP BY Matr) MaxExEco i
p
e
r
s
t
u
d
e
n
t
e
)

visualizzare in quante facoltà insegna il docente Ettore Majorana.;

SELECT Count(DISTINCT Cod_Fac)


FROM CORSO_DI_LAUREA
WHERE Codice_CdL IN
SELECT DISTINCT Codice_Corso_di_Laurea
FROM Insegnamento
WHERE Cod_Docente =
(SELECT Codice_Docente
FROM Docenti
WHERE
Nome=’Ettore’
AND
Cognome=’Majorana’)

eliminare dalla relazione STUDENTI tutti gli studenti iscritti alla facoltà di Economia.
DELETE FROM STUDENTI
WHERE
Cod_CorsodiLaurea IN
(SELECT Codice_CdL
FROM Corso_Di_Laurea, Facolta
WHERE
Cod_Fac = Codice_Fac
AND
Facolta.Nome = “ECONOMIA”)
)

Esercizio 1 (8 punti)
Scrivere un programma che svolga le seguenti operazioni:
Definisce una matrice M di 20x20 numeri interi.
Legge una sequenza di numeri interi da standard input ed inserisce i numeri pari nella
matrice M. La lettura della sequenza di numeri termina al riempimento della matrice
M.
Visualizza su standard input la frequenza assoluta di ogni elemento delle matrice.
#include <stdio.h>
#include <stdlib.h>
#define DIM 3
typedef int matrice[DIM][DIM];

int main()
{
matrice M;
int i, j, val, freqAss, k,w;
i=0; j=0;

while (i<DIM)
{
printf("intero: ");
scanf("%d",&val);
if (val % 2 == 0)
{ M[i][j] = val;
i = i + (j+1)/DIM;
j = (j + 1) % DIM;
}
}

for(i=0; i<DIM; i++)


for(j=0;j<DIM; j++)
{ freqAss=0;
for(k=0; k<DIM; k++)
for(w=0;w<DIM; w++)
if(M[i][j] == M[k][w])
freqAss++;
printf("%d freq. ass=%d\n",M[i][j], freqAss);
}
system("pause");
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato MV, struttura con due campi il primo di nome m di tipo matrice di
10x10 int ed il secondo di nome v tipo int. Scrivere una funzione con un parametro formale
di nome X di tipo MV che restituisce 1 se nel campo m di X è presente almeno un valore dello
stesso segno del campo v di X, 0 altrimenti.

#include <stdio.h>
#include <stdlib.h>
#define DIM 3
typedef struct{int m[DIM][DIM], v;}MV;

int funz(MV X)
{
int i,j;
for(i=0;i<DIM;i++)
for(j=0;j<DIM;j++)
if(X.m[i][j] * X.v > 0)
return 1;
return 0;
}
int main()//non richiesto dal testo
{
MV n={{8,9,12,34,1,6,7,9,783},0};

printf("%d\n",funz(n));
system("pause");
return 0;
}

Esercizio 3 (6 punti)
Sia dato il seguente schema di base di dati:

STUDENTI(Matricola, Nome, Cognome, Indirizzo, Telefono, Cod_CorsodiLaurea)


DOCENTI(Codice_Docente, Nome, Cognome)
CORSO_DI_LAUREA(Codice_CdL, Nome, Cod_Fac)
INSEGNAMENTO(Codice_Insegnamento, Nome, Cod_Docente, Codice_Corso_di_Laurea)
ESAMI(Matr, Voto, Data, Lode, Cod_Ins)
FACOLTA(Codice_Fac, Nome, Indirizzo_Sede, N_Telefonico)

Scrivere le query SQL per:

visualizzare i codici dei docenti della facoltà di Economia titolari del maggior numero di
insegnamenti;

SELECT Cod_Docente
FROM
Insegnamento
WHERE
Codice_Corso_di_Laurea IN (SELECT Codice_CdL
FROM Corso_Di_Laurea,
Facolta
WHERE
Cod_Fac =
Codice_Fac
AND
Facolta.Nome =
“ECONOMIA”)
GROUP BY Cod_Docente
HAVING Count(*) = (
SELECT MAX(Mx) Num
FROM (SELECT count(*) AS Mx ero
mas
FROM INSEGNAMENTO sim
WHERE o
Codice_Corso_di_Laurea IN ( di
cor
SELECT cod si
Codice_CdL ici per
FROM CdL doc
ent
Corso_Di_Laurea, Facolta di e.
WHERE Eco Eco
Cod_Fac = Codice_Fac nom nom
ia
AND ia

Facolta.Nome = “ECONOMIA”
)
GROUP BY Cod_Docente) X
)

visualizzare quanti insegnamenti prevede il corso di laurea in Economia e Commercio;

SELECT DISTINCT count(*)


FROM Insegnamento
WHERE Codice_Corso_di_Laurea = (SELECT Codice_CdL
FROM CORSO_DI_LAUREA
WHERE Nome = ‘Economia e
Commercio’)

modificare le tuple della relazione ESAMI diminuendo di un punto il voto di tutti gli
studenti iscritti alla facoltà di Economia.

UPDATE Esami
SET Voto = Voto -1
WHERE Matr IN
(SELECT Matricola
FROM STUDENTI
WHERE
Cod_Corso_di_Laurea IN
(SELECT
Codice_CdL
FROM
Corso_Di_Laurea, Facolta
WHERE

Cod_Fac = Codice_Fac
AND

Facolta.Nome = “ECONOMIA”)
)
Esercizio 1 (10 punti)
Sia dato un file di testo denominato dati.txt in cui in ogni riga vi sono tre numeri interi. Scrivere
un programma che svolga le seguenti operazioni:
Memorizza in un file di nome out1.txt le righe di dati.txt la cui somma del secondo e del
terzo elemento della riga è maggiore di 7.
Memorizza in un file di nome out2.txt il primo ed il secondo elemento di ogni riga del
file dati.txt.
Calcola la media M dei valori che sono il primo elemento di ogni riga di dati.txt ed
inserisce in un file di nome out3.txt le righe di dati.txt in cui il terzo elemento è minore
della media M.

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

int main()
{
FILE *fin, *fo1, *fo2,*fo3;
int uno,due,tre, el;
double som=0, M;

fin=fopen("dati.txt","r");
fo1=fopen("out1.txt","w");
fo2=fopen("out2.txt","w");
fo3=fopen("out3.txt","w");

if(fin==NULL || fo1==NULL || fo2==NULL || fo3==NULL)


exit(-1);

el=0;
while(fscanf(fin,"%d%d%d",&uno,&due,&tre) != EOF)
{
if(due+tre > 7)
fprintf(fo1,"%d %d %d\n",uno,due,tre);
som = som+uno;
fprintf(fo2,"%d %d\n",uno,due);
el = el +1;
}

M = som/el;

rewind(fin);
while( fscanf(fin,"%d%d%d",&uno,&due,&tre) != EOF)
if (tre < M)
fprintf(fo3,"%d %d %d\n",uno,due,tre);
fclose(fin); fclose(fo1); fclose(fo2); fclose(fo3);

system("pause"); return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato MAT, matrice 10x10 di interi. Scrivere una funzione con un parametro
formale di nome X di tipo MAT ed un parametro formale di nome Y di tipo vettore di 10 interi
che inserisce in Y i valori contenuti nella diagonale principale di X.

#include <stdio.h>
#include <stdlib.h>
#define DIM 10

typedef int MAT[DIM][DIM];

void diag(MAT X, int Y[])


{
int i;

for(i=0;i<DIM;i++)
Y[i] = X[i][i];
}

//NON RICHIESTO DAL TESTO


int main()
{
MAT A, B={0};
int i,j,t=0;
for(i=0;i<DIM;i++)
A[i][i] = t++;
diag(A,B);
for(i=0;i<DIM;i++)
{
for(j=0; j<DIM; j++)
printf("%3d ",B[i][j]);
printf("\n");
}
system("pause"); return 0;
}

Esercizio 3 (4 punti)
Sintetizzare la funzione f(x, y)= x-y, dove x e y sono numeri in complemento a due di 1 bit. La
funzione deve essere rappresentata in complemento a due con il minimo numero di bit.

X Y X Y X-Y U1 U0
0 0 0 0 0 0 0
0 1 0 -1 1 0 1
1 0 -1 0 -1 1 1
1 1 -1 -1 0 0 0

U1 = X-Y
U0 = -XY + X-Y

Esercizio 1 (10 punti)


Scrivere un programma che svolga le seguenti operazioni:
Definisce due vettori VETT1 e VETT2 entrambi contenenti 20 numeri interi.
Legge una sequenza di numeri interi da standard input ed inserisce i numeri pari nel
vettore VETT1 ed i numeri dispari nel vettore VETT2. La lettura della sequenza di
numeri termina al riempimento di uno dei due vettori.
Inserisce nelle restanti posizioni di VETT1 il valore 2 e nelle restanti posizioni di VETT2
il valore 3.
Visualizza su standard output la differenza tra i valori contenuti delle medesime
posizioni di VETT1 e VETT2.

#include <stdio.h>
#include <stdlib.h>
#define DIM 5

typedef int VETT[DIM];

int main()
{
VETT VETT1, VETT2;
int i, j, val;

i=0; j=0;
while(i<DIM && j<DIM)
{
printf("dammi un intero: ");
scanf("%d",&val);
if (val % 2 == 0)
{VETT1[i] = val;
i++;}
else
{VETT2[j] = val;
j++;}
}

for( ;i<DIM; i++)


VETT1[i] = 2;
for( ;j<DIM; j++)
VETT2[j] = 3;

for(i=0;i<DIM; i++)
printf("%d) differenza: %d\n",i,VETT1[i]-VETT2[i]);

system("pause"); return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato MAT, matrice 10x10 di interi. Scrivere una funzione con due parametri
formali di nome X e Y entrambi di tipo MAT. La funzione inserisce in Y i valori contenuti in X
invertendo le righe con le colonne (calcolando così la matrice trasposta di X).

#include <stdio.h>
#include <stdlib.h>
#define DIM 10

typedef int MAT[DIM][DIM];

void trasposta(MAT X, MAT Y)


{
int i, j,k;

for(i=0;i<DIM;i++)
for(j=0; j<DIM; j++)
Y[j][i] = X[i][j];
}

//NON RICHIESTO DAL TESTO


int main()
{
MAT A, B;
int i,j,t=0;
for(i=0;i<DIM;i++)
for(j=0; j<DIM; j++)
A[i][j] = t++;
trasposta(A,B);
for(i=0;i<DIM;i++)
{
for(j=0; j<DIM; j++)
printf("%3d ",B[i][j]);
printf("\n");
}
system("pause"); return 0;
}

Esercizio 3 (4 punti)
Sintetizzare la funzione f(x, y)= x+y, dove x e y sono numeri in complemento a due di 1 bit. La
funzione deve essere rappresentata in complemento a due con il minimo numero di bit.

X Y X Y X+Y U1 U0
0 0 0 0 0 0 0
0 1 0 -1 -1 1 1
1 0 -1 0 -1 1 1
1 1 -1 -1 -2 1 0

U1 = X + Y
U0 = -XY + X-Y

Esercizio 1 (punteggio 10)


Scrivere un programma C che:
Definisce un vettore di nome V contenente cento numeri interi.
Legge da standard input una sequenza di numeri interi ed inserisce dentro V, senza
lasciare spazi vuoti, i numeri positivi della sequenza che sono numeri primi.
L’operazione di lettura termina al riempimento del vettore V oppure quando viene letto
da standard input il valore 0.
Visualizza su standard output gli elementi contenuti in V che sono stati inseriti da
standard input.
Visualizza su standard output il massimo tra i valori inseriti dentro V.

#include <stdio.h>
#include <stdlib.h>
int primo (int x)
{
int p;
for (p=2; p<=x/2; p++)
if(x%p==0) return 0;
return 1;
}
int main()
{
int x[100], i=0,j,b,max;
while ((scanf("%d", &b)) && (i<=99) && (b!=0))
if ((primo(b)) && (b>0)) {x[i]=b; i++; }
for (j=0; j<=i-1; j++)
printf("%d\n", x[j]);
max=x[0];
for (j=0; j<=i-1; j++)
if (x[j]>max) max=x[j];
printf("massimo: %d\n", max);
system("PAUSE");
return 0;
}
Esercizio 2 (punteggio 6)

Definire un tipo di dato struct di nome ST con un campo A di tipo int ed un campo B di tipo
vettore di 10 int. Quindi scrivere una funzione con ingresso un parametro V di tipo ST che
restituisce 1 se ogni elemento del campo B di V è divisibile per il valore del campo A, 0
altrimenti.

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

typedef struct {int A; int B[10];} ST;

int f (ST V)
{int i;
for (i=0; i<=9; i++)
if ((V.B[i]%V.A) != 0) return 0;
return 1; /* perchè con l'else sarebbe stato errato? */
}

/* Il main non è richiesto e serve per provare f */

int main()
{ ST x;
int j;
scanf("%d", &x.A);
for (j=0; j<=9; j++)
x.B[j]=4*j;
printf("%d\n", f(x));
system("PAUSE");
return 0;
}

Esercizio 3 (punteggio 4)
Si deve realizzare un circuito che calcoli la funzione f(x,y,z)=(x-y)*z, dove x,y,z, sono tre numeri di un
bit in complemento a due. Calcolare il minimo numero di bit in uscita del circuito esibendo i calcoli,
scrivere la tavola di verità del circuito e le espressioni booleane che rappresentano la funzione.

x y z F(x,y,z) C1 C0
0 0 0 0 0 0
0 0 1 0 0 0
0 1 0 0 0 0
0 1 1 -1 1 1
1 0 0 0 0 0
1 0 1 1 0 1
1 1 0 0 0 0
1 1 1 0 0 0

C1=-xyz
C0=C1+x-yz

E1.
Il file di testo estratti.txt contiene su ogni riga un numero compreso fra 1 e 90. Si
desidera:
stabilire la frequenza assoluta di ogni numero e memorizzare tale informazione in un
vettore di nome vFreq opportunamente dimensionato;
visualizzare quale è il numero che compare con più frequenza fra quelli possibili;
visualizzare quale è la media dei dati in vFreq;
caricare il file di testo freqRel.txt con la frequenza relativa (rapporto fra la
frequenza assoluta e il numero totale di valori in estratti.txt) di ognuno dei
possibili numeri.

#include<stdio.h>
int main(void){
FILE *f;
int x,vFreq[90],i;

f=fopen("estratti.txt","r");
if (f==NULL) return -1;
for(i=0;i<90;i++) vFreq[i]=0;

while(fscanf(f,"%d",&x) !=EOF){
vFreq[x-1]++;
}
fclose(f);

x=0;
for(i=1;i<90;i++){
if(vFreq[i]>vFreq[x]) x=i;
}
printf("%d e' uno dei numeri con frequenza massima\n",x+1);
f=fopen("freqRel.txt","w");

x=0;
for(i=0;i<90;i++) x=x+vFreq[i];

for(i=0;i<90;i++) fprintf(f,"%f\n",(1.0*vFreq[i])/x);
fclose(f);
return 0;

E2.
Si definisca la struttura dati COPPIA composta da due campi di tipo int di nome A e B. Si
definisca quindi il tipo VettoreDiCoppie vettore di 20 elementi di tipo COPPIA. Si
costruisca la funzione fzt() che ha in ingresso un parametro formale di tipo
VettoreDiCoppie di nome parVt e che restituisce attraverso un secondo parametro
formale di nome rest, di tipo opportuno, l’elemento di parVt che ha il valore del prodotto
dei campi A e B minore (se vi è più di un elemento con queste caratteristiche ne restituisce
uno qualsiasi).

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

#define DIM 20
typedef struct {int A, B;} COPPIA;
typedef COPPIA VettoreDiCoppie[DIM];

COPPIA fzt(VettoreDiCoppie parVt, COPPIA *rest)


{
int posMin, valMin, i;

posMin=0;
valMin=parVt[0].A * parVt[0].B;
for(i=1; i<DIM; i++)
if(parVt[i].A * parVt[i].B < valMin)
{
posMin = i;
valMin = parVt[i].A * parVt[i].B;
}
*rest = parVt[posMin];
return *rest;
}

int main(){ //NON RICHIESTO DAL TESTO


COPPIA rit, rit2;
VettoreDiCoppie v ={{8,9},{15,-7},{7,8},{-10,5}};

rit2 = fzt(v,&rit);
printf("<%d %d> <%d %d>\n",rit.A,rit.B,rit2.A,rit2.B);

system("pause");
return 0;
}

E3.
Una società che rileva i prezzi in alcune catene di supermercati ha deciso di racchiudere le
informazioni in un data base che contiene fra le altre le seguenti relazioni:
Catena (Nome, CodiceCatena, Sede)
Produttore (CodiceProduttore, Indirizzo, PrefissoTelefonico)
Prodotti (CodiceProdotto, CodiceProduttore, Descrizione)
Costo (CodiceNegozio, CodiceProdotto, prezzo, DataRilevazione)
Negozio (CodiceNegozio, CodiceCatena, indirizzo, CAP)
Gli attributi sono di tipo stringa tranne prezzo e DataRilevazione che sono
rispettivamente di tipo real e date.
Scrivere le interrogazioni SQL che permettano :
elencare in ordine crescente per l’attributo CodiceProduttore e quindi in ordine
decrescente per l’attributo Descrizione le tuple della relazione Prodotti;

indicare per ogni valore di Descrizione della relazione Prodotti quante rilevazioni
di prezzo ha avuto;
indicare per ogni valore di CodiceCatena e di DataRilevazione il prezzo medio
dei prodotti venduti.

1- select * from prodotti order by CodiceProduttore, Descrizione desc

2- select Descrizione,count(*)
from Prodotti,Costo,
where Predotti.CodiceProdotto=Costo.CodiceProdotto
group by Descrizione

3- select CodiceCatena,DataRilevazione,avg(prezzo)
from Negozio,Costo
where Negozio.CodiceNegozio=Costo.CodiceNegozio
group by CodiceCatena,DataRilevazione

E1.
Sia dato il file di testo valori.txt contenente su ogni riga 4 numeri interi positivi. Si
compiano le seguenti elaborazioni:
si crei, a partire dai valori contenuti in questo file,un nuovo file di testo denominato
elabora.txt che contiene il terzo elemento di ogni riga di valori.txt;
si carichi il vettore vt di 20 int con i primi 20 elementi di elabora.txt (se
elabora.txt contiene meno di 20 elementi le restanti celle del vettore vengono
riempite con 0);
si stampi a video il valor medio degli elementi presenti in vt.

#include<stdio.h>
int main(void){
FILE *f,*q;
int x,y,z,k,vt[20];

f=fopen("valori.txt","r");
q=fopen("elabora.txt","w");
if (f==NULL || q==NULL) return -1;

while(fscanf(f,"%d%d%d%d",&x,&y,&z,&k) !=EOF){
fprintf(q,"%d",z);
}
fclose(f);
fclose(q);

q=fopen("elabora.txt","r");

for(x=0;x<20;x++) vt[x]=0;

x=0;
while(fscanf(q,"%d",&y)!=EOF && x<20) {
vt[x]=y;
x++;
}
fclose(q);

y=0;
for(x=0;x<20;x++){
y=y+vt[x];
}
printf("%f",y/20.0);

return 0;

E2.
Si definisca la struttura dati COPPIA formata da due campi X ed Y di tipo int; si definisca
inoltre la matrice matriceDiCoppie di dimensione 4 x 4 composta da elementi di tipo
COPPIA. Si definisca la funzione fH() che ha
-due parametri di tipo COPPIA rispettivamente di nome PA ed DI ed
-un parametro mat di tipo matriceDiCoppie.
La funzione copia nelle righe di indice pari del parametro mat il parametro PA e nelle righe di
indice dispari del parametro mat il parametro DI.

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

#define DIM 4
typedef struct {int X, Y;} COPPIA;
typedef COPPIA MatriceDiCoppie[DIM][DIM];

void fH(COPPIA PA, COPPIA DI, MatriceDiCoppie mat)


{
int i,j;

for(i=0; i<DIM; i++)


for(j=0; j<DIM; j++)
if (i%2==0) mat[i][j] = PA;
else mat[i][j]=DI;
}

int main(){ //NON RICHIESTO DAL TESTO


COPPIA par={20,-10};
MatriceDiCoppie m;
int i,j;

fH(par,m);

for(i=0; i<DIM; i++)


{
for(j=0; j<DIM; j++)
printf("<%d %d>\t",m[i][j].X,m[i][j].Y);
printf("\n");
}

system("pause");
return 0;
}

E3
Una società che rileva i prezzi in alcune catene di supermercati ha deciso di racchiudere le
informazioni in un data base che contiene fra le altre le seguenti relazioni:
Catena (Nome, CodiceCatena, Sede)
Produttore (CodiceProduttore, Indirizzo, PrefissoTelefonico)
Prodotti (CodiceProdotto, CodiceProduttore, Descrizione)
Costo (CodiceNegozio, CodiceProdotto, prezzo, DataRilevazione)
Negozio (CodiceNegozio, CodiceCatena, indirizzo, CAP)
Gli attributi sono di tipo stringa tranne prezzo e DataRilevazione che sono
rispettivamente di tipo real e date.
Scrivere le seguenti interrogazioni SQL:
che permette di elencare in ordine decrescente per l’attributo CodiceCatena ed in
ordine crescente per l’attributo CAP tutte le tuple della relazione Negozio;
per indicare per ogni valore di CodiceCatena e Nome della catena quanti negozi
possiede;
per ogni valore di CodiceProdotto e di DataRilevazione il prezzo medio del
prodotto.

SELECT *
FROM negozio
ORDER BY CodiceCatena DESC, CAP

SELECT Catena.CodiceCatena,Nome,count(*) AS ‘Totale negozi’


FROM Catena,Negozio
WHERE Catena.CodiceCatena=Negozio.CodiceCatena
GROUP BY Catena.CodiceCatena,Nome

SELECT CodiceProdotto,DataRilevazione, avg(prezzo) AS ‘Prezzo


medio’
FROM Costo
GROUP BY CodiceProdotto,DataRilevazione

Esercizio 1 (8 punti)
Sia dato un file di testo denominato dati.txt contenente numeri interi. Scrivere un programma
C che:
Definisce una matrice di nome M di dimensione 10x10 contenente numeri interi.
Legge i numeri interi contenuti nel file dati.txt ed inserisce nella diagonale principale di
M solo i numeri positivi di dati.txt. La lettura termina quando si è riempita la diagonale
principale di M oppure quando sono terminati i valori del file. In quest’ultimo caso le
restanti posizioni della diagonale principale devono essere riempite con il valore 0.
Per ogni riga della matrice M, il valore dell’elemento della diagonale principale viene
copiato in tutte le colonne della riga.
Visualizza su standard output il contenuto della diagonale secondaria.
Si ricorda che la diagonale principale di una matrice è la linea di valori che unisce la cella in
alto a sinistra con quella in basso a destra; la diagonale secondaria, invece, unisce la cella in
altro a destra con quella in basso a sinistra.

#include <stdio.h>
#include <stdlib.h>
#define DIM 10
int main()
{
int M[DIM][DIM], i, j, val;
FILE *f;

f = fopen("dati.txt","r");
if (f == NULL)
exit(-1);

i=0;
while (i<DIM &&fscanf(f,"%d",&val) != EOF)
if(val >0)
{ M[i][i] = val;
i++;}

for(;i<DIM;i++)
M[i][i] = 0;

for(i=0;i<DIM;i++)
for(j=0; j<DIM; j++)
M[i][j] = M[i][i];

for(i=0;i<DIM;i++)
printf("%4d \n",M[i][DIM-i-1]);

fclose(f);

system("pause");
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato T1, struct con due campi di nome A di tipo int e B di tipo double.
Definire un tipo di dato T2, struct con un campo di nome C di vettore di 100 numeri interi.
Scrivere la funzione fz() con due parametri K di tipo T1 e H di tipo puntatore ad un elemento
di tipo T2. La funzione deve modificare l’area di memoria puntata da H inserendo in tutti gli
elementi del campo C il rapporto tra il campo A di K ed il campo B di K.

#include <stdio.h>
#include <stdlib.h>
#define DIM 100
typedef struct{int A; double B;} T1;
typedef struct {int C[DIM];} T2;

void fz(T1 K, T2 *H)


{
int i;

for(i=0; i<DIM;i++)
H->C[i] = K.A / K.B;
}

int main()
{
T1 x ={6, 1.4};
T2 y;
int i;

fz(x,&y);

for(i=0;i<DIM;i++)
printf("%d\n",y.C[i]);

system("pause");
return 0;
}

Esercizio 3 (6 punti)
Siano dati i seguenti schemi di relazione:
Treni(Codice,CittaPartenza, CittaArrivo)
Partenze(Codice,data, prezzoBiglietto)
dove nella relazione Treni l’attributo Codice è la chiave primaria. Nella relazione Partenze gli
attributi Codice e data formano la chiave primaria mentre l’attributo Codice è chiave esterna
per le relazione Treni.

Scrivere le interrogazioni SQL che permettono di:


Visualizzare i valori di CittaPartenza e CittaArrivo di tutti i treni che partono il 10 luglio
2009 e con un valore dell’attributo prezzoBiglietto superiore a 100.
Eliminare dalla relazione Partenze tutte le tuple relative a Treni che partono da
Firenze.
Visualizzare per ogni Treno il valore massimo dell’attributo prezzoBiglietto.

a SELECT CittaPartenza, CittaArrivo


FROM Treni, Partenze
WHERE Treni.Codice = Partenze.Codice
AND
data = 10/07/2009
AND
prezzoBiglietto >100
b DELETE FROM Partenze
WHERE Codice IN (SELECT Codice
FROM Treni
WHERE CittaPartenza = ‘Firenze’)
c SELECT Codice, MAX(prezzoBiglietto)
FROM Partenze
GROUP BY Codice
Esercizio 1 (8 punti)
Sia dato un file di testo denominato dati.txt contenente numeri interi. Scrivere un programma
C che:
Definisce una matrice di nome M di dimensione 2x10 contenente numeri interi.
Inserisce in ogni posizioni dispari delle due righe della matrice M il valore 1.
Legge i numeri interi contenuti nel file dati.txt ed inserisce nella posizioni pari di della
prima riga di M i numeri negativi del file dati.txt. La lettura termina quando si sono
riempite tutte le posizioni pari della prima riga di M oppure quando sono terminati i
valori del file. In quest’ultimo caso le restanti posizioni non occupate devono essere
riempite con il valore 0.
Inserisce nelle posizioni pari della seconda riga di M il valore della corrispondente
posizione nella prima riga di M incrementato di 1.
Visualizza su standard output il contenuto della seconda riga di M.

#include <stdio.h>
#include <stdlib.h>
#define DIM 10
int main()
{
int M[2][DIM], i, j, val;
FILE *f;

f = fopen("dati.txt","r");
if (f == NULL)
exit(-1);

for(i=1; i<DIM;i=i+2)
M[0][i] = M[1][i] = 1;

i=0;
while (i<DIM &&fscanf(f,"%d",&val) != EOF)
if(val <0)
{ M[0][i] = val;
i=i+2;}

for(;i<DIM;i=i+2)
M[0][i] = 0;

for(i=0;i<DIM;i=i+2)
M[1][i] = M[0][i] + 1;

for(i=0;i<DIM;i++)
printf("%4d \n",M[1][i]);

fclose(f);
system("pause");
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato S, struct con due campi di nome M di tipo int e N di tipo double.
Definire un tipo di dato T, struct con un campo di nome F di vettore di 100 numeri interi.
Scrivere la funzione ft() con due parametri H di tipo S e G di tipo puntatore ad un elemento di
tipo T. La funzione deve modificare l’area di memoria puntata da G inserendo in tutti gli
elementi del campo F la somma tra il campo M di H ed il campo N di H.

#include <stdio.h>
#include <stdlib.h>
#define DIM 10

typedef struct{int M; double N;} S;


typedef struct{int F[DIM];} T;

void ft(S H, T *G)


{
int i;

for(i=0;i<DIM;i++)
G->F[i] = H.M + H.N;
}

int main()
{
S U={12,-3.4};
T R;
int i;

ft(U,&R);
for(i=0;i<DIM;i++)
printf("%4d ", R.F[i]);

system("pause");
return 0;
}

Esercizio 3 (6 punti)
Siano dati i seguenti schemi di relazione:
Treni(Codice,CittaPartenza, CittaArrivo)
Partenze(Codice,data, prezzoBiglietto)
dove nella relazione Treni l’attributo Codice è la chiave primaria. Nella relazione Partenze gli
attributi Codice e data formano la chiave primaria mentre l’attributo Codice è chiave esterna
per le relazione Treni.

Scrivere le interrogazioni SQL che permettono di:


Visualizzare i valori di data e prezzoBiglietto di tutti i treni che partono da Milano ed
arrivano a Moneglia.
Eliminare dalla relazione Treni tutte le tuple relative a Treni con un prezzo del biglietto
superiore a 200.
Visualizzare per ogni Treno il valore medio dell’attributo prezzoBiglietto.

a SELECT data, prezzoBiglietto


FROM Treni, Partenze
WHERE Treni.Codice = Partenze.Codice
AND CittaPartenza = ‘Milano’
AND CittaArrivo = ‘ Moneglia’
b DELETE FROM treni
WHERE Codice = (SELECT Codice
FROM Partenze
WHERE prezzoBiglietto >200)
c SELECT codice, AVG(prezzoBiglietto)
FROM Partenze
GROUP BY Codice

E1.
Scrivere il programma C che:
definisce un tipo struct di nome COPPIA composto da due campi A e B di tipo double;
definisce il tipo VSx come vettore di 1000 elementi di tipo COPPIA;
dato il file di testo dati.txt, le cui righe contengono due valori numerici, legge ogni
riga del file e mette il contenuto in un elemento Vett di tipo VSx (il primo valore
numerico nel campo A, il secondo nel campo B). La lettura termina o quando Vett è
pieno o alla fine del file;
Esempio
dati.txt
27.9 23.6
-90.9 118
123 -67.8
: :

Vett 27.9 -90.9 123 ...


23.6 118 -67.8 ...

definisce la funzione media() che ha in ingresso un parametro V di tipo Vsx ed un


parametro lung di tipo int che rappresenta il numero effettivo di elementi presenti in v.
La funzione restituisce attraverso un valore di ritorno un elemento di tipo COPPIA
contenente nel campo A il valor medio dei valori presenti nel
campo A di V e nel campo B il valor medio del campo B di V.
richiama la funzione media() e stampa il contenuto della struttura da essa restituito.

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

#define DIM 1000


typedef struct{double A,B;} COPPIA;
typedef COPPIA VSx[DIM];

COPPIA media(VSx v, int lung)


{ int i;
COPPIA el;
el.B = el.A = 0.0;

for (i=0; i<lung; i++)


{ el.A = el.A + v[i].A;
el.B = el.B + v[i].B;
}
el.A = el.A/lung;
el.B = el.B/lung;
return el;
}

int main()
{
VSx Vett;
FILE *f;
COPPIA rit;
int i;

f = fopen("dati.txt","r");
if (f == NULL)
{printf("errore file\n"); exit(-1);}

for(i=0; i<DIM && fscanf(f,"%lf %lf", &Vett[i].A, &Vett[i].B) != EOF; i++)


;

rit = media(Vett, i);


printf("%f %f\n",rit.A, rit.B);

close(f);

system ("pause"); return 0;


}

E2.

Definire un nuovo tipo di dato di nome RETTANGOLO contenente 2 campi di nome BASE e
ALTEZZA, entrambi di tipo int. Scrivere una funzione con un parametro formale X vettore di
elementi di tipo RETTANGOLO ed un parametro formale di nome DIM di tipo intero che
rappresenta il numero di componenti di X. La funzione fa quanto segue:
restituisce attraverso un opportuno parametro formale 1 se ogni campo di ogni
componente di X è strettamente positivo, 0 altrimenti.
restituisce, attraverso un opportuno parametro formale, un elemento di X il cui prodotto
dei due campi è il massimo.
#include <stdio.h>
#include <stdlib.h>
typedef struct{int BASE, ALTEZZA;}RETTANGOLO;

void fz(RETTANGOLO X[], int DIM, int *ret,RETTANGOLO *maxSup)


{
int i, max, s;
max = X[0].BASE * X[0].ALTEZZA;
*ret=1;
for(i=0;i<DIM;i++)
{
if(!(X[i].BASE >0 && X[i].ALTEZZA >0))
*ret = 0;
else
s = X[i].BASE * X[i].ALTEZZA;

if(s > max)


{ max = s;
*maxSup = X[i];
}
}
}

int main()
{ RETTANGOLO x[]={{4,5},{-2,3},{8,9}}, sp;
int r;
fz(x,3,&r,&sp);
printf("%d %d\n",r,sp.BASE*sp.ALTEZZA);
system("pause"); return 0;
}

E3.
Sintetizzare la funzione booleana f(x), dove x è numero rappresentabile in complemento a 2
a tre bit, definita come segue:
se x>=0, allora la funzione vale la parte intera della radice quadrata,
se x<0, allora la funzione vale -1.
Le uscite della funzione devono essere rappresentate in complemento a due con il minor
numero di bit.

X2 X1 X0 X U1 U0
0 0 0 0 0 0 0
0 0 1 1 1 0 1
0 1 0 2 1 0 1
0 1 1 3 1 0 1
1 0 0 -4 -1 1 1 U1 = X2
1 0 1 -3 -1 1 1 U0 = X2 + X1 + X0
1 1 0 -2 -1 1 1
1 1 1 -1 -1 1 1

E1.
Scrivere il programma C che:
definisce un tipo struttura EL composto tipo di due campi X ed Y rispettivamente di tipo
int e double;
definisce un tipo vettore di 5000 elementi di tipo EL denominato VEl;
definito un vettore Vett di tipo VEl e dati i file di testo dati1.txt e dati2.txt
contenenti su ogni riga rispettivamente un numero intero ed un numero decimale, il
programma si comporta come segue: i numeri in dati1.txt sono memorizzati
campo X delle celle di Vett, i numeri in dati2.txt sono memorizzati nel
campo Y delle celle di Vett. I file dati1.txt e dati2.txt contengono lo stesso
numero di elementi; la lettura termina o con l’esaurimento dei dati nel file o con il
riempimento completo di Vett;

Esempio
dati1.txt dati2.txt
27 23.6
-90 1.78
123 -67.8
: :

Vett X 27 -90 123 ...


Y 23.6 1.78 -67.8 ...

definisce la funzione max() che ha in ingresso un parametro V di tipo VEl e un


parametro lung di tipo int che contiene il numero di elementi
effettivamente presenti in V. La funzione restituisce in un elemento di
tipo El il valor massimo dei campi X e Y.

richiama la funzione max() e stampa il contenuto della struttura da essa restituito.

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

#define DIM 5000


typedef struct {int X; double Y;} EL;
typedef EL VEl[DIM];

EL max(VEl v, int lung)


{
EL rit;
int i;

rit.X = v[0].X;
rit.Y = v[0].Y;

for(i=1;i<lung;i++)-
{ if(rit.X < v[i].X)
rit.X = v[i].X;
if(rit.Y < v[i].Y)
rit.Y = v[i].Y;
}
return rit;
}

int main()
{
FILE *f1, *f2;
VEl Vett;
EL mx;
int i;

f1 = fopen("dati1.txt","r");
f2 = fopen("dati2.txt","r");

if (f1==NULL || f2==NULL)
{ printf("errore apertura\n");
exit(-1);}

for(i=0; i<DIM && fscanf(f1,"%d",&Vett[i].X) != EOF; i++)


fscanf(f2,"%lf",&Vett[i].Y);

mx = max(Vett,i);
printf("%d %f\n",mx.X,mx.Y);

system ("pause"); return 0;


}

E2.
Definire un nuovo tipo di dato di nome IMPIEGATO contenente i campi di nome COD e EARN,
entrambi di tipo int. Scrivere una funzione con un parametro formale di nome X vettore
composto da elementi di tipo IMPIEGATO ed un parametro formale di nome DIM di tipo intero
che rappresenta il numero di componenti di X. La funzione deve restituire:
attraverso un parametro formale media dei valori contenuti nel campo EARN
attraverso il parametro formale TOT il numero di elementi di X che hanno un valore nel
campo EARN maggiore o uguale al valor medio.

#include <stdio.h>
#include <stdlib.h>
typedef struct {int COD, EARN;} IMPIEGATO;

void fz(IMPIEGATO X[], int DIM, double *media,int *TOT)


{

int i;
*TOT = 0;
*media=0.0;

for(i=0; i<DIM; i++)


*media = *media + X[i].EARN;
*media = *media/DIM;

for(i=0; i<DIM; i++)


if( X[i].EARN >= *media)
(*TOT)++;
}

int main()
{
IMPIEGATO v[]={{1,45}, {2,67}, {3,16}};
int t; double m;
fz(v,3,&m,&t);

printf("%f %d\n",m,t);
system("pause"); return 0;
}

E3.
Sintetizzare la funzione f(x,y)=x*x+y dove x è un numero rappresentabile in complemento a
due con 2 bit e y è un numero rappresentabile in complemento a due con un bit. L'uscita della
funzione deve essere rappresentata in complemento a due.

X1 X0 Y0 X Y X^2+Y U3 U2 U1 U0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 -1 -1 1 1 1 1
0 1 0 1 0 1 0 0 0 1
0 1 1 1 -1 0 0 0 0 0 U0 = -X1-X0Y0 + -X1X0-Y0
1 0 0 -2 0 4 0 1 0 0 X1-X0Y0+ X1X0-Y0
1 0 1 -2 -1 3 0 0 1 1 U1 = -X1-X0Y0 + X1-X0Y0
1 1 0 -1 0 1 0 0 0 1 U2 =-X1-X0Y0 + X1-X0-Y0
1 1 1 -1 -1 0 0 0 0 0 U3 = -X1-X0Y0

E1.
Il file di testo val.txt contiene su ogni riga dei numeri interi. Si desidera caricare sul vettore
vett di 80 elementi di tipo int quei valori contenuti in val.txt che sono positivi e dispari. Il
caricamento del vettore termina in uno dei seguenti casi:
gli elementi di val.txt che rispondono alle caratteristiche volute sono terminati, in
questo caso vett viene completato con degli elementi di valore -1;
gli elementi del vettore sono stati tutti riempiti.

#include <stdio.h>
#include <stdlib.h>
#define DIM 80
int main()
{
FILE *f;
int vt[DIM], i, v;

f = fopen("val.txt","r");
if (f == NULL) exit(-1);

for (i=0;i<DIM;i++)
vt[i] = -1;

i=0;
while (fscanf(f,"%d",&v) != EOF && i<DIM)
if(v >0 && v%2==1)
{
vt[i] = v;
i = i + 1;
}
for(i=0;i<DIM;i++) //NON RICHIESTO DAL TESTO
printf("%d ",vt[i]);

fclose(f);
system("pause");
return 0;
}

E2.
Si desidera comparare il costo per lavaggio di 30 diversi detersivi in polvere. A questo scopo
si definisce la struct denominata detersivo composta dai seguenti campi:
pesoConfezione di tipo int,
costoConfezione di tipo double,
quantitaDiDetersivoPerLavaggio di tipo double,
costoPerLavaggio di tipo double.
e il vettore confronto di 30 elementi di tipo detersivo.
Si chiede di:
dichiarare i tipi per le due strutture dati (detersivo e confronto),
scrivere la funzione minimo() che ha in ingresso un parametro V di tipo
confronto in cui ogni elemento contiene i valori di tutti i campi eccetto per il
campo costoPerLavaggio e che
per ogni posizione di V calcola il valore del costo per lavaggio ed inserisce
tale risultato nel campo costoPerLavaggio;
restituisce la posizione di V dell’elemento che ha il valore minimo del
campo costoPerLavaggio. In caso vi fosse più di un elemento con
queste caratteristiche sceglie uno fra quelli che hanno il valore di
pesoConfezione minimo.

#include <stdio.h>
#include <stdlib.h>
#define DIM 30

typedef struct{int pesoConfezione;


double costoConfezione,quantitaDiDetersivoPerLavaggio,
costoPerLavaggio; } detersivo;
typedef detersivo confronto[DIM];

int minimo (confronto V)


{
int i, posMin, minPeso;
double min;

for(i=0;i<DIM;i++)
V[i].costoPerLavaggio =\
V[i].costoConfezione/(V[i].pesoConfezione/V[i].quantitaDiDetersivoPerLavaggio);

min = V[0].costoPerLavaggio;
posMin = 0;

for(i=1;i<DIM;i++)
if(V[i].costoPerLavaggio < min)
{ min = V[i].costoPerLavaggio;
posMin = i; }

minPeso = V[posMin].pesoConfezione;
for(i=0;i<DIM;i++)
if(V[i].costoPerLavaggio == min && V[i].pesoConfezione < minPeso)
{ minPeso = V[i].pesoConfezione;
posMin = i; }

return posMin;
}

int main()
{
confronto vDt ={{1000, 3.6, 100, 0}, {100, 3.6, 10, 0}, {1000, 2, 100, 0}};

printf("%d ",minimo(vDt));

system("pause");
return 0;
}

E3.
Sia dato il seguente schema di base di dati:

STUDENTI(Matricola, Nome, Cognome)


INSEGNAMENTO(Codice, Nome)
ESAMI(Matricola, Voto, Data, Lode, Insegnamento)

dove nella relazione STUDENTI l’attributo Matricola è la chiave primaria; nella relazione
INSEGNAMENTO l’attributo Codice è la chiave primaria. Infine nella relazione ESAMI gli
attributi Matricola e Insegnamento formano la chiave primaria, l’attributo Matricola è chiave
esterna per la relazione STUDENTI e l’attributo Insegnamento è chiave esterna per la
relazione INSEGNAMENTO.
Scrivere le query SQL per:

visualizzare le Matricole degli studenti che non hanno registrato nessun esame;
visualizzare per ogni insegnamento il codice dell’insegnamento e il numero di studenti
che hanno registrato l’esame.
visualizzare l’elenco degli esami, voto e nome dell’insegnamento, dello studente
Giovanni Verga.

SELECT Matricola
FROM STUDENTI
WHERE Matricola NOT IN (SELECT Matricola
FROM Esami)
SELECT Insegnamento, COUNT(*) AS TotRegistrati
FROM Esami
GROUP BY Insegnamento

SELECT Insegnamento.Nome, Voto


FROM Studenti, Insegnamento, Esami
WHERE Insegnamento = Codice
AND Studenti.Matricola = Esami.Matricola
AND Studenti.Nome = ‘Giovanni’
AND Studenti.Cognome = ‘Verga’

E1.
Il contenuto del vettore vtD di 20 elementi di tipo double ed il contenuto del vettore vtI di 20
elementi di tipo int devono essere scritti sul file di testo uscita.txt mettendo su ogni riga del file
un elemento di vtD ed un elemento di vtI. Terminata la scrittura dei valori è aggiunta sul file
una riga contenente la media dei valori in vtD e vtI. Supponete i vettori già caricati.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
int main()
{ FILE *f;
int vtI[DIM]={5, -3, 69, -789, 12}, i, mediaInt=0;
double vtD[DIM]={78.2, 16.9, -56.25, 14.36, 126.89}, mediaDouble=0.0;

f = fopen("uscita.txt","w");
if (f == NULL) exit(-1);

for (i=0;i<DIM;i++)
{
fprintf(f,"%f %d\n",vtD[i], vtI[i]);
mediaInt = mediaInt + vtI[i];
mediaDouble = mediaDouble + vtD[i];
}
fprintf(f,"%f %d\n",mediaDouble/DIM, mediaInt/DIM);

fclose(f);
system("pause");
return 0;
}

E2.
Si devono scegliere a fronte di un prestito 20 diverse modalità di rimborso caratterizzate da
un numero di rate, costo per rata e costo di pratica da pagare in una unica soluzione.
Si è pensato di creare per ogni proposta una struttura chiamata proposta formata dai
seguenti campi:
numeroRate di tipo int,
costoRata di tipo double,
costoPratica di tipo double,
costoTotale di tipo double.
Si è anche deciso di raggruppare tutte le proposte in un vettore denominato scelte
composto da 20 elementi di tipo proposta.
Si chiede di:
dichiarare i tipi delle due strutture dati (proposta e scelte)
scrivere la funzione ilMeglio() che ha un parametro X di tipo scelte che:
per ogni posizione di X calcola il valore del costo finale ed inserisce tale
risultato nel campo costoTotale,
restituisce la posizione di X dell’elemento che ha il valore minimo del
campo costoTotale. In caso vi fosse più di un elemento con queste
caratteristiche sceglie uno fra quelli che hanno il valore di numeroRate
minimo.
#include <stdio.h>
#include <stdlib.h>
#define DIM 3

typedef struct{
int numeroRate;
double costoRata,
costoPratica,
costoTotale; } proposta;
typedef proposta scelte[DIM];

int ilMeglio (scelte X)


{
int i, posMin, minRate;
double minCosto;

for(i=0;i<DIM;i++)
X[i].costoTotale = X[i].numeroRate * X[i].costoRata + X[i].costoPratica;

minCosto = X[0].costoTotale;
posMin = 0;

for(i=1;i<DIM;i++)
if(X[i].costoTotale < minCosto)
{ minCosto = X[i].costoTotale;
posMin = i; }

minRate = X[posMin].numeroRate;
for(i=0;i<DIM;i++)
if(X[i].costoTotale == minCosto && X[i].numeroRate < minRate)
{ minRate = X[i].numeroRate;
posMin = i; }

return posMin;
}

int main() //NON RICHIESTO DAL TESTO


{
scelte vDt ={{120, 400.25, 100, 0}, {1200, 40.025, 100, 0}, {100, 700, 100, 0}};

printf("%d ",ilMeglio(vDt));

system("pause");
return 0;
}

E3
Sia dato il seguente schema di base di dati:
STUDENTI(Matricola, Nome, Cognome)
INSEGNAMENTO(Codice, Nome)
ESAMI(Matricola, Voto, Data, Lode, Insegnamento)

dove nella relazione STUDENTI l’attributo Matricola è la chiave primaria; nella relazione
INSEGNAMENTO l’attributo Codice è la chiave primaria. Infine nella relazione ESAMI gli
attributi Matricola e Insegnamento formano la chiave primaria, l’attributo Matricola è chiave
esterna per la relazione STUDENTI e l’attributo Insegnamento è chiave esterna per la
relazione INSEGNAMENTO. Inoltre nel campo Lode della relazione ESAMI contiene 1 se
l’esame è stato superato con la lode, 0 altrimenti.
Scrivere le query SQL per:

visualizzare le Matricole degli studenti che non hanno avuto nessuna lode;
visualizzare per ogni studente che ha ottenuto almeno una lode il numero di esami
superati con la lode.
visualizzare Nome e Cognome degli studenti che hanno registrato un esame il 12-01-
2008.

SELECT Matricola
FROM STUDENTI
WHERE MATRICOLA NOT IN (SELECT MATRICOLA
FROM ESAMI
WHERE Lode = 1)
SELECT Matricola, SUM(Lode) AS TotaleLodi
FROM Esami
GROUP BY Matricola
HAVING SUM(Lode) >=1
SELECT Cognome, Nome
FROM STUDENTI
WHERE MATRICOLA IN (SELECT MATRICOLA
FROM ESAMI
WHERE Data = ‘12/01/2008’)

E1
Scrivere un programma C che:

Legge da standard input 20 valori interi positivi e li inserisce in un vettore denominato


VAL. La lettura deve essere interrotta se l’utente inserisce valori negativi.
Legge da standard input 5 valori reali e li inserisce in un vettore denominato PARAM
Scrive sul file risultati.txt i prodotti tra ciascuno dei valori presenti nel vettore
VAL e la media aritmetica dei valori contenuti nel vettore PARAM

#include <stdlib.h>
#define DIM 20
int main()
{
int VAL[DIM], i,j;
double PARAM[5], media=0.0;
FILE *f;

f = fopen("risultati.txt","w");
if (f == NULL) exit(-1);

i=-1;
do {i++;
printf("dammi un intero positivo: ");
scanf("%d",&VAL[i]);
} while(i<DIM-1 && VAL[i] >= 0);

media=0.0;
for (j=0;j<5;j++)
{
printf("dammi un numero decimale: ");
scanf("%lf",&PARAM[j]);
media = media + PARAM[j];
}
media = media/j;

for(j=0;j<i;j++)
fprintf(f,"%f\n",VAL[j]*media);

fclose(f);
system("pause"); return 0;
}

E2
Scrivere una funzione C che ha in ingesso attraverso un opportuno parametro una struct x
con tre campi a, b e c di tipo int. La funzione restituisce attraverso un parametro formale
dello stesso tipo di x, quanto segue: nel campo a il minimo fra x.a, x.b e x.c, nel campo b il
massimo fra x.a, x.b e x.c, e nel campo c la media aritmetica fra x.a, x.b e x.c.

#include <stdio.h>
#include <stdlib.h>
typedef struct {int a,b,c;} REC;

REC funz(REC x, REC *y)


{
if(x.a > x.b)
{
y->a = x.b;
y->b = x.a;
}
else
{
y->a = x.a;
y->b = x.b;
}
if(y->a > x.c)
y->a = x.c;
if(y->b < x.c)
y->b = x.c;
y->c = (x.a+x.b+x.c)/3;
return *y;
}

/* NON RICHIESTO DAL TESTO*/


int main()
{ REC x={4,15,-36}, y, z;

z = funz(x,&y);

printf("%d %d %d\n",x.a,x.b,x.c);
printf("%d %d %d\n",z.a,z.b,z.c);
printf("%d %d %d\n",y.a,y.b,y.c);

system("pause"); return 0;
}

E3
Una base di dati per la gestione dei movimenti finanziari dei conti correnti si compone, fra le
altre, delle seguenti relazioni (gli attributi che formano la chiave sono indicati in neretto):

Contribuente
(CodiceFiscale, via, numCivico, citta, CAP)

Banca
(Piva, denominazione, ABI)

Contribuente Banca
(CFContribuente, ABI, CAB, CC)

Movimento
(idMov, ABI,CAB,CC, Data, Importo)

Scrivere le interrogazioni SQL per:

indicare il numero totale di conti correnti posseduti da ogni contribuente

SELECT CFContribuente, count(*) AS ‘Totale c/c’


FROM ContribuenteBanca
GROUP BY CFContribuente

indicare il valore totale dei movimenti di ogni filiale di ogni banca indicando anche il
valore dell’attributo denominazione (si ricorda che il valore di CAB indica la filiale ed il
valore di ABI il codice della banca).

SELECT denominazione, ContribuenteBanca.CAB,


sum(Importo) AS ‘Totale Movimenti’
FROM Banca, ContribuenteBanca, Movimento
WHERE
Banca.ABI =ContribuenteBanca.ABI
AND
Movimento.ABI = ContribuenteBanca.ABI
AND
Movimento.CAB = ContribuenteBanca.CAB
AND
Movimento.CC = ContribuenteBanca.CC
GROUP BY
Movimento.ABI, Movimento.CAB, Movimento.CC, denominazione

eliminare dalla relazione Movimento tutti i movimenti eseguiti nell’anno 2002

DELETE
FROM Movimento
WHERE Data between ‘2002-01-01’ AND ‘2002-12-31’

E1
Scrivere un programma C che:
ha in ingresso un file denominato valori.txt, del quale non si conosce la
lunghezza a priori, contenente su ogni riga due numeri interi.
legge i valori contenuti nel file, interrompendo la lettura se si incontra la coppia di
valori -65535 ; -65535. Nel caso non si incontri tale coppia di valori, il file dovrà essere
letto interamente fino alla fine.
Stampa a video la media aritmetica dei numeri pari letti e la media aritmetica dei
numeri dispari letti. Se termina con la lettura della coppia di valori -65535; -65535
questi ultimi non vanno contati nel calcolo della media dei numeri dispari.

Esempio
valori.txt
3 2
5 1
4 4
2 6
-65535 -65535
Media valori pari = 3.6 ; Media valori dispari = 3

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

int main()
{
FILE *f;
double mediaP=0.0, mediaD=0.0;
int v1, v2, totP=0, totD=0;

f = fopen("valori.txt","r");
if(f==NULL) exit(-1);

while (fscanf(f,"%d%d",&v1,&v2) != EOF)


{
if(v1 == -65535 && v2 == -65535)
break;

if (v1%2 == 0)
{mediaP = mediaP + v1;
totP++;}
else
{mediaD = mediaD + v1;
totD++;}

if (v2%2 == 0)
{mediaP = mediaP + v2;
totP++;}
else
{mediaD = mediaD + v2;
totD++;}
}

printf("media pari: %f; “,mediaP/totP);


printf("media dispari: %f\n", mediaD/totD);

fclose(f);
system("pause"); return 0;
}

/* NOTA invece di
while (fscanf(f,"%d%d",&v1,&v2) != EOF)
{
if(v1 == -65535 && v2 == -65535)
break;
si poteva scrivere:
while (fscanf(f,"%d%d",&v1,&v2)!=EOF &&(v1!=-65535 || v2!=-65535))
{
*/

E2
Scrivere una funzione C che ha in ingesso attraverso un opportuno parametro una struct x
con due campi a di tipo int e b di tipo vettore di 10 int. La funzione restituisce un
parametro formale di nome y dello stesso tipo di x i cui campi contengono i seguenti dati:
y.a contiene il minimo di x.b,
y.b contiene in ogni componenteil valore di x.a.

#include <stdlib.h>
#define DIM 10
typedef struct {int a, b[DIM];} REC;

REC funz (REC x, REC *y)


{
int i;

y->a = x.a; // corretto 10-9-2008


y->a = x.b[0];
y->b[0] = x.a;
for(i=1;i<DIM;i++)
{
y->b[i] = x.a;
if(y->a > x.b[i])
y->a = x.b[i];
}

return *y;
}

/* NON RICHIESTO DAL TESTO*/


int main()
{ REC x={4,{15,-36, 45, 89, 245, -890, 5, 8, 9, 23}}, y, z;

z = funz(x,&y);

printf("%d %d %d\n",x.a,x.b[0],x.b[1]);
printf("%d %d %d\n",z.a,z.b[0],z.b[1]);
printf("%d %d %d\n",y.a,y.b[0],y.b[1]);

system("pause"); return 0;
}
E3
Una base di dati per la gestione dei movimenti finanziari dei conti correnti si compone, fra le
altre, delle seguenti relazioni (gli attributi che formano la chiave sono indicati in neretto):

Contribuente
(CodiceFiscale, via, numCivico, citta, CAP)
Banca
(Piva, denominazione, ABI)

Contribuente Banca
(CFContribuente, ABI, CAB, CC)

Movimento
(idMov, ABI,CAB,CC, Data, Importo)

Scrivere le interrogazioni SQL per:

indicare il numero complessivo di contribuenti presenti nelle città Milano e Roma

SELECT count(*) AS ‘totale contribuenti Mi e RM’


FROM Contribuente
WHERE
citta = ‘Milano’ OR citta = ‘Roma’;

indicare i valori di ABI, CAB e CC per i conti correnti con più di 2 movimenti

SELECT ABI,CAB,CC, count(*) AS ‘totale movimenti’


FROM Movimento
GROUP BY ABI, CAB, CC
HAVING count(*) > 2;

aggiornare la relazione Movimento decrementando di 2 euro i valori Importo relativi ai


movimenti effettuati a partire dal 1° Gennaio 2008

UPDATE Movimento
SET Importo = Importo -2
WHERE Data >= ‘2008-01-01’ AND Data <= '2008-12-31'

E1(7 punti)
Scrivere un programma che fa quanto segue:
Definisce un vettore V di 10 interi;
Carica il vettore V con dati provenienti dalla tastiera. I dati devono essere inseriti in V se e
solo se sono compresi tra zero e sette estremi inclusi. Il caricamento di V termina quando
tutte le sue celle sono state riempite con un dato proveniente da tastiera.
Il programma interpreta ogni dato in V come la cifra di un numero in base otto e ne
stampa a video la conversione in base 2.

#include <stdio.h>
#include <stdlib.h>
typedef int T[10];
typedef int A[3];
int main()
{int i,x,y,z,j;T V;A a;
i=0;
for(j=0;j<3;j++)
a[j]=0;
printf("inserisci valori:\n");
do
{scanf("%d",&x);
if((x>=0)&&(x<=7))
{V[i]=x; i++;}}
while (i<10);
for(i=0;i<10;i++)
{j=2;
{while(V[i]!=0)
{ y=V[i]/2; z=V[i]%2; a[j]=z; j--; V[i]=y;}
for(j=0;j<3;j++)
{printf("%d",a[j]); a[j]=0;}
printf("\n");}}
system("pause");
return 0;
}

E2(7 punti)
Definite un nuovo tipo di dato K, struct contenente un campo M, matrice di 10x10 di interi. Scrivere
una funzione con due parametri formali di tipo nome A e B entrambi di tipo K. La funzione deve
restituire, attraverso un valore di ritorno, il parametro formale A se il totale degli elementi nel campo M
di A è superiore al totale degli elementi nel campo M di B, altrimenti la funzione deve restituire il
parametro formale B.

typedef struct { int M[10][10];} K;


K f ( K A, K B)
{int i, j, tot1, tot2; tot1=0; tot2=0;
for (i=0;i<10;i++)
for (j=0;j<10;j++)
{tot1=tot1+A.M[i][j];
tot2=tot2+B.M[i][j];}
if(tot1>tot2)
return A;
else return B;
}
E3(6 punti)

Una sistema di ordini on line si compone fra le altre delle seguenti relazioni (in neretto sono
indicati gli attributi che compongono la chiave primaria):
Utente (IDUtente, password, CAP)
Merce (IDMerce, descrizione, prezzoUnitario)
Ordine (NumeroOrdine, IDUtente, data, importoOrdine)
VociOrdine(NumeroOrdine, IDMerce, importoVoce)

Per semplicità si supponga che il formato di data sia gg/mm/aaaa.


Formulare le seguenti interrogazioni:

Cancellare dalla relazione Merce quelle tuple che corrispondono a merci che non sono
mai state ordinate(ovvero che non compaiono in VociOrdine).

DELETE
FROM Merce
WHERE Merce.IdMerce NOT IN(SELECT IdMerce
FROM VociOrdine)

Abbassare di 5 il prezzoUnitario di quelle tuple di Merce che hanno prezzo Massimo

UPDATE Merce
SET prezzo Unitario=prezzo Unitario-5
WHERE prezzo Unitario=(SELECT Max(PrezzoUnitario)
FROM Merce)

Di ogni tupla in Ordine il cui importoOrdine sia sopra la media, visualizzare


ImportoOrdine e ImportoOrdine diminuito del 10%

SELECT ImportoOrdine, ImportoOrdine *0,9


FROM Ordine
WHERE ImportoOrdine > (SELECT AVG(ImportoOrdine) FROM Ordine)

E1(7 punti)
E' stato organizzato un torneo ad eliminazione diretta (tipo incontri di tennis). I partecipanti
vengono accoppiati. Se il numero i partecipanti è dispari, un giocatore ottiene un bonus e
passa d'ufficio, insieme ai giocatori che vincono il proprio incontro, al turno successivo. Si
procede con questo modo di accoppiare i giocatori e farli giocare fino a determinare il
vincitore del torneo.
Scrivere un programma che
legga un intero positivo che rappresenta il numero di giocatori iscritti al torneo. Il
programma deve controllare anche che il numero inserito sia strettamente positivo ed in
caso contrario chiederlo nuovamente fino a quando non viene inserito un dato corretto;
per ogni turno del torneo stampi a video il numero di giocatori, quante partite si giocano e
se c’è o meno un giocatore che ha avuto il bonus.

As esempio, se ci sono 10 giocatori il programma deve stampare:


turno 1: 10 giocatori,5 partite, 0 bonus;
turno 2: 5 giocatori,2 partite, 1 bonus;
turno 3: 3 giocatori,1 partita, 1 bonus;
turno 4: 2 giocatori,1 partita, 0 bonus.

#include<stdio.h>
#include<stdlib.h>
int main()
{int x,bonus,turno,partite,y;bonus=0;turno=1;partite=0;
do{printf ("inserisci un numero\n");
scanf("%d",&x);}
while(x<=0);
while(x>=2)
{if(x%2==0)
{partite=x/2;
bonus=0;
printf("turno %d:%d giocatori,%d partita/e,%d bonus \n", turno, x,
partite, bonus);
turno=turno+1;
x=x/2;}
else{partite=(x-1)/2;
bonus=1;
printf("turno %d:%d giocatori,%d partita/e,%d bonus \n", turno, x,
partite, bonus);
turno=turno+1;
x=(x+1)/2;}}
system("pause");
return 0;
}

E2(7 punti)
Definite un tipo MATR, matrice di 10x10 di tipo int ed un tipo K, struct con un campo di nome
M di tipo MATR e due campi di nome freq1 e freq2 entrambi di tipo int.
Scrivere una funzione con un parametro formale di tipo MATR che restituisce attraverso un
valore di ritorno una struct di tipo K contenente nel campo M il parametro formale della
funzione, nel campo freq1 quante volte compare nel campo M del parametro formale il
numero 1 e nel campo freq2 quante volte compare nel campo M del parametro formale il
numero 2.

typedef int MATR [10] [10] ;


typedef struct { MATR M ; int frequ1; int frequ2 ; } K ;
K f ( MATR b )
{ i , j , conta1, conta2 ; K a ;
conta1=0;
conta2=0;
for (i=0;i<10;i++)
for (j=0;j<10;j++)
{a.M[i][j]=b.M[i][j];
if (b.M[i][j]==1)
conta1=conta1+1;
if(b.M[i][j]==2_) conta2=conta2+1}
a.frequ1=conta1;
a.freq2=conta2;
return a;
}

E3(6 punti)

Un sistema per la gestione degli spettacoli teatrali contiene fra le altre le relazioni (in
grassetto sono indicati gli attributi che costituiscono la chiave).

Abbonati (IdAbb, Cognome, Nome, Indirizzo, CAP, telefono)


Cartellone (IdSpett, Titolo, dalGiorno, alGiorno, Prezzo)
SpettacoliVisti (IdAbb, IdSpett, data)

Per semplicità si supponga che il formato di data sia gg/mm/aaaa.


Formulare le seguenti interrogazioni:

Inserire nella relazione di schema Milanesi(IdAbb) il campo IdAbb di quegli abbonati il


cui CAP è 20100;

CREATE TABLE Milanesi


(IdAbb Integer);

INSERT INTO Mianesi


(SELECT idAbb FROM Abbonati WHERE CAP = 20100)

2.Cancellare dalla relazione Abbonati coloro che nel 2002 non hanno visto spettacoli.

DELETE *
FROM Abbonati
WHERE IdAbb NOT IN (SELECT IdAbb
FROM SpettacoliVisti
WHERE Data BETWEEN ‘01/01/2002’ AND ‘31/12/2002’)
Aumentare del 10% il prezzo di quegli spettacoli che hanno prezzo minimo.

UPDATE Cartellone
SET Prezzo = Prezzo * 1.1
WHERE Prezzo = ( SELECT min (Prezzo)
FROM Cartellone )

E1.
I file di testo dati1.txt e dati2.txt contengono su ogni riga un numero intero. Scrivere il
programma C che legge in parallelo i due file e scrive sul file risultati.txt il prodotto dei
due numeri letti. Quando un file fra dati1.txt e dati2.txt termina mentre l’altro contiene
ancora degli elementi, su risultati.txt vengono scritti gli elementi del file non ancora
terminato.
Esempio

dati1.tx dati2.tx risultati.txt


t t
23 5 115
4 8 32
12 -3 -36
-3 -3
6 6

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

int main()
{
FILE *f1, *f2, *f3;
int v1,v2;

f1 = fopen("dati1.txt","r");
f2 = fopen("dati2.txt","r");
f3 = fopen("risultati.txt","w");

if (f1==NULL || f2==NULL || f3==NULL)


exit(-1);

while(fscanf(f1,"%d",&v1)!=EOF && fscanf(f2,"%d",&v2)!=EOF)


fprintf(f3,"%d\n",v1*v2);

while(feof(f1) == 0)
{
fprintf(f3,"%d\n",v1);
fscanf(f1,"%d",&v1);
}

while(feof(f2) == 0)
{
fprintf(f3,"%d\n",v2);
fscanf(f2,"%d",&v2);
}

fclose(f1); fclose(f2); fclose(f3);


system("pause"); return 0;
}

E2.
Definire la struttura ST1 composta da un campo a di tipo vettore di 3 int ed un campo b
vettore di 3 double.
Definire anche la struttura ST2 composta da un campo x di tipo double e da un campo y di
tipo ST1.
Scrivere la funzione fz con un parametro formale P di tipo puntatore a ST2. La funzione
fz scrive nel campo x la somma dei valori contenuti nei campi a e b del campo y (in breve,
fz calcola il totale dei valori presenti nei due vettori a e b e pone tale totale nel campo x).

#include <stdio.h>
#include <stdlib.h>
typedef struct {int a[3]; double b[3];} ST1;
typedef struct {double x; ST1 y;} ST2;

void fz(ST2 *P)


{
int i;

P->x = 0.0;
for(i=0;i<3;i++)
P->x = P->x + P->y.a[i] + P->y.b[i];
}
int main()
{
ST2 par ={0,{{1, 2,3},{-2.3,5.9,7.2}}};
int i;

fz(&par);
printf("x: %f\n\t",par.x);
for(i=0; i<3;i++)
printf("%d ",par.y.a[i]);
printf("\n\t ");
for(i=0; i<3;i++)
printf("%f ",par.y.b[i]);
printf("\n");
system("pause"); return 0;
}
E3

Un sistema per la gestione degli spettacoli teatrali contiene fra le altre le relazioni (in
grassetto sono indicati gli attributi che costituiscono la chiave).

Abbonati (IdAbb, Cognome, Nome, Indirizzo, CAP, telefono)


Cartellone (IdSpett, Titolo, dalGiorno, alGiorno)
SpettacoliVisti (IdAbb, IdSpett, data)

Per semplicità si supponga che il formato di data sia gg/mm/aaaa.


Formulare le seguenti interrogazioni:

Visualizzare Cognome e Nome degli abbonati il cui cognome inizia per la lettera B
oppure è composto da almeno 4 lettere.

SELECT Cognome, Nome


FROM Abbonati
WHERE cognome LIKE “B%” or cognome LIKE “____%”

Visualizzare il Cognome ed il Nome degli abbonati che nel 2002 abbiano visto almeno
10 spettacoli

SELECT Cognome, Nome


FROM Abbonati, SpettacoliVisti
WHERE Abbonati.IdAbb = SpettacoliVisti.IdAbb
AND data between 01-01-2002 AND 31-12-2002
GROUP BY Abbonati.IdAbb, Cognome, Nome
HAVING count(*) >= 10

Visualizzare Cognome, Nome ed IdAbb degli abbonati omonimi rispetto al cognome,


ovvero che abbiano lo stesso cognome di un altro abbonato presente nel database.

SELECT X.IdAbb, X.Nome, X.Cognome


FROM Abbonati X, Abbonati Y
WHERE X.Cognome = Y.Cognome
AND X.IdAbb != Y.IdAbb

E1.
Il file di testo rsa.txt contiene su ogni riga un numero intero positivo ottenuto dal prodotto
di due numeri primi diversi da 1. Scrivere il programma C che legge i valori di questo file e per
ciascuno scrive sui file uno.txt e due.txt i fattori in cui si scompone il numero letto (si noti
che non è necessario verificare la primalità dei numeri che dividono il valore letto da
rsa.txt).
Esempio:
rsa.tx uno.tx due.txt
t t
21 3 7
15 3 5
91 7 13
77 7 11

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

int main()
{
FILE *f1, *f2, *f3;
int v, ft1, ft2;

f1 = fopen("coppie.txt","r");
f2 = fopen("uno.txt","w");
f3 = fopen("due.txt","w");

if (f1==NULL || f2==NULL || f3==NULL)


exit(-1);

while(fscanf(f1,"%d",&v) != EOF)
{
ft1=2;
while (v % ft1 != 0)
ft1 = ft1 + 1;
ft2 = v / ft1;

fprintf(f2,"%d\n",ft1);
fprintf(f3,"%d\n",ft2);
}

fclose(f1); fclose(f2); fclose(f3);


system("pause"); return 0;
}

E2.
Definire la struttura ST composta da un campo a di tipo vettore di 3 double e da un campo b
di tipo double.
Scrivere la funzione fk che ha un parametro formale par di tipo ST ed un parametro formale
vt di tipo vettore di tre elementi di tipo double. La funzione:
scrive in ogni elemento del vettore vt il prodotto fra il corrispondente elemento del
campo a di par ed il valore del campo b di par;
restituisce attraverso un valore di ritorno il numero di elementi del campo a di par che
sono maggiori del valore nel campo b.
#include <stdio.h>
#include <stdlib.h>
#define DIM 3
typedef struct {double a[DIM], b;} ST;

int fk(ST par, double vt[DIM])


{
int i, tot;

tot = 0;
for(i=0; i<DIM; i++)
{
vt[i] = par.b*par.a[i];
if (par.a[i] > par.b)
tot++;
}
return tot;
}
int main()
{
ST pt={{4.2,-4.2,9.0},3.2};
double v[DIM];
int i;

printf("%d\n",fk(pt,v));

for(i=0;i<DIM;i++)
printf("%6.3f ",v[i]);
system("pause"); return 0;
}

E3

Una sistema di ordini on line si compone fra le altre delle seguenti relazioni (in neretto sono
indicati gli attributi che compongono la chiave primaria):
Utente (IDUtente, password, CAP)
Merce (IDMerce, descrizione, prezzoUnitario)
Ordine (NumeroOrdine, IDUtente, data, importoOrdine)
VociOrdine(NumeroOrdine, IDMerce, importoVoce)

Per semplicità si supponga che il formato di data sia gg/mm/aaaa.


Formulare le seguenti interrogazioni:

Visualizzare il valore di IDUtente per gli utenti che hanno effettuato almeno 10 ordini
ciascuno di importo superiore a 1000 Euro.

SELECT IDUtente
FROM Ordine
WHERE importoOrdine > 1000
GROUP BY IDUtente
HAVING count(*) > 10
Visualizzare per ogni valore di IDUtente l’importo totale di tutti gli ordini effettuati

SELECT IDUtente, sum(importoOrdine) AS ‘Totale Ordini’


FROM Ordine
GROUP BY IDUtente

Cancellare dalla relazione Utente gli utenti non hanno fatto ordini.

DELETE
FROM UTENTE
WHERE IDUtente NOT IN (SELECT DISTINCT IDUtente FROM Ordine)

E1
Dato un file di testo chiamato dati.txt già esistente contenente uno per riga valori che
rappresentano numeri relativi, scrivere un programma in linguaggio C in cui si dichiarino due
struct ST1 e ST2 ciascuna con due campi a e b di tipo int e che effettua le seguenti
operazioni:

scrive su video quanti valori contiene il file dati.txt;


pone nel campo a di ST1 il più grande valore contenuto in dati.txt;
pone nel campo b di ST1 il più piccolo valore contenuto in dati.txt;
pone nel campo a di ST2 la differenza fra il più grande e il più piccolo valore contenuto
in dati.txt;
pone nel campo a di ST2 il prodotto fra il più grande e il più piccolo valore contenuto in
dati.txt.

#include <stdlib.h>
#include <stdio.h>
typedef struct {int a, b;} ST;
int main()
{
ST ST1, ST2;
FILE *f;
int val;

f = fopen("dati.txt","r");
if (f==NULL)
exit(-1);

fscanf(f,"%d",&ST1.a);
ST1.b = ST1.a;
while(feof(f) == 0)
{
fscanf(f,"%d",&val);
if(val > ST1.a)
ST1.a = val;
else if (val < ST1.b)
ST1.b = val;
}
fclose(f);

ST2.a = ST1.a - ST1.b;


ST2.b = ST1.a * ST1.b;

printf("%d %d\n\t %d %d\n", ST1.a,ST1.b,ST2.a,ST2.b);

system("pause");
return 0;
}

E2
Definire un nuovo tipo di dato chiamato VT vettore di 10 int. Scrivere in C la funzione ft che:
ha in ingresso un vettore A di tipo VT già caricato e restituisce, attraverso un
opportuno parametro, un vettore di tipo VT che contiene gli stessi elementi del
vettore di ingresso ma in ordine inverso;
restituisce il prodotto di tutti gli elementi di A.

#include <stdlib.h>
#include <stdio.h>
typedef int VT[10];

int ft (VT A, VT B)
{
int i,j, prod=1;

for(i=0, j=9; i<10; i++, j--)


{
B[j] = A[i];
prod *= A[i];
}

return prod;
}

int main() //non richiesto dal testo


{
VT v ={2,-4,8,9,12,1,6,-9,5,3}, w;
int j;

printf("prodotto: %d\n",ft(v,w));
for(j=0;j<10;j++)
printf("%d\n",w[j]);
system("pause");
return 0;
}

E3
Sintetizzare la funzione booleana f(x)=x*3 +1 dove x è un numero binario di 2 bit in
complemento a 2 e l'uscita deve essere espressa in complemento a 2 con il minor numero di
bit.

X1 X0 X f(x) U3 U2 U1 U0
0 0 0 1 0 0 0 1
0 1 1 4 0 1 0 0
1 0 -2 -5 1 0 1 1
1 1 -1 -2 1 1 1 0

U3 = X1
U2 = X0
U1 = X1
U0 = -X0

E1
Dato un file di testo chiamato dati.txt già esistente contenente uno per riga valori che
rappresentano numeri relativi, scrivere un programma in linguaggio C in cui si dichiarino due
file F1 e F2 che esternamente si chiameranno rispettivamente dati1.txt e dati2.txt e effettua le
seguenti operazioni:

scrive su video quanti valori contiene il file dati.txt;


pone in dati1.txt gli elementi di dati.txt divisibili per 7;
pone in dati2.txt gli elementi di dati.txt divisibili per 5;
scrive su video quanti valori contiene il file dati1.txt;
scrive su video quanti valori contiene il file dati2.txt;
#include <stdlib.h>
#include <stdio.h>
int main()
{
FILE *f, *f1, *f2;
int val, cont=0, cont7=0, cont5=0;

f = fopen("dati.txt","r");
f1 = fopen("dati1.txt","w");
f2 = fopen("dati2.txt","w");
if (f==NULL || f1==NULL || f2==NULL)
exit(-1);

while(fscanf(f,"%d",&val) != EOF)
{
cont++;
if(val % 7 == 0)
{ cont7++;
fprintf(f1,"%d\n",val);}
if(val % 5 == 0)
{ cont5++;
fprintf(f2,"%d\n",val); }
}

printf("%d %d %d\n",cont,cont7,cont5);

fclose(f); fclose(f1); fclose(f2);

system("pause");
return 0;
}

E2
Definire un nuovo tipo di dato chiamato VT vettore di 10 int. Scrivere in C la funzione ft che:
ha in ingresso un vettore A di tipo VT già caricato e restituisce, attraverso un
opportuno parametro, una struct con 2 campi a e b di tipo int che contengono
rispettivamente la somma degli elementi di A di posto pari e quella degli
elementi di A di posto dispari;
restituisce la sommatoria di tutti gli elementi di A.

#include <stdlib.h>
#include <stdio.h>
typedef int VT[10];
typedef struct {int a, b;} SOM;

int ft (VT A, SOM *s)


{

int i, som=0;

s->a=s->b=0;

for(i=0; i<10;i++)
{
som = som + A[i];
if (i%2 == 0)
s->a = s->a + A[i];
else
s->b = s->b + A[i];
}
return som;
}

int main() //non richiesto dal testo


{
VT v ={2,-4,8,9,12,1,6,-9,5,13};
SOM s;

printf("%d %d %d\n",ft(v,&s),s.a,s.b);

system("pause");
return 0;
}

E3
Sintetizzare la funzione booleana f(x)=x*2 -1 dove x è un numero binario di 2 bit in
complemento a 2 e l'uscita deve essere espressa in complemento a 2 con il minor numero di
bit.

X1 X0 X f(x) U3 U2 U1 U0
0 0 0 -1 1 1 1 1
0 1 1 1 0 0 0 1
1 0 -2 -5 1 0 1 1
1 1 -1 -3 1 1 0 1

U3 = -X1-X0 + X1-X0 + X1X0 = -X1-X0 + X1 = -X0 + X1


U2 = -X1-X0 + X1X0
U1 = -X0
U0 = 1

Esercizio 1 (8 punti)
Scrivere un programma C che:
Definisce una matrice di nome M contenente 100x100 di numeri interi e due vettori V1
e V2 entrambi contenenti 100 numeri interi.
Legge da standard input una sequenza di numeri interi ed inserisce dentro M i numeri
positivi della sequenza.
L’operazione di lettura termina al riempimento della matrice M.
Inserisce nel vettore V1 gli elementi di M che sono numeri pari e nel vettore V2 gli
elementi di M che sono numeri dispari. L’operazione termina al riempimento dei due
vettori o quando la matrice ha esaurito i suoi elementi.
#include<stdio.h>
#include<stdlib.h>

#define DIM 100

int main()
{
int M[DIM][DIM], V1[DIM], V2[DIM];
int i,j, k, h;

for(i=0;i<DIM;i++ )
for(j=0;j<DIM;j++)
do{ printf("dammi un intero positivo: ");
scanf("%d",&M[i][j]);
} while (M[i][j] < 0);

for(i=0, k=0, h=0;i<DIM;i++ )


for(j=0;j<DIM;j++)
if(k<DIM && M[i][j] % 2 == 0)
V1[k++] = M[i][j];
else
if(h<DIM && M[i][j] % 2 == 1)
V2[h++] = M[i][j];

for(i=0;i<DIM;i++ )
{
for(j=0;j<DIM;j++)
printf("%d ",M[i][j]);
printf("\n");
}

for(i=0;i<k;i++)
printf("\t %2d: %d\n",i,V1[i]);
printf("\n\n");
for(i=0;i<h;i++)
printf("\t %2d: %d\n",i,V2[i]);

system("pause");
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato ST, struct con tre campi di nome A, B di tipo int e C di tipo float.
Definire un tipo di dato VT, vettore di 100 elementi di tipo int. Scrivere una funzione che ha in
ingresso x di tipo VT e restituisce come uscita una struct di tipo ST contenente nel campo A il
minimo, nel campo B il massimo e nel campo C la media aritmetica degli elementi di x.

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

#define DIM 100

typedef struct{int A,B; float C;} ST;


typedef int VT[DIM];

ST fz(VT x, ST *ret)
{
int i;

ret->A = ret-> B = ret->C = x[0];

for(i=1;i<DIM;i++)
{
if(ret->A > x[i])
ret->A = x[i];

if(ret->B < x[i])


ret->B = x[i];

ret->C += x[i];
}
ret->C /= DIM;

return *ret;
}
int main()
{
VT v ={1, -8, 15, 9, 10};
ST out1, out2;

out2 = fz(v,&out1);

printf("%d %d\n",out1.A, out2.A);


printf("%d %d\n",out1.B, out2.B);
printf("%f %f\n",out1.C, out2.C);

system("pause");
return 0;
}

Esercizio 3 (6 punti)
Siano dati i seguenti schemi di relazione:
Nazioni(NomeStato,Superficie,Abitanti,Capitale)
Aeroporti(Nazione,NomeAereoporto, MovimentiAnnui)
dove nella relazione Nazioni l’attributo NomeStato è la chiave primaria. Nella relazione
Aeroporti gli attributi NomeAereoporto e Nazione formano la chiave primaria mentre
l’attributo Nazione è chiave esterna per le relazione Nazioni.
Scrivere le interrogazioni SQL che permettono di:
visualizzare il nome dell’aeroporto con il maggior numero di movimenti annui,
aumentare del 5% il valore dell’attributo MovimentiAnnui di tutte le tuple della relazione
Aeroporti il cui valore dell’attributo Nazione è “Italia”,
per ogni nazione, visualizzare quanti aeroporti possiede.

SELECT NomeAeroporto, MovimentiAnnui


FROM Aeroporti
WHERE MovimentiAnnui = (SELECT MAX(MovimentiAnnui)
FROM Aeroporti)

UPDATE Aeroporti
SET MovimentiAnnui = MovimentiAnnui * 1.05
WHERE Nazione=’Italia’

SELECT Nazione, COUNT(*) AS ‘Totale Aeroporti’


FROM Aeroporti
GROUP BY Nazione

Esercizio 1 (8 punti)
Scrivere un programma C che:
Definisce una matrice di nome M contenente 2x100 (due righe e 100 colonne) di
numeri interi ed un vettore V contenente 1000 numeri interi.
Legge da standard input una sequenza di numeri interi ed inserisce dentro V i numeri
pari della sequenza.
L’operazione di lettura termina al riempimento del vettore V.
Inserisce nella prima riga della matrice M numeri positivi contenuti nel vettore V e nella
seconda riga di M i numeri negativi contenuti nel vettore V. L’operazione termina al
riempimento di entrambe le righe di M o quando il vettore V termina.

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

#define DIMCOL 100


#define DIMVET 1000
int main()
{
int M [2][DIMCOL], V[DIMVET];
int i, k, h;

for(i=0;i<DIMVET;i++)
do{
printf("numero intero: ");
scanf("%d",&V[i]);
}while(V[i] %2 != 0); //il resto di numero <0 vale -1

k=h=0;
for(i=0; i<DIMVET; i++)
if(k<DIMCOL && V[i] > 0)
M[0][k++] = V[i];
else
if(h<DIMCOL && V[i] < 0)
M[1][h++] = V[i];

for(i=0;i<DIMVET;i++)
printf("%d\n",V[i]);
printf("\n\n");
for(i=0;i<k;i++)
printf("%d ",M[0][i]);
printf("\n");
for(i=0;i<h;i++)
printf("%d ",M[1][i]);
printf("\n");

system("PAUSE");
return 0;
}

Esercizio 2 (6 punti)
Definire un tipo di dato ST, struct con tre campi di nome A, B di tipo int e C di tipo float.
Definire un tipo di dato VT, vettore di 100 elementi di tipo int. Scrivere una funzione che ha in
ingresso x di tipo VT e restituisce come uscita una struct di tipo ST contenente nel campo A
la somma, nel campo B il prodotto e nel campo C la media aritmetica degli elementi di x.

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

#define DIM 4
typedef struct{int A,B; float C;} ST;
typedef int VT[DIM];

ST fh(VT x, ST *rit)
{
int i;
rit->A=rit->B=rit->C=x[0];

for(i=1;i<DIM;i++)
{
rit->A += x[i];
rit->B *= x[i];
rit->C += x[i];
}
rit->C = rit->C / DIM;
return *rit;
}

int main()
{
VT v={9, -12, 3, 7};
ST out1, out2;

out1 = fh(v,&out2);

printf("%d %d\n",out1.A,out2.A);
printf("%d %d\n",out1.B,out2.B);
printf("%f %f\n",out1.C,out2.C);

printf("\n");

system("PAUSE");
return 0;
}

Esercizio 3 (6 punti)
Siano dati i seguenti schemi di relazione:
Nazioni(NomeStato,Superficie,Abitanti,Capitale)
Aeroporti(Nazione,NomeAereoporto,MovimentiAnnui)
dove nella relazione Nazioni l’attributo NomeStato è la chiave primaria. Nella relazione
Aeroporti gli attributi NomeAereoporto e Nazione formano la chiave primaria mentre
l’attributo Nazione è chiave esterna per le relazione Nazioni.

Scrivere le interrogazioni SQL che permettono di:


visualizzare il nome dell’aeroporto con il minor numero di movimenti annui,
diminuire del 5% il valore dell’attributo MovimentiAnnui di tutte le tuple della relazione
Aeroporti il cui valore dell’attributo Nazione è “Stati Uniti”,
per ogni nazione, visualizzare i nomi degli aeroporti che possiede.

SELECT NomeAeroporto, MovimentiAnnui


FROM Aeroporti
WHERE MovimentiAnnui = (SELECT MIN(MovimentiAnnui)
FROM Aeroporti)

UPDATE Aeroporti
SET MovimentiAnnui = MovimentiAnnui * 0.95
WHERE Nazione=’Stati Uniti’

SELECT Nazione, NomeAeroporto


FROM Aeroporti
ORDER BY Nazione

E1
Scrivere il programma C che:
carica un vettore di 10 numeri interi vInt;
carica un vettore di 10 numeri decimali vDec,
scrive sul file di testo valori.txt gli elementi di valore pari da vInt e gli elementi di
valore negativo da vDec alternandoli.
Esempio
vInt =[ 2, 24, 13, 5, 9, 31,8, 12, 79, 16]
vDec= [3.7, -2.8, 10.8, -7.1, 22.7, -12.6, 90.1,-84.2, -22.8, -10.8]
il file valori.txt conterrà i seguenti valori:
2, -2.8, 24, -7.1, 8, -12.6, 12, -84.2, 16, -22.8, -10.8

#include <stdio.h>
#include <stdlib.h>
#define DIM 10

int main()
{
int vInt[DIM], i,j;
double vDec[DIM];
FILE *f;

printf("dammi %d interi: ",DIM);


for(i=0;i<DIM;i++)
scanf("%d",&vInt[i]);

printf("dammi %d decimali: ",DIM);


for(i=0;i<DIM;i++)
scanf("%lf",&vDec[i]);

f = fopen("valori.txt","w");
if(f == NULL)
exit(-1);

i=j=0;
do{
while (i<DIM && vInt[i] % 2 != 0)
i++;
if (i<DIM)
{fprintf(f,"%d\n",vInt[i]); i++;}

while(j<DIM && vDec[j] > 0)


j++;
if(j<DIM)
{fprintf(f,"%lf\n",vDec[j]); j++;}
}while (i<DIM || j<DIM);

fclose(f);
return 0;
}

E2
Formulare le dichiarazioni necessarie per:
definire un tipo struct di nome unoSt composto di un campo A di tipo double ed
un campo B vettore di 6 elementi di tipo int;
definire un tipo vettore denominato vetUnoSt di 20 elementi di tipo unoSt.
Scrivere la funzione elabora che ha come argomento il parametro A di tipo vetUnoSt e che
restituisce l'elemento di A per il quale la somma degli elementi del campo B ha il valore
massimo. Se vi è più di un elemento che soddisfa questa condizione ne restituisce uno
qualsiasi.

#include <stdio.h>
#include <stdlib.h>
#define DIM 20
typedef struct {double A; int B[6];}unoSt;
typedef unoSt vetUnoSt[DIM];

//basta o che restituisca tramite return l’elemento


// o che restituisca l’elementoo tramite parametro
unoSt elabora(vetUnoSt A, unoSt *e)
{
int max, posMax, i, j, som;

posMax=0;
for(j=0, max=0; j<6; j++)
max = max + A[0].B[j];

for(i=1; i<DIM; i++)


{
som = 0;
for(j=0, max=0; j<6; j++)
som = som + A[i].B[i];
if (som > max)
{
max = som;
posMax = i;
}
}
*e = A[posMax];
return *e;
}
//NON RICHIESTO DAL TESTO
int main()
{
vetUnoSt v={{3.0, {1,2,3,4,5,6}},
{-4.3,{0,1,2,3,4,5}},
{9.45,{2,3,4,5,6,7}}};
unoSt rit;
int i, j;

for(j=0;j<DIM;j++)
{
printf("%f ",v[j].A);
for(i=0;i<6;i++)
printf("%d ",v[j].B[i]);
printf("\n");
}

printf("elemento restituito: ");


rit = elabora(v,&rit);
printf("%f ",rit.A);
for(i=0;i<6;i++)
printf("%d ",rit.B[i]);
printf("\n");

return 0;
}

E3
Sintetizzare la funzione booleana che ha in ingresso tre cifre binarie che rappresentano un numero in
complemento a due e che produce in uscita il quoziente (intero) del numero in ingresso diviso 2.
L'uscita è rappresentata in complemento a 2 con il numero minore di cifre possibili.

X2 X1 X0 X X/2 U1 U0
0 0 0 0 0 0 0
0 0 1 1 0 0 0
0 1 0 2 1 0 1
0 1 1 3 1 0 1
1 0 0 -4 -2 1 0
1 0 1 -3 -1 1 1
1 1 0 -2 -1 1 1
1 1 1 -1 0 0 0

U0 = -X2X1 + X2-X1X0 + X2X1-X0


U1 = X2-X1-X0 + X2-X1X0+ X2X1-X0

E1
Scrivere il programma C che:
carica un file di testo chiamato mieiDati.txt con dei numeri decimali finché l'utente
non inserisce il valore 0;
inserisce in un vettore di nome valori di dimensione 100 gli elementi contenuti in
mieiDati.txt che rappresentano un numero negativo o un numero intero positivo.
Il programma termina o quando si è riempito il vettore o quando il file è finito.

Esempio
il file mieiDati.txt contiene i seguenti valori:
2, -2.8, 24.4, -7.1, 8, -13, 12.34, -84.2, 16, -22.8, 10.8
Il vettore valori contiene i seguenti valori:
2, -2.8, -7.1, 8, -13, -84.2, 16, -22.8

#include <stdio.h>
#include <stdlib.h>
#define DIM 100

int main()
{
FILE *f;
double val=1.0, valori[DIM];
int i, valInt;

f = fopen("mieiDati.txt","w+");
while (val != 0)
{
printf("dammi un numero: ");
scanf("%lf",&val);
if(val != 0.0)
fprintf(f,"%f\n",val);
}

rewind(f);

i=0;
while(fscanf(f,"%lf",&val) != EOF && i<DIM)
{
valInt = val;
if(val < 0)
valori[i++] = val;
else
if (valInt == val)
valori[i++] = val;
}

//NON RICHIESTO DAL TESTO


printf("contenuto vettore (al contrario): ");
for( i-- ;i>=0; i--)
printf("%lf ",valori[i]);
printf("\n");
return 0;
}

E2
Formulare le dichiarazioni necessarie per:
definire un tipo struct di nome nuovaSt composto di un campo A di tipo double ed
un campo B di tipo int;
definire un tipo struct chiamato altraSt composto da un campo X vettore di 10
elementi di tipo nuovaSt ed un campo Y di tipo int.
Scrivere la funzione cerca che ha come parametro un elemento di tipo altraSt e che
inserisce nel campo Y il numero di elementi del campo X per i quali il valore del campo A è
maggiore di quello nel campo B.

#include <stdio.h>
#include <stdlib.h>
#define DIM 4

typedef struct {double A; int B;} nuovaSt;


typedef struct {nuovaSt X[DIM]; int Y;} altraSt;

void cerca(altraSt *aS)


{
int i;

aS -> Y = 0;
for(i=0; i<DIM; i++)
if (aS->X[i].A > aS->X[i].B)
aS -> Y++;
}

//NON RICHIESTO DAL TESTO


int main()
{
altraSt altra ={{{2,4},{3.7,5},{-3.9, -4},{9,-12}},0};
cerca(&altra);
printf("%d\n",altra.Y);
return 0;
}
E3
Sintetizzare la funzione booleana che ha in ingresso due cifre binarie che rappresentano un numero in
complemento a due e che produce in uscita il prodotto del numero in ingresso per 2. L'uscita è
rappresentata in complemento a 2 con il numero minore di cifre possibili.

X1 X0 X X*2 U2 U1 U0
0 0 0 0 0 0 0
0 1 1 2 0 1 0
1 0 -2 -4 1 0 0
1 1 -1 -2 1 1 0

U0 = 0
U1 = X0
U2 = X1

E1.
Scrivere un programma C che dato un intero n stampi a video il valore della seguente
sommatoria.

#include<stdio.h>
#include<stdlib.h>
int main(void){
int i,j,n,num,den;
double s;

scanf("%d",&n);
s=0;
for(i=1;i<=n;i++){
num=1;
for(j=1;j<=i;j++){ num=num*j;}
den=0;
for(j=i;j<=n;j++) { den=den+j;}
s=s+1.0*num/den;
}
printf("%lf",s);
system("pause");
}

E2
Una matrice quadrata M è detta matrice identità se tutti gli elementi della diagonale principale
valgono 1 e tutti gli altri valgono 0. Ad esempio, la seguente è una matrice identità.

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

Scrivere una funzione di nome Identita con un parametro formale di nome M di tipo matrice di
dimensione 10x10.
Attraverso un parametro formale di tipo opportuno la funzione deve restituire:
1.5, se M è una matrice identità;
la quantità di elementi diversi da zero presenti in M, altrimenti.

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

void Identita(int M[10][10], double *risp){


int i,j,tot,flag;
flag=0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
if ((i==j && M[i][j]!= 1) ||
(i!=j && M[i][j]!=0)) flag=1;
}
}
if (flag==0) *risp=1.5;
else {
*risp=0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
if (M[i][j] != 0) {*risp=*risp+1;}
}
}
}
}
E3
I dati relativi ad aeroporti sono stati organizzati in tre tabelle. La prima, Nazioni, riporta un
elenco di nazioni, dove di ogni nazione sono memorizzati alcuni dati; la seconda, Aeroporti,
memorizza, per ogni aeroporto, alcuni dati; la terza, MovimentiAnnui, riporta il movimento
passeggeri per ogni aeroporto ed ogni anno. In particolare gli schemi sono i seguenti:

Nazioni(idNazione, Nome, Superficie, Abitanti, Capitale)


Aeroporti(idAeroporto, idNazione, NomeAeroporto)
MovimentiAnnui(idAeroporto,anno,nroPasseggeri)

dove nella relazione Nazioni l’attributo idNazione è la chiave primaria. Nella relazione
Aeroporti l'attributo idAeroporto è la chiave primaria mentre l’attributo idNazione è chiave
esterna per la relazione Nazioni. Nella relazione MovimentiAnnui gli attributi idAeroporto e
anno formano la chiave primaria e idAeroporto è chiave esterna per la relazione Aeroporti.

Scrivere le interrogazioni SQL che permettono di:


stabilire il numero totale di passeggeri degli aereoporti che stanno nella nazione di
nome Italia nell'anno 2008;

select sum(nroPasseggeri)
from MovimentiAnnui,Nazioni,Aeroporti
where MovimentiAnnui.idAeroporto=Aeroporto.idAeroporto AND
Nazioni.idNazione=Aeroporti.idNazione and nome=’Italia’ and
anno=2008;

stabilire idAeroporto e NomeAeroporto di quegli aeroporti che hanno il numero minimo


di passeggeri;

select Aeroporti.idAeroporto, NomeAeroporto


from Aeroporti,MovimentiAnnui
where NroPasseggeri= (select min(NroPasseggeri) from
MovimentiAnnui) and Aeroporti.idAeroporto=
MovimentiAnnui.idAeroporto

inserire nella relazione di schema


TopMovimenti(idAeroporto, NomeAeroporto, anno)
idAeroporto, NomeAeroporto, anno degli aeroporti che hanno trasportato il massimo
numero di passeggeri.

Insert into TopMovimenti


(
select Aeroporti.idAeroporto, Nome Aeroporto,anno
from Aeroporti,MovimentiAnnui
where NroPasseggeri= (select max(NroPasseggeri) from
MovimentiAnnui) and Aeroporti.idAeroporto=
MovimentiAnnui.idAeroporto
)
E1.
Scrivere un programma C che dato un intero n stampi a video il valore della seguente
sommatoria. Non è ammesso usare la funzione pow della libreria matematica del linguaggio
C.

#include<stdio.h>
#include<stdlib.h>
int main(void){
int i,j,n,num,pot;
double s;

scanf("%d",&n);
s=0;pot=1;
for(i=1;i<=n;i++){
pot=pot*2;
num=0;
for(j=i;j<=n;j++) { num=num+j;}
s=s+1.0*num/pot;
}
printf("%lf",s);
system("pause");
}

E2
Una matrice M è detta di Incidenza se ogni sua colonna contiene esattamente due valori pari
a uno ed il valore zero altrove. Ad esempio, la seguente è una matrice di Incidenza:

0 1 0 1
1 0 1 0
1 1 1 0
0 0 0 1
Scrivere una funzione di nome Incidenza con un parametro formale di nome M di tipo matrice
di int di dimensione 10x10. Attraverso un valore di ritorno la funzione deve restituire:
1, se M è una matrice di incidenza;
la frequenza del numero 0 altrimenti.
#include<stdio.h>
#include<stdlib.h>

int Incidenza(int M[10][10]){


int i,j,totZero,totUno,flag;

flag=1;
for(i=0;i<10;i++){
totZero=totUno=0;
for(j=0;j<10;j++){
if(M[i][j]== 0) totZero++;
else if (M[i][j]==1) totUno++;
}
if (totUno != 2 || totZero!= 8) flag=0;
}

if (flag==1) return 1;
else
{ totZero=0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
if(M[j][i]== 0) totZero++;
}
}
return totZero;
}
}

E3 (6 punti)
I dati relativi a ricette di cucina sono stati organizzati in tre tabelle: la tabella Ricette contiene
l’elenco delle ricette e specifica anche il cuoco che l'ha inventata; la tabella Ingredienti
contiene i diversi ingredienti che compongono le ricette; la tabella Cuochi contiene dati
anagrafici relativi a cuochi che hanno inventato ricette. In particolare gli schemi di relazione
sono:

Ingredienti(IdRicetta, Ingrediente, Quantita)


Ricette(idCuoco,idRicetta, NomeRicetta, Costo, Stagione)
Cuochi(IdCuoco,Cognome,Nazionalita)

dove nella relazione


Cuochi l'attributo IdCuoco è la chiave primaria. Nella relazione Ricette l’attributo IdRicetta è
la chiave primaria e l'attributo IdCuoco è chiave esterna per la relazione Cuochi. Nella
relazione Ingredienti gli attributi IdRicetta e Ingrediente formano la chiave primaria, mentre
l’attributo IdRicetta è chiave esterna per le relazione Ricette.
Scrivere le interrogazioni SQL per:
stabilire idRicetta e NomeRicetta, di quelle ricette inventate da cuochi di nazionalità
italiana;
select idRicetta,NomeRicetta
from Cuochi,Ricette
where Ricette.idCuoco= Cuochi.idCuoco
and Nazionalità=’Italia’

cancellare dalla relazione Cuochi i dati dei cuochi che non hanno alcuna ricetta
elencata in Ricette;
delete from cuochi
where idCuoco not in (select idcuoco from ricette);

inserire nella relazione TopIngrediente(Ingrediente) quegli ingredienti che compaiono


almeno 5 volte nella relazione Ingredienti.

Insert into TopIngrediente


(select Ingrediente
from Ingredienti
group by Ingrediente
having count(*)>=5
)

E1.

Il file dati.txt contiene per ogni riga, nell’ordine, un numero decimale ed un numero intero.
Scrivere il programma C che legge le righe del file dati.txt e per ciascuna scrive sul file
risultato.txt il valore del numero decimale se è maggiore del numero intero presente
sulla stessa riga. Il programma visualizza quanti numeri sono stati scritti sul file
risultato.txt e la loro media aritmetica.
Esempio

dati.txt risultato.txt visualizza


12.4 6 12.400000 2 17.90000
5.90 8 23.400000
-89.3 100
23.4 -34

#include <stdio.h>
#include <stdlib.h>
int main()
{ FILE *fi, *fo;
double dec, med;
int inte, cont;
fi = fopen("dati.txt","r");
fo = fopen("risultato.txt","w");

if(fi == NULL || fo == NULL)


exit(-1);

med = 0.0; cont = 0;


while(fscanf(fi,"%lf%d",&dec,&inte) != EOF)
{
if(dec > inte)
{
cont++;
med = med + dec;
fprintf(fo,"%f\n",dec);
}
}

fclose(fi); fclose(fo);
printf("%d %f\n",cont, med/cont);
system("pause"); return 0;
}

E2.
Definire il tipo di dato MATRIX come matrice di interi 2X4 e VET come vettore di 4 interi.
Scrivere la funzione dividi() che ha un parametro formale di nome M di tipo MATRIX e due
parametri formali di nome pari e dispari entrambi di tipo VET. La funzione dividi()
carica nel parametro pari gli elementi della prima riga di M e nel parametro dispari gli
elementi della seconda riga di M.

#include <stdio.h>
#include <stdlib.h>
typedef int MATRIX[2][4];
typedef int VET[4];

void dividi(MATRIX M, VET pari, VET dispari)


{ int i;

for(i=0; i<4; i++)


pari[i] = M[0][i];
for(i=0; i<4; i++)
dispari[i] = M[1][i];
}

//NON RICHIESTO DAL TESTO


int main()
{
MATRIX mt={2,5,7,8,-9,-3,3,7};
VET v1, v2;
int i;

dividi(mt,v1,v2);

for(i=0;i<4;i++)
printf("%4d %4d\n",v1[i], v2[i]);
system("pause"); return 0;
}

E3
Un’agenzia immobiliare per la sua gestione utilizza, fra le altre, le seguenti relazioni (gli
attributi che formano la chiave sono indicati in neretto):

Immobile
(Id, DatiCatastali, Citta, via, numCivico, piano, prezzoRichiesto)

Proprietario
(CFproprietario, telefono)

Visitatore
(CFvisitatore, telefono)

ImmobileProprietario
(IdImmobile, CFProprietario)

Visita
(IdImmobile, CFVisitatore, data, prezzoProposto)

Scrivere le interrogazioni SQL per:


Indicare DatiCatastali, Citta, e numero di visitatori per ogni immobile presente nella
relazione Visita.

SELECT DatiCatastali, Citta, count(*) AS 'Visitatori'


FROM immobile, visita
WHERE Id=IdImmobile
GROUP BY Id, DatiCatastali, Citta

Indicare per ogni CFVisitatore che ha effettuato più di una visita, il suo numero di
telefono e il valore più alto di prezzoProposto

SELECT visita.CFVisitatore, telefono,


max(prezzoProposto) AS Massimo
FROM visita, visitatore
WHERE visita.CFVisitatore = visitatore.CFVisitatore
GROUP BY visita.CFVisitatore, Telefono
HAVING count(*) > 1

Data la seguente istanza della base di dati precedente:

Immobile
I DatiCatastal Citta Via NumCivic pian prezzoRichiest
d i o o o
1 A2B0 Milano Rossi 12 2 120000
2 A1B0 Milano Grandi 14 8 500000
3 A3B0 Rozzan Grandi 12 14 200000
o
4 A4B0 Milano Verdi 0 0 8000000
5 A5B0 Rho Bianch 7 5 20000
i
6 A2B1 Milano Rossi 13 7 250000

Proprietario
CFProprietario Telefono
AAA 100
BBB 200
CCC 300
DDD 400
EEE 500
FFF 600

ImmobileProprietario
IdImmobil CFProprietario
e
1 AAA
1 DDD
2 BBB
3 CCC
3 EEE
4 EEE
5 DDD
5 FFF
6 BBB

Visitatore
CFVisitatore Telefono
AAA 100
EEE 500
XXX 700
YYY 800
ZZZ 900
Visita
IdImmobil CFVisitatore Data PrezzoProposto
e
1 EEE 2008-04-12 80000
1 YYY 2008-04-15 150000
2 AAA 2008-04-13 700000
2 ZZZ 2008-03-31 500000
3 XXX 2008-03-27 800000
5 YYY 2008-04-27 120000

Mostrare il risultato delle seguenti interrogazioni:

SELECT CFVisitatore
FROM visita, Immobile
WHERE Id = IdImmobile
GROUP BY CFVisitatore
HAVING count(DISTINCT citta) > 1

CFVisitatore
YYY

SELECT CFVisitatore
FROM visita
WHERE CFVisitatore IN (
SELECT CFProprietario
FROM ImmobileProprietario
WHERE IdImmobile IN (
SELECT IdImmobile
FROM ImmobileProprietario
GROUP BY IdImmobile
HAVING count(*) > 1
)
)

CFVisitatore
EEE
AAA

E1.
Il file valori.txt contiene per ogni riga due numeri interi.
Scrivere un programma che legge il contenuto del file valori.txt e scrive sul file
rivisti.txt tutte le righe di valori.txt tali che il primo valore è pari ed il secondo
dispari. Al termine dell'elaborazione il programma deve visualizzare (mostrare a video) il
numero di righe lette da valori.txt e quelle scritte su rivisti.txt.
Esempio

valori.txt rivisti.txt visualizza


23 57 18 31 5 2
45 36 -88 43
18 31
-88 43
18 26

#include <stdio.h>
#include <stdlib.h>
int main()
{ FILE *fi, *fo;
int n1, n2;
int letti, scritti;
fi = fopen("valori.txt","r");
fo = fopen("rivisti.txt","w");

if(fi == NULL || fo == NULL)


exit(-1);

letti = 0; scritti = 0;
while(fscanf(fi,"%d%d",&n1,&n2) != EOF)
{
letti++;
if(n1%2==0 && n2%2==1)
{
scritti++;
fprintf(fo,"%d %d\n",n1,n2);
}
}

fclose(fi); fclose(fo);
printf("%d %d\n",letti, scritti);
system("pause"); return 0;
}

E2.
Definire il tipo di dato MATR come matrice di numeri decimali 3X3. Scrivere la funzione
crea() che ha tre parametri formali, K di tipo int, M1 ed M2 di tipo MATR; la funzione
crea():
incrementa del valore K quelle celle di M1 contenenti un valore strettamente positivo e
le memorizza in M2,
decrementa del valore K quelle celle di M1 contenenti un valore negativo e le
memorizza in M2
trascrive in M2 quelle celle di M1 che hanno valore 0.

#include <stdio.h>
#include <stdlib.h>
#define DIM 3
typedef double MATR[DIM][DIM];

void crea(int K, MATR M1, MATR M2)


{ int i,j;

for(i=0; i<DIM; i++)


for(j=0; j<DIM; j++)
if (M1[i][j] > 0)
M2[i][j] = M1[i][j] + K;
else if (M1[i][j] < 0)
M2[i][j] = M1[i][j] - K;
else
M2[i][j] = M1[i][j];
}

//NON RICHIESTO DAL TESTO


int main()
{
MATR mt={2,5,7,
8,-9,-3,
3,0,9},rs;
int i,j;

crea(8,mt,rs);

for(i=0;i<DIM;i++)
{
for(j=0;j<DIM;j++)
printf("%3d ",rs[i][j]);
printf("\n");
}
system("pause"); return 0;
}

E3
Un’agenzia immobiliare per la sua gestione utilizza, fra le altre, le seguenti relazioni (gli
attributi che formano la chiave sono indicati in neretto):

Immobile
(Id, Dati Catastali, Citta, via, numCivico, piano, prezzoRichiesto)

Proprietario
(CFproprietario, telefono)

Visitatore
(CFvisitatore, telefono)

ImmobileProprietario
(IdImmobile, CFProprietario)

Visita
(IdImmobile, CFVisitatore, data, prezzoProposto)

Scrivere le interrogazioni SQL per:


Determinare di ogni immobile il suo indirizzo e numero dei suoi proprietari.

SELECT Id, Citta, Via, NumCivico, count(*) AS 'Proprietari'


FROM immobile, immobileProprietario
WHERE Id=IdImmobile
GROUP BY Id, Citta, Via, NumCivico

Indicare il valore dell’attributo CFproprietario per tutti i proprietari che hanno in vendita
degli immobili il cui valore complessivo supera i 500000 Euro

SELECT CFProprietario, sum(prezzoRichiesto)


FROM Immobile, ImmobileProprietario
WHERE Id = IdImmobile
GROUP BY CFProprietario
HAVING sum(prezzoRichiesto) > 500000
Data la seguente istanza della base di dati precedente:

Immobile
I DatiCatastal Citta Via NumCivic pian prezzoRichiest
d i o o o
1 A2B0 Milano Rossi 12 2 120000
2 A1B0 Milano Grandi 14 8 500000
3 A3B0 Rozzan Grandi 12 14 200000
o
4 A4B0 Milano Verdi 0 0 8000000
5 A5B0 Rho Bianch 7 5 20000
i
6 A2B1 Milano Rossi 13 7 250000

Proprietario
CFProprietario Telefono
AAA 100
BBB 200
CCC 300
DDD 400
EEE 500
FFF 600

ImmobileProprietario
IdImmobil CFProprietario
e
1 AAA
1 DDD
2 BBB
3 CCC
3 EEE
4 EEE
5 DDD
5 FFF
6 BBB

Visitatore
CFVisitatore Telefono
AAA 100
EEE 500
XXX 700
YYY 800
ZZZ 900
Visita
IdImmobil CFVisitatore Data PrezzoProposto
e
1 EEE 2008-04-12 80000
1 YYY 2008-04-15 150000
2 AAA 2008-04-13 700000
2 ZZZ 2008-03-31 500000
3 XXX 2008-03-27 800000
5 YYY 2008-04-27 120000

Mostrare il risultato delle seguenti interrogazioni:

SELECT CFProprietario
FROM ImmobileProprietario, Immobile
WHERE Id = IdImmobile
AND citta = 'Milano'
GROUP BY CFProprietario
HAVING count(DISTINCT via) > 1

CFProprietario
BBB

SELECT CFVisitatore
FROM Visitatore
WHERE CFVisitatore IN (SELECT CFProprietario
FROM ImmobileProprietario)

CFVisitatore
AAA
EEE

E1
Siano dati due file di testo denominati dati1.txt e dati2.txt e un vettore di double di 20 elementi
denominato VtD con valore iniziale pari a -1. Supponendo che dati1.txt contenga, uno per riga
dei numeri interi maggiori di 0, e dati2.txt, sempre uno per riga, dei numeri decimali e che
contengano entrambi lo stesso numero di elementi, scrivere il programma che svolge i
seguenti compiti:
legge in parallelo un valore dal file dati1.txt lo pone nella variabile N e calcola il valore
della seguente espressione:

quindi legge l'elemento nella stessa posizione del file dati2.txt e pone 1 in VtD se il
valore letto da dati2.txt è uguale al valore dell'espressione, 0 altrimenti. La lettura
termina o con la fine dei file o dopo 20 elementi;
dopo aver caricato VtD stampa i valori di dati1.txt per i quali il valore in VtD è 1.

Esempio:
dati1.txt dati2.txt valore sommatoria
8 3.1 2.7178
6 2.45 2.45
3 -42.21 1.8333
quindi in VtD si avrà [0, 1, 0, gli altri 17 valori sono -1] e stamperà solo il valore 6.)

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

double expr(int N)
{
double ris=0.0;
int i;
for (i=1;i<=N;i++)
ris = ris + 1.0/i;

return ris;
}

int main()
{
FILE *f1, *f2;
double VtD[20],vF2;
double prec = 0.0000001;
int i, j, vF1;

f1 = fopen("dati1.txt","r");
f2 = fopen("dati2.txt","r");

if (f1 == NULL || f2 == NULL)


exit(-1);

for(i=0;i<20;i++) VtD[i] = -1;

i=0;
while(i<20 && fscanf(f1,"%d",&vF1)!=EOF && fscanf(f2,"%lf",&vF2) != EOF)
if (fabs(expr(vF1)- vF2) <= prec)
VtD[i++] = 1;
else
VtD[i++] = 0;

rewind(f1);

for(j=0;j<i; j++)
{
fscanf(f1,"%d",&vF1);
if (VtD[j] == 1)
printf("%d %.12lf\n",vF1,expr(vF1));
}

fclose(f1), fclose(f2);
system("pause"); return 0;
}

E2
Definire un nuovo tipo di dato chiamato ST formato da due campi A e B il primo di tipo double
ed il secondo di tipo int. Scrivere la funzione ft che ha in ingresso un parametro K di tipo ST e
che:
restituisce, attraverso un opportuno parametro, un vettore di 20 elementi di tipo ST in
cui tutti gli elementi sono uguali a K,
restituisce il valore massimo fra il campo A e B di K.

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

typedef struct {double A; int B;} ST;


double ft(ST K, ST vt[])
{ int i;
for(i=0; i<20; i++)
vt[i] = K;
if (K.A > K.B)
return K.A;
else
return K.B;
}

int main() //NON RICHIESTO DAL TESTO


{ ST v[20], el={2.45, -7};

printf("%lf\n",ft(el,v));

system("pause"); return 0;
}

E3
Sintetizzare la funzione booleana f(x)=x/2 + 1 dove x è un numero binario senza segno di 2
bit e l'uscita deve essere espressa in complemento a 2 con il minor numero di bit.

X1 X0 X X*2-1 U2 U1 U0
0 0 0 1 0 0 1
0 1 1 1 0 0 1
1 0 2 2 0 1 0
1 1 3 2 0 1 0

U0 = -X1
U1 = X1
U2 = 0

Potrebbero piacerti anche