Usando um manipulador de fluxo (endl) ou um caractere de escape de nova linha (\ n)?

12

Não tenho um contexto específico no qual estou fazendo a pergunta, mas enquanto estava lendo um livro para iniciantes em C ++, notei o uso de um manipulador de fluxo endl e de um caractere de escape de nova linha ao lidar com um objeto de fluxo.

O exemplo é o seguinte:

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

Minhas perguntas são:

  1. É mais apropriado usar o manipulador de fluxo (endl) em uma determinada situação e um caractere de escape em outra?
  2. Existem desvantagens em termos de eficiência em usar um dos dois?
  3. Eles são completamente intercambiáveis?
  4. Eu li que uma sequência de escape é armazenada na memória como um único caractere. Isso significa que é mais apropriado usar endl se você estiver consumindo pouco memória?
  5. O manipulador de fluxo acaba consumindo memória de alguma forma, se for, é mais do que a sequência de escape?

Obrigado, desculpas pelo StackExchange. Se eu postei isso na seção errada, achei que isso contaria como estruturas de dados.

Nathan Taylor
fonte
2
endl também causa um flush em alguns fluxos, '\ n' não.
James

Respostas:

12

o << std::endl é equivalente ao seguinte código:

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

Em outras palavras, você deve usar somente std::endlquando precisar liberar o fluxo. Por exemplo:

  • Você está prestes a executar uma operação demorada e deseja exibir uma mensagem antes de fazê-lo.
  • Outro processo está aguardando sua saída.
  • Se mais de um encadeamento ou processo estiver em execução, pode ser necessário liberar a saída para que a saída de cada encadeamento ou processo seja exibida corretamente. (Caso contrário, você poderá obter blocos de saída aparentemente aleatórios intercalados em intervalos difíceis.)

Se você não precisar liberar o fluxo, use em \nvez de std::endl. As chamadas extras para flushpodem prejudicar o desempenho (às vezes significativamente).

Para mais detalhes, consulte cppreference.com .

Quanto ao uso da memória: Preocupar-se com o \nversus std::endlé quase certamente uma micro-otimização desnecessária, mas, em geral, eu esperaria \ngastar menos memória. \né apenas mais um byte no final de uma string literal, enquanto a escrita std::endlé traduzida pelo compilador em (provavelmente inline) chamadas de função para pute flush.

As diferenças específicas da plataforma nas terminações de linha (Windows \r\nversus Linux e OS X \n) são tratadas em um nível mais baixo que std::endle \n:

  • Se um fluxo for aberto no modo de texto, se você escrever \n, ele o converterá automaticamente para o final de linha específico da plataforma apropriado. Se você ler um final de linha específico da plataforma, o fluxo o converterá automaticamente \n.
  • Se um fluxo é aberto no modo binário, eles passam todas as terminações de linha literalmente, e é com você.
  • Para std::coute std::cin, em particular, eles são tratados como se eles estão em modo texto.
Josh Kelley
fonte
1

1) Para portabilidade, use endl. As novas linhas do Windows são \r\nLinux \ne Mac \r. Editar: conforme comentários, as terminações específicas do sistema de linha são tratadas em um nível inferior.

2) endllibera o fluxo, "\n"não.

3) Depende da portabilidade.

Quanto ao uso da memória, você pode minimizá-lo liberando para outro armazenamento o mais rápido possível endl. No entanto, isso diminuirá o desempenho.

Edit: Esclarecer alguns erros.

Kent
fonte
2
O Mac é baseado em unix desde o OS X e, portanto, também está \nem qualquer máquina moderna.
7
Desculpe, mas isso está incorreto. endle \nsão equivalentes em relação às terminações de linha específicas da plataforma; as diferenças de plataforma são tratadas em um nível inferior.
21413 Josh Kelley
2
Seu primeiro ponto está errado. endl () envia '\ n' para o fluxo (além de liberá-lo). O caractere '\ n' é convertido para a plataforma específica End of line sequence(assumindo o modo de texto). O End of line sequenceé convertido novamente em '\ n' quando lido de um arquivo. O ponto 3) é duvidoso. E o último parágrafo está novamente errado: liberar não economizará espaço e liberar mais do que o necessário reduzirá a velocidade do código (o objetivo do buffer é melhorar a eficiência da gravação em um dispositivo lento).
Martin York