PDA

Visualizza la versione completa : [C++] Prendere un intero e restituire una stringa


notexpert
30-07-2011, 19:07
Salve. Ho un problema. In pratica ho una funzione, chiamiamola Alpha, che prende un intero e, a seconda di una condizione restituisce (dovrebbe restituire) una stringa. Ad esempio


Alpha (int a) {
if (a>0) return "Positivo";

Il che non funziona affatto.

Qualcuno può gentilmente spiegarmi dove sbaglio?

Ringraziando anticipatamente,

Lorenzo.

Freax
30-07-2011, 19:09
codice a parte, manca il linguaggio ...

Celebron
30-07-2011, 19:22
Originariamente inviato da notexpert
Salve. Ho un problema. In pratica ho una funzione, chiamiamola Alpha, che prende un intero e, a seconda di una condizione restituisce (dovrebbe restituire) una stringa. Ad esempio


Alpha (int a) {
if (a>0) return "Positivo";

Il che non funziona affatto.

Qualcuno può gentilmente spiegarmi dove sbaglio?

Ringraziando anticipatamente,

Lorenzo.

se è C, il motivo è banale

una stringa di quel tipo viene allocata staticamente nello stack della funzione a compile time. Questo significa che appena esci dalla funzione perdi ogni riferimento a quella stringa in quanto lo stack di quella funzione esaurisce il suo compito

E' lo stesso motivo per il quale non puoi restituire un array allocato staticamente in una funzione ad un altra funzione

una soluzione banale prevede che allochi lo spazio dinamicamente e usi una strcpy per inserire "positivo" all'interno della tua stringa. L'allocazione dinamica fa si che la variabile sia allocata nell'heap che non si "esaurisce" all'uscita dalla funzione

MItaly
31-07-2011, 23:30
Originariamente inviato da Celebron
se è C, il motivo è banale

una stringa di quel tipo viene allocata staticamente nello stack della funzione a compile time. Questo significa che appena esci dalla funzione perdi ogni riferimento a quella stringa in quanto lo stack di quella funzione esaurisce il suo compito

In realtà, se il codice è effettivamente come l'ha scritto, quello che hai detto non è corretto, dato che "Positivo" non è una variabile allocata sullo stack, ma è uno string literal, per cui se restituisci un char * (meglio const char *) che punta ad esso non hai problemi. Lo standard infatti garantisce che gli string literal esistano per tutta l'esecuzione del programma; in genere essi sono memorizzati nella tabella delle stringhe dell'eseguibile (che sta in un particolare segmento), e questa è mappata in memoria per tutta l'esecuzione del programma.

Ovviamente il tuo discorso si applica per le stringhe effettivamente allocate sullo stack.

Celebron
01-08-2011, 00:08
:confused: cavolo probabilmente hai ragione e ricordo io male
devo decisamente ridare un occhiata alla documentazione in merito

Freax
01-08-2011, 00:20
diciamo che ti accorgi di quanto detto da MItaly anche facendo semplici esperimenti con un puntatore ( tiro dentro i puntatori solo perché sono variabili che possono trattare indirizzi, non per altro ) ed una costante, vedrai che praticamente le costanti non hanno indirizzo, non puoi assegnare l'indirizzo della costante al puntatore semplicemente perché non ha nulla da assegnare, quindi diciamo che vengono memorizzate/allocate in altre porzioni di memoria e la loro referenziazione non è gestita quindi per indirizzo ma direttamente dal compilatore.

MItaly
01-08-2011, 00:25
Falso, gli string literal hanno indirizzo, altrimenti non li potresti trattare come stringhe. Sono i literal degli altri tipi che sono degli rvalue e quindi sono privi di indirizzo (questo in genere perché spesso vengono incorporati direttamente nel codice macchina generato come valori "immediate").

notexpert
01-08-2011, 00:26
Grazie! semplicemente non mettevo l'asterisco dopo char... ma che differenza fa tra char * e const char * ? Grazie!

Freax
01-08-2011, 00:28
Originariamente inviato da MItaly
Falso, gli string literal hanno indirizzo, altrimenti non li potresti trattare come stringhe. Sono i literal degli altri tipi che sono degli rvalue e quindi sono privi di indirizzo (questo in genere perché spesso vengono incorporati direttamente nel codice macchina generato come valori "immediate").

ma tu per string literal che intendi? io capisco che intendi dei const char, gli string literal li ho sentiti in java, ma in C mai, fammi capire meglio ...

MItaly
01-08-2011, 00:33
const a sinistra di un tipo indica che la variabile in questione non può essere modificata.
Nei puntatori, la questione è un po' più complessa, dato che ci sono due cose che potrebbero essere "non modificabili": il puntatore stesso e i dati a cui punta. Per capire a cosa si riferisca il const, basta leggere la dichiarazione al contrario:

char * => puntatore (*) a dei char (char) => posso modificare sia il puntatore (ad esempio, rilocarlo e farlo puntare ad altro) sia i dati a cui punta (ovvero, modificare la stringa)
const char * => puntatore (*) a dei char (char) costanti (const) => è un puntatore che posso modificare, ma i dati a cui punta non possono essere modificati (la stringa a cui punta è costante)
char * const => puntatore costante (const *) a char => è un puntatore che non posso rilocare, ma posso modificare la stringa a cui punta
const char * const => puntatore cosante (const *) a char (char) costanti (cont) => né il puntatore né i dati a cui punta sono modificabili

In pratica, vedrai soltanto char * (stringa modificabile) e const char * (stringa non modificabile); nel caso degli string literal è fondamentale usare const char *, dato che lo standard dice che cercare di modificare uno string literal è "undefined behavior", che nella stragrande maggior parte dei casi si traduce in un crash del programma, dato che gli string literal sono memorizzati in un area di memoria di sola lettura.

Loading