อะไรคือคำจำกัดความของคำนิยามของสตริงใน C?


10

ฉันควรจะตอบคำถามการบ้านสำหรับชั้นเรียนของฉัน โดยเฉพาะฉันควรจะบอกว่าอาร์เรย์บางตัวใน C ถือเป็นสตริงหรือไม่ อ้างอิงจากบทความนี้ ( https://www.geeksforgeeks.org/strings-in-c-2/ ) ฉันรู้ว่าสตริงนั้นเป็นอาร์เรย์ของตัวละครที่มีตัวสิ้นสุด null ในตอนท้าย

Hangup หลักของฉันเป็นส่วนหนึ่งของคำถามที่ถามเกี่ยวกับอาร์เรย์ที่มีลักษณะดังนี้:

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

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

แก้ไข: จากความคิดเห็นฉันได้ให้ถ้อยคำที่แท้จริงของคำถาม:

"อาร์เรย์ใดต่อไปนี้ถือเป็น" สตริง "เพื่อจุดประสงค์ในการใช้เป็นอาร์กิวเมนต์สำหรับ strcpy (), strncpy (), strcmp (), strcmp (), strncmp () และฟังก์ชั่นสตริงที่คล้ายกัน (ระบุถึงการใช้ทั้งหมด)"

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


4
คุณอาจบอกว่ามันเป็นสตริงที่"CS"มีการเพิ่มขยะขนาดไม่กี่ไบต์ (ในกรณีนี้อักขระ NUL สุดท้ายไม่เกี่ยวข้อง) แต่ไม่ใช่สตริง "โดยรวม" - อย่างไรก็ตามการป้อนข้อมูลนี้strcpyเป็นต้นไม่ได้ทำให้พีซีของคุณระเบิดเพราะฟังก์ชั่นเหล่านี้จะ "เห็น" เฉพาะ"CS"ส่วน
Hagen von Eitzen

2
c1 สามารถอย่างstrcmp()ถูกนำมาใช้เป็นอาร์กิวเมนต์ไปยัง ไม่ว่าจะสามารถใช้เป็นอาร์กิวเมนต์ในการกลายพันธุ์ฟังก์ชั่นสตริงขึ้นอยู่กับปัจจัยเพิ่มเติมที่ไม่ได้ให้ไว้
EOF

2
เนื้อหาของc1ไม่แน่นอนดังนั้นฉันไม่เห็นว่าทำไมจึงไม่สามารถเป็นอาร์กิวเมนต์ปลายทางที่ถูกต้องสำหรับstrcpyหรือคล้ายกันได้เว้นแต่จะมีขนาดไม่ใหญ่พอที่จะรองรับสตริงต้นทาง นั่นจะไม่ทำให้มันไม่ใช่สตริง แต่ไม่ใช่สตริงที่เหมาะสมสำหรับจุดประสงค์ที่กำหนด
John Bollinger

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

1
โปรดทราบว่าชนิดcharไม่จำเป็นต้องเป็น ตัวละครประเภทใดจะทำ
chux - Reinstate Monica

คำตอบ:


8

c1ส่วนใหญ่ [1] เทียบเท่ากับการที่มีการถือครองหนึ่งสตริง&c1[0]"CS"

มีสายที่สองเป็นที่ซุ่มซ่อนในนั้น"324"เริ่มต้นที่&c1[3]- แต่ตราบใดที่คุณเข้าถึงc1เป็นc1สตริง"CS"เป็นฟังก์ชั่นstrcpy(), et al จะเห็น.


[1]: c1เป็นอาร์เรย์&c1[0]เป็นตัวชี้


ดังนั้นมันเหมาะสมที่จะใช้c1เป็นสตริงเป้าหมายในstrcpy()คำสั่งหรือไม่? คำถามนั้นคลุมเครือ - อย่างดีที่สุด
Andrew Henle

1
แน่นอนคุณสามารถใช้เป็นอาร์กิวเมนต์ใดอย่างหนึ่งเพื่อc1 strcpy()มันเป็นสายสามัญที่สมบูรณ์แบบในทุกแง่มุม สตริงสามัญมักจะมีขยะที่เหลือหลังจากเทอร์มินอล ความจริงที่ว่าขยะนี้ถูกเขียนโค้ดลงในโปรแกรมทำให้เกิดความประทับใจที่ผู้เขียนตั้งใจจะใช้c1ในรูปแบบที่ไม่ใช่สายอักขระ แต่นั่นไม่ใช่ส่วนหนึ่งของคำถาม
Lee Daniel Crocker

" c1เทียบเท่ากับ&c1[0]" การเข้าใจผิด c1เป็นอาร์เรย์ &c1[0]เป็นตัวชี้
chux - Reinstate Monica

2

หากคุณต้องการทราบรายละเอียดเฉพาะของคำนิยามของสตริงใน C ให้ไปที่แหล่งที่มา

จากมาตรฐาน C90 :

7 ห้องสมุด

7.1 คำนำ

7.1.1 นิยามของคำสตริงเป็นลำดับต่อเนื่องกันของตัวละครและยกเลิกโดยรวมทั้งอักขระ null แรก สตริง“ ตัวชี้ไป” เป็นตัวชี้ไปยังอักขระเริ่มต้น “ ความยาว” ของสตริงคือจำนวนอักขระที่อยู่หน้าอักขระ null และ“ ค่า” ของมันคือลำดับของค่าของอักขระที่มีอยู่ตามลำดับ

(ไม่มีการเปลี่ยนแปลงที่เกี่ยวข้องในมาตรฐานภายหลัง)

ดังนั้นจึงc1มีสองสายติดต่อกัน "CS" และ "324" แต่ไม่ใช่ตัวสตริง

ถ้าเราส่งอาร์เรย์ไปยังฟังก์ชั่นมันจะสลายตัวไปยังตัวชี้ไปยังองค์ประกอบแรกดังนั้น+c1ชี้ไปที่สตริง (อันแรก) ซึ่งดีพอสำหรับฟังก์ชั่นใด ๆ ที่คาดหวังว่าตัวชี้ไปยังสตริง มันไม่ได้ชี้ไปที่สตริง "CS \ 0324" แต่นั่นอาจจะดีสำหรับคำถามผู้สอนของคุณซึ่งไม่ชัดเจน


4
ฉันจะยืนยันว่าแม้ตามคำจำกัดความนี้ c1 ก็ชัดเจนว่าสตริง "CS" ระยะเวลา ความจริงที่ว่ามันอาจมีไบต์ที่ไม่เป็นศูนย์หลังจากเทอร์มินัลไม่เกี่ยวข้อง - สตริงจำนวนมากจะเป็นเช่นนั้นตลอดชีวิต
Lee Daniel Crocker

+c1ชี้ไปที่สตริงเนื่องจากc1เริ่มต้นด้วยสตริง ที่ไม่ได้อยู่ในรูปแบบหรือรูปแบบใด ๆ ที่สร้างc1สตริงแม้ว่า
Deduplicator

2
มันคือที่อยู่ของส่วนของหน่วยความจำที่มีอักขระบางตัวที่ถูกยกเลิกโดยศูนย์ไบต์ ถ้า printf () ใช้ได้กับ a% s มันจะให้จำนวนที่ดีอย่างสมบูรณ์ที่ส่งผ่านไปยัง strlen () จะทำงานได้ถ้าผ่านไปยัง strcpy () ฯลฯ ดูเหมือนว่าจะเป็นสตริงสำหรับฉัน
Lee Daniel Crocker


แน่นอน. แต่อาร์เรย์สามารถเป็นสตริงได้อย่างแน่นอน
Lee Daniel Crocker

0

การเพิ่มคำตอบของ @ DevSolar สิ่งที่ฉันค้นพบหลังจากเล่นด้วยสตริงที่กำหนดถ้าเป็น:

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

หากคุณส่งออกสายนี้คุณจะได้รับCS03240และขนาดของสายนี้คือ 7 เท่าที่ความเข้าใจของฉันไป\\0จะใช้ในการแสดงถึงตัวละครโมฆะ ( เช่น \0 ) ถ้าคุณทำ:

printf("\0");

คุณไม่เห็นอะไรเลยในบันทึกผลลัพธ์ แต่ถ้าคุณ:

printf("\\0");

คุณเห็น\0สิ่งที่คาดว่าจะได้เนื่องจากการส่งออกอักขระพิเศษเช่นแบ็กสแลชหรือเครื่องหมายคำพูดคุณต้องใช้เครื่องหมาย\พร้อมกับพวกเขา

บางสิ่งที่ทำให้ฉันจับต้องได้คือเอาท์พุทCS03240และขนาด 7 มันเป็นความเข้าใจร่วมกันว่าขนาดของสตริงคือจำนวนตัวอักษรในนั้นบวกหนึ่ง (สำหรับอักขระโมฆะ) นอกจากนี้ขนาดคือ 7 แม้กระทั่งสำหรับสตริง, char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };.

ดังนั้นอาจเป็นไปตามคำถามนี้เกิดอะไรขึ้นที่นี่?


1
'\\0'ไม่ได้เป็นอักขระ null มันเป็นค่าคงที่หลายตัวละคร charมันมีค่าดำเนินการที่กำหนดไว้อย่างแน่นอนนอกช่วงของ c1[]ไม่ได้เป็นสตริงที่มันขาดอักขระ null "คุณเอาท์พุทสายนี้" ผลมีแนวโน้มในพฤติกรรมที่ไม่ได้กำหนด
chux - Reinstate Monica

ฉันไม่ได้รับคุณอย่างแน่นอนแม้ว่าฉันจะค้นหาค่าคงที่ตัวละครหลายตัว ถ้า c1 [] ไม่ใช่สตริงเนื่องจากไม่มีอักขระว่างท้ายทำไมขนาดออกมาเป็น 7 ในกรณีเริ่มต้นตามที่โพสต์โดย OP
rasengan__

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };คือขนาด 7 เนื่องจากถูกกำหนดค่าเริ่มต้นด้วย 7 ค่า มันขนาดมีอะไรจะทำอย่างไรกับสตริง char c1[] = { 1, 2, 3, 4, 5, 6, 7 };ยังคงทำให้มันมีขนาด 7
chux - Reinstate Monica

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