DOMANDA C++: esercizio con funzione

tomm891

Utente Attivo
355
136
CPU
i5 9600k
Dissipatore
Corsair H55i
Scheda Madre
Asus Tuf z390m
HDD
Samsung
RAM
16GB HyperX
GPU
MSI GTX980ti
PSU
Cooler Master G750m
Case
Corsair Air 240
OS
Windows 10 Pro

MPG

Utente Attivo
544
4
MI pare come ho scritto io in pratica......
Hai ragionissima. Avevo letto male.

Io farei così: (testato e funzionante) mi sono permesso di rinominare qualche variabile

C++:
#include <iostream>

//Passo le referenze delle due variabili che voglio settare e imposto i loro valori dentro alla funzione
void setCalcoloNetto(double totale, double& netto, double& iva)
{
    iva = (100 * totale) / 122; //l'iva è al 22!
    netto = totale - iva;
}

int main()
{
    double iva;
    double totale;
    double netto;

    totale = 2000; //setto un totale iniziale es. 2000 euro.

    setCalcoloNetto(totale, iva, netto);

    std::cout << "netto=" << netto << ", iva=" << iva << std::endl;
}


Ma cosa cambia dal mio code?? Insomma come caspita va bene questo esercizio??? Andretti60 non hai detto nulla a Tomasov ma nel mio dici che non è giusto....

C++:
#include <iostream>


using namespace std;

void IvaCompresa(const double t, double &i,double &n)

{

n=(100 * t) / 120;
i=t-n;


}


int main()
{
    double totale;
    double netto;
    double iva;
    cin>>totale;
IvaCompresa(totale,iva,netto);
cout<<netto<<endl<<iva;



}
 
Ultima modifica:

tomm891

Utente Attivo
355
136
CPU
i5 9600k
Dissipatore
Corsair H55i
Scheda Madre
Asus Tuf z390m
HDD
Samsung
RAM
16GB HyperX
GPU
MSI GTX980ti
PSU
Cooler Master G750m
Case
Corsair Air 240
OS
Windows 10 Pro
MI pare come ho scritto io in pratica......



Ma cosa cambia dal mio code?? Insomma come caspita va bene questo esercizio??? Andretti60 non hai detto nulla a Tomasov ma nel mio dici che non è giusto....

C++:
#include <iostream>


using namespace std;

void IvaCompresa(const double t, double &i,double &n)

{

n=(100 * t) / 120;
i=t-n;


}


int main()
{
    double totale;
    double netto;
    double iva;
    cin>>totale;
IvaCompresa(totale,iva,netto);
cout<<netto<<endl<<iva;



}

Si il tuo codice è giusto. (con il void) Inizialmente avevo capito un problema diverso. sul cin>> andrebbe messo un messaggio per dire all'utente di inserire un dato.. ma va :D
 

MPG

Utente Attivo
544
4
No.
1) Leggi bene it testo del problema: la funzione deve calcolare e tornare DUE valori.
2) un metodo definito void significa che non ritorna un bel nulla.

TI richiedo : visto anche quello che ha scritto Tommasov che è uguale al mio in pratica mi dici dove sbagliamo a questo punto e la correzione ? Grazie.
 

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Scusate se mi intrometto. Aggiungo anche che non sono un programmatore e che non so programmare. Ma c'è tanta confusione in questo thread! Mi è venuto il mal di testa durante la lettura.
A vista, il primo codice postato aveva cose buone, ma anche dei difetti: la funzione IvaCompresa non ha il return, e non serve che si passino come argomenti tutte e tre le variabili, basta il solo prezzo di vendita. Inoltre, secondo la traccia, deve ritornare due valori, il prezzo ante iva e l'iva. Quindi, suppongo, i due valori ottenuti andranno assegnati a delle variabili che poi verranno stampate a video.
L’ipotesi richiede di ritornare due valori da una funzione. Anche se non sei un programmatore sai che in matematica una funzione associa ad ogni elemento uno ed un solo elemento, perciò è necessario o ritornare un array o un oggetto con due double membri per risolvere il problema, oppure come in questo caso con reference (o puntatori).

Il codice è corretto, ma se magari dopo tutto ciò si riesce anche a scrivere il codice in una maniera decente non sarebbe male, anche perché l’IDE e il Tab fanno tutto da soli...
 

clessidra

Utente Attivo
766
272
CPU
VIA C3
GPU
Ati Rage
OS
linux - Red Hat 1.1
Io non so cosa sono i puntatori :skept:, e nemmeno lo voglio sapere.
 

Mursey

Super Moderatore
Staff Forum
Utente Èlite
8,246
5,675
IDE e Tab?? cosa intendi?
Cosa usi per scrivere il codice ?

Se usi un IDE hai un bel pò di funzionalità che ti aiutano anche ad indentare il codice (cosa che non hai ancora fatto nonostante i nostri consigli), se usi notepad puoi andare di spazi o tab...
 
  • Mi piace
Reazioni: _Achille

Andretti60

Utente Èlite
6,440
5,091
TI richiedo : visto anche quello che ha scritto Tommasov che è uguale al mio in pratica mi dici dove sbagliamo a questo punto e la correzione ? Grazie.
Te lo hanno gia' detto gli altri, all'inizio hai dichiarato una funzione "double" ma non ritorni nessun valore, poi hai corretto dichiarandola "void".
 

pabloski

Utente Èlite
2,868
916
TI richiedo : visto anche quello che ha scritto Tommasov che è uguale al mio in pratica mi dici dove sbagliamo a questo punto e la correzione ? Grazie.

In pratica ti stanno dicendo due cose.

Primo, l'esercizio dice che devi scrivere una funzione che ritorna due elementi ( netto e iva ). Alla lettera significa che dovrebbe esserci un
C++:
return netto,iva;

In C++ non esiste questa cosa ( in altri linguaggi si ). Quindi puoi usare un trucco e restituire una struct, un oggetto, un vettore, una map. Ma onestamente ( a parte forse la struct ) è assurda anche solo pensare di doversi arrampicare su simili specchi per ritornare due banali numeretti.

Se non presa alla lettera, quella specifica ti dice di fare come hai fatto tu. Cioè due parametri della funzione sono passati per riferimento, in modo che la funzione possa accedere alle rispettive variabili nello scope del main. In questo modo la funzione modifica direttamente le variabili nel main e il main ottiene così i due risultati che gli servono.

Ma in questo caso, il parametro di ritorno della funzione non ha proprio senso. Cioè scrivere

C++:
float IvaCompresa(const double t, double &i,double &n)

che senso avrebbe? Tanto comunque non ritorni niente ( col return ).

Ed è questa la seconda cosa che ti stanno dicendo. Cioè, visto che non ritorni niente tramite il normale meccanismo di ritorno delle funzioni, definisci una funzione void ( cioè una procedura ).
 
  • Mi piace
Reazioni: Mursey

Andretti60

Utente Èlite
6,440
5,091
... . Cioè, visto che non ritorni niente tramite il normale meccanismo di ritorno delle funzioni, definisci una funzione void ...
Permettimi una piccola precisazione. C’è differenza tra il valore di ritorno di una funzione e i possibili valori di ritorno di una funzione, in quanto se passi i parametri per riferimento anziché per valore (cosa che si può fare in quasi tutti i linguaggi, anzi in certi è il metodo di default) tali parametri possono essere cambiati dalla funzione. Infatti è quello che si fa in genere, solitamente una funzione viene dichiarata o booleana o intera, e il valore di ritorno è un "codice" che rappresenta il risultato della operazione, equivalente a un codice di errore. Eventuali "valori di ritorno" sono parametri che vengono passati come riferimento. Questo è tipico per esempio delle API scritte per linguaggi che non hanno un meccanismo try/catch per catturare gli errori a runtime.
 
  • Mi piace
Reazioni: _Achille e Mursey

pabloski

Utente Èlite
2,868
916
Permettimi una piccola precisazione. C’è differenza tra il valore di ritorno di una funzione e i possibili valori di ritorno di una funzione, in quanto se passi i parametri per riferimento anziché per valore (cosa che si può fare in quasi tutti i linguaggi, anzi in certi è il metodo di default) tali parametri possono essere cambiati dalla funzione. Infatti è quello che si fa in genere, solitamente una funzione viene dichiarata o booleana o intera, e il valore di ritorno è un "codice" che rappresenta il risultato della operazione, equivalente a un codice di errore. Eventuali "valori di ritorno" sono parametri che vengono passati come riferimento. Questo è tipico per esempio delle API scritte per linguaggi che non hanno un meccanismo try/catch per catturare gli errori a runtime.

Che abbiamo dovuto fare negli anni per bypassare le limitazioni del C/C++ :D

Però mi chiedo cosa ne pensano i puristi dell'assimilare i parametri passati per riferimento ai valori di ritorno. Cioè un parametro passato per riferimento consente di manipolare l'oggetto riferito da un altro scope, ma non tutte le funzioni lo fanno. Per cui formalmente è una definizione border line.

Se ci si pensa, questa è una grave inconsistenza semantica del modello di programmazione del C/C++.
 

Andretti60

Utente Èlite
6,440
5,091
... Se ci si pensa, questa è una grave inconsistenza semantica del modello di programmazione del C/C++.
Hai assolutamente ragione! (grande punto esclamativo)

Ma ricorda, il C venne creato non come linguaggio generico, ma pensato per scrivere kernel e applicazioni di un sistema operativo (Unix) e ancora adesso la fa da padrone in quel campo (drivers inclusi). Ed e' essenzialmente un linguaggio imperativo, strutturato, "vecchia scuola", derivato da Pascal e Fortran, la versione ANSII ha tappato qualche buco, ma la struttura del linguaggio e' la stessa. Purtroppo il C++ ne eredita i problemi. Ecco perche' chi vuole usare linguaggi ad alto livello evitando le incongruenze e pazzie del C usa linguaggi moderni (esempio Java e C#) che hanno una sintassi rigorosa e dove occorre specificare esplicitamente quali "parametri" possano essere modificati e tornare un valore.

Con l'introduzione del OOP, le funzioni in pratica non esistono piu', sostituite con i "metodi" delle classi, che operano sui membri interni delle classi. Il concetto di "parametro" come dato sparisce, sostituito con quello di "proprieta'". Si dichiara una classe, la si inizializza, si chiamano i suoi metodi (ovvio quelli accessibili), e dopo di quello si chiede alla classe solo i parametri che interessano chiamando le sue proprieta'.
Per fare un esempio, il problema originale di questo thread puo' essere risolto banalmente con una classe, chiamiamola CalcolaIVA, da usare in questo modo
C++:
CalcolaIVA c = new CalcolaIVA();
c.IvaPercent = 20; // inizializza la percentuale della tassa
c.SetLordo(42);  // calcola gli altri parametri usando 42 come prezzo lordo
cout << "Netto: " << c.PrezzoNetto;
cout << "Iva: " << c.IVA;

Per inciso, tutti i parametri passati a funzione nel C sono passati per valore. Tutti. Se si vuole tornare un valore non si passa il valore, ma l'indirizzo del valore stesso (che quindi viene passato per valore, tanto per confondere le cose). E nonostante cio', non sempre per default il C passa il valore, ma per certi tipi di dati implicitamente ne passa il puntatore: caso esemplare i vettori, di cui viene passato l'indirizzo del primo elemento, e quindi i cui valori possono essere cambiati dalla funzione.

E poi ci si chiede perche' il C non sia un buon linguaggio per imparare a programmare :) e non abbiamo neanche iniziato a parlare di allocazione di memoria!
 

pabloski

Utente Èlite
2,868
916
Ma ricorda, il C venne creato non come linguaggio generico, ma pensato per scrivere kernel e applicazioni di un sistema operativo (Unix)

Considerando che doveva essere un assembly portabile, direi che ha centrato tutti i suoi obiettivi ed è andato pure molto oltre.

Con l'introduzione del OOP, le funzioni in pratica non esistono piu', sostituite con i "metodi" delle classi, che operano sui membri interni delle classi

Sull'OOP stavo ruminando giorni fa, mentre studiavo il modello di rendering dei widget in Flutter. Elegante l'architettura, poi mi sono venuti in mente un paio di articoli sulle prestazioni dei giochi scritti con Unity. L'OOP ne usciva maluccio. E Flutter lo sfrutta oltremodo.

Per la cronaca, gli autori proponevano una nuova metodologia, il Data Driven/Oriented Design e il pattern Entity-Component-System.

E' OT ma posto un paio di link, magari qualcuno è interessato

http://gamesfromwithin.com/data-oriented-design
https://software.intel.com/en-us/ar...tem-ecs-c-sharp-job-system-and-burst-compiler

Notare la tabella in fondo al secondo articolo. Risultati mostruosi. E il gioco passa dall'essere CPU-bound a GPU-bound.

Tutto questo mi fa pensare che il successo ( ancora attuale ) del C è dovuto al fatto di essere uno strumento non "opinionated" e di permettere pertanto l'implementazione di vari modelli e pattern di programmazione. Già questo da solo, riesce a colmare tutte le lacune che si porta dietro. Non a caso, C e C++ sono ancora oggi nella top10 dei linguaggi più usati.
 
  • Mi piace
Reazioni: Andretti60

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili