อะไรคือกฎสำหรับลำดับการประเมินใน Java?


86

ฉันกำลังอ่านข้อความ Java และได้รับรหัสต่อไปนี้:

int[] a = {4,4};
int b = 1;
a[b] = b = 0;

ในข้อความผู้เขียนไม่ได้ให้คำอธิบายที่ชัดเจนและผลของบรรทัดสุดท้ายคือ: a[1] = 0;

ฉันไม่แน่ใจว่าฉันเข้าใจแล้ว: การประเมินเกิดขึ้นได้อย่างไร?


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

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

คำตอบ:


173

ให้ฉันพูดอย่างชัดเจนเพราะผู้คนเข้าใจผิดตลอดเวลา:

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

พิจารณา A() + B() + C() * D() . การคูณมีลำดับความสำคัญสูงกว่าการบวกและการบวกคือการเชื่อมโยงด้านซ้ายดังนั้นสิ่งนี้จึงเทียบเท่ากับ(A() + B()) + (C() * D()) แต่การรู้ว่ามีเพียงการบอกคุณว่าการบวกครั้งแรกจะเกิดขึ้นก่อนการบวกครั้งที่สองและการคูณจะเกิดขึ้นก่อนการบวกครั้งที่สอง มันไม่ได้บอกคุณว่าจะเรียก A (), B (), C () และ D () ในลำดับใด! (นอกจากนี้ยังไม่ได้บอกคุณด้วยว่าการคูณเกิดขึ้นก่อนหรือหลังการเพิ่มครั้งแรก) จะเป็นไปได้อย่างสมบูรณ์แบบที่จะปฏิบัติตามกฎของลำดับความสำคัญและการเชื่อมโยงโดยรวบรวมสิ่งนี้เป็น:

d = D()          // these four computations can happen in any order
b = B()
c = C()
a = A()
sum = a + b      // these two computations can happen in any order
product = c * d
result = sum + product // this has to happen last

มีการปฏิบัติตามกฎของลำดับความสำคัญและการเชื่อมโยงทั้งหมด - การเพิ่มครั้งแรกเกิดขึ้นก่อนการเพิ่มครั้งที่สองและการคูณจะเกิดขึ้นก่อนการเพิ่มครั้งที่สอง เห็นได้ชัดว่าเราสามารถเรียก A (), B (), C () และ D () ตามลำดับใดก็ได้และยังคงปฏิบัติตามกฎของลำดับความสำคัญและการเชื่อมโยง!

เราต้องการกฎ ไม่เกี่ยวข้องกับกฎของลำดับความสำคัญและการเชื่อมโยงเพื่ออธิบายลำดับที่มีการประเมินนิพจน์ย่อย กฎที่เกี่ยวข้องใน Java (และ C #) คือ "นิพจน์ย่อยถูกประเมินจากซ้ายไปขวา" เนื่องจาก A () ปรากฏทางด้านซ้ายของ C () จึงมีการประเมิน A () ก่อนโดยไม่คำนึงถึงข้อเท็จจริงที่ว่า C () เกี่ยวข้องกับการคูณและ A () เกี่ยวข้องกับการบวกเท่านั้น

ตอนนี้คุณมีข้อมูลเพียงพอที่จะตอบคำถามของคุณ ในa[b] = b = 0กฎของการเชื่อมโยงบอกว่านี่เป็นa[b] = (b = 0);แต่ไม่ได้หมายความว่าb=0วิ่งก่อน! กฎของลำดับความสำคัญกล่าวว่าการจัดทำดัชนีมีความสำคัญสูงกว่าการกำหนด แต่ไม่ได้หมายความว่าผู้จัดทำดัชนีจะทำงานก่อนการกำหนดด้านขวาสุดนั่นไม่ได้หมายความว่าทำดัชนีก่อนจะวิ่งขวาสุดที่ได้รับมอบหมาย

(อัปเดต: เวอร์ชันก่อนหน้าของคำตอบนี้มีการละเว้นเล็กน้อยและไม่สำคัญในทางปฏิบัติในส่วนที่ตามมาซึ่งฉันได้แก้ไขแล้วฉันได้เขียนบทความบล็อกที่อธิบายว่าเหตุใดกฎเหล่านี้จึงเหมาะสมใน Java และ C # ที่นี่: https: // ericlippert.com/2019/01/18/indexer-error-cases/ )

ความสำคัญและการเชื่อมโยงกันเพียงบอกเราว่าได้รับมอบหมายของศูนย์ที่จะbต้องเกิดขึ้นก่อนที่จะมอบหมายให้a[b]เพราะการมอบหมายของศูนย์คำนวณค่าที่ได้รับมอบหมายในการดำเนินงานการจัดทำดัชนีที่ ลำดับความสำคัญและการเชื่อมโยงเพียงอย่างเดียวไม่ได้พูดอะไรเกี่ยวกับการa[b]ประเมินก่อนหน้านี้หรือไม่หรือหลังจากb=0

อีกครั้งนี่ก็เหมือนกับ: A()[B()] = C() - ทั้งหมดที่เรารู้ก็คือการจัดทำดัชนีจะต้องเกิดขึ้นก่อนการมอบหมาย เราไม่รู้ว่า A (), B () หรือ C () ทำงานก่อนตามลำดับความสำคัญและการเชื่อมโยงในวันที่มีความสำคัญและเชื่อมโยงกันตามเราต้องการกฎอื่นเพื่อบอกเราว่า

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

แล้วจะเกิดอะไรขึ้น?

  • a[b]อยู่ทางด้านซ้ายของb=0ดังนั้นการa[b]วิ่งครั้งแรกa[1]ที่เกิดใน อย่างไรก็ตามการตรวจสอบความถูกต้องของการดำเนินการจัดทำดัชนีนี้ล่าช้า
  • แล้วสิ่งที่b=0เกิดขึ้น
  • จากนั้นการตรวจสอบที่aถูกต้องและa[1]อยู่ในระยะจะเกิดขึ้น
  • การกำหนดค่าที่จะa[1]เกิดขึ้นล่าสุด

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

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

หากหัวข้อนี้คุณสนใจโปรดดูบทความของฉันในหัวข้อนี้เพื่ออ่านเพิ่มเติม:

http://blogs.msdn.com/b/ericlippert/archive/tags/precedence/

เป็นเรื่องเกี่ยวกับ C # แต่สิ่งนี้ส่วนใหญ่ใช้ได้ดีกับ Java


6
โดยส่วนตัวแล้วฉันชอบแบบจำลองทางจิตที่ในขั้นตอนแรกคุณสร้างแผนภูมิการแสดงออกโดยใช้ลำดับความสำคัญและการเชื่อมโยง และในขั้นตอนที่สองประเมินต้นไม้นั้นซ้ำ ๆ โดยเริ่มจากราก ด้วยการประเมินผลของโหนดเป็นอยู่: ประเมินทันทีโหนดลูกซ้ายไปขวาและจากนั้นบันทึกของตัวเอง | ข้อดีอย่างหนึ่งของโมเดลนี้คือจัดการกับกรณีที่ตัวดำเนินการไบนารีมีผลข้างเคียงเล็กน้อย แต่ข้อดีหลัก ๆ ก็คือมันเหมาะกับสมองของฉันมากกว่า
CodesInChaos

ฉันถูกต้องหรือไม่ที่ C ++ ไม่รับประกันสิ่งนี้ แล้ว Python ล่ะ?
Neil G

2
@Neil: C ++ ไม่รับประกันอะไรเกี่ยวกับลำดับของการประเมินผลและไม่เคยทำ (หรือไม่ C. ) Python รับประกันอย่างเคร่งครัดตามลำดับก่อนหลัง การมอบหมายงานคือ R2L ไม่เหมือนอย่างอื่น
Donal Fellows

2
@aroth สำหรับฉันคุณฟังดูสับสน และกฎลำดับความสำคัญเป็นเพียงนัยว่าเด็กต้องได้รับการประเมินต่อหน้าผู้ปกครอง แต่พวกเขาไม่ได้พูดอะไรเกี่ยวกับลำดับที่เด็กได้รับการประเมิน Java และ C # เลือกจากซ้ายไปขวา C และ C ++ เลือกพฤติกรรมที่ไม่ได้กำหนด
CodesInChaos

6
@noober: ตกลงพิจารณา: M (A () + B (), C () * D (), E () + F ()) คุณต้องการให้นิพจน์ย่อยได้รับการประเมินในลำดับใด ควรประเมิน C () และ D () ก่อน A (), B (), E () และ F () เนื่องจากการคูณมีความสำคัญสูงกว่าการบวก พูดง่ายๆว่า "ชัด" ลำดับน่าจะต่างกัน การคิดตามกฎจริงที่ครอบคลุมทุกกรณีนั้นค่อนข้างยากกว่า นักออกแบบของ C # และ Java เลือกกฎที่เรียบง่ายและอธิบายได้ง่ายนั่นคือ "จากซ้ายไปขวา" สิ่งที่คุณเสนอมาทดแทนคืออะไรและทำไมคุณถึงเชื่อว่ากฎของคุณดีกว่า
Eric Lippert

32

คำตอบที่เชี่ยวชาญของ Eric Lippert นั้นไม่มีประโยชน์อย่างถูกต้องเพราะมันกำลังพูดถึงภาษาอื่น นี่คือ Java โดยที่ข้อกำหนดภาษา Java เป็นคำอธิบายขั้นสุดท้ายของความหมาย โดยเฉพาะอย่างยิ่ง§15.26.1มีความเกี่ยวข้องเนื่องจากอธิบายถึงลำดับการประเมินสำหรับตัว=ดำเนินการ (เราทุกคนรู้ว่ามันเชื่อมโยงถูกต้องใช่หรือไม่) ตัดทอนให้เหลือเพียงเล็กน้อยที่เราสนใจในคำถามนี้:

หากนิพจน์ตัวถูกดำเนินการด้านซ้ายเป็นนิพจน์การเข้าถึงอาร์เรย์ ( §15.13 ) จำเป็นต้องมีหลายขั้นตอน:

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

[…จากนั้นจะอธิบายความหมายที่แท้จริงของงานนั้นเองซึ่งเราสามารถเพิกเฉยต่อความสั้นได้…]

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

C และ C ++ แตกต่างจาก Java ในด้านนี้อย่างแน่นอน: คำจำกัดความภาษาของพวกเขาออกจากลำดับการประเมินโดยไม่ได้กำหนดโดยเจตนาเพื่อให้สามารถปรับแต่งได้มากขึ้น เห็นได้ชัดว่า C # เหมือน Java แต่ฉันไม่รู้จักวรรณกรรมของมันดีพอที่จะชี้ไปที่คำจำกัดความที่เป็นทางการได้ (สิ่งนี้แตกต่างกันไปตามภาษาจริงๆ Ruby เป็น L2R อย่างเคร่งครัดเช่นเดียวกับ Tcl - แม้ว่าจะไม่มีตัวดำเนินการมอบหมายต่อ seด้วยเหตุผลที่ไม่เกี่ยวข้องที่นี่ - และ Python คือL2R แต่ R2L ในแง่ของการมอบหมายซึ่งฉันคิดว่าแปลก แต่เอาล่ะไป .)


11
สิ่งที่คุณกำลังพูดคือคำตอบของ Eric นั้นผิดเพราะ Java กำหนดโดยเฉพาะให้เป็นอย่างที่เขาพูด?
กำหนดค่า

8
กฎที่เกี่ยวข้องใน Java (และ C #) คือ "นิพจน์ย่อยถูกประเมินจากซ้ายไปขวา" - ฟังดูเหมือนว่าเขากำลังพูดถึงทั้งสองอย่าง
กำหนดค่า

2
สับสนเล็กน้อยที่นี่ทำให้คำตอบข้างต้นของ Eric Lippert เป็นจริงน้อยลงหรือเป็นเพียงการอ้างถึงการอ้างอิงที่เฉพาะเจาะจงว่าเหตุใดจึงเป็นจริง
GreenieMeanie

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

1
สิ่งที่แปลกคือทางขวามือจะถูกประเมินก่อนที่ตัวแปรทางซ้ายจะได้รับการแก้ไข ในa[-1]=c, cการประเมินก่อนที่จะ-1ได้รับการยอมรับในฐานะที่ไม่ถูกต้อง
ZhongYu

5
a[b] = b = 0;

1) ตัวดำเนินการจัดทำดัชนีอาร์เรย์มีลำดับความสำคัญสูงกว่าตัวดำเนินการกำหนด (ดูคำตอบนี้ ):

(a[b]) = b = 0;

2) ตาม 15.26. ผู้ดำเนินการมอบหมายของJLS

มีผู้ดำเนินการกำหนด 12 คน; ทั้งหมดมีการเชื่อมโยงจากขวาไปทางไวยากรณ์ (จัดกลุ่มจากขวาไปซ้าย) ดังนั้น a = b = c หมายถึง a = (b = c) ซึ่งกำหนดค่าของ c ถึง b จากนั้นกำหนดค่าของ b ให้กับ a

(a[b]) = (b=0);

3) ตาม 15.7. ลำดับการประเมินของJLS

ภาษาการเขียนโปรแกรม Java รับประกันว่าตัวถูกดำเนินการของตัวดำเนินการจะได้รับการประเมินตามลำดับการประเมินเฉพาะกล่าวคือจากซ้ายไปขวา

และ

ตัวถูกดำเนินการทางซ้ายมือของตัวดำเนินการไบนารีดูเหมือนจะได้รับการประเมินอย่างสมบูรณ์ก่อนที่จะประเมินส่วนใด ๆ ของตัวถูกดำเนินการทางขวามือ

ดังนั้น:

ก) (a[b])ประเมินก่อนถึงa[1]

b) แล้ว(b=0)ประเมินเป็น0

c) (a[1] = 0)ประเมินล่าสุด


1

รหัสของคุณเทียบเท่ากับ:

int[] a = {4,4};
int b = 1;
c = b;
b = 0;
a[c] = b;

ซึ่งจะอธิบายผล


7
คำถามคือทำไมถึงเป็นเช่นนั้น
จ้า

@ แมทคำตอบคือเพราะนี่คือสิ่งที่เกิดขึ้นภายใต้ประทุนโดยพิจารณาจากรหัสที่ให้ไว้ในคำถาม นั่นคือวิธีที่การประเมินเกิดขึ้น
Jérôme Verstrynge

1
ใช่ฉันรู้. ยังคงไม่ตอบคำถามผ่าน IMO ซึ่งเป็นสาเหตุว่าทำไมการประเมินจึงเกิดขึ้น
จ้า

1
@ แมท 'เหตุใดจึงเกิดการประเมินผล' ไม่ใช่คำถามที่ถาม 'การประเมินเกิดขึ้นได้อย่างไร?' คือคำถามที่ถาม
Jérôme Verstrynge

1
@JVerstry: ยังไงก็ไม่เทียบเท่า นิพจน์ย่อยการอ้างอิงอาร์เรย์ของตัวถูกดำเนินการด้านซ้ายคือตัวถูกดำเนินการด้านซ้ายสุด ดังนั้นการพูดว่า "ทำซ้ายสุดก่อน" จึงเหมือนกับการพูดว่า "ทำการอ้างอิงอาร์เรย์ก่อน" หากผู้เขียนข้อมูลจำเพาะ Java เลือกที่จะใช้คำมากและซ้ำซ้อนโดยไม่จำเป็นในการอธิบายกฎนี้ก็จะดีสำหรับพวกเขา สิ่งนี้สร้างความสับสนและควรเป็นมากกว่าคำน้อย แต่ฉันไม่เห็นว่าลักษณะที่กระชับของฉันมีความหมายแตกต่างจากการแสดงลักษณะของ prolix อย่างไร
Eric Lippert

0

ลองพิจารณาตัวอย่างเชิงลึกอื่น ๆ ด้านล่าง

ตามกฎทั่วไปของ Thumb:

ที่ดีที่สุดคือมีตารางลำดับความสำคัญของกฎและความสัมพันธ์ที่มีให้อ่านเมื่อแก้คำถามเหล่านี้เช่นhttp://introcs.cs.princeton.edu/java/11precedence/

นี่คือตัวอย่างที่ดี:

System.out.println(3+100/10*2-13);

คำถาม: อะไรคือผลลัพธ์ของบรรทัดด้านบน?

คำตอบ: ใช้กฎแห่งความสำคัญและความสัมพันธ์

ขั้นตอนที่ 1: ตามกฎของลำดับความสำคัญ: / และ * ตัวดำเนินการจะมีลำดับความสำคัญมากกว่าตัวดำเนินการ + - ดังนั้นจุดเริ่มต้นในการดำเนินการสมการนี้จะแคบลงเป็น:

100/10*2

ขั้นตอนที่ 2: ตามกฎและลำดับความสำคัญ: / และ * มีความสำคัญเท่ากัน

ตัวดำเนินการในฐานะ / และ * มีความสำคัญเท่ากันเราจำเป็นต้องดูความสัมพันธ์ระหว่างตัวดำเนินการเหล่านั้น

ตามกฎความสัมพันธ์ของตัวดำเนินการสองตัวนี้เราเริ่มดำเนินการสมการจากซ้ายไปขวาคือ 100/10 ได้รับการดำเนินการก่อน:

100/10*2
=100/10
=10*2
=20

ขั้นตอนที่ 3: ขณะนี้สมการอยู่ในสถานะการดำเนินการดังต่อไปนี้:

=3+20-13

ตามกฎและลำดับความสำคัญ: + และ - มีความสำคัญเท่ากัน

ตอนนี้เราต้องดูความสัมพันธ์ระหว่างตัวดำเนินการ + และ - ตัวดำเนินการ ตามความเชื่อมโยงของตัวดำเนินการสองตัวนี้เราเริ่มดำเนินการสมการจากซ้ายไปขวาเช่น 3 + 20 ได้รับการดำเนินการก่อน:

=3+20
=23
=23-13
=10

10 คือผลลัพธ์ที่ถูกต้องเมื่อคอมไพล์

อีกครั้งเป็นสิ่งสำคัญที่จะต้องมีตารางลำดับความสำคัญของกฎและการเชื่อมโยงกับคุณเมื่อแก้ปัญหาเหล่านี้เช่นhttp://introcs.cs.princeton.edu/java/11precedence/


1
คุณกำลังบอกว่า "การเชื่อมโยงระหว่างตัวดำเนินการ + และ -" คือ "RIGHT TO LEFT" 10 - 4 - 3พยายามที่จะใช้ตรรกะที่และประเมินผลการศึกษา
Pshemo

1
ฉันสงสัยว่าความผิดพลาดนี้อาจเกิดจากความจริงที่ว่าที่ด้านบนของintrocs.cs.princeton.edu/java/11precedence +เป็นตัวดำเนินการแบบ unary (ซึ่งมีการเชื่อมโยงจากขวาไปซ้าย) แต่การเติมแต่ง + และ - เหมือนกับการคูณ * /% ทางซ้าย เพื่อการเชื่อมโยงที่เหมาะสม
Pshemo

เห็นแล้วและได้รับการแก้ไขอย่างดีขอบคุณ Pshemo
Mark Burleigh

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