Usando un manipolatore di stream (endl) o un carattere di escape newline (\ n)?


12

Non ho un contesto specifico in cui sto ponendo la domanda, ma mentre stavo leggendo un libro per principianti su C ++ ho notato l'uso di un manipolatore di flusso endl e di un carattere di escape newline quando ho a che fare con un oggetto stream.

L'esempio è il seguente:

cout << "Hello World" << endl;
cout << "Hello World\n";

Le mie domande sono:

  1. È più appropriato usare il manipolatore di stream (endl) in una determinata situazione e un carattere di escape in un'altra?
  2. Ci sono degli svantaggi in termini di efficienza nell'uso di uno dei due?
  3. Sono completamente intercambiabili?
  4. Ho letto che una sequenza di escape è memorizzata come singolo carattere. Ciò significa che è più appropriato usare endl se stai andando a basso consumo di memoria?
  5. Il manipolatore di stream utilizza la memoria in qualche modo, in caso affermativo è qualcosa di più della sequenza di escape?

Grazie, StackExchange mi scuso se l'ho pubblicato nella sezione sbagliata, ho pensato che fosse considerato una struttura di dati.


2
endl provoca anche un flush su alcuni stream, '\ n' no.
James,

Risposte:


12

o << std::endl è equivalente al seguente codice:

o.put(o.widen('\n'));
o.flush();

In altre parole, dovresti usarlo solo std::endlquando devi scaricare lo stream. Per esempio:

  • Stai per eseguire un'operazione che richiede tempo e vuoi assicurarti di visualizzare un messaggio prima di farlo.
  • Un altro processo è in attesa del tuo output.
  • Se è in esecuzione più di un thread o processo, potrebbe essere necessario svuotare l'output in modo che l'output di ciascun thread o processo sia visualizzato correttamente. (Altrimenti, potresti ottenere blocchi apparentemente casuali di output interlacciati a intervalli scomodi.)

Se non è necessario scaricare lo stream, utilizzare \ninvece di std::endl. Le chiamate extra a flushpossono danneggiare le prestazioni (a volte in modo significativo).

Per maggiori dettagli, vedi cppreference.com .

Per quanto riguarda l'utilizzo della memoria: preoccuparsi di \nversus std::endlè quasi certamente una non ottimizzazione micro necessaria, ma in generale mi aspetterei \ndi prendere meno memoria. \nè solo un altro byte alla fine di una stringa letterale, mentre la scrittura std::endlviene tradotta dal compilatore in (probabilmente inline) chiamate di funzione a pute flush.

Le differenze specifiche della piattaforma nelle terminazioni di linea (Windows \r\nrispetto a Linux e OS X \n) sono gestite a un livello inferiore rispetto a std::endle \n:

  • Se uno stream viene aperto in modalità testo, quindi se si scrive \n, lo traduce automaticamente nel finale di riga specifico della piattaforma appropriato. Se leggi un finale di riga specifico per la piattaforma, lo stream lo traduce automaticamente in \n.
  • Se uno stream viene aperto in modalità binaria, passa in modo letterale qualsiasi terminazione di riga e dipende da te.
  • Per std::coute std::cinin particolare, sono trattati come se fossero in modalità testo.

1

1) Per la portabilità, utilizzare endl. Newline di Windows sono \r\n, Linux \ne Mac \r. Modifica: come da commenti, i finali specifici del sistema di linea vengono gestiti a un livello inferiore.

2) endlsvuota il flusso, "\n"no.

3) Dipende dalla portabilità.

Per quanto riguarda l'utilizzo della memoria, è possibile minimizzarlo scaricando su altra memoria il più spesso possibile con endl. Tuttavia, ridurrà le prestazioni.

Modifica: cancella alcuni errori.


2
Mac è stato unix basato su OS X e quindi è anche \nsu qualsiasi macchina moderna.

7
Siamo spiacenti, ma questo non è corretto. endle \nsono equivalenti per quanto riguarda i finali di linea specifici della piattaforma; le differenze della piattaforma sono gestite a un livello inferiore.
Josh Kelley,

2
Il tuo primo punto è sbagliato. endl () invia '\ n' allo stream (oltre a scaricarlo). Il carattere '\ n' viene convertito nello specifico della piattaforma End of line sequence(presupponendo la modalità testo). Il End of line sequenceè tornato convertito a '\ n' quando viene letto da un file. Il punto 3) è dubbio. E l'ultimo paragrafo è di nuovo sbagliato: lo svuotamento non ti farà risparmiare spazio e lo svuotamento più del necessario rallenterà il codice (il punto del buffer è migliorare l'efficienza di scrittura su un dispositivo lento).
Martin York,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.