Sử dụng trình điều khiển luồng (endl) hoặc ký tự thoát dòng mới (\ n)?


12

Tôi không có bối cảnh cụ thể trong đó tôi đang đặt câu hỏi, nhưng trong khi tôi đang đọc một cuốn sách dành cho người mới bắt đầu về C ++, tôi nhận thấy việc sử dụng cả trình điều khiển luồng endl và ký tự thoát dòng mới khi xử lý đối tượng luồng.

Sơ đồ như sau:

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

Câu hỏi của tôi là:

  1. Có thích hợp hơn để sử dụng trình điều khiển luồng (endl) trong một tình huống nhất định và một ký tự thoát trong một tình huống khác không?
  2. Có những hạn chế hiệu quả khôn ngoan khi sử dụng một trong hai?
  3. Họ hoàn toàn có thể thay thế cho nhau?
  4. Tôi đọc rằng một chuỗi thoát được lưu trữ trong bộ nhớ dưới dạng một ký tự. Điều đó có nghĩa là nó phù hợp hơn để sử dụng endl nếu bạn đang tiêu thụ bộ nhớ thấp?
  5. Liệu trình xử lý luồng endl sử dụng hết bộ nhớ theo bất kỳ cách nào, nếu vậy nó có nhiều hơn chuỗi thoát không?

Cảm ơn, StackExchange xin lỗi nếu tôi đăng bài này trong phần sai, tôi nghĩ rằng nó được tính là cấu trúc dữ liệu.


2
endl cũng gây ra một luồng trên một số luồng, '\ n' thì không.
James

Câu trả lời:


12

o << std::endl tương đương với đoạn mã sau:

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

Nói cách khác, bạn chỉ nên sử dụng std::endlkhi bạn cần tuôn ra luồng. Ví dụ:

  • Bạn sắp thực hiện một hoạt động tốn thời gian và muốn đảm bảo rằng bạn sẽ hiển thị một tin nhắn trước khi thực hiện.
  • Một quá trình khác đang chờ đợi trên đầu ra của bạn.
  • Nếu có nhiều luồng hoặc tiến trình đang chạy, bạn có thể cần phải xóa đầu ra để đầu ra từ mỗi luồng hoặc tiến trình được hiển thị chính xác. (Nếu không, bạn có thể nhận được các khối đầu ra dường như ngẫu nhiên xen kẽ vào các khoảng thời gian khó xử.)

Nếu bạn không cần phải xóa luồng, sau đó sử dụng \nthay vì std::endl. Các cuộc gọi thêm flushcó thể làm giảm hiệu suất (đôi khi đáng kể).

Để biết thêm chi tiết, xem cppreference.com .

Về việc sử dụng bộ nhớ: Lo lắng về \nso với std::endlgần như chắc chắn là tối ưu hóa vi mô không cần thiết, nhưng nói chung, tôi hy vọng \nsẽ chiếm ít bộ nhớ hơn. \nchỉ là một byte nữa ở cuối một chuỗi ký tự, trong khi viết std::endlđược trình biên dịch dịch thành hàm (có thể được nội tuyến) gọi đến putflush.

Sự khác biệt về nền tảng cụ thể trong các kết thúc dòng (Windows \r\nso với Linux và OS X \n) được xử lý ở mức thấp hơn std::endl\n:

  • Nếu một luồng được mở trong chế độ văn bản, thì nếu bạn viết \n, nó sẽ tự động dịch nó thành dòng kết thúc cụ thể theo nền tảng. Nếu bạn đọc một dòng kết thúc dành riêng cho nền tảng, luồng sẽ tự động dịch nó sang \n.
  • Nếu một luồng được mở ở chế độ nhị phân, thì chúng sẽ chuyển bất kỳ kết thúc dòng nào qua nguyên văn và tùy thuộc vào bạn.
  • Đối với std::coutstd::cinđặc biệt, chúng được đối xử như thể chúng là chế độ văn bản.

1

1) Đối với tính di động, sử dụng endl. Dòng mới của Windows là \r\n, Linux \nvà Mac \r. Chỉnh sửa: Theo nhận xét, các kết thúc cụ thể của hệ thống được xử lý ở mức thấp hơn.

2) endltuôn ra dòng, "\n"không.

3) Phụ thuộc vào tính di động.

Đối với việc sử dụng bộ nhớ, bạn có thể giảm thiểu nó bằng cách xả vào bộ lưu trữ khác thường xuyên nhất có thể với endl. Tuy nhiên, nó sẽ làm giảm hiệu suất.

Chỉnh sửa: Xóa một số sai lầm.


2
Mac đã được unix dựa trên OS X và do đó cũng có \ntrên bất kỳ máy hiện đại nào.

7
Xin lỗi, nhưng điều này không chính xác. endl\ntương đương với các kết thúc dòng cụ thể nền tảng; sự khác biệt nền tảng được xử lý ở mức thấp hơn.
Josh Kelley

2
Điểm đầu tiên của bạn là sai. endl () gửi '\ n' đến luồng (ngoài việc xóa nó). Ký tự '\ n' được chuyển đổi thành nền tảng cụ thể End of line sequence(giả sử chế độ văn bản). Nó End of line sequenceđược chuyển đổi trở lại '\ n` khi đọc từ tệp. Điểm 3) là đáng ngờ. Và đoạn cuối lại một lần nữa sai: Flushing sẽ không giúp bạn tiết kiệm dung lượng và xả nhiều hơn mức cần thiết sẽ làm chậm mã của bạn (điểm của bộ đệm là cải thiện hiệu quả ghi vào thiết bị chậm).
Martin York
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.