Nhiều như tôi yêu C và C ++, tôi không thể không gãi đầu khi lựa chọn các chuỗi kết thúc null:
- Các chuỗi có tiền tố (ví dụ Pascal) tồn tại trước C
- Các chuỗi tiền tố có độ dài làm cho một số thuật toán nhanh hơn bằng cách cho phép tra cứu độ dài thời gian không đổi.
- Các chuỗi tiền tố có độ dài làm cho việc gây ra lỗi tràn bộ đệm trở nên khó khăn hơn.
- Ngay cả trên máy 32 bit, nếu bạn cho phép chuỗi có kích thước của bộ nhớ khả dụng, chuỗi có tiền tố dài chỉ rộng hơn ba byte so với chuỗi kết thúc null. Trên máy 16 bit, đây là một byte đơn. Trên các máy 64 bit, 4GB là giới hạn độ dài chuỗi hợp lý, nhưng ngay cả khi bạn muốn mở rộng nó thành kích thước của từ máy, máy 64 bit thường có bộ nhớ rộng làm cho thêm bảy byte đối số null. Tôi biết tiêu chuẩn C ban đầu được viết cho các máy cực kỳ kém (về bộ nhớ), nhưng đối số hiệu quả không bán cho tôi ở đây.
- Khá nhiều ngôn ngữ khác (ví dụ Perl, Pascal, Python, Java, C #, v.v.) sử dụng các chuỗi có tiền tố dài. Các ngôn ngữ này thường đánh bại C trong các điểm chuẩn thao tác chuỗi vì chúng hiệu quả hơn với chuỗi.
- C ++ đã sửa lỗi này một chút với
std::basic_string
khuôn mẫu, nhưng các mảng ký tự đơn giản mong đợi các chuỗi kết thúc null vẫn còn phổ biến. Điều này cũng không hoàn hảo bởi vì nó đòi hỏi phân bổ heap. - Các chuỗi kết thúc không phải dự trữ một ký tự (cụ thể là null), không thể tồn tại trong chuỗi, trong khi các chuỗi có tiền tố dài có thể chứa các null được nhúng.
Một vài trong số những điều này đã được đưa ra ánh sáng gần đây hơn C, vì vậy sẽ có ý nghĩa đối với C khi không biết về chúng. Tuy nhiên, một số đơn giản là tốt trước khi C đến. Tại sao các chuỗi kết thúc null được chọn thay vì tiền tố chiều dài rõ ràng vượt trội?
EDIT : Vì một số người hỏi về sự thật (và không giống như những gì tôi đã cung cấp) về điểm hiệu quả của tôi ở trên, chúng xuất phát từ một số điều:
- Việc sử dụng chuỗi kết thúc null yêu cầu độ phức tạp thời gian O (n + m). Tiền tố độ dài thường chỉ yêu cầu O (m).
- Độ dài sử dụng chuỗi kết thúc null yêu cầu độ phức tạp thời gian O (n). Tiền tố độ dài là O (1).
- Chiều dài và concat là các hoạt động chuỗi phổ biến nhất. Có một số trường hợp chuỗi kết thúc null có thể hiệu quả hơn, nhưng những điều này xảy ra ít thường xuyên hơn.
Từ các câu trả lời dưới đây, đây là một số trường hợp chuỗi kết thúc null hiệu quả hơn:
- Khi bạn cần cắt bỏ phần bắt đầu của một chuỗi và cần chuyển nó sang một phương thức nào đó. Bạn thực sự không thể làm điều này trong thời gian liên tục với tiền tố độ dài ngay cả khi bạn được phép hủy chuỗi gốc, bởi vì tiền tố độ dài có thể cần phải tuân theo quy tắc căn chỉnh.
- Trong một số trường hợp khi bạn chỉ lặp qua ký tự chuỗi theo ký tự, bạn có thể lưu thanh ghi CPU. Lưu ý rằng điều này chỉ hoạt động trong trường hợp bạn chưa phân bổ động chuỗi (Vì sau đó bạn phải giải phóng nó, bắt buộc phải sử dụng thanh ghi CPU mà bạn đã lưu để giữ con trỏ ban đầu bạn có được từ malloc và bạn bè).
Không có cái nào ở trên gần như phổ biến như chiều dài và concat.
Có thêm một câu khẳng định trong các câu trả lời dưới đây:
- Bạn cần cắt bỏ phần cuối của chuỗi
nhưng điều này là không chính xác - đó là cùng một khoảng thời gian cho các chuỗi tiền tố kết thúc và độ dài null. (Các chuỗi kết thúc không có chỉ là một null trong đó bạn muốn kết thúc mới, các tiền tố có độ dài chỉ trừ đi tiền tố.)