Pubblicato il

Come eliminare un elemento in testa a una lista lineare in C

Reading Time: 2 minutes

1 Cosa è una lista


Una lista è una collezione di elementi omogenei, cioè di elementi tra loro tutti uguali. A differenza dell’array, occupa in memoria una posizione qualsiasi, che tra l’altro può cambiare dinamicamente durante l’utilizzo della lista stessa.

Continua a leggere Come eliminare un elemento in testa a una lista lineare in C
Pubblicato il

Come inserire un elemento in testa a una lista lineare in C

Reading Time: 2 minutes

1 Cosa è una lista


Una lista è una collezione di elementi omogenei, cioè di elementi tra loro tutti uguali. A differenza dell’array, occupa in memoria una posizione qualsiasi, che tra l’altro può cambiare dinamicamente durante l’utilizzo della lista stessa.

2 Strumenti per creare una lista

Per questo tutorial andremmo a utilizzare strumenti come: malloc, puntatori e struct.

malloc è il nome di una funzione delle librerie standard del linguaggio C (ma anche del linguaggio C++) ed è l’abbreviazione di “memory allocation” (allocamento di memoria).

L’utilizzo di tale funzione avviene come di seguito:

void* malloc(size_t size);

 Tale funzione alloca in memoria un numero di bytes pari a size, restituendo un puntatore di tipo void che indica un generico indirizzo di memoria.

Le strutture, definibili con la parola chiave struct, permettono l’aggregazione di più variabili in un unico tipo.

Un puntatore è una variabile che contiene l’indirizzo di memoria di un’altra variabile.

3 Cosa contiene una lista

Una lista:

  • Può contenere uno o più campi di informazione che possono essere di ogni tipo (es. int, char, float, ecc.), e un campo “puntatore al nodo successivo (next)”;
  • Ha il primo elemento della lista che è un puntatore a nodo di tipo Nodo*, quando la lista è vuota, questo puntatore è settato a NULL.
  • Esempio di dichiarazione di una lista: Nodo *lista = NULL;
  • L’ultimo nodo della lista ha il campo “next” settato a NULL

Esempio grafico di una lista lineare

4 Struttura base di una lista lineare

Definizione della struttura Nodo:

Struct Nodo{        
int info; //variabile che contiene l’informazione, puo essere di qualsiasi tipo(int,float,double…)        
struct Nodo* next //Puntatore al prossimo elemento della lista 
}; 
typedef struct Nodo Nodo;

5 Esempio di inserimento in testa di un elemento in una lista lineare

Prototipo:

Nodo* aggiungiInTesta(Nodo* list, int val);

Esempio:

Nodo* aggiungiInTesta(Nodo* list, int val) {     
Nodo* nuovoElemento = NULL; // Puntatore       
nuovoElemento = (Nodo*) malloc(sizeof(Nodo)); // Allocazione   
if (nuovoElemento == NULL) { // Check dell’allocazione se è andata a buon fine         
printf("Errore in memoria.");        
 exit(-1);     
}     
// Assegnazione al next della nuova testa l'indirizzo della vecchia    
 nuovoElemento->next = list;     // Assegnazione all'info della nuova testa il valore passato      
 nuovoElemento->info = val;     // Restituisce l’indirizzo del primo elemento della lista   
  return nuovoElemento; 
} 
Pubblicato il

Come ricevere assistenza da remoto su Windows 10

woman sitting on sofa while looking at phone with laptop on lapReading Time: 2 minutes
  • Premere il tasto windows e digitare “assistenza rapida”.
  • Premere sulla applicazione chiamata “Assistenza rapida”, come evidenziato in figura sotto.
Figura 1 applicazione di assistenza rapida evidenziata in rosso
  • Verrà mostrata la seguente finestra.
Figura 2 Digitare il codice a 6 cifre fornito dall’assistente nel campo evidenziato in rosso
  • Cliccare “consenti” come da figura.
Figura 3 Premere il tasto Consenti come evidenziato in figura in rosso
  • Attendere che l’assistente abbia concluso.
woman in gray sweater drinking coffee

Hai bisogno di assistenza remota?

Se hai bisogno di assistenza remota contattaci tramite WhatsApp oppure scrivici una mail a orangejellybeanojb@gmail.com. Che aspetti? AFFRETTATI!

Pubblicato il

Come scrivere il codice di un programma C++ per il calcolo della media dei voti scolastici

Reading Time: < 1 minute

Vuoi scrivere un programma C++ che calcoli la media dei tuoi voti scolastici? Qui di seguito ti propongo un esempio.

La procedura che segue il programma esempio è la seguente:

  • chiede all’utente quanti voti vuole immettere;
  • chiede all’utente di immettere il numero di voti che ha dichiarato uno a uno;
  • calcola la media aritmetica dei valori inseriti;
  • termina il programma dichiarando la media aritmetica dei voti.

Qui di seguito riporto il codice (copialo e incollalo se ti serve!):

#include <iostream>
#include <string>
using namespace std;
// dichiarazioni funzione per il calcolo della media aritmetica
float averageFloat(float vet[], int N);

int main()
{
int numElem = 0;
cout << "Quanti sono i voti che vuoi inserire?"; 
cin >> numElem;
cout << "Il numero di voti che vuoi inserire e' " << numElem << "\n"; 
float vectorFloat[numElem]; 
for(int k=0; k < numElem; k++)
     { 
     cout << "Inserisci il voto numero " << (k + 1) << "\n"; 
     cin >> vectorFloat[k];
     }
float res = 0;
res = averageFloat(vectorFloat, numElem);
cout <<"La media dei valori che hai inserito e': " << res;
return 0;
}

//funzione per il calcolo della media aritmetica
float averageFloat(float vet[], int N) {
int i;
float avg = 0;
for ( i = 0; i < N; i++) {
avg = avg + vet[i];
}
avg = avg / N; //calcolo della media
return avg;
}
Pubblicato il

Come stimare la posizione di un punto materiale in un moto qualunque conoscendone la funzione accelerazione

Reading Time: 3 minutes

Si supponga di conoscere la funzione vettoriale dell’accelerazione nel tempo \vec{a}(t) di un punto materiale. La posizione del punto materiale può essere ricavata tramite doppia integrazione successiva delle componenti della funzione vettoriale dell’accelerazione.
Si supponga dapprima che \vec{a}(t) sia costante e chiamiamo tale vettore costante semplicemente \vec{a}.
Si considerino le tre componenti del vettore accelerazione costante:

\vec{a}\left(a_{x}, a_{y}, a_{z}\right)

Per ricavare le velocità del punto materiale si considera che in fisica vale:

\vec{v}\left(\begin{array}{l} \int a_{x} d t \\ \int a_{y} d t \\ \int a_{z} d t \end{array}\right)

Ovvero:

\vec{v} \left( \begin{array}{c} a_{x}t+v_{0x} \\ a_{y}t+v_{0y} \\ a_{z}t+v_{0z} \end{array}\right)


In cui \vec{v}_{0} \left(v_{0x}, v_{0y}, v_{0z} \right) è il vettore dei termini costanti derivanti dall’integrazione delle componenti di \vec{v} e rappresenta il vettore velocità iniziale nelle tre direzioni dello spazio. Per poter ricavare la posizione si deve integrare ancora, questa volta la velocità. Così si ottiene:

\vec{s} \left(\begin{array}{c} \int a_{x} t+v_{0 x} d t \\ \int a_{y} t+v_{0 y} d t \\ \int a_{z} t+v_{0z} dt \end{array} \right)

E quindi:

\vec{s}\left(\begin{array}{l} \frac{1}{2} a_{x} t^{2}+v_{0 x} t+s_{0x} \\ \frac{1}{2} a_{y} t^{2}+v_{0 y} t+s_{0y} \\ \frac{1}{2} a_{z} t^{2}+v_{0 z} t+s_{0z} \end{array}\right)

Quest’ultimo rappresenta il vettore delle posizioni del punto materiale nello spazio con accelerazione costante. Le componenti di tale vettore posizione sono quelle che in fisica si chiamano legge oraria del moto rettilineo uniformemente accelerato. Risulta insensato pretendere che tale legge valga anche quando l’accelerazione è variabile, inoltre praticamente in nessuna applicazione dinamica reale l’accelerazione è sempre costante.

Tuttavia è anche vero che, per intervalli di tempo sufficientemente piccoli l’accelerazione può essere considerata costante. Per tale motivo, in applicazione di algoritmi software per il calcolo della posizione di un punto materiale note le sue accelerazioni, può risultare sensato l’utilizzo della legge oraria. Supponiamo di voler calcolare la posizione di un punto materiale via software e di rilevarne l’accelerazione digitalmente, tramite accelerometro.

Sia data, di tale misurazione, la frequenza di campionamento f_c.La distanza temporale tra un campione e l’altro è di:

T = \frac{1}{f_c}

Utilizzare la legge oraria per il calcolo della posizione del punto materiale ogni T secondi appare ragionevole solo se T è sufficientemente piccolo. Il periodo è sufficientemente piccolo se non ci si aspetta entro T secondi che ci siano variazioni significative di accelerazione lineare in nessuna delle tre direzioni spaziali. Questa assunzione è sicuramente approssimativa però abbastanza giustificata se si considera un intervallo di tempo sufficientemente piccolo.

Siano i campioni di accelerazione, provenienti dal sensore, nominati come segue:

\vec{a}_{1}, \vec{a}_{2}, \vec{a}_{3}, \vec{a}_{4}, \ldots, \vec{a}_{n-1}, \vec{a}_{n}

Siano gli istanti di tempo, relativi a quelle accelerazioni, nominati come segue:

t_{1}, t_{2}, t_{3}, t_{4}, \ldots, t_{n-1}, t_{n}

Le velocità, in ogni istante di tempo saranno:

\vec{v}_{1}=\left(t_{1}-t_{0}\right) \vec{a}_{0}+\vec{v}_{0}

\vec{v}_{2}=\left(t_{2}-t_{1}\right) \vec{a}_{1}+\vec{v}_{1}

\vec{v}_{i}=\left(t_{i}-t_{i-1}\right) \vec{a}_{i-1}+\vec{v}_{i-1}

\vec{v}_{n}=\left(t_{n}-t_{n-1}\right) \vec{a}_{n-1}+\vec{v}_{n-1}

Siccome non è nota la velocità \vec{v}_{1} e non può esserlo a causa della mancanza di dati allora, per comodità, si può imporre uguale a zero e considerare significativi i valori di velocità a partire da \vec{v}_{2}. Per questo tipo di algoritmo è necessario che \vec{v}_{0} = 0.

Quando invece si calcola la posizione si considera che, per ogni intervallo, vale quanto segue:

\vec{s}_{i}=\vec{s}_{i-1}+\vec{v}_{i-1} t+\frac{1}{2} \vec{a}_{i-1} t^{2}

Per migliorare il modo di calcolare la velocità e la posizione del punto materiale si potrebbe pensare di fare la media delle due accelerazioni \vec{a}_{i-1} e \vec{a}_{i}.

\vec{a}_{AVG} \left( \frac{a_{i, x}+a_{i-1, x}}{2}, \frac{a_{i, y}+a_{i-1, y}}{2}, \frac{a_{i, z}+a_{i-1, z}}{2} \right)

Quindi il moto del punto materiale sarebbe meglio definito da:

\left \{ \begin{matrix} \vec{v}_{i}=\left(t_{i}-t_{i-1}\right) \vec{a}_{AVG}+\vec{v}_{i-1} \\ \vec{s}_{i}=\vec{s}_{i-1}+\vec{v}_{i-1}(t_{i}-t_{i-1})+\frac{1}{2} \vec{a}_{AVG}\left(t_{i}-t_{i-1} \right)^{2} \end{matrix} \right.

Anche questa soluzione risulta incompleta per motivi di rumore. Infatti non è proprio vero che le varie accelerazioni misurate sono nella forma:

\vec{a}_{1}, \vec{a}_{2}, \vec{a}_{3}, \vec{a}_{4}, \ldots, \vec{a}_{n-1}, \vec{a}_{n}

Piuttosto è vero che esse sono nella forma:

\vec{a}_{i} + \vec {\varepsilon}_{i} per i = 1, 2,..., n-1, n

In cui i vari termini \vec {\varepsilon}_{i} sono gli errori di misurazione che la sensoristica inevitabilmente commette. Nei prossimi post quali sono i problemi che possono nascere da questi errori e una delle tecniche possibili che si utilizzano per contenerli.

Qui di seguito puoi scaricare il documento relativo a questo post:

Pubblicato il

Come effettuare la rotazione della funzione seno (con codice Matlab)

Reading Time: 3 minutesPer ragionare più profondamente sul contenuto di cui sotto si faccia riferimento a quanto precedentemente discusso in “Sistema di riferimento ruotato

Per ruotare la funzione seno si deve tenere in considerazione che essa deve mantenersi uguale a se stessa quando ruotata e quindi deve essere rigidamente ruotata. Continua a leggere Come effettuare la rotazione della funzione seno (con codice Matlab)

Pubblicato il

Come fare il grafico di due rette su OpenOffice Calc

Reading Time: 3 minutesDi seguito viene mostrato come utilizzare OpenOffice Calc per rappresentare due rette sullo stesso piano cartesiano. Continua a leggere Come fare il grafico di due rette su OpenOffice Calc

Pubblicato il

Investire o non investire?

Reading Time: 5 minutesRecentemente mi sono chiesto quanto veramente ha senso investire sul lungo termine, perchè non sono mai stato molto convinto che i potenziali profitti avrebbero potuto cambiare significativamente il mio capitale finale.

Continua a leggere Investire o non investire?

Pubblicato il

Creazione di un dataset da registrazione Doppler con Matlab

Reading Time: 2 minutesIn questo post faccio vedere come creare un dataset in matlab in modo automatizzato, avendo a disposizione delle annotazioni in estensione “.mat”.

Nel mio caso sono un insieme di registrazioni fetali Doppler perchè, essendo un dottorando nel settore della biomedica, mi sono capitati recording di questo tipo.

Quello che faccio in questo codice è:

  1. Creare una struttura con tutte le immagini presenti nella cartella corrente (nel mio caso le registrazioni Doppler) e che hanno un ending tag noto (nel mio caso ‘*filtered.bmp’)
  2. Decidere dei labels coerenti con le annotazioni di cui dispongo (le mie annotazioni avevano, nella terza colonna della matrice “annotations”, numeri da 1 a 3, indicanti la tipologia del ciclo fetale: ciclo, flip di ciclo cardiaco o non ciclo)
  3. Creare delle cartelle in cui inserire i sample una volta estratti
  4. Fase di estrazione dei sample e inserimento nella cartella opportuna

Qui di seguito la prima fase:

% select all images with the desired ending and create the struct
TAG_EndNameImgs = '*filtered.bmp'; % choose the correct ending for you
imgs = dir(endNameImgs);
%% Load annotation on your workspace and prepare.
load('annotations.mat')
imgsStruct=imgs;
period=128; % my period was of 128 sample approximatively
imagesLabeled (1:size(annotations, 1)) = struct ('Image', [], 'Label', '');

Bisogna caricare nel workspace le annotazioni (erano un .mat). Nel mio caso la colonna tre della matrice delle annotazioni conteneva gli indici di inizio di un ciclo cardiaco o non cardiaco (annotazioni prese da un medico).

Qui di seguito la seconda fase:

%% choose your own labels
labels = ["heart_cicle" "heart_cicle_flipped" "NOT_heart_cicle"];

Terza fase:

 

%% here I'm dividing the folders that will contain the samples
if (~exist(pwd + "\heart_cicle", 'dir')||~exist(pwd + "\heart_cicle", 'dir'))
mkdir(pwd + "\heart_cicle");
mkdir(pwd + "\NOT_heart_cicle");
else
disp("the folders already exist");
end

Quarta fase:

 %% Go through each record in imgsStruct (for me was the doppler)
% and cut selectively.
% Insert all the cut images in imgsStruct
disp("Now, from all records, I'll build sample images. Please be patient...");
for i=1:size(imgsStruct, 1)
% find all the annotations for that file
indexes = find(annotations(:,3)==i);
imgTmp = imread(imgsStruct(i,1).name);

for j = 1:size(indexes,1)
beg_col =annotations(indexes(j),1); % annotated index tells the begin
end_col = annotations(indexes(j),1)+ period; % end on period
imgTmpSplitted = imageDopplerSplitter(imgTmp, beg_col, end_col);
% establish the labels and insert the sample into the appropriate folder
if ((annotations(indexes(j),2)==1)) % heart_cicle
imagesLabeled(indexes(j)).Label = labels(1);
imagesLabeled(indexes(j)).Image = imgTmpSplitted;
baseFileName = "sample" + int2str(indexes(j)) + ".bmp"; % Whatever....
fullFileName = fullfile(pwd + "\" + labels(1), baseFileName);
imwrite(imagesLabeled(indexes(j)).Image, fullFileName);
elseif ((annotations(indexes(j),2)==2)) % heart_cicle_flipped
imagesLabeled(indexes(j)).Label = labels(2);
imagesLabeled(indexes(j)).Image = imgTmpSplitted;
baseFileName = "sample" + int2str(indexes(j)) + ".bmp"; % Whatever....
fullFileName = fullfile(pwd + "\" + labels(1), baseFileName);
imwrite(imagesLabeled(indexes(j)).Image, fullFileName);
elseif ((annotations(indexes(j),2)==3)) % NOT_heart_cicle
imagesLabeled(indexes(j)).Label = labels(3);
imagesLabeled(indexes(j)).Image = imgTmpSplitted;
baseFileName = "sample" + int2str(indexes(j)) + ".bmp"; % Whatever....
fullFileName = fullfile(pwd + "\" + labels(3), baseFileName);
imwrite(imagesLabeled(indexes(j)).Image, fullFileName);
end
end
end
disp ("Now samples are separated into the folder heart_cycle and NOT_heart_cycle");

In questo post è stato presentato un esempio di codice Matlab per la creazione di un dataset esempio (nel mio caso un Doppler). Questa creazione di dataset può essere adattata ai propri scopi.

Non posso fornire il dataset su cui sto lavorando in quanto proprietà dell’Università per la quale lavoro e non posso neanche fornire i dettagli delle elaborazioni successive degli studi correlati. Nessuna domanda in tal senso verrà presa in considerazione e/o riceverà delle risposte.

Pubblicato il

Architettura 8086 (Execution Unit)

Reading Time: 3 minutesQui di seguito vengono mostrati i punti generali dell’architettura dell’8086 e una breve argomentazione dei blocchi nella parte dell’Execution Unit di tale datapath.

Di seguito viene riportata un’immagine rappresentante lo schema a blocchi elementare per l’8086.

Architettura8086
Figura1. Schema a blocchi tratto dalla documentazione ufficiale del manuale utente per l’8086

Come si può notare l’architettura è suddivisa in due grandi sezioni:

  • Execution Unit
    • Si tratta della parte esecutiva dell’architettura. Essa si interfaccia al mondo esterno grazie alla Bus Interface Unit e da quest’ultima riceve le prossime istruzioni da eseguire. Per poter avere accesso alle memorie la EU deve riferirsi alla BIU. Ogni registro all’interno della EU è a 16 bit. La EU ha traccia anche dello stato della CPU, il quale è Status Register.
  • Bus interface unit
    • È la sezione che si occupa dell’interfacciame dell’EU con le memorie esterne e le periferiche I/O esterne. La BIU si occupa anche di garantire un anticipo delle fetch, secondo una logica di pipeline nella quale fetch ed execute non avvengono in modo temporalmente sequenziale ma in modo ottimizzato.

La Execution Unit

Come già anticipato la EU è la parte esecutiva dell’architettura della CPU e  si articola in 5 sottosezioni:

  • I registri generali
  • I registri temporanei
  • La Aritmetic Logic Unit (ALU)
  • Il sistema di controllo della EU

Di seguito viene discussa la funzione dei blocchi in elenco.

I registri generali e temporanei

I registri generali sono 8 e da 16 bit ciascuno. Solo 4 dei registri generali (per esempio AX, BX) possono essere allocati nella loro parte alta (o “High”) (per esempio AH, BH etc.) e/o nella parte bassa (o “Low”) separatamente (AL, BL, etc.).

I registri generali sono:

  • AX (compreso di AH|AL) si chiama registro accumulatore e viene utilizzato per operazioni di moltiplicazione, divisione etc. sulle word mentre la sua parte alta e la sua parte bassa si usano per le operazioni tra byte.
  • BX (compreso di BH|BL) si chiama registro base e viene utilizzato per stabilire l’indirizzo di base (iniziale) di una tabella o di un vettore.
  • CX (compreso di CH|CL) si chiama registro contatore e viene usato per le operazioni sulle stringhe e nei loop
  • DX (compreso di DH|DL) si chiama registro dei dati viene utilizzato per specificare le porte di I/O ma anche per eseguire operazioni di moltiplicazione e di divisione sulle word.
  • SP (stack pointer, è un puntatore che punta alla sommità dello stack) e BP (Base pointer, è un puntatore che punta ad una allocazione interna allo stack) vengono utilizzati per le operazioni con gli stack.
  • SI (Source Index) è un offset che consente di puntare a una locazione specifica nel segmento di memoria destinato ai dati. Tipicamente viene utilizzato per le operazioni tra le stringhe e indirizza l’operando o il dato sorgente
  • DI (Destination Index) è un offset che consente di puntare a una locazione specifica nel segmento di memoria destinato ai dati. Tipicamente viene utilizzato per le operazioni tra le stringhe e indirizza l’operando o il dato di destinazione

I temporary registers invece sono dei registri buffer in cui vengono caricati i valori su cui deve operare la ALU.

La ALU e lo Status Register (SR)

ALU sta per Artimetic Logic Unit ed è un circuito combinatorio adibita all’esecuzione di tutte le operazioni richieste, siano esse somme, sottrazioni, operazioni booleane etc. La ALU è responsabile del settaggio dei bit nello Status Register, in cui viene tenuto conto dello stato della CPU. Per esempio se la ALU durante una somma va in overflow (cioè il risultato risulta non essere più rappresentabile in 16 bit) il bit numero 11 (chiamato anche bit OF, che sta per OverFlow) del registro dell’ SR va a uno, indicando appunto lo stato di overflow.

Control System

Questo blocco controlla il flusso dei dati verso la Execution Unit.