สตริง C ถูกยกเลิกเป็นโมฆะเสมอหรือขึ้นอยู่กับแพลตฟอร์มหรือไม่


13

ตอนนี้ฉันกำลังทำงานกับระบบฝังตัวและหาวิธีที่จะใช้สตริงในไมโครโปรเซสเซอร์ที่ไม่มีระบบปฏิบัติการ จนถึงตอนนี้สิ่งที่ฉันทำคือการใช้ความคิดของการมีตัวชี้ NULL สิ้นสุดตัวอักษรและปฏิบัติต่อพวกเขาเป็นสตริงที่ NULL หมายถึงจุดสิ้นสุด ฉันรู้ว่านี่เป็นเรื่องธรรมดา แต่คุณสามารถเสมอนับเกี่ยวกับเรื่องนี้จะเป็นกรณีที่?

เหตุผลที่ฉันถามคือฉันกำลังคิดว่าอาจจะใช้ระบบปฏิบัติการแบบเรียลไทม์ในบางจุดและฉันต้องการใช้รหัสปัจจุบันของฉันให้มากที่สุด ดังนั้นสำหรับตัวเลือกต่าง ๆ ที่อยู่ข้างนอกฉันจะคาดหวังได้ไหมว่าสตริงจะทำงานเหมือนกันหรือไม่?

ให้ฉันเจาะจงมากขึ้นสำหรับกรณีของฉัน ฉันกำลังใช้ระบบที่ใช้และประมวลผลคำสั่งผ่านพอร์ตอนุกรม ฉันสามารถรักษารหัสการประมวลผลคำสั่งของฉันไว้เหมือนกันได้หรือไม่แล้วคาดว่าวัตถุสตริงที่สร้างขึ้นบน RTOS (ซึ่งมีคำสั่ง) ทั้งหมดนี้จะถูกยกเลิกเป็น NULL หรือไม่ หรือว่ามันจะแตกต่างกันไปตามระบบปฏิบัติการหรือไม่

ปรับปรุง

หลังจากได้รับคำแนะนำให้ดูคำถามนี้ฉันตัดสินใจแล้วว่าไม่ตอบคำถามที่ฉันขอ คำถามก็คือการถามว่าความยาวของสตริงควรส่งผ่านซึ่งแตกต่างอย่างสิ้นเชิงกับสิ่งที่ฉันถามหรือไม่และถึงแม้ว่าคำตอบบางส่วนจะมีข้อมูลที่เป็นประโยชน์ในพวกเขาพวกเขาไม่ใช่สิ่งที่ฉันกำลังมองหา คำตอบที่ดูเหมือนจะให้เหตุผลว่าทำไมหรือทำไมไม่ยุติสตริงด้วยอักขระ null ความแตกต่างกับสิ่งที่ฉันถามคือถ้าฉันสามารถคาดหวังมากขึ้นหรือน้อยลงสตริงที่เกิดในแพลตฟอร์มที่แตกต่างกันเพื่อยุติสตริงของตัวเองด้วย null โดยไม่ต้องออกไปข้างนอกและลองทุกแพลตฟอร์มเดียวถ้ามันสมเหตุสมผล


3
ฉันไม่ได้ใช้ C เป็นเวลานาน แต่ฉันไม่สามารถนึกถึงเวลาที่ฉันวิ่งเข้าสู่การใช้งานที่ไม่ได้ใช้สตริงที่สิ้นสุดด้วยค่า NULL เป็นส่วนหนึ่งของมาตรฐาน C หากฉันจำได้อย่างถูกต้อง (เหมือนที่ฉันบอกว่ามันผ่านไปสักพักแล้ว)
MetalMikester

1
ฉันไม่ใช่ผู้เชี่ยวชาญใน C แต่เท่าที่ฉันรู้ว่าสตริงทั้งหมดใน C เป็นอาร์เรย์ของถ่านสิ้นสุดด้วย null คุณสามารถสร้างประเภทสตริงของคุณเองได้ แต่คุณต้องใช้ฟังก์ชั่นการจัดการสตริงทั้งหมดด้วยตัวเอง
Machado


1
@MetalMikester คุณคิดว่าข้อมูลนี้สามารถพบได้ในข้อมูลจำเพาะ C มาตรฐานหรือไม่
Snoop

3
@ ไม่มีส่วนใหญ่ใช่ แต่จริงๆแล้วเมื่อพูดถึงสตริงใน C พวกเขาเป็นเพียงอาร์เรย์ของอักขระที่ลงท้ายด้วย NULL และนั่นคือถ้าคุณใช้ไลบรารี่สตริงที่ไม่ได้มาตรฐาน แต่นั่นไม่ใช่สิ่งที่เรากำลังพูดถึงที่นี่ ฉันสงสัยว่าคุณจะพบแพลตฟอร์มที่ไม่เคารพโดยเฉพาะอย่างยิ่งกับจุดแข็งของ C ที่สามารถพกพาได้
MetalMikester

คำตอบ:


42

สิ่งที่เรียกว่า "สตริง C" จะถูกยกเลิกเป็นโมฆะบนแพลตฟอร์มใด ๆ นั่นคือวิธีที่ฟังก์ชันไลบรารี C มาตรฐานกำหนดจุดสิ้นสุดของสตริง

ภายในภาษา C ไม่มีสิ่งใดที่ห้ามไม่ให้คุณมีตัวละครมากมายที่ไม่ได้จบลงด้วยการเป็นโมฆะ อย่างไรก็ตามคุณจะต้องใช้วิธีอื่นเพื่อหลีกเลี่ยงการปิดท้ายของสตริง


4
เพียงเพื่อเพิ่ม; โดยปกติแล้วคุณจะมีจำนวนเต็มเพื่อติดตามความยาวของสตริงและจากนั้นคุณก็จบลงด้วยโครงสร้างข้อมูลที่กำหนดเองเพื่อทำสิ่งที่ถูกต้องบางอย่างเช่นคลาส QString ใน Qt
Rudolf Olah

8
กรณีตรงประเด็น: ฉันทำงานกับโปรแกรม C ที่ใช้รูปแบบสตริงที่แตกต่างกันอย่างน้อยห้ารูปแบบ: อาร์เรย์ที่มีค่าเป็นโมฆะchar, charอาร์เรย์ที่มีความยาวเข้ารหัสในไบต์แรก (เรียกกันทั่วไปว่า "สตริงปาสกาล") wchar_t- รุ่นที่ใช้ ด้านบนและcharอาร์เรย์ที่รวมทั้งสองวิธี: ความยาวที่เข้ารหัสในไบต์แรกและอักขระ null ที่ยกเลิกสตริง
Mark

4
@Mark Interfacing ที่มีส่วนประกอบ / แอปพลิเคชั่นบุคคลที่สามจำนวนมากหรือมีรหัสเดิม
Dan Is Fiddling โดย Firelight

2
@DanNeely ทุกอย่างที่กล่าวมา สตริง Pascal สำหรับการเชื่อมต่อกับ MacOS แบบคลาสสิก, สตริง C สำหรับการใช้งานภายในและ Windows, สตริงที่กว้างสำหรับการเพิ่มการสนับสนุน Unicode และสตริงไอ้นั่นเพราะมีคนพยายามที่จะฉลาดและสร้างสตริงที่สามารถเชื่อมต่อกับ MacOS และ Windows ในเวลาเดียวกัน
มาร์ค

1
@ Mark ... และแน่นอนว่าไม่มีใครเต็มใจที่จะจ่ายเงินเพื่อชำระหนี้ทางเทคนิคเพราะ MacOS แบบคลาสสิกนั้นตายไปนานแล้ว ความเห็นอกเห็นใจของฉัน
Dan Is Fiddling โดย Firelight

22

การกำหนดอักขระการยกเลิกนั้นขึ้นอยู่กับคอมไพเลอร์สำหรับตัวอักษรและการใช้งานไลบรารีมาตรฐานสำหรับสตริงโดยทั่วไป มันไม่ได้ถูกกำหนดโดยระบบปฏิบัติการ

การประชุมเรื่องการNULเลิกจ้างกลับไปที่มาตรฐาน C ล่วงหน้าและใน 30 ปีขึ้นไปฉันไม่สามารถพูดได้ว่าฉันได้พบกับสภาพแวดล้อมที่ทำสิ่งอื่นใดแล้ว พฤติกรรมนี้ได้รับการประมวลผลใน C89 และยังคงเป็นส่วนหนึ่งของมาตรฐานภาษา C (ลิงก์ไปยังร่างของ C99):

  • ส่วน 6.4.5 ตั้งค่าสเตจสำหรับNULสตริงที่สิ้นสุดโดยกำหนดให้ a NULต่อท้ายสตริงตัวอักษร
  • ส่วนที่ 7.1.1 จะนำฟังก์ชั่นดังกล่าวไปใช้ในไลบรารีมาตรฐานโดยการกำหนดสตริงเป็น "ลำดับอักขระที่ต่อเนื่องกันซึ่งถูกยกเลิกโดยและรวมถึงอักขระ null ตัวแรก"

ไม่มีเหตุผลใดที่ใครบางคนไม่สามารถเขียนฟังก์ชั่นที่จัดการกับสตริงที่ถูกยกเลิกโดยตัวละครอื่น ๆ ได้ แต่ก็ไม่มีเหตุผลที่จะใช้มาตรฐานที่กำหนดในกรณีส่วนใหญ่เว้นแต่ว่าเป้าหมายของคุณคือให้โปรแกรมเมอร์เหมาะสม :-)


2
เหตุผลหนึ่งคือหลีกเลี่ยงการค้นหาจุดสิ้นสุดของสายอักขระเดียวกันซ้ำแล้วซ้ำอีก
Paŭlo Ebermann

@ PaŭloEbermannถูกต้อง ค่าใช้จ่ายในการผ่านสองค่าแทนที่จะเป็นหนึ่งค่า printf("string: \"%s\"\n", "my cool string")ซึ่งเป็นบิตน่าเบื่อถ้าคุณเพียงแค่ผ่านตัวอักษรสตริงในขณะที่ วิธีเดียวในการส่งผ่านพารามิเตอร์สี่ตัวในกรณีนี้ (นอกเหนือจากไบต์การเลิกจ้างบางส่วน) คือการกำหนดสตริงให้เป็นสิ่งที่ต้องการstd::stringใน C ++ ซึ่งมีปัญหาและข้อ จำกัด ของตัวเอง
cmaster - คืนสถานะโมนิก้า

1
มาตรา 6.4.5 ไม่จำเป็นต้องอักษรสตริงที่จะถูกยกเลิกด้วยตัวอักษรโมฆะ มันบันทึกอย่างชัดเจน " ตัวอักษรสตริงตัวอักษรไม่จำเป็นต้องเป็นสตริง (ดู 7.1.1) เพราะตัวละคร null อาจจะฝังอยู่ในมันโดยลำดับหนี 0 \ "
bzeaman

1
@bzeaman เชิงอรรถกล่าวว่าคุณสามารถสร้างสตริงตัวอักษรที่ไม่ตรงตามคำจำกัดความของ 7.1.1 แต่ประโยคที่อ้างถึงว่าคอมไพเลอร์ที่เข้ากันได้ - NULกำจัดพวกเขาไม่ว่า: "ในการแปลเฟส 7, ไบต์หรือรหัส ของค่าศูนย์ถูกผนวกเข้ากับลำดับอักขระหลายไบต์ที่เป็นผลมาจากสตริงตัวอักษรหรือตัวอักษร " ฟังก์ชั่นห้องสมุดที่ใช้คำจำกัดความของ 7.1.1 หยุดในตอนแรกที่NULพบและจะไม่ทราบหรือไม่สนใจว่ามีอักขระเพิ่มเติมอยู่นอกเหนือ
Blrfl

ฉันยืนแก้ไขแล้ว ฉันค้นหาคำต่างๆเช่น 'null' แต่พลาดไป 6.4.5.5 พูดถึง 'value zero'
bzeaman

3

ฉันกำลังทำงานกับระบบฝังตัว ... โดยไม่มีระบบปฏิบัติการ ... ฉัน ... โดยใช้ความคิดของการมีตัวชี้สิ้นสุดอักขระ NULL และปฏิบัติต่อพวกเขาเป็นสตริงที่ NULL หมายถึงจุดสิ้นสุด ฉันรู้ว่านี่เป็นเรื่องธรรมดา แต่คุณสามารถนับได้ว่าเป็นกรณีนี้หรือไม่?

ไม่มีประเภทสตริงข้อมูลในภาษา C เป็น แต่มีตัวอักษรของสตริง

หากคุณใส่สตริงตัวอักษรในโปรแกรมของคุณโดยปกติแล้วจะเป็น NUL ที่ถูกยกเลิก (แต่ดูกรณีพิเศษที่กล่าวถึงในความคิดเห็นด้านล่าง) กล่าวคือถ้าคุณใส่"foobar"ในสถานที่ที่const char *คาดว่าจะมีค่าคอมไพเลอร์จะปล่อยfoobar⊘ไปที่ const / ส่วนรหัส / ส่วนของโปรแกรมของคุณและค่าของการแสดงออกจะเป็นตัวชี้ไปยังที่อยู่ที่มันเก็บตัวfอักษร (หมายเหตุ: ฉันกำลังใช้เพื่อบ่งบอกถึง NUL ไบต์)

ความรู้สึกอื่น ๆ เท่านั้นที่ภาษา C มีสตริงคือมันมีรูทีนไลบรารีมาตรฐานบางอย่างที่ทำงานกับลำดับอักขระที่สิ้นสุดด้วย NUL รูทีนไลบรารีเหล่านั้นจะไม่มีอยู่ในสภาพแวดล้อมที่ไม่มีโลหะเว้นแต่ว่าคุณจะย้ายมันด้วยตัวเอง

มันเป็นแค่รหัส --- ไม่ต่างจากรหัสที่คุณเขียนเอง หากคุณไม่แยกพวกเขาเมื่อคุณพอร์ตพวกเขาพวกเขาจะทำในสิ่งที่พวกเขาทำเสมอ (เช่นหยุดที่ NUL)


2
Re: "ถ้าคุณใส่ตัวอักษรสตริงในโปรแกรมของคุณมันจะถูกยกเลิก NUL เสมอ": คุณแน่ใจหรือไม่? ฉันค่อนข้างแน่ใจว่า (เช่น) char foo[4] = "abcd";เป็นวิธีที่ถูกต้องในการสร้างอาเรย์ที่ไม่สิ้นสุดด้วยอักขระสี่ตัว
ruakh

2
@ruakh โอ๊ะโอ! เป็นกรณีที่ฉันไม่ได้พิจารณา ฉันคิดเกี่ยวกับสตริงตัวอักษรที่ปรากฏในสถานที่ที่คาดว่าจะchar const * แสดงออก ฉันลืมว่า C initializersบางครั้งสามารถปฏิบัติตามกฎที่แตกต่างกัน
โซโลมอนช้า

@ruakh ตัวอักษรสตริงถูกยกเลิก NUL อาร์เรย์ไม่ได้
jamesdlin

2
@ruakh char[4]คุณมี นั่นไม่ใช่สตริง แต่เริ่มต้นจากหนึ่ง
Caleth

2
@ Caleth "เริ่มต้นจากที่หนึ่ง" ไม่ใช่สิ่งที่จะต้องเกิดขึ้นในเวลาทำงาน ถ้าเราเพิ่มคีย์เวิร์ดstaticลงในตัวอย่างของ Ruakh แล้วคอมไพเลอร์อาจปล่อยNUL ที่ไม่ได้ยกเลิก "abcd" ไปยังส่วนของข้อมูลเริ่มต้นเพื่อให้ตัวแปรถูกเริ่มต้นโดยตัวโหลดโปรแกรม ดังนั้น Ruakh ถูกต้อง: มีอย่างน้อยหนึ่งกรณีที่การปรากฏตัวของสตริงตัวอักษรในโปรแกรมไม่ต้องการให้คอมไพเลอร์ปล่อยสตริงที่สิ้นสุดด้วย NUL (ps, ฉันรวบรวมตัวอย่างจริง ๆ ด้วย gcc 5.4.0 และคอมไพเลอร์ไม่ปล่อย NUL)
โซโลมอนช้า

2

ดังที่คนอื่น ๆ ได้กล่าวถึงการยกเลิกสตริงเป็นข้อตกลงของ C Standard Library คุณสามารถจัดการสตริงได้ทุกวิธีที่ต้องการหากคุณไม่ต้องการใช้ไลบรารีมาตรฐาน

นี่เป็นความจริงของระบบปฏิบัติการใด ๆ ที่มีคอมไพเลอร์ 'C' และคุณสามารถเขียนโปรแกรม 'C' ที่ไม่ได้ทำงานภายใต้ระบบปฏิบัติการจริงตามที่คุณพูดถึงคำถามของคุณ ตัวอย่างเช่นตัวควบคุมสำหรับเครื่องพิมพ์อิงค์เจ็ทที่ฉันออกแบบหนึ่งครั้ง ในระบบฝังตัวค่าใช้จ่ายหน่วยความจำของระบบปฏิบัติการอาจไม่จำเป็น

ในสถานการณ์ที่แน่นหนาหน่วยความจำฉันจะดูลักษณะของคอมไพเลอร์ของฉันต่อคำสั่งชุดประมวลผลเช่น ในแอปพลิเคชันที่มีการประมวลผลสตริงจำนวนมากอาจเป็นที่พึงปรารถนาที่จะใช้ descriptor เช่นความยาวสตริง ฉันกำลังคิดกรณีที่ CPU มีประสิทธิภาพโดยเฉพาะอย่างยิ่งในการทำงานกับ offsets สั้นและ / หรือ offsets สัมพัทธ์กับการลงทะเบียนที่อยู่

ดังนั้นสิ่งที่สำคัญในใบสมัครของคุณ: ขนาดรหัสและประสิทธิภาพหรือความเข้ากันได้กับระบบปฏิบัติการหรือห้องสมุด? การพิจารณาอื่นอาจเป็นการบำรุงรักษา ยิ่งคุณหลงทางจากการประชุมยิ่งยากที่จะรักษาคนอื่น


1

คนอื่น ๆ ได้กล่าวถึงปัญหาที่ใน C สตริงเป็นส่วนใหญ่สิ่งที่คุณทำจากพวกเขา แต่ดูเหมือนจะมีความสับสนในคำถามของคุณที่จะบอกถึงจุดสิ้นสุดและจากมุมมองหนึ่งนี่อาจเป็นสิ่งที่บางคนในตำแหน่งของคุณเป็นห่วง

สตริง C สิ้นสุดด้วยค่า null นั่นคือพวกเขาจะถูกยกเลิกโดยอักขระ null NULที่ พวกมันจะไม่ถูกยกเลิกด้วยตัวชี้ null NULLซึ่งเป็นค่าที่แตกต่างอย่างสิ้นเชิงกับจุดประสงค์ที่แตกต่างอย่างสิ้นเชิง

NULรับประกันว่าจะมีค่าจำนวนเต็มเป็นศูนย์ ภายในสตริงมันก็จะมีขนาดของประเภทตัวละครพื้นฐานซึ่งมักจะเป็น 1

NULLไม่รับประกันว่าจะมีประเภทจำนวนเต็มเลย NULLมีไว้สำหรับใช้ในบริบทของตัวชี้และโดยทั่วไปคาดว่าจะมีประเภทตัวชี้ซึ่งไม่ควรแปลงเป็นอักขระหรือจำนวนเต็มถ้าคอมไพเลอร์ของคุณดี ในขณะที่ความหมายของNULLเกี่ยวข้องกับสัญลักษณ์0ก็ไม่รับประกันว่าจะจริงมีว่าค่า [1] และถ้าการดำเนินการคอมไพเลอร์ของคุณคงเป็นตัวหนึ่ง#define(จำนวนมากไม่ได้เพราะNULL มันไม่ควรจะมีความหมายในที่ไม่ใช่ บริบทตัวชี้) ดังนั้นโค้ดที่ถูกขยายจึงไม่รับประกันว่าจะเกี่ยวข้องกับค่าที่เป็นศูนย์จริง ๆ (แม้ว่ามันจะมีค่า glyph เป็นศูนย์ก็ตาม)

หากNULLพิมพ์แล้วจะไม่น่าจะมีขนาดเท่ากับ 1 (หรือขนาดอักขระอื่น) สิ่งนี้อาจทำให้เกิดปัญหาเพิ่มเติมได้ถึงแม้ว่าค่าคงที่ตัวอักษรจริงไม่มีขนาดตัวอักษรเป็นส่วนใหญ่

ตอนนี้คนส่วนใหญ่จะเห็นสิ่งนี้และคิดว่า "ตัวชี้ว่างเป็นสิ่งอื่นใดนอกจากศูนย์ทั้งหมดบิตอะไรไร้สาระ" - แต่สมมติฐานเช่นนี้มีความปลอดภัยบนแพลตฟอร์มทั่วไปเช่น x86 เท่านั้น เนื่องจากคุณได้กล่าวถึงความสนใจอย่างชัดเจนในการกำหนดเป้าหมายแพลตฟอร์มอื่นคุณต้องคำนึงถึงปัญหานี้เนื่องจากคุณได้แยกรหัสของคุณออกอย่างชัดเจนจากสมมติฐานเกี่ยวกับลักษณะของความสัมพันธ์ระหว่างตัวชี้และจำนวนเต็ม

ดังนั้นในขณะที่สตริง C ถูกยกเลิกค่า null แต่จะไม่ถูกยกเลิกNULLแต่โดยNUL(มักเขียน'\0') รหัสที่ใช้NULLเป็นตัวยุติสตริงอย่างชัดเจนจะทำงานบนแพลตฟอร์มที่มีโครงสร้างที่อยู่ที่ตรงไปตรงมาและจะคอมไพล์ด้วยคอมไพเลอร์จำนวนมาก แต่ก็ไม่ถูกต้องอย่างแน่นอน C


[1] ค่าตัวชี้โมฆะจริงถูกแทรกโดยคอมไพเลอร์เมื่อมันอ่าน0 โทเค็นในบริบทที่มันจะถูกแปลงเป็นประเภทตัวชี้ นี่ไม่ใช่การแปลงจากค่าจำนวนเต็ม0 และไม่รับประกันว่าจะใช้สิ่งใดนอกจากโทเค็น0เองเช่นค่าไดนามิกจากตัวแปร การแปลงไม่สามารถย้อนกลับได้และตัวชี้โมฆะไม่จำเป็นต้องให้ค่า 0 เมื่อแปลงเป็นจำนวนเต็ม


จุดที่ดี ฉันได้ส่งการแก้ไขเพื่อช่วยแก้ไขปัญหานี้
Monty Harder

" NULรับประกันว่าจะมีค่าเป็นศูนย์" -> C ไม่ได้กำหนดNULไว้ แทน C ให้นิยามว่าสตริงมีchracter nullสุดท้ายเป็นไบต์ที่มีบิตทั้งหมดตั้งค่าเป็น 0
chux - Reinstate Monica

1

ฉันใช้สตริงใน C หมายความว่าอักขระที่มีการยกเลิกค่า null เรียกว่า Strings

มันจะไม่มีปัญหาใด ๆ เมื่อคุณใช้ใน baremetal หรือในระบบปฏิบัติการใด ๆ เช่น Windows, Linux, RTOS: (FreeRTO, OSE)

ในการสิ้นสุด null โลกที่ฝังตัวช่วยให้โทเค็นอักขระเป็นสตริงได้มากขึ้น

ฉันใช้สายใน C เช่นนั้นในระบบที่สำคัญด้านความปลอดภัย

คุณอาจสงสัยว่าสตริงตัวจริงใน C คืออะไร?

สตริง C-style ซึ่งเป็นอาร์เรย์นอกจากนี้ยังมีตัวอักษรของสตริงเช่น "this" ในความเป็นจริงประเภทสตริงทั้งสองนี้เป็นเพียงแค่ชุดอักขระที่อยู่ติดกันในหน่วยความจำ

เมื่อใดก็ตามที่คุณเขียนสตริงที่อยู่ในเครื่องหมายคำพูดคู่ C จะสร้างอาร์เรย์ของอักขระสำหรับเราโดยอัตโนมัติซึ่งมีสตริงนั้นซึ่งถูกยกเลิกด้วยอักขระ \ 0

ตัวอย่างเช่นคุณสามารถประกาศและกำหนดอาร์เรย์ของตัวละครและเริ่มต้นด้วยค่าคงที่สตริง:

char string[] = "Hello cruel world!";

คำตอบที่ตรงไปตรงมา: คุณไม่จำเป็นต้องกังวลเกี่ยวกับการใช้อักขระด้วยการยกเลิก null ซึ่งจะทำงานโดยไม่ขึ้นกับแพลตฟอร์มใด ๆ


ขอขอบคุณไม่ทราบว่าเมื่อประกาศด้วยเครื่องหมายคำพูดคู่NULจะเป็นการต่อท้ายโดยอัตโนมัติ
นูป

1

อย่างที่คนอื่น ๆ บอกไว้การยกเลิกโมฆะนั้นค่อนข้างเป็นสากลสำหรับมาตรฐาน C แต่ (อย่างที่คนอื่น ๆ ชี้ไป) ไม่ใช่ 100% ตัวอย่างเช่น (อื่น ๆ ) ระบบปฏิบัติการ VMS มักใช้สิ่งที่เรียกว่า "string descriptors" http://h41379.www4.hpe.com/commercial/c/docs/5492p012.htmlเข้าถึงได้ใน C โดย#include <descrip.h >

สิ่งที่ระดับแอปพลิเคชันสามารถใช้การยกเลิกแบบ null หรือไม่อย่างไรก็ตามนักพัฒนาเห็นว่าเหมาะสม แต่เนื้อหา VMS ระดับต่ำจำเป็นต้องมีตัวอธิบายอย่างแน่นอนซึ่งไม่ได้ใช้การยกเลิกแบบ null เลย (ดูลิงก์ด้านบนเพื่อดูรายละเอียด) นี่คือส่วนใหญ่เพื่อให้ทุกภาษา (C, แอสเซมบลี ฯลฯ ) ซึ่งใช้ VMS ภายในสามารถมีอินเทอร์เฟซร่วมกับพวกเขาโดยตรง

ดังนั้นหากคุณคาดการณ์สถานการณ์ที่คล้ายกันประเภทใดคุณอาจต้องระวังให้มากขึ้นกว่า "การสิ้นสุดด้วยค่า null แบบสากล" ที่อาจจะแนะนำ ฉันจะระมัดระวังมากกว่านี้ถ้าฉันทำสิ่งที่คุณทำ แต่สำหรับสิ่งที่ระดับแอปพลิเคชันของฉันมันปลอดภัยที่จะถือว่าการยกเลิกเป็นโมฆะ ฉันแค่จะไม่แนะนำระดับความปลอดภัยให้กับคุณ รหัสของคุณอาจต้องติดต่อกับชุดประกอบและ / หรือรหัสภาษาอื่น ๆ ณ จุดหนึ่งในอนาคตซึ่งอาจไม่สอดคล้องกับมาตรฐาน C ของสตริงที่สิ้นสุดด้วยค่า null


วันนี้การเลิกจ้าง 0 จริง ๆ แล้วค่อนข้างผิดปกติ C ++ std :: string ไม่, Java String ไม่ได้, Objective-C NSString ไม่, Swift String ไม่ได้ - ดังนั้นไลบรารีภาษาแต่ละภาษาจะสนับสนุนสตริงที่มีรหัส NUL ภายในสตริง (ซึ่งเป็นไปไม่ได้กับ C สตริงด้วยเหตุผลที่ชัดเจน)
gnasher729

@ gnasher729 ฉันเปลี่ยน "... ค่อนข้างเป็นสากลมาก" เป็น "สวยมากทั่วไปสำหรับมาตรฐาน C" ซึ่งฉันหวังว่าจะลบความคลุมเครือและยังคงถูกต้องในวันนี้ (ซึ่งเป็นสิ่งที่ฉันหมายถึงตามหัวข้อและคำถามของ OP)
John Forkosh

0

จากประสบการณ์ของฉันเกี่ยวกับการฝังตัวระบบความปลอดภัยที่สำคัญและแบบเรียลไทม์ไม่ใช่เรื่องแปลกที่จะใช้ทั้งการประชุมสตริง C และ PASCAL เช่นการจัดหาความยาวสตริงเป็นอักขระตัวแรก (ซึ่งจำกัดความยาวไว้ที่ 255) และเพื่อสิ้นสุด สตริงที่มีอย่างน้อยหนึ่ง 0x00, ( NUL) ซึ่งลดขนาดที่สามารถใช้งานได้เป็น 254

เหตุผลหนึ่งคือเพื่อทราบว่าข้อมูลที่คุณคาดหวังหลังจากรับไบต์แรกและอีกประการหนึ่งคือในระบบดังกล่าวขนาดบัฟเฟอร์แบบไดนามิกจะถูกหลีกเลี่ยงหากเป็นไปได้ - การจัดสรรขนาดบัฟเฟอร์ 256 คงที่เร็วกว่าและปลอดภัยกว่า (ไม่ ต้องตรวจสอบว่าmallocล้มเหลว) อีกข้อหนึ่งคือระบบอื่น ๆ ที่คุณสื่อสารด้วยอาจไม่ได้เขียนใน ANSI-C

ในงานฝังใด ๆ มันเป็นสิ่งสำคัญที่จะสร้างและรักษาควบคุมเอกสารอินเตอร์เฟซ (IDC) ที่กำหนดทั้งหมดของโครงสร้างการสื่อสารของคุณรวมทั้งรูปแบบสตริง endianness จำนวนเต็มขนาด ฯลฯ โดยเร็วที่สุดเท่าที่เป็นไปได้ ( นึกคิดก่อนที่จะเริ่ม ) และควรเป็นหนังสือศักดิ์สิทธิ์ของคุณและทุกทีมเมื่อเขียนระบบ - ถ้ามีคนต้องการแนะนำโครงสร้างหรือรูปแบบใหม่จะต้องมีการบันทึกไว้ที่นั่นก่อนและทุกคนที่อาจได้รับผลกระทบแจ้งอาจมีตัวเลือกในการยับยั้งการเปลี่ยนแปลง .

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.