Newsgroup: it.comp.lang.c++
Titolo: Utilizzo delle strutture in una funzione

 
Riprendendo l'esercizio suggerito in un altro thread, ho provato a
scrivere una funzione che restituisce resto e divisione con l'uso
delle strutture:
 
=======================================
#include <iostream>
 using namespace std;
 
  struct operazione { // dichiarazione globale
  int div;
  int resto;
} operdiv;
 
 
void divisione (int a, int b, operazione &div_e_resto)
 {
 
 
  div_e_resto.div = a/b;
  div_e_resto.resto = a%b;
 
   }
 
 
int main ()
 
{
 
 divisione(9,5,operdiv);
 
 cout << "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
 return 0;
 
}
 
 
=================================================
 
 
oppure:
 
 
===================================================
 
#include <iostream>
 using namespace std;
 
 
 
  struct operazione { // dichiarazione globale
  int div;
  int resto;
} operdiv;
 
 
void divisione (int a, int b) {
 
 
  operdiv.div = a/b;
  operdiv.resto = a%b;
 
 
   }
 
 
int main ()
 
{
 
operdiv.div=0;
operdiv.resto=0;
 
 divisione(9,5);
 
 cout << "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
 return 0;
 
}
 
=================================================
 
ma sia nel primo programma che nel secondo mi sono accorto che la
*struttura e' dichiarata a livello globale*...e mi sono ricordato che,
per discorsi gia' affrontati,  l'uso delle variabili globali e' da
evitare....ma probabilmente non e' con nessuno dei predetti programmi
il modo migliore per risolvere l'esercizio con le strtture?
 
Ciao e grazie mille!
 

 
 
Ciao!


....prima che leggessi il tuo post, avevo provato con:
 
divisione(9,5,operazione operdiv)
 
...ma la chiamata ad una funzione, NON prevede la dichiarazione delle
variabili al suo *interno* (a differenza della funzione chiamata),
pero', questo aspetto, non mi sembra venga spiegato in modo esplicito
al link:
 
http://www.cplusplus.com/doc/tutorial/functions/
 
 
....o mi sbaglio??
 
Ciao e grazie mille!

 
 
Conoscendo un po' come funzionano parser/compilatori la risposta sarebbe
veramente facile, ma cerco di darti un'idea immediata di perché, anche se
funzionasse, non sarebbe per nulla utile :)
 
Le cose da prendere in considerazione sono due:
 
1- La prima è abbastanza facile:
Come spero saprai, in C++ una variabile è definita solo nel suo scope; per fare
un esempio scemo:
while (i<10) {
 int j;
 /* varie operazioni con j */
}
/* ??? cos'è j? qui non è definita! */
 
2- La seconda riguarda come le funzioni vengono chiamate in C/C++
Se fai qualcosa come:
my_function(a, b, min(c, d));
Prima viene calcolata la funzione min e poi, una volta che abbiamo il valore di
ritorno, viene chiamata la funzione passando i tre valori.
 
Se fin qui è tutto chiaro, mettiamo insieme i pezzi.
- quando scrivi: "operazione operdiv" d'accordo, definisci una variabile, ma
che valore di ritorno ha quest'espressione? In C++ nessuna.
- anche se ritornasse, mettiamo, la variabile dichiarata, che scope avrebbe?
Beh, quello interno alla definizione della funzione; il che vuol dire che, una
volta finita la chiamata a funzione, la variabile non sarebbe più accessibile.
 
Per cui, non solo non funziona per definizione del linguaggio, ma anche se
lo facesse sarebbe di pochissima utilità!
 
Mi sono dilungato un sacco, spero almeno si capisca tutto!
Ciao!

 Mi sono dilungato un sacco, spero almeno si capisca tutto!
 
Ti rigrazio per la disponibilita' e competenza!
 
Ciao
 

 
 
E questo invece è il punto (2), ovvero la dichiarazione di una variabile
non ha un valore di ritorno.
 
Se "fosse" o "non fosse" è un discorso di poco senso, perché bisognerebbe
andare a guardare altri linguaggi che permettono una sintassi simile.. il
C++ risolve facilmente definendo i blocchi con le graffe e le dichiarazioni
come non facenti parte degli [l-r]-value, cosa che i parametri di funzione
devono essere.
 
Ciao!


NON capisco cosa intendi per  [l-r]-value?
 
PS
*Quando ti e' possibile* puoi dare uno sguardo al thread "Passaggio di
array a funzione" dove chiedo un chiarimento per gli array
multidimensionali?
 
 
Ciao e grazie mille!
 


 
 
-- 
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
 

 
 
L'ho fatto, e ho pure scritto! In quel thread comunque hanno partecipato 
persone molto più skill-ate di me, per cui il mio intervento è superfluo ;)
 
Ciao!

 sperando che siano validi.
 
Mazziate pure....io NON mi arrendo! :-)
 
....pero' una bozza, se pur semplice e con qualche imprecisione, di
programma con le strutture sono riuscito a scrivere: sono proprio
sottozero?
 
Ciao e grazie milleeeeee!
 
 


Sto visualizzando, con google-groups, il thread: "Passaggio di array a
funzione", mi riferisco al mio  post N°42.....
 
Ciao e grazie milleeeeee!
 
 
 
 

 
 
Dai che vai bene.
 
E, a proposito, quand'è che hai l'esame? No perché se lo passi devi a tutti 
una bevuta! ;)
 
Ciao!


Non è un gran che come riferimento, anch'io uso google groups ma mi dice che
su quel thread ci sono 41 post in totale, e te hai scritto molto, per cui è
difficile capire quale intendevi.
Se è una domanda diversa rispetto all'oggetto iniziale ti conviene aprire un
nuovo thread, almeno chi (come me) ha lasciato la discussione a parte perché
pensa di essere di poco aiuto può dire la suo senza dover seguire tutto il
discorso - altrimenti meglio lasciar parlare chi sta seguendo quel ramo..
 
Ciao!

 una bevuta! ;)
 
:-)
 
Corso (due ore di lezione al giorno per 3 volte a settimana) iniziato
a Marzo, prevista fine verso meta' Giugno....ll prof. titolare viene
raramente a lezione: quasi sempre manda i suoi assistenti( almeno
credo siano i suoi assistenti)....la prima volta che si e' presentato
in aula, ha assegnato un programma poi e' andato a fumarsi una
sigaretta, ritorna e chiede:
 
<Avete fatto il programma?"...NOOOO??...*azzi vostri, andiamo avanti>
 
...ecco, questo e' uno dei motivi per cui mi sono rifugiato in questo
ng. ;-)
 
PS
NON ancora deciso quale esame daro' per primo tra Analisi mat. II,
Fisica I e Programmazione.
 
Ciao e grazie mille!

 Ciao e grazie mille!
 
 


 
 
PS
Eh, dipende da come sei preparato..
Il mio primo anno di università (a Pisa, anno 2000) ho fatto Informatica I al
primo appello (30), Matematica (che era analisi I e un quasi tutta analisi II)
a Giugno (28) e Fisica (che era Fisica I e II, insieme) l'ho data 5 volte
prima di riuscire a passarla: me la sono cavata con un 23 e tanti insulti :(
Dopo tutte le nottate passate a studiare quella materia del ca**o.. non mi
scorderò le equazione di Maxwell per tutto il resto della vita.
Oltretutto mi bloccava Elettrotecnica (e quindi Elettronica Digitale, che
sapevo a menadito) per cui ho praticamente perso quasi un anno..
Quindi, fosse per me, ti direi di dare Fisica il prima possibile! :D
 
Ciao!

 delle strutture:
 
Nessuna delle due interfaccie che hai proposto � ideale. Oltretutto
le implementazioni sono errate perch� non tengono conto della divisione
per zero che in C++ genera comportamento indefinito, cio� sei fortunato 
se ti va in crash il programma.
 
Usa:
 
operazione divisione(int a, int b) {
    if (!b)
       throw std::invalid_argument("divisione per 0!");
    return {a / b, a % b};
}
 
operdiv = divisione(4, 3);
 

 operdiv = divisione(4, 3);


 novità ?
 
E' una novità di C++11, il costrutto prende il nome di "braced
initialization" che insieme alla "list initialization" rende
praticamente uniforme la modalità di inizializzazione di oggetti
di vario tipo: infatti tutti i contenitori standard sono stati adatti
per l'inizializzazione tramite lista.
 
Nel tuo caso, volendo appunto inizializzare un temporaneo con graffe,
l'espressione che hai scritto non è valida perchè provi
a convertire "std::initializer_list<int>", che è il tipo dedotto di
"{quoz, resto}", in "operazione" che non supporta l'inizializzazione
tramite lista. Quindi si sarebbe dovuto invece scrivere:
 
operazione{quoz, resto}.DeduciNumero();
 
Ripeto in altre parole:
 
(operazione){4, 3}.DeduciNumero();
 
può essere valida se solo se definisci per "operazione" un costruttore
valido che accetti "std::initializer_list<int>", ma non ha praticamente
alcun senso per il tipo "operazione", non essendo un contenitore.
 

 alcun senso per il tipo "operazione", non essendo un contenitore.
 
certo, era solo un esempio tirato per capire se il 
linguaggio era stato esteso dal nuovo standard. E così è


 di default, ma che si invoca con le graffe !
 
Esatto. In genere, si dovrebbe preferire questo modo per
l'inizializzazione di un oggetto, perchï¿œ ï¿œ piï¿œ sicuro, in quanto
vieta volutamente conversioni implicite di tipo, che a volte sono
indesiderate.
 

 operdiv = divisione(4, 3);
 
NON ho ben capito....."divisione" e' una funzione che ritorna i
due valori?
 
Inoltre, dove si inseriscono nel programma le istruzioni che
suggerisci per estrarre i dati richiesti: a/b e a%b?
 
Ciao e grazie milleeeeeeee!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 suggerisci per estrarre i dati richiesti: a/b e a%b?
 
https://ideone.com/qLgdsI
 
 
 


Molto interessante!!....anche se, al momento, le classi e' un
argomento che e' stato solo accennato ...ho trovato questo
tutorial(oltre quello che hai suggerito) per il c++:
 
http://www.learncpp.com/
 
 
....sembra piu' approfondito rispetto al:
 
http://www.cplusplus.com
   (di cui hai dato parere negativo)
 
PS
Sono in attesa che arrivi lo Stroustrup.
 
Ciao e grazie mille!
 
 
 
 
 

 tutorial(oltre quello che hai suggerito) per il c++:
 
Ho dato uno sguardo al lik:
 
http://www.cplusplus.com/reference/stdexcept/invalid_argument/?kw=invalid_argument
 
 
mi sembra di capire che la gestione dell'errore avviene attaverso i
blocchi try  e catch ...noto che .e' differente, la gestione
dell'errore rispetto al tuo esempio dove hai usato throw...pero',
come  gia' detto, le classi, sono un argomento di cui si e' parlato,
almomento, solo teoricamente a lezione.
 
Ciao e grazie milleeee!
 

 almomento, solo teoricamente a lezione.
 
 
Seguendo l'esempio al link:
 
http://www.cplusplus.com/doc/tutorial/exceptions/
 
 
...ho provato:
 
===============================================
 
#include <iostream>
 
using namespace std;
 
struct operazione {
  int div;
  int resto;
 
} ;
 
operazione divisione(int a, int b) {
   if (!b)
    try
   {
      throw b ;
   }
 
   catch (int e){
 
   cout<< "Errore, divisione per: "<<e;
   }
 
   return {a / b, a % b};
}
 
int main () {
 
 operazione operdiv;
 operdiv = divisione(9, 0);
 
 cout << "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
}
 
 
==================================================
 
...se ho ben capito ottengo lo stesso risultato per la gestione
dell'errore ma senza ricorrere alle classi...infatti non ho utilizzato
la libreria:
#include <stdexcept>.
 
Ciao e grazie mille!
 


 
 



Ho fatto qualche prova come suggerisci ma non ho ottenuto i risulatti
voluti.....ho trovato un esempio al link:
 
http://www.matteolucarelli.net/opendev/appunticpp.htm
 
 
ma non ho capito l'utilizzo del puntaore char*.
 
Ciao e grazie mille!
 
 
 


 
 


 > ma non ho capito l'utilizzo del puntaore char*.
 
Se ho ben capito quanto hai suggerito, occorre inserire il calcolo
della divisione direttamente al'interno del blocco Try senza usare il
controllo if inserito nel precedente programma:
 
 
=======================================
 
#include <iostream>
 
using namespace std;
 
struct operazione {
   int div;
   int resto;
 
} ;
 
operazione divisione(int a, int b) {
 
     try
    {
       throw return {a / b, a % b};
    }
 
   catch (int e){
 
   cout<< "Errore, divisione per: "<<e;
    }
 
 
 
}
 
int main () {
 
 operazione operdiv;
  operdiv = divisione(9, 0);
 
 cout << "Risultato_div=" << operdiv.div << endl;
  cout << "Resto=" << operdiv.resto << endl;
 
}
 
 
============================================
 
....ma viene generato errore "C:\Users\\Desktop\prova\main.cpp|15|
error: expected primary-expression before 'return'|alla riga" per
l'struzione:
 
 throw return {a / b, a % b};
 
Inoltre NON conosco come verficare se, effettivamente, l'errore
generato e' un intero... istruzione: catch(int e).
 
Un esempio di gestione errori e' riportato al link :
 
http://www.matteolucarelli.net/opendev/appunticpp.htm
 (*vedi gestioni
delle eccezzioni*)
 
ma non mi e' chiaro, nell'es. al predetto link, l'utilizzo del
puntatore char*: puoi darmi qualche delucidazione a riguardo?
 
Ciao e grazie milleeee!!!
 
 

 Ciao e grazie milleeee!!!


 >
http://www.matteolucarelli.net/opendev/appunticpp.htm(*vedi
 gestioni

Ho provato, sulla base dell'ultimo es. al link:
 
http://www.matteolucarelli.net/opendev/appunticpp.htm
 (*vedi gestioni
delle eccezzioni*)
 
========================================================
 
#include <iostream>
 
using namespace std;
 
struct operazione {
   int div;
   int resto;
 
} ;
 
operazione divisione(int a, int b)throw(char*)  {
 
if ( b==0) throw "Divisione per zero";
 
return {a / b, a % b};
 
 
}
 
int main () {
 
 operazione operdiv;
 
try{
 
operdiv = divisione(9, 0);
 
}
 
 catch (char* message) {
 
 cout<< message ;
 }
 
 cout << "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
}
 
===========================================================
 
ed ottengo il seguente errore in fase di esecuzione:
 
"terminate called after throwing an instance of 'char const*'
 
This application has requested the Runtime to terminate it in an
unusual way.
Please contact the application's support team for more information.
 
Process returned 3 (0x3)   execution time : 2.402 s
Press any key to continue."
 
 
Inoltre ho un dubbio sull'uso del puntatore char* message, che
dovrebbe intercettare la stringa "Divisione per zero".
 
Mi spiego:
 
char* message, definisce definisce un puntatore (punta ad un indirizzo
di memoria) ad un tipo di variabile char.
 
Ma il tipo char puo' contenere *un solo carattere*, ad es. char car
='A' ; .....nel nostro caso, "Divisione per zero" e' un *tipo string*
e non char.
 
Inoltre , essendo char* message un puntatore non dovrebbe restituire
un indirizzo di memoria?....per avere il contenuto (deferenziare)
dovrei avere *message.
 
Scusa per la probabile banalita' delle domande, ma molti concetti,
come hai gia' capito, NON mi sono chiari e, sui puntatori, ancora non
ho molta dimistichezza.
 
Inoltre, le classi e la programmazione ad oggetti  sono state
introdotte solo teoricamente (senza fare esempi ed esercizi), per cui,
esempi di codice con le classi ed eventuale gestione degli errori ho
difficolta' a comprenderli.
 
Ciao e grazie mille!
 
 
 
 
 
 
 
 
 
 

 Ciao e grazie mille!


 cui accenna. A te serve il manuale completo
 
Sono in attesa dello Stroustrup.....ho trovato questo sito:
 
http://www.learncpp.com/
 
 
...sembra piu' approfondito rispetto al sito:
 
http://www.cplusplus.com/
 
 
Cosa ne pensi?
 
Ciao e grazie mille per la disponibilita' e  tempestivita' delle
risposte!
 
 

 const char * const
 
Provando ad inserire  "const char const *"  nel seguente modo:
 
==========================================
#include <iostream>
 
using namespace std;
 
struct operazione {
   int div;
   int resto;
 
} ;
 
operazione divisione(int a, int b)throw(const char const*)  {
 
if ( b==0) throw "Divisione per zero";
 
return {a / b, a % b};
 
 
}
 
int main () {
 
 operazione operdiv;
 
try{
 
operdiv = divisione(9, 0);
 
}
 
 catch (const char const* message) {
 
 cout<< message <<endl;
 }
 
 cout << "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
}
 
==============================================
 
ottengo l'errore: " C:\Users\\Desktop\prova\main.cpp|12|error:
duplicate 'const'|
C:\Users\Desktop\prova\main.cpp||In function 'int main()':|
C:\Users\Desktop\prova\main.cpp|31|error: duplicate 'const'|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|
"
 
 
 
Provando con "const char *" (oppure con "const char * const" ):
 
================================================
#include <iostream>
 
using namespace std;
 
struct operazione {
   int div;
   int resto;
 
} ;
 
operazione divisione(int a, int b)throw(const char *)  {
 
if ( b==0) throw "Divisione per zero";
 
return {a / b, a % b};
 
 
}
 
int main () {
 
 operazione operdiv;
 
try{
 
operdiv = divisione(9, 0);
 
}
 
 catch (const char * message) {
 
 cout<< message <<endl;
 }
 
 cout << "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
}
 
=====================================
 
ottengo:
 
" Divisione per zero
 Risultato_div=-1441189135
 Resto=-2
 
Process returned 0 (0x0)   execution time : 0.107 s
Press any key to continue. "
 
In pratica, * se ho ben capito*,  viene eseguito il blocco catch, ma
il *programma NON si interrompe* e vengono cmq valutate le successive
istruzioni che restituiscono :
 
 Risultato_div=-1441189135
 Resto=-2
 
Cosa ne pensi?
 
Ciao e grazie milleeeeee!
 
 

 Ciao e grazie milleeeeee!



OK...ma nel caso in esame, volendo fare in modo di NON visualizzare
Risultato_div e Resto,  dopo l'istruzione nel catch:
 
cout<<  message<<endl;
 
dovrei inserire una istruzione che interrompe il programma e non
prosegue: giusto?...quale istruzione e' piu' idonea per ottenere cio'?
 
Quando invece suggerisci:
 
" nel blocco catch avresti ad es. dovuto impostare come opportuno
i valori della struct. "
 
....ma  in caso di errori, i valori della struct non sono definiti,
potrei impostarli a zero nel catch()
 
operdiv.div =0;
operdiv.resto =0;
 
e poi visualizzarli con le successive istruzioni, cioe':
 
=============================================================
 
#include <iostream>
 
using namespace std;
 
struct operazione {
   int div;
   int resto;
 
} ;
 
 
operazione divisione(int a, int b)throw(const char *) {
 
if ( b==0) throw  "Errore div. 0.";
 
return {a / b, a % b};
 
 
}
 
int main () {
 
 operazione operdiv;
 
try{
 
operdiv = divisione(9, 0);
 
}
 
 catch(const char * message)  {
 
operdiv.div =0;
operdiv.resto =0;
 
cout<< message <<endl;
 
  }
 
 cout <<endl<< "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
return 0;
 
}
 
================================================================
 
Ciao e grazie milleeee!!
 
 


Inoltre per quanto mi hai suggerito:
 
"Il costrutto throw devi usarlo per trasmettere uno stato di
 eccezione, o RItrasmetterla allorquando non hai saputo
 gestirla localmente.
 
Però non sei l'unico che possiede facoltà di lanciare
 eccezioni. In questo caso non devi SOLLEVARE nessuna
 eccezione, perché di norma il tuo calcolo non è una
 divisione per zero. *Lascia che sia il runtime a lanciarla, e
 la intercetterai."*
 
..se ho ben capito, la gestione degli errori, nel caso in esame,
dovrebbe essere fatta senza l'uso di throw, cioe' e' il runtime che
lancia l'errore:
 
 
=========================================================================
 
 
#include <iostream>
 
using namespace std;
 
struct operazione {
   int div;
   int resto;
 
} ;
 
 
operazione divisione(int a, int b){
 
 
return {a / b, a % b};
 
}
 
int main () {
 
 operazione operdiv;
 
try{
 
operdiv = divisione(9, 0);
 
}
 
 
 catch(...)  {
 
operdiv.div =0;
operdiv.resto =0;
 
cout<< "Errore, div. 0" <<endl;
 
  }
 
 cout <<endl<< "Risultato_div=" << operdiv.div << endl;
 cout << "Resto=" << operdiv.resto << endl;
 
return 0;
 
===================================================================
 
...ma il cath(...) generico NON viene eseguito in quanto, se ho ben
capito, deve *sempre* essere preceduto da altri catch() che
intercettano il tipo di dato dell'errore...pero' NON saprei come
procedere.
 
Ciao e grazie milleeee!!
 
 
 
 
 
 
 
 

 Ciao e grazie milleeee!!


 
[cut]
 
OK...ma ritornando al seguente caso:
 
================================================
 #include <iostream>
 
using namespace std;
 
struct operazione {
    int div;
    int resto;
 
} ;
 
operazione divisione(int a, int b)throw(const char *)  {
 
if ( b==0) throw "Divisione per zero";
 
return {a / b, a % b};
 
}
 
int main () {
 
 operazione operdiv;
 
try{
 
operdiv = divisione(9, 0);
 
}
 
 catch (const char * message) {
 cout<< message <<endl;
 
 
  }
 
 cout << "Risultato_div=" << operdiv.div << endl;
  cout << "Resto=" << operdiv.resto << endl;
 
}
 
===========================================
 
...quale istruzione posso inserire nel catch() per fare in modo che le
successive istruzioni:
 
  cout << "Risultato_div=" << operdiv.div << endl;
  cout << "Resto=" << operdiv.resto << endl;
 
 
 ...NON vengano eseguite?
 
Ho provato  questa istruzione 
http://www.cplusplus.com/reference/cstdlib/abort/
 
:
 nel catch:
 
abort();
 
...ed in effetti il l'esecuzione del programma si interrompe ma prima
mi compare cmq la classica finestra di Windows con il msg: " Il
rpogramma ha smesso di funzionare...".
 
Ciao e grazie mille!

 Ciao e grazie mille!


 rilasciata la memoria dinamica con i vari modi.
 
In effetti, utilizzando ( 
http://www.cplusplus.com/reference/cstdlib/exit/?kw=exit
:
)
 
 
exit (EXIT_FAILURE);
 
oppure:
 
exit (EXIT_SUCESS);
 
non compare la finestra di windows con il msg di errore..
 
...nel mio caso, sarebbe indifferente utilizzare una delle suddette,
cambierebbe solo il valore return (1 o 0)?
 
Ciao e grazie mille!


Fallo cosi che è piu logico:
 
#include <iostream>
using namespace std;
 
struct operazione {
     int div;
     int resto;
 
} ;
 
operazione divisione(int a, int b)throw(const char *)  {
	if ( b==0) throw "Divisione per zero";
	return {a / b, a % b};
}
 
int main () {
try{
	operazione operdiv= divisione(9, 0);
  	cout << "Risultato_div=" << operdiv.div << endl;
   	cout << "Resto=" << operdiv.resto << endl;
	return 0;
}
catch (const char * message) {
  	cout<< message <<endl;
   }
return 1;
 
}
 

 > In effetti, utilizzando (
http://www.cplusplus.com/reference/cstdlib/exit/?kw=exit
:

OK, grazie mille!
 
Interessante e' la gestione dell'errore suggerita da Luca Risolia in
questo thread:
 
operazione divisione(int a, int b) {
     if (!b)
        throw std::invalid_argument("divisione per 0!");
     return {a / b, a % b};
 
}
 
...le classi pero', e' un argomento che e' stato solo affrontato
teoricamente a lezione.
 
Ciao!

 }
 
Un modo alternativo è usare boost::optional, quando si vuole non obbligare il 
chiamante a gestire l'eccezione:
 
boost::optional<operazione> divisione(int a, int b) {
	return b ? operazione{a / b, a % b} : optional<operazione>{};
}
 
int main() {
	auto risultato =  divisione(9, 4);
	if (risultato)
		std::cout << "quoziente: "
		     << risultato.get().quoziente
		     << " resto: " << risultato.get().resto
		     << '\n';
}
 
http://www.boost.org/doc/libs/1_53_0/libs/optional/doc/html/index.html
 
 

 if ( b==0) throw "Divisione per zero";
 
Lanciare un'eccezione di tipo const char* o altro tipo non derivato da 
std::exception non è buona prassi in generale, perchè obbliga il chiamante a 
fare assunzioni specifiche sul significato dell'eccezione lanciata.
 


Perfetto, Osvald avrà di che lavorare per perfezionare il programma
 
P.S.:comunque il sottoscritto ma non ha mai usato (nei suoi programmi) 
nè il caso 1 o 2