• Non ci sono risultati.

APPUNTI DI INFORMATICA

N/A
N/A
Protected

Academic year: 2021

Condividi "APPUNTI DI INFORMATICA"

Copied!
58
0
0

Testo completo

(1)

APPUNTI DI INFORMATICA

(2)

Le componenti di un elaboratore si dividono in due grandi categorie : HARDWARE – SOFTWARE .

Il termine hardware indica la parte della componentistica cosiddetta

“dura” (monitor – scheda madre – tastiera – schede etc .etc. )

Il termine software indica l’insieme dei comandi,programmi,usati per determinare le operazione che il computer deve svolgere. Il software comanda L’hardware.

Il software si divide in : APPLICATIVO e DI BASE.

I software applicativi sono quelli che vengono applicati successivamente all’atto dell’acquisto, o che comunque non fanno parte del sistema

operativo.Sono software applicativi , elaborazione testi, fogli di calcolo programmi di grafica , gestione di archivi ,compilatori

Il software di base viene fornito all’atto dell’acquisto del P.C. e

(3)
(4)
(5)
(6)

I SISTEMI OPERATIVI

1.

COSTITUISCE UNA INTERFACCIA TRA IL P.C. E L’UTENTE RENDENDO QUEST’ ULTIMO IN

GRADO DI OPERARE IN MODO SEMPLICE EFFICIENTE E SICURO

2.

Un sistema operativo è un insieme di programmi che permettono di gestire le risorse di un sistema

informatico facilitando l’interazione dell’utente con il

sistema

(7)

Le due parti fondamentali nelle quali possiamo vedere suddiviso un S.O. sono il KERNEL e la SHELL. Il kernel è il nucleo del SO, ed è responsabile della creazione dell’ambiente nel quale vengono calate le applicazioni utente. Il kernel è il nocciolo del sistema

operativo. I programmi utilizzano le funzioni fornite dal kernel, e in questa maniera sono sollevati dall'agire

direttamente con la CPU.

L’utente non comunica mai direttamente con il kernel, ma esegue le necessarie operazioni facendo uso di un apposito linguaggio di comando che viene interpretato dallo shell (l’interprete dei comandi di un SO).

Un SO è schematizzabile come una ‘cipolla’, ossia è formato da più strati o

“livelli” concentrici.

(8)

La shell

La shell è il programma più importante in un sistema operativo, dopo il kernel. È in pratica il mezzo con cui si comunica con il sistema e attraverso il quale si avviano e si controlla l'esecuzione degli altri programmi.

La shell ha questo nome (conchiglia) perché di fatto è la superficie con cui l'utente entra in contatto quando

vuole interagire con il sistema: la shell che racchiude il kernel.

Una shell è qualsiasi programma in grado di consentire all'utente di interagire con il sistema. Può trattarsi di

qualcosa di molto semplice come una riga attraverso cui è possibile digitare dei comandi, oppure un menù di

comandi già pronti, o un sistema grafico a icone, o

(9)

Quando una shell attende ed esegue i comandi impartiti dall'utente, si trova in una modalità di funzionamento interattivo. La disponibilità da parte della shell di ricevere comandi viene

evidenziata sullo schermo del terminale con un

messaggio di invito o prompt .

(10)

STRUTTURA A LIVELLI DI UN SISTEMA OPERATIVO

Oggi prendiamo in considerazione la struttura a livelli dei SO. Si tenga presente che i SO reali possono avere una struttura meno articolata di quella che

presentiamo qui di seguito.

1) PROGRAMMA UTENTE.

2) INTERPRETE DEI COMANDI (SHELL). Questo livello si occupa della traduzione dei comandi simbolici in invocazioni di moduli di memoria.

3) PROGRAMMI DI UTILITÀ. Programmi di sistema per il supporto allo sviluppo dei programmi, editor di testi, fogli elettronici, database, videogiochi etc.[1].

4) FILE SYSTEM. Gestione di blocchi di informazioni

strutturati logicamente e registrati nella memoria secondaria (file), e controllo degli accessi (chi può leggere, scrivere,

modificare i file).

5) PERIFERICHE VIRTUALI. Simulazione di periferiche

virtuali dedicate: implementazione di primitive di I/O, gestione

(11)

S.O. come gestore di risorse

Considerate un ristorante con un capo-cuoco e i suoi aiutanti,

una cucina, camerieri e clienti

i clienti scelgono un piatto da un menu

un cameriere prende l'ordine e lo consegna al capo-cuoco

il capo-cuoco riceve l'ordine e assegna uno o più aiutanti alla preparazione del piatto

ogni aiutante si dedicherà alla preparazione di un piatto, il che potrà richiedere più attività diverse

il capo-cuoco supervisiona la preparazione dei piatti e gestisce le risorse (limitate) disponibili

(12)

S.O. come gestore di risorse

Il capo-cuoco è il sistema operativo!

i clienti sono gli utenti

le ricette associate ai piatti corrispondono ai programmi

il menu e il cameriere costituiscono l'interfaccia verso il sistema operativo (grafica e non)

gli aiutanti corrispondono ai processi

la cucina corrisponde al computer; pentole, fornelli, etc.

corrispondono alle componenti di un computer

(13)

GESTIONE DELLE RISORSE

Il ruolo principale del sistema operativo è la gestione delle risorse di cui il sistema dispone LE RISORSE POSSONO ESSERE DEFINITE

COME UNA QUALSIASI ENTITA’

(HARDWARE O SOFTWARE) PRESENTE IN UN SISTEMA DI ELABORAZIONE

ALLO SCOPO DI PERMETTERE DI FARE

AVANZARE UN PROCESSO

(14)

RISORSE FISICHE

1. UTILIZZO E SINCRONIZZAZIONE DELLA CPU

2. GESTIONE DELLA MEMORIA

3. GESTIONE DELLE PERIIFERICHE DI I/O

RISORSE LOGICHE

1. GESTIONE DELLE INFORMAZIONI

2. INTERFACCIA REALIZZATA DAI LINGUAGGI DI PROGRAMMAZIONE

3. FUNZIONI DI UTILITA’ PER L’UTENTE

(15)

Una risorsa può essere assegnata in modo statico o dinamico , questo dipende dalla complessità

della risorsa e dalla gestione del S.O.

(monoprogrammazione – time sharing)

Una risorsa può essere riusabile e non riusabile, in quanto alcune risorse possono essere

ripetutamente usate da più processi

(16)

Gestione dei PROCESSI

Il PROGRAMMA E’ UNA ENTITA’ STATICA DATA DA UNA SEQUENZA DI ISTRUZIONI DA ESEGUIRE .

IL PROCESSO E’ UNA ATTIVITA DINAMICA , CONSEGUENZA DELL’ESECUZIONE DI TALI

ISTRUZIONI E QUINDI DELLO SFRUTTAMENTO E DELLA GESTIONE DELLE RISORSE COINVOLTE.

IL PROCESSO E’ L’INSIEME DEGLI STATI ASSUNTI

DALL’ELABORATORE DURANTE L’ESECUZIONE DEL PROGRAMMA

(17)

STATI DI UN PROCESSO

Processo in stato di esecuzione (running),

quando il processore sta operando per il suo avanzamento

Processo in stato di pronto (ready) quando attende la disponibilita’ del processore

Processo in stato di attesa (waiting) quando richiede l’intervento di una risorsa non

disponibile

Il nucleo del sistema operativo governa le transizioni tra gli stati

(18)

Ci sono due strategie fondamentali nello stato di un processo :

1.

EVENT DRIVEN : Il passaggio da uno stato all’altro avviene in base ad eventi , come la terminazione di un processo in esecuzione o una richiesta di

interruzione

2.

TIME DRIVEN : Il passaggio da uno stato all’altro avviene in base al fattore tempo. La CPU serve a

turno i vari processi , ripartendo equamente il tempo

di servizio fino all’esaurimento delle richieste

(19)

POLITICA DEL TIME DRIVEN

GESTIONE DEL ROUND ROBIN

Ogni processo ottiene la CPU per un tempo massimo prefissato , terminato il quale passa

dallo stato di running allo stato di ready , a meno

che nel corso dell’elaborazione no debba passare

anticipatamente allo stato di waiting.

(20)

GESTIONE DELLA

CPU

(21)

UNITA’ CENTRALE DI ELABORAZIONE (C.P.U.)

Componente hardware che gestisce controlla e coordina le attività del computer

È composta da due parti fondamentali UNIT CONTROL (U.C.) che ha la funzione di verificare la corretta esecuzione delle istruzioni e coordina il lavoro degli altri elementi hardware.

ARITMETIC LOGIC UNIT (A.L.U.)Esegue i calcoli logici e matematici . La potenza dei microprocessori (a.l.u.) si misura in MIPS (MILIONI DI ISTRUZIONI PER SECONDO) .

La velocità della CPU si misura in megahertz,il lavoro è scandito da impulsi detti clock

LA POTENZA DI UN ELABORATORE SI MISURA IN MIPS ,MILIONI DI ISTRUZIONI PER SECONDO.Un processore a 32 bit vuol dire che elabora i dati a 32 bit per volta

(22)

La CPU è una risorsa attiva ,non divisibile,ma interrompibile.

Non è divisibile , come un motore non può muovere

contemporaneamente due macchine , ma è interrompibile , ossia può ripartire il suo tempo tra processi , servendone prima uno poi l’altro secondo criteri imposti dal sistema di gestione

THROUGHPUT : NUMERO DI PROCESSI SERVITI DALLA CPU NELL’ UNITA’ DI TEMPO

(23)

MONOPROGRAMMAZIONE

E’ una modalità di gestione che prevede che un solo programma alla volta stia in memoria

centrale durante l’esecuzione .

L’eccessivo spreco di tempo di CPU che resta inutilizzata a lungo , la scarsa ottimizzazione delle risorse , hanno condotto a cercare nuove soluzioni per ridurre i tempi attesa e di

ottimizzazione delle risorse.

(24)

Le interruzioni

Un’interruzione è un evento che causa la

sospensione dell’esecuzione di un processo.Si

può trattare di una interruzione esterna , come la richiesta di immissione di un dato , oppure di

una interruzione interna , come il verificarsi di un errore di esecuzione (divisione per zero),

in questo caso si parla di TRAP

(25)

Caratteristiche

introdotti per aumentare l'efficienza di un sistema di calcolo permettono ad un S.O. di "intervenire"

durante l'esecuzione di un processo utente, allo scopo di gestire efficacemente le risorse del

calcolatore ,processore, memoria, dispositivi di I/O possono essere sia hardware che software ,

possono essere mascherati (ritardati) se la CPU sta

svolgendo compiti non interrompibili

(26)

Gestione Interrupt – Panoramica Cosa succede in seguito ad un interrupt

Un segnale "interrupt request" viene spedito al processore Il processore sospende le operazioni del processo corrente salta ad un particolare indirizzo di memoria contenente la routine di gestione dell'interrupt (interrupt handler)

L'interrupt handler gestisce nel modo opportuno l'interrupt ritorna il controllo al processo interrotto (o a un altro

processo, nel caso di scheduling)

Il processore riprende l'esecuzione del processo interrotto come se nulla fosse successo

(27)
(28)

Gestione Interrupt - Dettagli

1. Un segnale di interrupt request viene spedito alla CPU

2. La CPU finisce l'esecuzione dell'istruzione corrente

3. La CPU verifica la presenza di un segnale di interrupt, e in caso affermativo spedisce un segnale di conferma al device che ha generato l'interrupt

(29)

Multiprogrammazione

Definizione: multiprogrammazione

Più programmi risiedono contemporaneamente in memoria e possono concorrere all’uso di risorse

utilizzare il processore durante i periodi di I/O di un job per eseguire altri job

Vantaggi

il processore non viene lasciato inattivo (idle) durante operazioni di I/O molto lunghe

la memoria viene utilizzata al meglio, caricando il maggior numero di job possibili

Nota

per gestire la multiprogrammazione, il S.O. deve gestire un pool ("insieme") di job da eseguire, fra cui alternare il processore

Simultaneous Peripheral Operation On-line (SPOOL)

ad esempio: print spooler

(30)

Caratteristiche tecniche:

Più job contemporaneamente in memoria

Una componente del S.O. detto

scheduler si preoccupa di alternarli nell'uso della CPU quando un job

richiede un'operazione di I/O, la CPU

viene assegnata ad un altro job.

(31)

Time-sharing

Definizione

E’ l’estensione logica della multiprogrammazione

L'esecuzione della CPU viene suddivisa in un certo numero di quanti temporali

Allo scadere di un quanto, il job corrente viene interrotto e l'esecuzione passa ad un altro job anche in assenza di richieste di I/O

I passaggi (context switch) avvengono così

frequentemente che più utenti possono interagire con i

programmi in esecuzione

(32)

S.O. time-sharing: quali caratteristiche?

Gestione della memoria

Il numero di programmi eseguiti dagli utenti può essere molto grande; si rende necessario la

gestione della memoria virtuale (non è una memoria

effettiva , ma il risultato di una opportuna gestione della

memoria reale con l’ausilio di una memoria periferica ad

accesso veloce)

(33)

La memoria virtuale

La memoria virtuale è un'estensione della memoria centrale attraverso l'utilizzo della memoria di massa. In pratica, l'estensione apparente della memoria RAM avviene

attraverso lo scambio con un'area adibita a

questo scopo nel disco fisso. Il termine inglese

swap deriva da questa continua operazione di

scambio.

(34)

Questa tecnica può essere applicata sia nell’ambito di una memoria paginata, sia nell’ambito di una memoria

segmentata. Noi esamineremo in particolare la tecnica della memoria virtuale applicata alla paginazione.

La memoria (segmentata o paginata che sia) non coincide più con la RAM ma risulta essere fisicamente allocata sulla memoria di massa; solo un sottoinsieme di questa memoria rimane nella RAM. Durante l’esecuzione di un processo, può accadere che lo stesso abbia bisogno di accedere ad una particolare pagina residente non nella RAM ma sul disco; in questo caso il SO deve prevedere un meccanismo automatico che effettui l'arresto del processo, l'ingresso della pagina mancante in memoria e la ripresa del

(35)

in questo caso la trap (detta di page fault ) non provoca un abort del processo, bensì il travaso di una pagina dalla memoria di

massa alla RAM o viceversa. Naturalmente è possibile che questo travaso, chiamiamolo

(per pura comodità) Swap in, comporti

preventivamente un trasferimento inverso, ovvero uno Swap out da RAM a disco,

perché potrebbe non esserci memoria RAM

a sufficienza per effettuare il solo Swap in.

(36)

Sistemi real-time

Definizione: sistemi real-time

Sono i sistemi per i quali la correttezza del risultato non dipende

solamente dal suo valore ma anche dall'istante nel quale il risultato viene prodotto

I sistemi real-time si dividono in:

hard real-time:

se il mancato rispetto dei vincoli temporali può avere effetti catastrofici

controllo assetto velivoli, controllo centrali nucleari, apparecchiature per terapia intensiva

soft real-time:

se si hanno solamente disagi o disservizi , programmi interattivi , programmi gestionali

N.B.

real-time non significa necessariamente esecuzione veloce

(37)

L’ASSEGNAZIONE DELLE RISORSE E LO STALLO

SI PARLA DI SITUAZIONE DI STALLO QUANDO DUE O PIU’

PROCESSI SONO IN ATTESA DI EVENTI CHE POSSONO CAPITARE PERCHE’ IN MUTUO CONFLITTO , COME AD ESEMPIO LA DISPONIBILITA’ DI UNA RISORSA (CPU O ALTRO) CHE NON PUO’ ESSERE RILASCIATA IN QUANTO ASSEGNATA AD UNO DEI PROCESSI BLOCCATI.

ESEMPIO: due processi P1 P2 richiedono le stesse risorse R1 R2 per avanzare . Se il sistema risponde ad entrambe le richieste,concedendo la risorsa R1 al processo P1 , e la risorsa R2 al processo P2 , allora

nessuno dei due processi potrà proseguire perché ognuno necessita della risorsa che è stata assegnata all’altro .

(38)

Per evitare lo stallo

prevenzione :Le risorse vengono assegnate solo quando sono tutte disponibili

fuga : Se dopo un certo tempo una risorsa non è disponibile il processo viene bloccato

Soluzione possibile (priorità dei processi )

(39)

GESTIONE DELLA MEMORIA

La memoria centrale interviene nella gestione del sistema, realizzando la funzione di magazzino di informazioni (dati e istruzioni). E’ costituita da un insieme di locazioni dette anche parole indirizzabili singolarmente.

Un programma sorgente contiene istruzioni simboliche che agiscono su aree logiche e non su aree fisiche della memoria centrale.Dovrà allora attuarsi a carico dell’S.O. Un passaggio detto ALLOCAZIONE O RILOCAZIONE tra tali istruzioni tradotte in linguaggio macchina e lo spazio fisico in memoria.

(40)

Indirizzi logici e indirizzi fisici

Spazio di indirizzamento logico

ogni processo è associato ad uno spazio di indirizzamento logico

gli indirizzi usati in un processo sono indirizzi logici, ovvero riferimenti a questo spazio di indirizzamento

Spazio di indirizzamento fisico

ad ogni indirizzo logico corrisponde un indirizzo fisico

la MMU opera come una funzione di traduzione da

indirizzi logici a indirizzi fisici Indirizzi

(41)

 La fase di rilocazione di dati e di istruzioni consiste nel far

corrispondere ad uno spazio logico (il programma) uno spazio fisico (gli

indirizzi di memoria centrale,ossia le locazioni effettive ove andranno a

risiedere istruzioni e dati).

(42)

INDIRIZZAMENTO ASSOLUTO

Si parla di rilocazione assoluta se durante la fase di compilazione del programma vengono calcolati gli indirizzi effettivi di

memoria centrale

RILOCAZIONE STATICA

Gli indirizzi effettivi vengono calcolati solo al

momento del caricamento del programma in memoria centrale per l’esecuzione e quindi possono variare da

(43)

In memoria centrale posson coesisterepiù processi , purchè lo spazio totale disponibile lo consenta .In ogni caso l’aera

occupata deve essere sempre contigua e deve essere la massima prevista per ogni processo.Questo crea uno dei

principali inconvenienti relativi alla gestione della memoria : LA FRAMMENTAZIONE. Tale situazione viene causata dal rilascio di aree liberate da processi ormai conclusi , ma che non sono recuperabili

RILOCAZIONE STATICA

(44)

RILOCAZIONE STATICA

A(12K) B(8K) C(40K)

D(2K) (2 K liberi)

Supponiamo che in una memoria con una

disponibilità di 64 k vengono allocati quattro processi A,B,C,D, rimane ancora disponibile un’area di solo 2K,non utilizzabile per un ulteriore processo E che richieda uno spazio

maggiore , esempio 12K.Alla terminazione dei processi B e D , si ottengono due

ulteriori spazi con disponibilità totale

sufficiente per il processo E , ma non utilizzabili in

quanto non su aree

A(12K) B(8K)

C(40K)

D(2K) (2 K liberi)

E(12K)

(45)

RILOCAZIONE DINAMICA

E’ caratterizzata dalla possibilità di effettuare una traduzione degli indirizzi durante l’esecuzione del processo,per riconfigurare la memoria in caso di evenienze sopraggiunte.Si tratta della

modalità più sofisticata e complessa , per ridurre

la frammentazione e recuperare aree di memoria

non contigue

(46)

LE PARTIZIONI

PARTIZIONI FISSE

• PARTIZIONI DINAMICHE

(47)

Da completare

**************

(48)

Da completare

*******************

(49)

Da completare

*******************

(50)

La funzione di ogni linguaggio è soprattutto quella di

permettere la comunicazione di messaggi ‘corretti’ da una sorgente (ente che emette il messaggio) a una destinazione (ente che lo riceve), in grado di comprenderne il

significato.

Qualunque linguaggio è caratterizzato da un alfabeto . Con questo termine si indica un insieme non vuoto di elementi detti caratteri.

Un computer per poter “capire” le istruzioni di un

programma scritto in un linguaggio ad alto livello deve

“tradurlo” in un linguaggio comprensibile alla macchina.

(51)

Introduzione sulla COMPILAZIONE e INTERPRETAZIONE

Per Compilazione PURA, si intende l' operazione attraverso la quale si sostituisce al programma originario(programma sorgente) un programma funzionalmente equivalente

scritto in linguaggio a basso livello (linguaggio macchina).

L' operazione viene eseguita in maniera statica, ovvero, prima di poter eseguire il programma, è necessario completare correttamente la fase di compilazione:

Programma Programma Dati Risultati Sorgente Oggetto FASE DI COMPILAZIONE FASE DI ESECUZIONE

Per Interpretazione PURA, si intende quando il programma originario, rimane in macchina, durante l'esecuzione,in forma originale, ed è eseguito tramite un programma (interprete) che effettua un procedimento di

interpretazione di ogni singola istruzione.

Dati Risultati

(52)

INTERPRETAZIONE

Le soluzioni Compilazione/Interpretazione pure,offrono vantaggi e svantaggi

contemporaneamente.Nella compilazione, si ha la difficoltà che bisogna, per effettuare delle

modifiche, disporre del programma originario, per poi compilarlo e quindi lanciarlo in

esecuzione; al contrario, l' interprete, permette molta più flessibiltà in quanto consente di

individuare facilmente eventuali errori semantici

e di correggerli immediatamente.

(53)

Per quanto riguarda la velocità di esecuzione,

utilizzando dei compilatori, avremo una efficenza molto

maggiore che nel caso di interpreti, con in più anche la sicurezza che non si verifichino errori sintattici durante

l'esecuzione. Esiste anche la possibilità di adottare una soluzione mista, ovvero di poter definire un linguaggio intermedio, ottimizzato per

l'interpretazione da parte di un opportuno

programma (run time executor). In questo caso, infatti, si otterranno tutte le garanzie date dalla

compilazione, si migliorerà l'efficenza in fase di interpretazione e, sicuramente si ottimizzeranno gli ingombri del programma oggetto, in quanto le primitive ricorrenti saranno contenute nel Run-

Time.

(54)

La generazione del linguaggio intermedio, permette anche di poter utilizzare linguaggi diversi che

utilizzino un unico run-time, consentendo al programmatore di scrivere programmi per una

stessa procedura, utilizzando il linguaggio che più si adatta per ogni situazione.

A questo punto, qualcuno potrebbe chiedersi se esistano dei procedimenti di traduzione

(procedimento statico: ogni componente al livello i, viene SOSTITUITO da un insieme di

componenti al livello j) o interpretazione

(55)

(procedimento dinamico: non avviene la sostituzione , ma possono coesistere elementi appartenenti

al livello i ed al livello j) che permettano di definire i meccanismi al livello i tramite politiche al livello j.

Per chiarire meglio questa posizione, cerchiamo di focalizzare opportunamente cos'é un Linguaggio Generalizzato.

Facendo riferimento alle situazioni pratiche, possiamo individuare come Linguaggio Generalizzato, sia

Pacchetti Applicativi, sia i linguaggi di programmazione, sia i Sistemi di comunicazione con altri sistemi e/o

strumenti. Secondo questa definizione, il senso della relazione gerarchica va individuato essenzialmente al tempo di

esecuzione (RUN-TIME).

(56)

Possiamo associare, in definitiva, ad ogni

livello virtuale MVi un "supporto a tempo di esecuzione" (runtime- support) di Li, che chiameremo RTS(Li). In definitiva, un

RTS(Li) può essere visto come una libreria di algoritmi e strutture dati, implementati utilizzando l'insieme dei livelli Mvj (0<j<i), atti ad eseguire i meccanismi di Li.

Possiamo a questo punto dare una prima definizione di ARCHITETTURA di

SISTEMA, riferendoci alla

(57)

Questa fa se di traduzione si chiama compilazione.

Un compilatore converte un programma o un segmento di programma scritto in un linguaggio ad alto livello in un modulo oggetto in codice macchina.

FASI DELLA COMPILAZIONE

1. ANALISI LESSICALE 2. ANALISI SINTATTICA 3. ANALISI SEMANTICA 4. GENERAZIONE DEL C

(58)

Bibliografia

**********

**********

*********

*********

*********

*********

*********

Riferimenti

Documenti correlati

• Una variabile dichiarata in una certa funzione è locale a quella funzione: non può essere utilizzata direttamente fuori dalla funzione in cui è stata definita e viene distrutta non

Per introdurre questa caratteristica nella funzione, utilizziamo un nuovo puntatore t a lelem su cui salviamo l’indirizzo della struct che deve essere eliminata, quindi, dopo

2.1 Il processo di deterritorializzazione - Il processo di deterritorializzazione, ovvero di destrutturazione delle relazioni territoriali pre-esistenti e di

•  Nella progettazione di un algoritmo il programmatore inizia a porsi problemi relativi alla rappresentazione delle informazioni che deve essere efficiente (senza sprechi

| Un algoritmo viene valutato facendolo operare su una particolare stringa di riferimenti alla memoria e calcolando il numero di page fault.. | In tutti i nostri esempi la stringa

Se abbiamo un sistema numerico a dieci simboli, quante combinazioni diverse possiamo formare utilizzando ad esempio due sole cifre.. 11, 12, 45,

La sentenza sopra indicata affronta il delicato problema dell’accertamento della sussistenza di un collegamento sostanziale tra due o più imprese partecipanti alla medesima

La consapevolezza di essere riusciti a raggiungere il nostro scopo ci rende soddisfatti, perché per il nostro laboratorio risulta importante sapere di essere in grado