เราสามารถเขียนความคิดเห็นภายในชื่อตัวแปรได้หรือไม่?


144

หากฉันมีรหัสด้านบนและต้องการนับโทเค็นจะเป็นโทเค็น 14 หรือ 13 หรือไม่?

การเขียนความคิดเห็นภายในชื่อตัวแปรถูกต้องหรือไม่ คุณสามารถคิดว่าint i, int a, int iaมีการกำหนดทั่วโลก


13
ใน pre-ANSI "ดั้งเดิม" C อย่างน้อยเป็นที่ดำเนินการโดยGNUcpp -traditionalia = 10;ก็จะขยายตัวออกไป
Nate Eldredge

37
คำถามที่น่าสนใจคืออะไร - ทำไมถึงไม่เคยเกิดขึ้นกับฉันมาก่อน
StephenBoesch

178
@javadba: เพราะคนที่มีสติสัมปชัญญะไม่คิดจะทำสิ่งนั้น?
jamesqf

5
หากคุณต้องการทำเช่นนั้นจริงๆคุณสามารถเปลี่ยนไปใช้ Fortran ช่องว่างนอกสตริงจะถูกลบออกในขั้นตอนการแยกวิเคราะห์แรก
mpez0

3
ฉันกำลังจะแก้ไขชื่อเรื่องเป็น ".... ภายในชื่อตัวแปร ... " แต่แล้วก็รู้ว่าคุณอาจหมายถึง "ระหว่าง" จริงๆ (ฉันต้องการแก้ไขเพราะคำตอบของชื่อเรื่องเดิมคือ "ทำไมชัด!" ส่วนที่สำคัญคือ "ไม่มีช่องว่าง") ชื่อ "แสดงความคิดเห็น (ไม่มีช่องว่างรอบข้าง) จะแยกโทเค็นใน C หรือไม่" แสดงคำถามที่แท้จริงของคุณ?
Peter - คืนสถานะ Monica

คำตอบ:


198

ความคิดเห็นจะถูกลบออกในช่วงที่ 3 ของการแปลโปรแกรม1 : แต่ละความคิดเห็นจะถูกแทนที่ด้วยอักขระเว้นวรรคหนึ่งตัว ดังนั้นความคิดเห็น/*nt*/จึงไม่ใช่โทเค็นอย่างแน่นอน

ถ้าไม่มีint, main, i, aหรือreturnจะถูกกำหนดเป็น preprocessing แมโครแยกโปรแกรมผลิต14ราชสกุล (ไม่ใช่ 13):

int main ( ) { i a = 10 ; return 0 ; }

เว้นแต่iจะกำหนดเป็นประเภทที่มีtypedefคำสั่งจะมีข้อผิดพลาดทางไวยากรณ์เป็นi aไม่ตรงกับกฎในไวยากรณ์ C

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

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

แต่นิยามมาโครข้างต้นไม่ได้กำหนดมาโครที่เหมือนฟังก์ชัน แต่เป็นมาโครปกติSTATที่ขยายเป็น( a ) - 1ที่ขยายเพื่อ

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

ด้านล่างนี้คือโค้ดแฟรกเมนต์3ที่สร้างโทเค็น 14 แบบเดียวกัน:

สังเกตว่า code colorizer พลาดคำหลักที่หั่นและหั่นสี่เหลี่ยมลูกเต๋าและแสดงความคิดเห็นได้อย่างไร :)


1) พฤติกรรมนี้ระบุไว้ใน ANSI-C aka C89 คอมไพเลอร์โบราณบางตัวมีพฤติกรรมที่แตกต่างกันเล็กน้อยซึ่งส่งผลให้มีการวางโทเค็น แต่ลักษณะเฉพาะดังกล่าวเป็นที่สนใจในประวัติศาสตร์เท่านั้น

2) คุณสามารถแทรกข้อคิดเห็นภายในค่าคงที่ของสตริงได้โดยใช้ประโยชน์จากความจริงที่ว่าค่าคงที่ของสตริงที่อยู่ติดกันจะเชื่อมต่อกันในขั้นตอนที่ 6 ของการแปลโปรแกรม: printf("Hello "/* my name is Luca */"world!\n");

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


ฉันสงสัยว่าเหตุใด Standard จึงต้องการให้อักขระแบ็กสแลชที่มีความต่อเนื่องบรรทัดไม่ถูกแยกออกจากบรรทัดใหม่ด้วยอักขระเว้นวรรคอื่น ๆ เนื่องจากไม่มีสถานการณ์อื่นใดที่การเว้นช่องว่างต่อท้ายหรือการขาดจะมีนัยสำคัญทางความหมายและรูปแบบไฟล์ข้อความบางรูปแบบอาจไม่ สามารถแยกแยะบรรทัดที่ลงท้ายด้วยช่องว่างจากบรรทัดที่ไม่มี?
supercat

@supercat: ฉันเห็นด้วย นอกจากนี้ยังครอบคลุมถึงกรณีของไฟล์ที่มาจากระบบเดิมที่ใช้ลำดับ CR LF เป็นส่วนท้ายบรรทัดที่ทำให้เกิดข้อผิดพลาดในการคอมไพล์บนระบบยูนิกซ์ที่ไม่รู้จักบรรทัดใหม่ที่ใช้ Escape ซึ่งรวมถึง\rก่อนหน้าไฟล์\n. ยังมีกรณีที่สิ่งนี้จะย้อนกลับ: ความคิดเห็นอาจมี \ ตัวอักษรตามด้วยช่องว่างโดยเฉพาะเพื่อหลีกเลี่ยงการวางบรรทัด:const char *path = "C:\\"; // the default path is C:\ 
chqrlie

มาตรฐานไม่ต้องการให้ไฟล์ข้อความสามารถรองรับอักขระเว้นวรรคที่ท้ายบรรทัด การเขียนความคิดเห็นเช่นThe path is "C:\"นี้ดูเหมือนจะดีกว่าการให้ความหมายของรหัสขึ้นอยู่กับการขึ้นบรรทัดใหม่
supercat

1
ในทางเทคนิคแล้วมาตรฐานไม่ได้กำหนดข้อกำหนดดังกล่าวเนื่องจากระยะการแปลที่ไม่สนใจระยะที่1ได้รับอนุญาตให้ตัดช่องว่างต่อท้ายจากทุกบรรทัดตราบเท่าที่มีการบันทึกพฤติกรรมนี้ไว้
zwol

4
คำตอบนี้ไปได้ไกลเพียงเพื่อพิสูจน์ว่าไม่มีคำถามโง่ ๆ ทำได้ดี.
Overbryd

65

จากมุมมองของคำศัพท์ความคิดเห็นจะเหมือนกับการเว้นวรรค

มาตรา 6.4p3 ของมาตรฐาน Cเกี่ยวกับสถานะของคำศัพท์:

... ราชสกุลกระบวนการเตรียมการผลิตสามารถแยกออกจากพื้นที่สีขาว ; ซึ่งประกอบด้วยข้อคิดเห็น (อธิบายในภายหลัง) หรืออักขระเว้นวรรค (ช่องว่างแท็บแนวนอนบรรทัดใหม่แท็บแนวตั้งและฟีดแบบฟอร์ม) หรือทั้งสองอย่าง ...

โดยเฉพาะอย่างยิ่งความคิดเห็นจะถูกแปลเป็นช่องว่างเดียว สิ่งนี้ระบุไว้ในส่วน 5.1.1.2p3:

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

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

ดังนั้นความคิดเห็นเช่นช่องว่างทำหน้าที่แยกโทเค็น

ซึ่งหมายความว่ารหัสจะมี 14 โทเค็นไม่ใช่ 13



12

ดูการแปล (aka การรวบรวม) ระยะที่ 3ขั้นตอนที่ 2: "แต่ละความคิดเห็นจะถูกแทนที่ด้วยอักขระเว้นวรรคหนึ่งตัว" "ความคิดเห็นแต่ละคนจะถูกแทนที่ด้วยอักขระช่องว่างหนึ่ง"

ดังนั้นในแนวความคิดi/*nt*/aจะกลายเป็นi aจุดนั้น


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Machavity

1

เพียงตรวจสอบว่าโค้ดของคุณอยู่ในรูปแบบใด

จะมีหลังจากการประมวลผลล่วงหน้า เพียงเพิ่มแฟล็ก "-E" ในคอมไพเลอร์ของคุณ gcc -E myscript.c และคุณจะได้ผลลัพธ์:

และแน่นอนคุณสามารถสรุปได้ว่ามีข้อผิดพลาด


-9

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


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