PDA

View Full Version : [C++] Restituzione di più valori da una funzione


smsc
25-08-2008, 12:44
Buon giorno a tutti,
mi sono da poco "buttato" nella programmazione del linguaggio c++, proveniendo comunque da Visual Basic, quindi con un minimo di base. Perdonatemi quindi l'estrema newbaggine! :D

Il mio problema è:
Come faccio a far restituire ad una funzione più valori?
Mi spiego meglio, se io ho 3 variabili (diciamo 2 intere e 1 stringa), chiamo una funzione passandogli queste variabili, le elaboro e modifico.... e poi??

Con il return, mi ritorna ovviamente uno solo dei tre valori... :muro:

Immagino debba usare una struttura, ma cosa passare alla funzione??
Non è che c'è qualche anima pia che mi possa scrivere 2 righe di esempio??

Grazie! ;)

SerMagnus
25-08-2008, 12:51
una funzione non può restituiere più valori, al massimo puoi ovviare con una struttura o un array, se devi lavorare con + valori è consigliabile usare i parametri di uscita

Noixe
25-08-2008, 13:26
Creati una semplice struct:


struct {
string s1, s2;
int i;
} Dato;


E poi usi la funzione in questo modo:

Dato fun(Dato d) {
d.s1 = "Ciao";
d.s2 = "Hello";
d.i = 123;
return d;
}


Oppure usi tre parametri per la funzione e poi all'interno del corpo della funzione stessa li assegni ai tre membri della struttura "Dato".

Ciao

dad_89
25-08-2008, 13:41
Non ti basta dichiarare la funzione di tipo void e passare i valori per riferimento? Come avviene in C fral'altro ...

the_ivos
25-08-2008, 15:07
Non ti basta dichiarare la funzione di tipo void e passare i valori per riferimento? Come avviene in C fral'altro ...

Questa è la soluzione migliore anche secondo me... ;)

Poi calcola che le variabili char vengono sempre passate per riferimento quindi non c'è alcun bisogno di "ritornarle".

smsc
25-08-2008, 15:19
Prima di tutto grazie a tutti per le risposte....

Proverò appena possible la soluzione di Noixe, nel frattempo dad, cosa vuol dire "passare i valori per riferimento?"

In VB basta dichiarare i parametri della call tipo:
call funzione(var1,var2,var3)
Poi automaticamente i 3 varlori (dopo essere stati calcolati dalla funzione chiamata dalla call venivano restituiti. Forse è questo che intendevi??

Noixe
25-08-2008, 15:35
Passarli per riferimento vuol dire passare alla funzione i valori effettivi al fine di apportare modifiche che rimarranno permamenti. Nel tuo caso puoi fare cosi:

void fun(string& s1, string& s2, int& i) { // Nota la e commerciale dopo il tipo
s1 = "ciao";
s2 = "hello";
i = 123;
}

in questo modo una chiamata del tipo

fun (x, y, z);

farà si che in x, y e z vengano memorizzati i valori assegnati all'interno della funzione.

Tuttavia, l'approccio che fa uso di una struct secondo me è migliore, soprattutto se devi restituire tanti valori, tutti correlati tra di loro.

Ciao

smsc
25-08-2008, 16:05
Grazie noxie,
ho provato il tuo codice di qualche post sopra ma mi da errore, soprattutto alla linea: "Dato fun(Dato d)"

Forse perchè sto utilizzando Visual c++! O forse perchè sono proprio newbie!!!:muro:

0rph3n
25-08-2008, 16:16
Proverò appena possible la soluzione di Noixe, nel frattempo dad, cosa vuol dire "passare i valori per riferimento?"

significa che devi prendere in mano un libro e studiare :Prrr:

Noixe
25-08-2008, 18:33
Allora, la struct andrebbe definita cosi:

struct Dato {
string s1, s2;
int i;
};

In effetti quella che avevo scritto prima definiva solo un identificatore di nome Dato utilizzabile come una comune variabile.

Invece mettendo il nome dopo struct definisci un vero e proprio tipo di dato.

Comunque per iniziare sconsiglio di fare uso di un ambiente visuale, meglio un ambiente semplice con un compilatore C++ standard.

Scarica Dev-C++.

Ciao

morskott
25-08-2008, 18:53
Allora, la prima soluzione è tramite una structtypedef struct _Dato{
char *stringa1;
char *stringa2;
int intero;
} Dato

Dato *getDato(){
Dato *dato=(Dato *)malloc(sizeof(Dato));
strcopy("Ciao",dato->stringa1); //non ricordo l'ordine dei parametri, in pratica copia la stringa "Ciao" nella posizione dato->stringa1 (non ricordo se devi prima allocarla con malloc)
//stessa cosa con stringa2
dato->intero=8;
return dato;
}

void chiamante(){
Dato *dat=getDato();
//usa il dato
free(dat);
}oppure il passaggio per riferimentovoid faiQualcosa(char *s1,char *s2,int *i){
(*s1)="nuovo valore";
(*s2)="altro valore";
(*i)=9;
}

void chiamante(){
char *prima="Prima";
char *seconda="Seconda";
int in=3;
faiQualcosa(prima,seconda,&in);
}col C(++) sono un po arrugginito, credo sia giusto

Noixe
25-08-2008, 20:13
La tua sintassi e' C non C++.

Per il secondo linguaggio esiste il tipo di dato string, che evita tutti i problemi dei noiosi char*.

Per il passaggio di valori per riferimento, meglio usare i reference (con la e commerciale) invece dei puntatori.

Ciao

dad_89
25-08-2008, 23:14
Proverò appena possible la soluzione di Noixe, nel frattempo dad, cosa vuol dire "passare i valori per riferimento?"
In poche parole quando passi una variabile ad una funzione questa viene passata per valore, in pratica vuol dire che essa non appare modificata all'uscita della funzione, per cui la funzione opera non sulla variabile passata ma bensì su di una copia del parametro, per quanto riguardo il passaggio per riferimento viene effettivamente passato l'indirizzo della variabile e tramite quest'ultimo la funzione può modificare il valore della variabile.
Spero di esserti stato utile :)

DanieleC88
26-08-2008, 05:38
Scarica Dev-C++.

Questa è blasfemia! Questa è follia!
No, questa è... SPARTAAAA!!


Seriamente, vi prego, non consigliate più Dev-C++ a nessuno... :asd:
Le alternative migliori e gratuite al momento sono Code::Blocks, wxDev-C++ (ok è quasi identico a Dev-C++, ma almeno non è morto), Visual C++ Express Edition.

ciao ;)

Noixe
26-08-2008, 08:20
Ma per iniziare un ambiente vale l'altro, dato che bisogna focalizzare l'attenzione sul linguaggio e non sul programma.

Noixe
26-08-2008, 08:25
cosa vuol dire "passare i valori per riferimento?"


Ecco un esempio banale che probabilmente chiarirà meglio della spiegazione teorica :D


Passaggio per copia o per valore (non c'e' la & dopo il tipo):

void fun (int i) {
i = 2;
};

int i = 1;
fun(i);


A questo punto il valore di i rimarrà 1.

Nel passaggio per indirizzo o per riferimento, il valore della i sarebbe diventato 2.

sottovento
26-08-2008, 08:54
Allora, la prima soluzione è tramite una structtypedef struct _Dato{
char *stringa1;
char *stringa2;
int intero;
} Dato

Dato *getDato(){
Dato *dato=(Dato *)malloc(sizeof(Dato));
strcopy("Ciao",dato->stringa1); //non ricordo l'ordine dei parametri, in pratica copia la stringa "Ciao" nella posizione dato->stringa1 (non ricordo se devi prima allocarla con malloc)
//stessa cosa con stringa2
dato->intero=8;
return dato;
}

void chiamante(){
Dato *dat=getDato();
//usa il dato
free(dat);
}oppure il passaggio per riferimentovoid faiQualcosa(char *s1,char *s2,int *i){
(*s1)="nuovo valore";
(*s2)="altro valore";
(*i)=9;
}

void chiamante(){
char *prima="Prima";
char *seconda="Seconda";
int in=3;
faiQualcosa(prima,seconda,&in);
}col C(++) sono un po arrugginito, credo sia giusto

Entrambe le soluzioni andranno in crash

DanieleC88
26-08-2008, 12:54
Ma per iniziare un ambiente vale l'altro, dato che bisogna focalizzare l'attenzione sul linguaggio e non sul programma.
Non sono d'accordo, un ambiente migliore ti toglie anche molte rogne che all'inizio dei tuoi "studi" è bene evitare. E comunque se ci sono strumenti migliori e gratuiti, meglio iniziare subito con la roba seria ed imparare nel modo giusto. ;)
Entrambe le soluzioni andranno in crash
Oddio è vero... :asd:
Anzi, la seconda già è tanto se compila, come minimo dovrebbe dare due warning.

cionci
26-08-2008, 15:16
Ma per iniziare un ambiente vale l'altro, dato che bisogna focalizzare l'attenzione sul linguaggio e non sul programma.
Non è però bello vedere Dev-C++ che ti si pianta buttando all'aria il lavoro di diversi minuti ;)

Noixe
26-08-2008, 16:22
Non mi si e' mai bloccato.

Albi89
26-08-2008, 17:13
Non mi si e' mai bloccato.

Avanti, non scherziamo :D
Dev-C++ è senza dubbio l'IDE più instabile con cui abbia mai avuto a che fare.
La cosa ancora più triste è che da me è anche usato per gli esami di programmazione I e fondamenti all'università.
Non si contano le persone che hanno compromesso l'esame per blocchi dell'IDE, ed anche io ho avuto vari problemi ridicoli (build di debug senza simboli di debug? eh?) che di solito si risolvono solo ripulendo la cartella del project e ricopiando tutti i file.
Terribile :cry:

DanieleC88
26-08-2008, 17:18
Infatti. Che brutti ricordi. Ogni tre compilazioni un crash. :asd:

dad_89
26-08-2008, 17:22
L'accopiata gcc+emacs è sempre la migliore :D

cionci
26-08-2008, 17:25
L'accopiata gcc+emacs è sempre la migliore :D
Io uso felicemente Code::Blocks anche su Linux ;)

DanieleC88
26-08-2008, 17:42
Anche io. Anjuta mi ricorda troppo Dev-C++. :D

Anche KDevelop non è male. :)

dad_89
26-08-2008, 18:01
Io uso felicemente Code::Blocks anche su Linux ;)
Code::Blocks non lo mai usato, alle volte mi è capitato di mettere le mani su eclipse e non mi è parso male anche se un pò troppo pesante (non voglio scatenare guerre di religione eh :D).

Noixe
26-08-2008, 21:28
Bo, vuol dire che sono stato fortunato, oppure voi sfigati? :D

ndakota
26-08-2008, 22:30
Bo, vuol dire che sono stato fortunato, oppure voi sfigati? :D

non sei l'unico, anche a me non ha mai crashato. Nonostante questo mi trovo d'accordo con loro :Prrr: