เท่าที่ฉันรัก C และ C ++ ฉันไม่สามารถช่วย แต่เกาหัวของฉันในการเลือกสตริงที่สิ้นสุดด้วยค่า null:
- มีความยาวนำหน้าสตริง (เช่น Pascal) ที่มีอยู่ก่อนหน้า C
- สตริงที่มีคำนำหน้าความยาวทำให้อัลกอริทึมหลายอย่างเร็วขึ้นโดยอนุญาตให้ค้นหาความยาวของเวลาคงที่
- สตริงที่มีคำนำหน้าความยาวทำให้ยากต่อการทำให้เกิดข้อผิดพลาดบัฟเฟอร์เกิน
- แม้บนเครื่อง 32 บิตหากคุณอนุญาตให้สตริงเป็นขนาดของหน่วยความจำที่มีอยู่สตริงที่ขึ้นต้นความยาวจะมีความกว้างเพียงสามไบต์กว้างกว่าสตริงที่สิ้นสุดด้วยค่า null บนเครื่อง 16 บิตนี่เป็นไบต์เดียว บนเครื่อง 64 บิต 4GB เป็นขีดจำกัดความยาวของสตริงที่เหมาะสม แต่แม้ว่าคุณต้องการขยายให้มีขนาดของคำว่าเครื่องเครื่อง 64 บิตมักจะมีหน่วยความจำเพียงพอที่จะทำให้อาร์กิวเมนต์ที่เจ็ดมีค่าเพิ่มขึ้นอีกเจ็ดไบต์ ฉันรู้ว่ามาตรฐาน C ดั้งเดิมเขียนขึ้นสำหรับเครื่องที่ไม่ดีอย่างบ้าคลั่ง (ในแง่ของหน่วยความจำ) แต่อาร์กิวเมนต์ประสิทธิภาพไม่ได้ขายที่นี่
- ค่อนข้างทุกภาษาอื่น ๆ (เช่น Perl, Pascal, Python, Java, C #, ฯลฯ ) ใช้สตริงคำนำหน้าความยาว ภาษาเหล่านี้มักจะเอาชนะ C ในมาตรฐานการจัดการสตริงเพราะพวกเขามีประสิทธิภาพมากขึ้นด้วยสตริง
- C ++ แก้ไขบิตนี้ด้วย
std::basic_string
เทมเพลต แต่อาร์เรย์อักขระธรรมดาคาดว่าสตริงที่สิ้นสุดด้วยค่า null จะยังคงแพร่หลาย สิ่งนี้ยังไม่สมบูรณ์เนื่องจากต้องการการจัดสรรฮีป - สตริงที่สิ้นสุดแล้ว Null ต้องสำรองอักขระ (กล่าวคือ null) ซึ่งไม่มีอยู่ในสตริงในขณะที่สตริงที่ขึ้นต้นด้วยความยาวสามารถมี null ที่ฝังตัวได้
สิ่งต่าง ๆ เหล่านี้มีแสงสว่างเมื่อเร็ว ๆ นี้มากกว่า C ดังนั้นจึงเหมาะสมที่ C ที่จะไม่รู้จัก อย่างไรก็ตามมีหลายคนที่เรียบง่ายก่อนที่ C จะมา เหตุใดจึงต้องเลือกสตริงที่สิ้นสุดด้วยค่า null แทนที่จะเป็นส่วนนำหน้ายาวที่เหนือกว่าอย่างเห็นได้ชัด
แก้ไข : เนื่องจากบางคนถามข้อเท็จจริง (และไม่ชอบสิ่งที่ฉันให้ไว้) ในจุดประสิทธิภาพของฉันด้านบนพวกเขามาจากบางสิ่ง:
- การเชื่อมต่อโดยใช้สตริงที่สิ้นสุดด้วยค่า Null ต้องใช้ความซับซ้อนของเวลา O (n + m) ความยาวของคำนำหน้ามักใช้เพียง O (m)
- ความยาวโดยใช้สตริงที่สิ้นสุดด้วยค่า Null ต้องใช้ความซับซ้อนของเวลา O (n) ความยาวส่วนนำหน้าคือ O (1)
- ความยาวและการต่อกันนั้นเป็นการดำเนินการของสตริงที่พบได้บ่อยที่สุด มีหลายกรณีที่สตริงที่สิ้นสุดด้วยค่า null จะมีประสิทธิภาพมากกว่า แต่เกิดขึ้นน้อยกว่ามาก
จากคำตอบด้านล่างนี่คือบางกรณีที่สตริงที่สิ้นสุดด้วยค่า null จะมีประสิทธิภาพมากกว่า:
- เมื่อคุณต้องการตัดจุดเริ่มต้นของสตริงและต้องผ่านไปยังวิธีการบางอย่าง คุณไม่สามารถทำสิ่งนี้ได้ในเวลาที่แน่นอนด้วยการขึ้นต้นความยาวแม้ว่าคุณจะได้รับอนุญาตให้ทำลายสตริงเดิมเพราะคำนำหน้าความยาวอาจต้องปฏิบัติตามกฎการจัดตำแหน่ง
- ในบางกรณีที่คุณเพิ่งวนลูปผ่านตัวอักษรสตริงโดยตัวละครคุณอาจจะสามารถบันทึกการลงทะเบียน CPU โปรดทราบว่าวิธีนี้ใช้งานได้เฉพาะในกรณีที่คุณไม่ได้จัดสรรสตริงแบบไดนามิก (เพราะคุณจะต้องปล่อยให้เป็นอิสระโดยจำเป็นต้องใช้ CPU ที่คุณบันทึกไว้เพื่อบันทึกตัวชี้ที่คุณได้รับจาก malloc และเพื่อน ๆ )
ไม่ตรงกับความยาวและความยาวเลย
มีอีกหนึ่งคำตอบที่ยืนยันด้านล่าง:
- คุณต้องตัดส่วนท้ายของสตริง
แต่อันนี้ไม่ถูกต้อง - มันเป็นจำนวนเวลาเท่ากันสำหรับการยกเลิก null และสตริงที่มีคำนำหน้ายาว (สตริงที่สิ้นสุดแล้วจะเป็นโมฆะแค่ติดค่า null ที่คุณต้องการให้ปลายใหม่เป็นส่วนนำหน้าความยาวเพียงลบออกจากคำนำหน้า)