Menggunakan manipulator aliran (endl) atau karakter pelarian baris baru (\ n)?

12

Saya tidak memiliki konteks khusus di mana saya mengajukan pertanyaan, tetapi ketika saya membaca buku pemula tentang C ++ saya memperhatikan penggunaan manipulator aliran akhir dan karakter pelarian baris baru ketika berhadapan dengan objek aliran.

Exmaple adalah sebagai berikut:

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

Pertanyaan saya adalah:

  1. Apakah lebih tepat menggunakan stream manipulator (endl) dalam situasi tertentu dan karakter pelarian di situasi yang berbeda?
  2. Apakah ada kelemahan efisiensi untuk menggunakan salah satu dari keduanya?
  3. Apakah mereka benar-benar dipertukarkan?
  4. Saya membaca bahwa urutan pelarian disimpan dalam memori sebagai satu karakter. Apakah itu berarti lebih tepat menggunakan endl jika Anda menggunakan memori yang rendah?
  5. Apakah manipulator aliran pada akhirnya menggunakan memori dengan cara apa pun, jika demikian apakah itu lebih dari urutan pelarian?

Terima kasih, StackExchange Maaf jika saya memposting ini di bagian yang salah, saya pikir itu dihitung sebagai struktur data.

Nathan Taylor
sumber
2
endl juga menyebabkan flush pada beberapa aliran, '\ n' tidak.
James

Jawaban:

12

o << std::endl setara dengan kode berikut:

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

Dengan kata lain, Anda hanya boleh menggunakan std::endlsaat Anda perlu menyiram aliran. Sebagai contoh:

  • Anda akan melakukan operasi yang memakan waktu dan ingin memastikan Anda menampilkan pesan sebelum melakukannya.
  • Proses lain sedang menunggu hasil Anda.
  • Jika lebih dari satu utas atau proses sedang berjalan, Anda mungkin perlu menyiram output sehingga keluaran dari setiap utas atau proses ditampilkan dengan benar. (Kalau tidak, Anda mungkin mendapatkan blok acak yang tampak disisipkan pada interval yang canggung.)

Jika Anda tidak perlu menyiram aliran, gunakan \nsebagai gantinya std::endl. Panggilan ekstra ke flushdapat merusak kinerja (kadang-kadang secara signifikan).

Untuk detail lebih lanjut, lihat cppreference.com .

Mengenai penggunaan memori: Mengkhawatirkan \nversus std::endlhampir pasti merupakan mikro-optimasi yang tidak perlu, tetapi secara umum, saya berharap \nuntuk mengambil lebih sedikit memori. \nhanya satu byte lagi di akhir string literal, sementara tulisan std::endlditerjemahkan oleh kompiler ke dalam (mungkin diuraikan) fungsi panggilan ke putdan flush.

Perbedaan spesifik platform pada ujung garis (Windows \r\nversus Linux dan OS X \n) ditangani pada tingkat yang lebih rendah daripada std::endldan \n:

  • Jika aliran dibuka dalam mode teks, maka jika Anda menulis \n, aliran itu secara otomatis menerjemahkannya ke akhir baris khusus platform yang sesuai. Jika Anda membaca akhir baris khusus platform, aliran otomatis menerjemahkannya ke \n.
  • Jika aliran dibuka dalam mode biner, maka mereka melewati ujung garis apa pun melalui kata demi kata, dan terserah Anda.
  • Untuk std::coutdan std::cinkhususnya, mereka diperlakukan seolah-olah mereka mode teks.
Josh Kelley
sumber
1

1) Untuk portabilitas, gunakan endl. Baris baru Windows adalah \r\n, Linux \ndan Mac \r. Sunting: Sesuai komentar, ujung khusus sistem garis ditangani pada tingkat yang lebih rendah.

2) endlmenyiram aliran, "\n"tidak.

3) Tergantung pada portabilitas.

Mengenai penggunaan memori, Anda dapat menguranginya dengan membilas ke penyimpanan lain sesering mungkin dengan endl. Namun, itu akan menurunkan kinerja.

Sunting: Hapus beberapa kesalahan.

Kent
sumber
2
Mac telah berbasis unix sejak OS X dan dengan demikian juga \npada mesin modern.
7
Maaf, tapi ini tidak benar. endldan \nsetara dalam hal akhir baris khusus platform; perbedaan platform ditangani di tingkat yang lebih rendah.
Josh Kelley
2
Poin pertama Anda salah. endl () mengirim '\ n' ke aliran (selain membilasnya). Karakter '\ n' dikonversi ke platform spesifik End of line sequence(dengan asumsi mode teks). Itu End of line sequencedikonversi kembali ke '\ n` ketika membaca dari file. Butir 3) meragukan. Dan paragraf terakhir sekali lagi salah: Pembilasan tidak akan menghemat ruang Anda dan pembilasan lebih dari yang dibutuhkan akan memperlambat kode Anda (titik buffer adalah untuk meningkatkan efisiensi penulisan ke perangkat yang lambat).
Martin York