ทำไมชื่อตัวแปรเริ่มต้นด้วยตัวเลขไม่ได้?


140

ฉันทำงานกับนักพัฒนา C ++ รายใหม่เมื่อเขาถามคำถาม: "ทำไมชื่อตัวแปรไม่สามารถขึ้นต้นด้วยตัวเลข"

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

นั่นคือคำตอบที่ถูกต้องหรือไม่? มีเหตุผลอะไรอีกไหม?

string 2BeOrNot2Be = "that is the question"; // Why won't this compile?

15
แล้วทำไมถึงไม่มีช่องว่างในนั้น?
ทิม

4
ปัญหานี้เกิดขึ้นก่อน C ++ เป็นเวลาอย่างน้อย 20 ปีหากไม่ย้อนกลับไปที่แอสเซมเบลอร์มาโครตัวแรก
Ken Gentle

2
ใน FORTH คุณทำได้ AFAIK มีคำที่เรียก0ว่ากด 0 ลงบนสแต็ก อีกวิธีหนึ่งคือ0=ตรวจสอบว่า 0 อยู่บนสแต็กหรือไม่
Ingo

12
ทำไมคำถามนี้จึงเป็นที่นิยมและคำตอบผิดมาก หลายภาษาอนุญาตให้ตัวแปรขึ้นต้นด้วยตัวเลข C ++ ไม่ได้เป็นเพียงข้อ จำกัด ที่สะดวกสบายที่หลีกเลี่ยงความคลุมเครือบางอย่าง บางครั้งก็ทำให้ฉันประหลาดใจในทางที่ผิด
david.pfx

5
หากวันนี้ถามคำถามนี้ใน SO คำถามจะถูกเรียกว่าตามความคิดเห็นและปิด ขอบคุณที่ถามสิ่งนี้
บุญ

คำตอบ:


121

เพราะงั้นสตริงของตัวเลขจะเป็นตัวระบุที่ถูกต้องและเป็นตัวเลขที่ถูกต้อง

int 17 = 497;
int 42 = 6 * 9;
String 1111 = "Totally text";

39
จะเป็นอย่างไรถ้าพวกเขาบอกว่าตัวแปรไม่สามารถเป็นเพียงตัวเลขได้ แล้วไง?
Pyrolistical

6
ฉันต้องใช้เวลานานขึ้นในการสร้างนิพจน์ทั่วไปสำหรับ lexer ในการรับตัวระบุโดยใช้กฎนั้นหากเป็นไปได้ดังนั้นฉันจึงเห็นได้ว่าเหตุใดจึงไม่มีการใช้ภาษาในลักษณะนั้นนอกเหนือจากเหตุผลที่ระบุไว้ใน คำตอบอื่น ๆ
skiphoppy

39
ถ้ามันต้องเป็นตัวเลข + อัลฟ่าคุณก็ยังทำ String 0x123 = "Hello World" ได้ เว้นแต่คุณจะระบุว่าชื่อตัวแปรเป็น "ตัวเลข + อัลฟาที่ไม่ได้แยกวิเคราะห์เป็นการกำหนดตัวเลขที่ถูกต้อง" และนั่นเป็นเรื่องไร้สาระ
eaolson

4
ไม่เป็นไรคอมไพเลอร์: คนที่ใช้ภาษาต้องสามารถแยกแยะชื่อตัวแปรจากตัวเลขได้อย่างง่ายดาย หากอักขระตัวแรกไม่ได้บอกคุณ - หากคุณต้องการค้นหาในส่วนที่เหลือของคำเพื่อดูว่ามีตัวอักษรที่ไม่ใช่ตัวเลขอยู่ที่ไหนรหัสก็จะอ่านยากขึ้น
comingstorm

10
@eaolson: ฉันเคยทำงานกับแอสเซมเบลอร์ซึ่งใช้กฎนั้นกับเลขฐานสิบหกซึ่งขึ้นต้นด้วยA- Fและลงท้ายด้วยh. ทำให้ฉันสะดุดในครั้งแรกที่ฉันพยายามกำหนดป้ายกำกับเพื่อชี้ไปที่ข้อมูลเพลงของ Bach's Two Part Invention # 13 (ชื่อตรรกะ? Bach)
supercat

121

ลองคิดดูสิ:

int 2d = 42;
double a = 2d;

คืออะไร? 2.0? หรือ 42?

คำใบ้ถ้าคุณไม่เข้าใจ d หลังตัวเลขหมายถึงตัวเลขก่อนที่จะเป็นลิเทอรัลคู่


11
นี่คือสัญกรณ์มาช้า [ค่อนข้าง] ("d" สำหรับ "คู่") C89 มาตรฐาน IIRC ตัวเลขนำหน้าในตัวระบุไม่สามารถทำได้หากโครงสร้างนี้เป็นภาษา แต่นั่นไม่ใช่เหตุผลที่ตัวเลขไม่สามารถเริ่มตัวระบุได้
Ken Gentle

1
dไม่ใช่คำต่อท้ายลิเทอรัลลอยตัวที่ถูกต้องใน C ++ ตัวอักษรลอยตัวจะเพิ่มเป็นสองเท่าโดยค่าเริ่มต้นคุณสามารถใช้ได้fหรือlถ้าคุณต้องการตัวลอยหรือลิเทอรัลแบบยาว
CB Bailey

1
สำหรับ Java และในขณะที่คำถามเดิมคือ C ++ แต่ก็ใช้กับภาษาอื่น ๆ เช่น Java แต่ฉันเห็นด้วย นี่ไม่ใช่สาเหตุดั้งเดิมที่ทำให้ตัวระบุไม่สามารถขึ้นต้นด้วยตัวเลขได้
Pyrolistical

52

ตอนนี้เป็นอนุสัญญา แต่เริ่มเป็นข้อกำหนดทางเทคนิค

ในสมัยก่อนตัวแยกวิเคราะห์ภาษาเช่น FORTRAN หรือ BASIC ไม่จำเป็นต้องใช้ช่องว่าง โดยพื้นฐานแล้วสิ่งต่อไปนี้จะเหมือนกัน:

10 V1=100
20 PRINT V1

และ

10V1=100
20PRINTV1

ตอนนี้สมมติว่าอนุญาตให้ใช้คำนำหน้าตัวเลข คุณจะตีความสิ่งนี้อย่างไร?

101V=100

เช่น

10 1V = 100

หรือเป็น

101 V = 100

หรือเป็น

1 01V = 100

ดังนั้นจึงถือว่าผิดกฎหมาย


1
จำนวนน้อย: หมายเลขบรรทัดต้องอยู่ในคอลัมน์ 1-6 และโค้ดที่เรียกใช้งานได้ต่อจากคอลัมน์ 8 ในทางกลับกันDO 10 I=1,50อาจถูกแยกวิเคราะห์อย่างคลุมเครือเป็นDO1 0I=1,50[โดยบังเอิญถ้ามีการใช้จุดแทนเครื่องหมายจุลภาคคำสั่งจะกลายเป็นการกำหนดให้กับ a DO10Iตัวแปรจุดลอยตัวชื่อ
supercat

คำอธิบายที่น่าสนใจ! นั่นเป็นเหตุผลสำหรับภาษาที่เก่ากว่า แต่ก็ยังทำให้ฉันสงสัยว่าทำไมเรายังคงเลือกออกแบบสำหรับภาษาเช่น Python หรือ JavaScript หรือ R.
Charles Clayton

ฉันจำสิ่งนี้ได้อย่างแน่นอนด้วย BASIC และรู้สึกว่านี่อาจเป็นเหตุผลที่ใช้ได้จริงที่สุดของการฝึกฝน ในทางเทคนิคฉันจำได้ไม่ชัดว่ามันอาจกลับไปเป็นภาษาแอสเซมบลีในช่วงต้น ฉันไม่แน่ใจว่าแอสเซมเบลอร์ตัวไหนและฉันก็อาจผิดพลาดได้
Brian Chandler

42

เนื่องจากหลีกเลี่ยงการย้อนรอยในการวิเคราะห์ศัพท์ในขณะที่รวบรวม ตัวแปรเช่น:

Apple;

คอมไพเลอร์จะรู้ว่าเป็นตัวระบุทันทีเมื่อตรงตามตัวอักษร 'A'

อย่างไรก็ตามตัวแปรเช่น:

123apple;

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


2
หากต้องการตอบโดยจดจำคลาสการออกแบบคอมไพเลอร์ของฉันคำตอบนี้ตรงไปตรงมา! Kudos
nehem

15

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

ภาษาที่เว้นวรรคไม่มีนัยสำคัญ (เช่น ALGOL และ FORTRAN ดั้งเดิมถ้าฉันจำไม่ผิด) ไม่สามารถยอมรับตัวเลขเพื่อเริ่มตัวระบุได้ด้วยเหตุผลนั้น

สิ่งนี้ย้อนกลับไปก่อนที่จะมีสัญลักษณ์พิเศษเพื่อแสดงถึงหน่วยเก็บข้อมูลหรือฐานตัวเลข


9

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

ฉันคิดว่าปัญหาส่วนหนึ่งมาจากตัวอักษรตัวเลขเช่น 0xdeadbeef ซึ่งทำให้ยากที่จะคิดกฎสำหรับตัวระบุที่สามารถเริ่มต้นด้วยตัวเลขได้ง่าย วิธีหนึ่งที่ทำได้คืออนุญาตให้มีสิ่งที่ตรงกับ [A-Za-z _] + ที่ไม่ใช่คีย์เวิร์ดหรือตัวเลขตามตัวอักษร ปัญหาคือมันจะนำไปสู่สิ่งแปลก ๆ เช่น 0xdeadpork ได้รับอนุญาต แต่ไม่ใช่ 0xdeadbeef ในที่สุดฉันคิดว่าเราควรจะยุติธรรมกับเนื้อสัตว์ทั้งหมด: P.

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


8
ฮ่า ๆ - "ปัญหาคือมันจะนำไปสู่สิ่งแปลก ๆ เช่น 0xdeadpork ได้รับอนุญาต แต่ไม่ใช่ 0xdeadbeef ในที่สุดฉันคิดว่าเราควรจะยุติธรรมกับเนื้อสัตว์ทั้งหมด: P"
mr-euro

7

ชื่อตัวแปรไม่สามารถขึ้นต้นด้วยตัวเลขได้เนื่องจากอาจทำให้เกิดปัญหาดังต่อไปนี้:

int a = 2;
int 2 = 5;
int c = 2 * a; 

ค่า c คืออะไร? คือ 4 หรือ 10!

ตัวอย่างอื่น:

float 5 = 25;
float b = 5.5;

เป็นตัวเลข 5 ตัวแรกหรือเป็นวัตถุ (ตัวดำเนินการ) มีปัญหาที่คล้ายกันกับ 5 ตัวที่สอง

บางทีอาจมีเหตุผลอื่น ๆ ดังนั้นเราไม่ควรใช้ตัวเลขใด ๆ ในจุดเริ่มต้นของชื่อตัวแปร


แม้ว่าจะกำหนดให้ตัวระบุมีอักขระที่ไม่ใช่ตัวเลขอย่างน้อยหนึ่งตัว แต่ก็ต้องกำหนดให้รูปแบบตัวเลขที่มีตัวอักษรต้องมีอักขระที่ไม่ใช่ตัวเลขและตัวอักษรด้วย [เช่นกำหนดให้ 0x1234 เขียนเป็น $ 1234 และ 1E6 จึงจะเขียนได้ เป็น 1.E6 หรือ 1.0E6] หรือมีชื่อตัวระบุที่ผิดกฎหมายและผิดกฎหมายผสมกัน
supercat

6

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

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

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


4

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

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

เท่าที่ฉันจำได้ (ประมาณ 40 ปี) ฉันไม่คิดว่าฉันไม่เคยใช้ภาษาที่อนุญาตให้ใช้ตัวเลขเพื่อเริ่มชื่อตัวแปร ฉันแน่ใจว่าได้ทำอย่างน้อยหนึ่งครั้ง อาจจะมีใครบางคนที่นี่เคยเห็นสิ่งนี้จริงๆ


1
มันไม่ยากเลย มันทำให้เฟสศัพท์ยากขึ้นนั่นคือทั้งหมด แน่นอนว่าย้อนกลับไปตอนที่ฉันใช้คอมไพเลอร์ฉันได้รับแจ้งว่าการสแกนคำศัพท์อาจใช้เวลามากกว่าหนึ่งในสี่ของเวลารวบรวมทั้งหมด
David Thornley

4

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

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

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

สำหรับตัวอย่างของภาษาที่ค่อนข้างง่าย HTML templating ตัวแปรที่ไม่อนุญาตให้เริ่มต้นด้วยตัวเลขและมีช่องว่างที่ฝังตัวดูที่Qompose


1
จริงๆแล้วมีหลายภาษาที่อนุญาตให้คุณมีอักขระที่ทำเครื่องหมายระบุตัวตนได้ พวกเขาเรียกว่า "sigils" และคุณมีใน Perl และ PHP
Jason Baker

ยกเว้นคุณยังไม่ได้รับอนุญาตให้เริ่มต้นชื่อตัวแปรใน PHP ด้วยตัวเลข - กฎของภาษาห้ามไว้ :-) แต่คุณสามารถทำได้ใน Qompose ด้วยเหตุผลเดียวกัน
staticsan

4

เนื่องจากถ้าคุณอนุญาตให้คีย์เวิร์ดและตัวระบุขึ้นต้นด้วยอักขระตัวเลขตัวเล็กเซอร์ (ส่วนหนึ่งของคอมไพเลอร์) จะไม่สามารถแยกความแตกต่างระหว่างจุดเริ่มต้นของลิเทอรัลตัวเลขและคีย์เวิร์ดได้โดยไม่ต้องซับซ้อนมากขึ้น (และช้ากว่า)


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



2

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

0x, 2d, 5555


ข้อ จำกัด นี้มีอยู่ในภาษาที่ไม่อนุญาตให้ใช้ไวยากรณ์ประเภทนั้น
Jason Baker

2

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

Dykstra ไม่ใช่หรือที่บอกว่า "สิ่งสำคัญที่สุดของเครื่องมือใด ๆ คือผลต่อผู้ใช้"?


1

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

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


สิ่งนี้ก็คือ Forth ไม่มีตัวแยกวิเคราะห์ที่ซับซ้อนมากนัก จริงๆแล้วสิ่งที่น่าสนใจก็คือหากตัวระบุอยู่ระหว่างสองชุดของช่องว่าง
Jason Baker

1

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

มีคำอธิบายที่ดีมากในการนี้เป็นที่นี่


1
เราจะออกแบบนิพจน์ทั่วไปอย่างไรเพื่อให้ตัวแปรชื่อifqหรือdoublezแต่ไม่ใช่ifหรือdouble? ปัญหาพื้นฐานในการอนุญาตให้ตัวระบุเริ่มต้นด้วยตัวเลขคือมีรูปแบบที่มีอยู่ของตัวอักษรฐานสิบหกและตัวเลขทศนิยมซึ่งประกอบด้วยอักขระที่เป็นตัวเลขและตัวอักษร (ภาษาจะใช้บางอย่างเช่น $ 1234 หรือ h'1234 แทน 0x1234 และต้องใช้ตัวเลขเช่น 1E23 เพื่อรวมช่วงเวลาสามารถหลีกเลี่ยงปัญหานั้นได้) โปรดทราบว่าความพยายามที่จะแยก regex-C 0x12E+5สามารถแล้วได้รับการดีดกลับขึ้นมาจากสิ่งที่ชอบ
supercat

1

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


1

คอมไพเลอร์มี 7 เฟสดังนี้:

  1. การวิเคราะห์คำศัพท์
  2. การวิเคราะห์ไวยากรณ์
  3. การวิเคราะห์ความหมาย
  4. การสร้างรหัสระดับกลาง
  5. การเพิ่มประสิทธิภาพรหัส
  6. การสร้างรหัส
  7. ตารางสัญลักษณ์

หลีกเลี่ยงการย้อนรอยในขั้นตอนการวิเคราะห์ศัพท์ในขณะที่รวบรวมส่วนของโค้ด ตัวแปรเช่น Apple คอมไพเลอร์จะทราบตัวระบุทันทีเมื่อตรงตามตัวอักษร 'A' ในขั้นตอนการวิเคราะห์ศัพท์ อย่างไรก็ตามตัวแปรเช่น 123apple คอมไพลเลอร์จะไม่สามารถตัดสินใจได้ว่าจะเป็นตัวเลขหรือตัวระบุจนกว่าจะถึง 'a' และจำเป็นต้องมีการย้อนกลับเพื่อไปในขั้นตอนการวิเคราะห์คำศัพท์เพื่อระบุว่าเป็นตัวแปร แต่ไม่ได้รับการสนับสนุนในคอมไพเลอร์

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


0

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

คำถามคล้ายกับการถามว่าทำไมราชาถึงขยับช่องว่างครั้งละสี่ช่องในหมากรุกไม่ได้? เป็นเพราะในหมากรุกเป็นการเคลื่อนไหวที่ผิดกฎหมาย ได้ในเกมอื่นแน่. มันขึ้นอยู่กับกฎที่กำลังเล่นอยู่


ยกเว้นว่า C ++ ถูกคิดค้นโดยคนที่ยังมีชีวิตอยู่เมื่อไม่นานมานี้ เราสามารถถามพวกเขาได้ว่าทำไมพวกเขาถึงเลือกสิ่งที่พวกเขาทำและปฏิเสธทางเลือกอื่น เช่นเดียวกันใช้ไม่ได้กับหมากรุก
Steve Jessop

แต่นั่นไม่ใช่ประเด็นที่ฉันกำลังทำ เป็นการเปรียบเทียบว่าเหตุใดจึงไม่มีตัวเลขที่จุดเริ่มต้นของชื่อตัวแปรและคำตอบที่ง่ายที่สุดคือเนื่องจากกฎของภาษาไม่อนุญาต
kemiller2002

แน่นอน แต่ฉันไม่คิดว่าผู้ถามเป็นคนโง่เขลา เขาคงทำงานมาไกลแล้วด้วยตัวเอง คำถาม IMO คือ "ทำไมกฎของภาษาไม่อนุญาต" เขาต้องการลดช่องว่างระหว่างการรู้กฎและเข้าใจกฎเหล่านั้น
Steve Jessop

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

ฉันไม่ได้บอกว่าคุณคิดผิดในใจบางครั้งการตัดสินใจของหน่วยงานมาตรฐาน C ++ นั้นเหนือกว่าความเข้าใจของมนุษย์และคุณลงเอยด้วย "เพราะพวกเขาต้องตัดสินใจอะไรบางอย่างและพวกเขาตัดสินใจอย่างนี้" แต่อย่างน้อยก็มีคำถามที่จะถาม :-)
Steve Jessop

0

แต่เดิมเป็นเพียงเพราะจำได้ง่ายกว่า (คุณสามารถให้ความหมายได้มากกว่า) ชื่อตัวแปรเป็นสตริงแทนที่จะเป็นตัวเลขแม้ว่าตัวเลขจะรวมอยู่ในสตริงเพื่อเพิ่มความหมายของสตริงหรืออนุญาตให้ใช้ชื่อตัวแปรเดียวกัน แต่ กำหนดให้มีความหมายหรือบริบทแยกต่างหาก แต่ใกล้เคียง ตัวอย่างเช่น loop1, loop2 ฯลฯ จะแจ้งให้คุณทราบเสมอว่าคุณอยู่ในลูปและ / หรือลูป 2 เป็นลูปภายในลูป 1 คุณต้องการ (มีความหมายมากกว่า) เป็นตัวแปร: address หรือ 1121298? แบบไหนจำง่ายกว่ากัน? อย่างไรก็ตามหากภาษาใช้บางสิ่งเพื่อแสดงว่าไม่ใช่แค่ข้อความหรือตัวเลข (เช่น $ ใน $ address) มันไม่ควรสร้างความแตกต่างเพราะจะบอกคอมไพเลอร์ว่าสิ่งที่ตามมาจะต้องถือว่าเป็นตัวแปร ( ในกรณีนี้).


0

ตัวแปรอาจถือว่าเป็นค่าในระหว่างเวลาคอมไพล์โดยคอมไพเลอร์ดังนั้นค่าอาจเรียกค่าซ้ำแล้วซ้ำอีก


0

ย้อนรอยจะหลีกเลี่ยงในขั้นตอนการวิเคราะห์คำศัพท์ในขณะที่รวบรวมชิ้นส่วนของรหัส ตัวแปรเช่น Apple; คอมไพเลอร์จะทราบตัวระบุทันทีเมื่อตรงตามตัวอักษร 'A' ในขั้นตอนการวิเคราะห์ศัพท์ อย่างไรก็ตามตัวแปรเช่น 123apple; คอมไพเลอร์จะไม่สามารถตัดสินใจได้ว่าเป็นตัวเลขหรือตัวระบุจนกว่าจะถึง 'a' และจำเป็นต้องมีการย้อนกลับเพื่อไปในขั้นตอนการวิเคราะห์คำศัพท์เพื่อระบุว่าเป็นตัวแปร แต่ไม่ได้รับการสนับสนุนในคอมไพเลอร์

ข้อมูลอ้างอิง


0

อาจไม่มีอะไรผิดปกติเมื่อมีการประกาศตัวแปร แต่มีความคลุมเครือบางอย่างเมื่อพยายามใช้ตัวแปรนั้นที่อื่นเช่นนี้:

ให้ 1 = "สวัสดีชาวโลก - - ' พิมพ์ (1) พิมพ์ (1)

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

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