Apa artinya membilas buffer?


97

Saya belajar C ++ dan saya menemukan sesuatu yang tidak saya mengerti:

Buffer keluaran dapat secara eksplisit dibilas untuk memaksa buffer ditulis. Secara default, membaca cinflushes cout; coutjuga di-flush ketika program berakhir secara normal.

Jadi pembilasan buffer (misalnya buffer keluaran): apakah ini membersihkan buffer dengan menghapus semua yang ada di dalamnya atau apakah itu membersihkan buffer dengan mengeluarkan semua yang ada di dalamnya? Atau apakah pembilasan buffer berarti sesuatu yang sangat berbeda?

Jawaban:


122

Pertimbangkan untuk menulis ke file. Ini adalah operasi yang mahal. Jika dalam kode Anda Anda menulis satu byte dalam satu waktu, maka setiap penulisan byte akan sangat mahal. Jadi, cara umum untuk meningkatkan kinerja adalah dengan menyimpan data yang Anda tulis dalam buffer sementara. Hanya jika ada banyak data buffer ditulis ke file. Dengan menunda penulisan, dan menulis blok besar sekaligus, kinerja ditingkatkan.

Dengan pemikiran ini, membersihkan buffer adalah tindakan mentransfer data dari buffer ke file.

Apakah ini menghapus buffer dengan menghapus semua yang ada di dalamnya atau apakah itu menghapus buffer dengan mengeluarkan semua yang ada di dalamnya?

Yang terakhir.


1
Terima kasih. satu hal lagi. Membaca cin flushes cout. Apakah ini "membaca cin" berarti ketika pengguna memasukkan sesuatu atau ketika pengguna diminta untuk memasukkan sesuatu?
Mohamed Ahmed Nabil

4
Membaca cin terjadi saat Anda menggunakan operator aliran untuk membaca dari cin. Biasanya Anda ingin flush cout ketika Anda membaca karena jika tidak, masukan mungkin muncul sebelum prompt.
David Heffernan

1
@DavidHeffernan Sejauh yang saya tahu, Anda tidak perlu flush cout sebelum cin, karena cin dan cout terikat (Stroustrup, The C ++ Programming Language, [io.tie]).
kokoh

24

Anda telah mengutip jawabannya:

Buffer keluaran dapat secara eksplisit dibilas untuk memaksa buffer ditulis.

Artinya, Anda mungkin perlu "mengosongkan" keluaran agar dapat ditulis ke aliran yang mendasarinya (yang mungkin berupa file, atau dalam contoh yang terdaftar, terminal).

Umumnya, stdout / cout adalah baris-buffer: keluaran tidak dikirim ke OS sampai Anda menulis baris baru atau secara eksplisit membersihkan buffer. Keuntungannya adalah sesuatu seperti std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlmenyebabkan hanya satu penulisan ke "file" yang mendasarinya, bukan enam, yang jauh lebih baik untuk kinerja. Kerugiannya adalah kode seperti:

for (int i = 0; i < 5; i++) {
    std::cout << ".";
    sleep(1); // or something similar
}

std::cout << "\n";

akan mengeluarkan .....sekaligus (untuk sleepimplementasi yang tepat , lihat pertanyaan ini ). Dalam kasus seperti itu, Anda akan menginginkan tambahan << std::flushuntuk memastikan bahwa output ditampilkan.

Membaca cinflushes coutsehingga Anda tidak memerlukan flush eksplisit untuk melakukan ini:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;

Melakukan ini untuk (int i = 0; i <5; i ++) {std :: cout << "."; tidur (1); } std :: cout << std :: endl; tidak mencetak ..... sekaligus. Ini mencetaknya dengan 1 milidetik di antaranya. Anda akan lebih menyadarinya saat Anda menggunakan sleep (1000)
Mohamed Ahmed Nabil

@MohamedAhmedNabil Anda tampaknya bingung sleep()(POSIX) dengan Sleep()(Windows)
tc.

1
Jawaban lama, tetapi hanya komentar yang kurang tentang konten dan lebih banyak tentang contoh. Anda memenuhi syarat coutdengan namespace (yaitu, std::cout) tetapi tidak melakukannya untuk endl, yang juga harus memerlukan kualifikasi itu.
vol7ron

1
Saya suka teladan Anda. Tapi saya pikir endl membersihkan buffer, tapi dalam contoh Anda, \ n membersihkan buffer. Saya bingung.
Naz

1
@Naz \ n tidak membersihkan buffer; buffer hanya di-flush di akhir program dalam contohnya (buffer selalu secara otomatis di-flush di akhir program C ++). \ n sepertinya hanya digunakan untuk pemformatan. Juga, Anda benar bahwa std :: endl membersihkan buffer (begitu pula std :: flush, tapi itu sudah cukup jelas).
liamnickell

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.