2013-07-27 11 views
9

Sto leggendo la 3a edizione di il linguaggio di programmazione C++ di Bjarne Stroustrup e sto tentando di completare tutti gli esercizi. Non sono sicuro di come affrontare l'esercizio 13 dalla sezione 6.6, quindi ho pensato di passare a Stack Overflow per alcune informazioni. Ecco la descrizione del problema:C++: come utilizzare il nuovo per trovare il valore di ritorno della funzione?

Scrivete una funzione gatto() che prende due argomenti stringa in stile C e restituisce una singola stringa che è la concatenazione degli argomenti. Utilizzare new per trovare il negozio per il risultato.

Ecco il mio codice finora, con i punti interrogativi in ​​cui io non sono sicuro di cosa fare:

? cat(char first[], char second[]) 
{ 
    char current = ''; 
    int i = 0; 

    while (current != '\0') 
    { 
     current = first[i]; 
     // somehow append current to whatever will eventually be returned 
     i++; 
    } 

    current = ''; 
    i = 0; 

    while (current != '\0') 
    { 
     current = second[i]; 
     // somehow append current to whatever will eventually be returned 
     i++; 
    } 

    return ? 
} 

int main(int argc, char* argv[]) 
{ 
    char first[] = "Hello, "; 
    char second[] = "World!"; 

    ? = cat(first, second); 

    return 0; 
} 

E qui sono le mie domande:

  1. Come si usa nuova per trovare un negozio? Mi aspettavo di fare qualcosa come std::string* result = new std::string; o dovrei usare new per creare in qualche modo un'altra stringa in stile C?
  2. Correlato alla domanda precedente, cosa devo restituire da cat()? Presumo che dovrà essere un puntatore se devo usare new. Ma un puntatore a cosa?
  3. Anche se il problema non menziona l'utilizzo di eliminare per liberare memoria, so che dovrei perché io ho usato nuovo da allocare. Dovrei semplicemente cancellare alla fine del main, giusto prima di tornare?
+1

+1 Domanda ben composta. – Sabuncu

risposta

4

Come uso nuovo di trovare negozio? Mi aspettavo di fare qualcosa come std::string* result = new std::string; o dovrei usare new per creare in qualche modo un'altra stringa in stile C?

Quest'ultimo; il metodo utilizza stringhe in stile C e nulla nel testo suggerisce che debba restituire qualcos'altro. Il prototipo della funzione dovrebbe quindi essere char* cat(char const*, char const*). Ovviamente questo è non come normalmente si scrivono le funzioni; la gestione manuale della memoria è completamente tabù nel moderno C++ perché è così soggetta a errori.

Anche se il problema non menziona l'utilizzo dell'eliminazione nella memoria libera, so che dovrei farlo perché ne avrò usato di nuovi da allocare. Dovrei semplicemente cancellare alla fine del main, giusto prima di tornare?

In questo esercizio si. Nel mondo reale, no: come ho detto sopra, questo è completamente tabù. In realtà si restituire un std::string e non allocare memoria utilizzando new. Se ci si trova ad allocare manualmente la memoria (e supponendo che sia per una buona ragione), si inserisce tale memoria non in un puntatore raw ma in un puntatore intelligente - std::unique_ptr o std::shared_ptr.

4

In un programma "reale", si, si userebbe std :: string. Sembra che questo esempio voglia usare una stringa C invece.

Così forse qualcosa di simile:

char * cat(char first[], char second[]) 
{ 
    char *result = new char[strlen(first) + strlen(second) + 1]; 

...

D: Come si fa a "aggiungere"?

A: Basta scrivere tutto in "primo" su "risultato".

Non appena hai finito, continua scrivendo tutto in "secondo" per ottenere il risultato (da dove hai lasciato). Quando hai finito, assicurati di aggiungere "\ 0" alla fine.

+0

Sta usando 'strlen' qualcosa relativo alla programmazione in C++? – Antonio

+0

@Antonio: Sì, quando si tratta di stringhe in stile C come indicato nella domanda. – Blastfurnace

+0

@Blastfurnace Allora non perché strcpy e strcat? Penso che se vuoi veramente esercitare sulla gestione delle stringhe e della memoria, devi essere consapevole dell'esistenza di queste funzioni, ma esercitati nell'implementare la tua. – Antonio

3
  1. si suppone di restituire una stringa stile C, quindi non è possibile utilizzare std::string (o almeno, non è "nello spirito della questione"). Sì, dovresti usare new per creare una stringa in stile C.
  2. Si dovrebbe restituire la stringa in stile C generata ... Quindi, il puntatore al primo carattere della stringa appena creata.
  3. Correggere, è necessario eliminare il risultato alla fine. Mi aspetto che possa essere ignorato, come in questo caso particolare, probabilmente non importa molto - ma per completezza/correttezza, dovresti.
2

L'esercizio significa utilizzare new per allocare memoria. "Trova negozio" è stranamente formulato, ma in realtà è quello che fa. Gli dici di quanto store hai bisogno, trova un blocco di memoria disponibile che puoi usare e restituisce il suo indirizzo.

Non sembra che l'esercizio voglia utilizzare std :: string. Sembra che tu debba restituire un char*. Quindi il prototipo di funzione dovrebbe essere:

char * cat (const char first [], const char second []);

Nota l'identificatore const. È importante in modo che tu possa passare letterali alle stringhe come argomenti.

Quindi, senza dare il codice fuori subito, quello che dovete fare è determinare quanto grande sia il char* stringa risultante dovrebbe essere, destinare la somma richiesta utilizzando new, copiare le due stringhe di origine nello spazio appena allocata, e restituirlo .

Si noti che normalmente non si esegue questo tipo di gestione della memoria manualmente in C++ (si utilizza invece std::string), ma è comunque importante conoscerlo, motivo per cui il motivo di questo esercizio.

3

Ecco qualche vecchio codice che ho scavato da un mio progetto un po 'indietro:

char* mergeChar(char* text1, char* text2){ 
    //Find the length of the first text 
    int alen = 0; 
    while(text1[alen] != '\0') 
     alen++; 

    //Find the length of the second text 
    int blen = 0; 
    while(text2[blen] != '\0') 
     blen++; 

    //Copy the first text 
    char* newchar = new char[alen + blen + 1]; 
    for(int a = 0; a < alen; a++){ 
      newchar[a] = text1[a]; 
    } 

    //Copy the second text 
    for(int b = 0; b < blen; b++) 
     newchar[alen + b] = text2[b]; 

    //Null terminate! 
    newchar[alen + blen] = '\0'; 
    return newchar; 
} 

In generale, in un programma di 'reale', sarete tenuti a utilizzare std::string, però. Assicurati di averlo delete[] newchar più tardi!

+1

Qualsiasi motivo specifico per la scrittura manuale di queste parti anziché utilizzare le funzioni appropriate ('std :: strlen',' std :: strcpy')? Questo è più lungo, meno leggibile e più soggetto a errori. Non farlo –

+1

A qualcuno che cerca di imparare non dovrebbero essere dati set completi di codice che risolvono esattamente lo stesso problema - non insegnerà allo studente qualcosa di diverso da CTRL-C + CTRL-V, che qualcuno che usa SO probabilmente (anche se a volte solo a malapena) sa . –

+2

Chiede di manipolare le stringhe in stile C. Gli sto mostrando cosa sta succedendo. Se non voleva imparare, non avrebbe letto il libro in primo luogo. Ha detto che non sta usando il codice per un'applicazione del mondo reale, sta esaminando il materiale nel libro. – BrainSteel

0

Sembra che sia necessario utilizzare new per allocare memoria per una stringa e quindi restituire il puntatore. Pertanto il tipo return di cat sarebbe `char*.

Si potrebbe fare fare qualcosa di simile:

int n = 0; 
int k = 0; 

//also can use strlen 
while(first[n] != '\0') 
    n ++ ; 
while(second[k] != '\0') 
    k ++ ; 

//now, the allocation 

char* joint = new char[n+k+1]; //+1 for a '\0' 

//and for example memcpy for joining 

memcpy(joint, first, n); 
memcpy(joint+n, second, k+1); //also copying the null 


return joint; 
0

E ti dice di fare questo il modo C praticamente:

#include <cstring> 

char *cat (const char *s1, const char *s2) 
{ 
    // Learn to explore your library a bit, and 
    // you'll see that there is no need for a loop 
    // to determine the lengths. Anything C string 
    // related is in <cstring>. 
    // 
    size_t len_s1 = std::strlen(s1); 
    size_t len_s2 = std::strlen(s2); 
    char *dst; 

    // You have the lengths. 
    // Now use `new` to allocate storage for dst. 


    /* 
    * There's a faster way to copy C strings 
    * than looping, especially when you 
    * know the lengths... 
    * 
    * Use a reference to determine what functions 
    * in <cstring> COPY values. 
    * Add code before the return statement to 
    * do this, and you will have your answer. 
    * 
    * Note: remember that C strings are zero 
    * terminated! 
    */ 

    return dst; 
} 

Non dimenticare di utilizzare l'operatore corretto quando si vai a liberare la memoria allocata. Altrimenti avrai una perdita di memoria.

Felice codifica! :-)

Problemi correlati