นิพจน์กับคำชี้แจง


431

ฉันถามเกี่ยวกับ c # แต่ฉันคิดว่ามันเหมือนกันในภาษาอื่น ๆ ส่วนใหญ่

ใครบ้างมีคำจำกัดความที่ดีของการแสดงออกและงบและสิ่งที่แตกต่างกันคืออะไร?


4
ฉันพบคำตอบที่คุณเลือกที่จะคลุมเครือ นิพจน์ยังทำอะไรบางอย่าง - มันประเมินค่า ฉันให้คำตอบที่ไม่ชัดเจน
Shelby Moore III

4
@ShelbyMooreIII - ไม่คลุมเครือและผิด คำตอบที่ได้รับการยอมรับนั้นใช้คำพูดในรูปแบบที่ไม่เป็นทางการ แต่ถ้อยคำที่ทำให้เข้าใจง่าย - และที่สำคัญที่สุดความหมายที่สื่อนั้นถูกต้อง
Justin Morgan

@JustinMorgan น่าเศร้าที่คำจำกัดความในคำตอบที่ยอมรับนั้นก็ผิดอย่างเห็นได้ชัด ("ประเมินค่า" / "บรรทัดของรหัส") สำหรับภาษาร่วมสมัยส่วนใหญ่รวมถึงภาษา C-like: การแสดงออกสามารถใช้ในบริบทที่ไม่ได้ประเมินค่า จะทำอย่างไรกับเส้น แม้จะมีคำอธิบายบ้างคำตอบสั้น ๆ ก็ทำให้สับสนและทำให้เข้าใจผิด
FrankHB

คำตอบ:


520

Expression:สิ่งที่ประเมินค่า ตัวอย่าง: 1 + 2 / x
Statement:บรรทัดของโค้ดที่ทำอะไรบางอย่าง ตัวอย่าง: GOTO 100

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

1 + 2 / X

เป็นข้อผิดพลาดใน FORTRAN เพราะไม่ได้ทำอะไรเลย คุณต้องทำอะไรบางอย่างด้วยนิพจน์นั้น:

X = 1 + 2 / X

FORTRAN ไม่มีไวยากรณ์อย่างที่เรารู้ในทุกวันนี้ - ความคิดนั้นถูกคิดค้นพร้อมกับ Backus-Naur Form (BNF) ซึ่งเป็นส่วนหนึ่งของนิยามของ Algol-60 ณ จุดนั้นความแตกต่างทางความหมาย ("มีค่า" กับ "ทำอะไรบางอย่าง") ได้รับการประดิษฐานในรูปแบบของวลีวลีประเภทหนึ่งเป็นการแสดงออกและอีกประโยคหนึ่งเป็นคำพูด

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

1 + 2 / x;

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

1 + 2 / callfunc(12);

เพราะcallfuncอาจทำสิ่งที่มีประโยชน์

เมื่อคุณอนุญาตให้มีการแสดงออกใด ๆ ที่จะเป็นคำสั่งคุณก็อาจอนุญาตให้ผู้ประกอบการที่ได้รับมอบหมาย (=) ภายในการแสดงออก นั่นเป็นเหตุผลที่ C ช่วยให้คุณทำสิ่งต่าง ๆ เช่น

callfunc(x = 2);

นี้ประเมินการแสดงออก x = 2 (การกำหนดค่าของ 2 x) และแล้วผ่านที่ (2) callfuncเพื่อฟังก์ชั่น

การเบลอของนิพจน์และคำสั่งนี้เกิดขึ้นใน C-Derivative ทั้งหมด (C, C ++, C #, และ Java) ซึ่งยังคงมีคำสั่งบางอย่าง (เช่นwhile) แต่อนุญาตให้ใช้นิพจน์เกือบทั้งหมดเพื่อเป็นคำสั่ง (ในการมอบหมาย C # เท่านั้น การโทรการเพิ่มและการลดสามารถใช้เป็นคำสั่งได้ดูคำตอบของ Scott Wisniewski )

การมี "หมวดหมู่วากยสัมพันธ์" สองอัน (ซึ่งเป็นชื่อทางเทคนิคสำหรับการเรียงลำดับข้อความและการแสดงออก) สามารถนำไปสู่การทำซ้ำของความพยายาม ตัวอย่างเช่น C มีสองรูปแบบของเงื่อนไขแบบฟอร์มคำสั่ง

if (E) S1; else S2;

และรูปแบบการแสดงออก

E ? E1 : E2

และบางครั้งผู้คนต้องการความซ้ำซ้อนที่ไม่มี: ในมาตรฐาน C ตัวอย่างเช่นคำสั่งเท่านั้นที่สามารถประกาศตัวแปรท้องถิ่นใหม่ - แต่ความสามารถนี้มีประโยชน์มากพอที่คอมไพเลอร์ GNU C จะให้ส่วนขยาย GNU ที่ช่วยให้นิพจน์ประกาศ ตัวแปรท้องถิ่นเช่นกัน

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


9
หากฉันไม่ได้ตีความคุณผิดที่นี่คุณดูเหมือนจะอ้างว่า "(setf (Third foo) 'goose)" เป็นการแสดงออกไม่ใช่คำสั่งเนื่องจากทั้ง Lisp ซึ่ง "ไม่มีคำสั่ง" และ เพราะ Lisp มีอายุมากกว่าหนึ่งทศวรรษที่เก่ากว่า C ซึ่งเป็น "ภาษาที่เก่าแก่ที่สุดในการทำให้เส้นไม่ชัดเจน [ระหว่างสำนวนและข้อความ] สามารถอธิบายรายละเอียดของสิ่งนั้นให้ฉันได้ไหม
cjs

2
@Curt Sampson คุณถามว่าเป็นคำถามแยกต่างหากหรือไม่
Kelly S. French

5
ถ้าฉันไม่ผิด, callfunc(x = 2);ผ่านxไปไม่ได้callfunc 2ถ้าxเป็นลอย, จะถูกเรียกว่าไม่callfunc(float) callfunc(int)และใน C ++ ถ้าคุณผ่านx=yไปfuncและfuncใช้อ้างอิงและการเปลี่ยนแปลงมันเปลี่ยนแปลงไม่ได้x y
กาเบรียล

ในคำตอบข้างต้นมันเขียนไว้ว่า "Haskell, ... เป็นภาษาทั้งหมดที่ไม่มีคำสั่งประโยค - พวกเขามีเพียงการแสดงออก" ฉันสงสัยว่าทำไมwhereประโยคใน Haskell ถือเป็นนิพจน์ไม่ใช่คำแถลง learnyouahaskell.com/syntax-in-functions#where
skgbanga

@skgbanga ฉันเชื่อว่าwhereเป็นส่วนหนึ่งของการประกาศฟังก์ชั่นไม่ใช่การแสดงออกหรือคำสั่ง
Akangka

22
  • การแสดงออกคือสิ่งที่ให้ค่า: 2 + 2
  • คำสั่งเป็นหนึ่งใน "บล็อก" พื้นฐานของการทำงานของโปรแกรม

โปรดทราบว่าใน C "=" เป็นจริงตัวดำเนินการซึ่งทำสองสิ่ง:

  • ส่งคืนค่าของนิพจน์ย่อยทางขวา
  • คัดลอกค่าของนิพจน์ย่อยทางขวาไปยังตัวแปรทางด้านซ้ายมือ

นี่คือส่วนแยกจากไวยากรณ์ ANSI C คุณจะเห็นได้ว่า C ไม่มีคำสั่งประเภทต่าง ๆ มากมาย ... ส่วนใหญ่ของคำสั่งในโปรแกรมคือคำสั่งการแสดงออกเช่นการแสดงออกด้วยเครื่องหมายอัฒภาคในตอนท้าย

statement
    : labeled_statement
    | compound_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement
    ;

expression_statement
    : ';'
    | expression ';'
    ;

http://www.lysator.liu.se/c/ANSI-C-grammar-y.html


2
ตรรกะไม่ถูกต้องในสิ่งที่เป็นคำสั่ง โปรแกรมการประกาศสามารถดำเนินการได้ แต่โปรแกรมการประกาศไม่มีคำสั่ง คำสั่งคือและไม่"ผลข้างเคียง"คือมีความจำเป็น cf เลย คำตอบของฉัน
Shelby Moore III

15

การแสดงออกเป็นสิ่งที่ส่งกลับค่าในขณะที่คำสั่งไม่ได้

ตัวอย่าง:

1 + 2 * 4 * foo.bar()     //Expression
foo.voidFunc(1);          //Statement

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


6
งบที่แน่นอนสามารถถูกล่ามโซ่ {stmt1; stmt2; stmt3;} เป็นสายโซ่และยังเป็นคำสั่ง (คำสั่งผสม)
ฮิวจ์อัลเลน

5
foo.voidFunc(1);เป็นนิพจน์ที่มีค่าเป็นโมฆะ whileและifเป็นงบ
tzot

ฉันอยากรู้เกี่ยวกับข้อความที่ไม่ผูกมัด จะมีลักษณะเช่น "if (x> 1) ส่งคืนหรือไม่" ถูกพิจารณาว่าเป็นการผูกมัดสองข้อความด้วยกันไหม?
Simon Tewsi

1
@SimonTewsi ฉันเชื่อว่าreturnถือว่าเป็นสถานะ
RastaJedi

@SimonTewsi คำสั่ง return ที่นี่อยู่ภายในบล็อก if ของคำสั่งโดยปริยายดังนั้นจึงเป็นส่วนหนึ่งของคำสั่ง if ที่ไม่ได้ถูกผูกมัดกับมัน คอมไพเลอร์ช่วยให้เราละเว้นการจัดฟันที่นี่เพราะมันเป็นบล็อกบรรทัดเดียว
user2597608

9

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

ดังนั้นการแสดงออกสามารถใช้ในงบ แต่ไม่ใช่วิธีอื่น ๆ

โปรดทราบว่าบางภาษา (เช่น Lisp และฉันเชื่อว่า Ruby และอีกหลายภาษา) ไม่ได้แยกความแตกต่างของคำสั่งกับการแสดงออก ... ในภาษาดังกล่าวทุกอย่างเป็นการแสดงออกและสามารถถูกล่ามโซ่กับการแสดงออกอื่น ๆ


8

สำหรับคำอธิบายของความแตกต่างที่สำคัญในการจัดองค์ประกอบ (ความสามารถในการแสดงออก) ของคำศัพท์และคำพูดการอ้างอิงที่ฉันโปรดปรานคือเอกสารรางวัลทัวริงของ John Backus การเขียนโปรแกรมสามารถปลดปล่อยจากสไตล์ของ von Neumann ได้หรือไม่? .

ภาษาที่จำเป็น (Fortran, C, Java, ... ) เน้นข้อความสำหรับการจัดโครงสร้างโปรแกรมและมีการแสดงออกเป็นความคิดหลัง ภาษาหน้าที่เน้นการแสดงออก หมดจดภาษาทำงานได้มีประสิทธิภาพเช่นการแสดงออกกว่างบก็จะถูกกำจัดออกไปโดยสิ้นเชิง


5

นิพจน์สามารถถูกประเมินเพื่อรับค่าในขณะที่ statement ไม่คืนค่า ( เป็นโมฆะประเภท)

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

ภาษาเชิงคำสั่งต้องใช้ขั้นตอนทั้งหมดเพื่อเป็นรายการของคำสั่ง Expression-oriented languages ​​ซึ่งอาจเป็นภาษาที่ใช้งานได้ทั้งหมดคือรายการของนิพจน์หรือในกรณีของ LISP ซึ่งเป็น S-expression แบบยาวหนึ่งรายการที่แสดงรายการของนิพจน์

แม้ว่าทั้งสองประเภทสามารถเขียนได้ แต่นิพจน์ส่วนใหญ่สามารถเขียนได้โดยพลการตราบเท่าที่ประเภทนั้นตรงกัน ข้อความแต่ละประเภทมีวิธีการเขียนข้อความอื่น ๆ ของตนเองหากสามารถทำได้ทั้งหมด Foreach และถ้า statement ต้องการทั้ง stat เดียวหรือว่า subordinate statement ทั้งหมดจะอยู่ใน block statement หนึ่งอันถัดไปยกเว้นว่า substatements จะอนุญาตให้มี substatements ของตัวเอง

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

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


ประเภทของคำสั่งเป็นประเภทด้านล่าง Voidไม่ใช่ประเภทด้านล่าง ดูคำตอบของฉัน
Shelby Moore III

1
ไม่ใช่null พิมพ์ประเภทด้านล่าง (ค่าเดียวของnull)? จะไม่voidเหมือนหน่วยประเภทมากขึ้น(แต่มีค่าเดียวไม่สามารถเข้าถึงได้)?
Mark Cidade

ถ้าvoidเป็นชนิดที่การกลับมาของฟังก์ชั่นที่ไม่เคยผลตอบแทน (เช่นฟังก์ชั่นที่throws ข้อผิดพลาด) มันเป็นประเภทด้านล่าง มิฉะนั้นvoidจะเป็นประเภทของหน่วย คุณถูกต้องที่คำสั่งที่ไม่สามารถแยกออกมีประเภทหน่วย แต่คำสั่งที่สามารถแยกออกเป็นประเภทด้านล่าง เนื่องจากทฤษฎีบท Halting เรามักจะไม่สามารถพิสูจน์ได้ว่าฟังก์ชั่นไม่ได้แตกต่างดังนั้นฉันคิดว่าหน่วยเป็นนิยาย nullประเภทด้านล่างไม่สามารถมีค่าจึงไม่สามารถมีค่าเดียวของ
Shelby Moore III

1
เกี่ยวกับสิ่งที่ฉันพูดเมื่อสามปีที่แล้วฉันไม่รู้ว่าฉันยังคิดว่างบเป็นประเภทโมฆะหรือประเภทใด ๆ จริง ๆ ในภาษาที่ใช้คำสั่งซึ่งฉันคุ้นเคยค่าและสิ่งใดที่เก็บหรือส่งคืนค่า (เช่นนิพจน์ตัวแปรสมาชิกและฟังก์ชั่น) สามารถมีประเภทได้ ฉันมักจะคิดว่าประเภทด้านล่างเป็นชุดว่าง (ไม่มีค่า) และดังนั้นสิ่งที่ไม่มีอยู่ ontologically จะมีประเภทนี้ nullค่าเป็นจริงpseudovalueแสดงถึงว่ามีการอ้างอิงหมายถึงบางสิ่งบางอย่างที่ไม่มีอยู่
Mark Cidade

1
Mark ฉันชื่นชมความสมเหตุสมผลของการตอบกลับของคุณ คุณเอาคำออกจากปากของฉันและฉันหวังว่ามันชัดเจนว่าฉันยอมรับคุณว่าคุณถูกต้องเพื่อเพิ่มจุดหน่วย ฉันคิดว่าเราเห็นด้วย ฉันไม่อยากจะพูดถึงเรื่องนี้ แต่ดูเหมือนว่าบางคนที่นี่คิดว่าฉันเป็นลบ ฉันแค่พยายามเป็นจริง
Shelby Moore III

4

เพียงแค่: การแสดงออกประเมินค่าเป็นคำสั่งไม่ได้


ดังนั้นคำสั่งทำอะไร? ไม่มีอะไร?
Shelby Moore III

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

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

1
@ShelbyMooreIII Statement ไม่จำเป็นต้องทำอะไรหรือมีผลข้างเคียง เช่น{}เป็นคำสั่ง การใส่คำนั้นด้วยคำพูดที่ทำให้ตกใจไม่เปลี่ยนแปลง งบเป็นโครงสร้างประโยคด้วยความหมาย ไม่มีสิ่งดังกล่าวเป็น "ชั้นความหมาย" - คุณดูเหมือนจะหมายถึงการดำเนินการ คุณบอกว่าคุณพยายามที่จะแม่นยำ แต่คุณล้มเหลว การร้องเรียนของคุณเกี่ยวกับ "ความไม่รู้ของผู้ลงคะแนนเสียง" นั้นเป็นโฆษณาที่บริสุทธิ์ คุณไม่มีข้อมูลเกี่ยวกับสภาพจิตใจของผู้ลงคะแนนเสียง
Jim Balter

ใช่ทุกคนผิดปกติยกเว้นคนที่ไม่ซื่อสัตย์ {}ถูกกำหนดให้เป็นคำสั่งในข้อมูลจำเพาะภาษา C #
Jim Balter

4

บางสิ่งเกี่ยวกับภาษาที่ใช้นิพจน์:


สำคัญที่สุด: ทุกสิ่งคืนค่า


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


ในภาษาที่ใช้นิพจน์ทุกอย่างจะส่งคืนค่า ในตอนแรกมันอาจจะแปลกไปหน่อย - อะไรจะ(FOR i = 1 TO 10 DO (print i))กลับมา?

ตัวอย่างง่ายๆ:

  • (1) ผลตอบแทน 1
  • (1 + 1) ผลตอบแทน 2
  • (1 == 1) ผลตอบแทน TRUE
  • (1 == 2) ผลตอบแทน FALSE
  • (IF 1 == 1 THEN 10 ELSE 5) ผลตอบแทน 10
  • (IF 1 == 2 THEN 10 ELSE 5) ผลตอบแทน 5

ตัวอย่างที่ซับซ้อนมากขึ้น:

  • บางสิ่งเช่นการเรียกใช้ฟังก์ชั่นบางอย่างไม่มีคุณค่าในการส่งคืนจริง ๆ (สิ่งที่สร้างผลข้างเคียงเท่านั้น) การโทร OpenADoor(), FlushTheToilet()หรือTwiddleYourThumbs()จะส่งคืนค่าทางโลกบางประเภทเช่นตกลงเสร็จสิ้นหรือสำเร็จ
  • เมื่อนิพจน์ที่ไม่เชื่อมโยงหลายนิพจน์ถูกประเมินภายในนิพจน์ที่ใหญ่กว่าหนึ่งค่าของสิ่งสุดท้ายที่ประเมินในนิพจน์ขนาดใหญ่จะกลายเป็นค่าของนิพจน์ขนาดใหญ่ ตัวอย่างของ(FOR i = 1 TO 10 DO (print i))ค่า for for loop คือ "10" ซึ่งทำให้(print i)นิพจน์ถูกประเมิน 10 ครั้งแต่ละครั้งที่ส่งคืน i เป็นสตริง เวลาสุดท้ายผ่านการส่งคืน10คำตอบสุดท้ายของเรา

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

เป็นตัวอย่างรวดเร็ว:

 FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO
 (
    LotsOfCode
 )

เป็นการแทนที่ที่สมบูรณ์แบบสำหรับนิพจน์

IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 
FOR i = 1 TO TempVar DO
(    
    LotsOfCode  
)

ในบางกรณีเลย์เอาต์ที่ใช้รหัสนิพจน์ทำให้ฉันรู้สึกเป็นธรรมชาติมากขึ้น

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

IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
(
    LotsOfCode
)

2

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

ตัวอย่างเช่นใน C # เรามีFunc<T1, T2, T3, TResult>ชุดตัวแทนทั่วไปที่มีประโยชน์มากเกินไป แต่เราก็ต้องมีAction<T1, T2, T3>ชุดที่สอดคล้องกันเช่นกันและวัตถุประสงค์ทั่วไปของการเขียนโปรแกรมที่สูงขึ้นอย่างต่อเนื่องจะต้องมีการทำซ้ำเพื่อจัดการกับการแยกไปสองทางที่โชคร้ายนี้

ตัวอย่างเล็กน้อย - ฟังก์ชันที่ตรวจสอบว่าการอ้างอิงเป็นโมฆะก่อนเรียกใช้ฟังก์ชันอื่นหรือไม่:

TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
                  where TValue : class
{
    return (value == null) ? default(TValue) : func(value);
}

คอมไพเลอร์สามารถจัดการกับความเป็นไปได้ของTResultการเป็นvoidอย่างไร ใช่. voidทั้งหมดก็จะต้องทำคือต้องมีผลตอบแทนที่ตามด้วยการแสดงออกที่เป็นที่พิมพ์ ผลลัพธ์ที่ได้default(void)จะเป็นประเภทvoidและ func ที่ถูกส่งผ่านจะต้องอยู่ในรูปแบบFunc<TValue, void>(ซึ่งจะเทียบเท่าAction<TValue>)

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


คำสั่งไม่ใช่กรณีพิเศษของการแสดงออก ในบางภาษา (เช่นผู้สืบทอด C ส่วนใหญ่) จริงๆแล้วมันเป็นวิธีอื่น
Akangka

2

งบ -> คำแนะนำในการติดตาม
นิพจน์ตามลำดับ-> การประเมินผลที่คืนค่า

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

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

ตัวอย่างของข้อความ:

for
goto
return
if

(ทั้งหมดนี้แสดงถึงความก้าวหน้าของบรรทัด (คำสั่ง) ของการดำเนินการไปยังอีกบรรทัดหนึ่ง)

ตัวอย่างของการแสดงออก:

2+2

(มันไม่ได้หมายความถึงความคิดของการดำเนินการ แต่จากการประเมินผล)


แล้วผลข้างเคียงล่ะ?
Austin Henley

@AustinHenley ไม่มีข้อกำหนดสำหรับสิ่งนั้น ในความเป็นจริงการแสดงออกสามารถมีผลข้างเคียงแน่นอน
Akangka

1

คำสั่ง ,

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

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

bool IsPositive(int number)
{
    if (number > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

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

การแสดงออก ,

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

int i = 5;
string s = "Hello World";

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


ฉันควรจะเขียนif(number >= 0) return true; else return false;หรือดียิ่งขึ้นbool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;}:)
Mahdi Tahsildari

1

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

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


1

ฉันไม่พอใจกับคำตอบใด ๆ ที่นี่ ฉันดูไวยากรณ์ของC ++ (ISO 2008)2008) อย่างไรก็ตามบางทีเพื่อประโยชน์ของการสอนและการเขียนโปรแกรมคำตอบอาจพอเพียงเพื่อแยกความแตกต่างขององค์ประกอบทั้งสอง (ความเป็นจริงดูซับซ้อนกว่า)

คำสั่งประกอบด้วยนิพจน์ที่เป็นศูนย์หรือมากกว่า แต่ยังสามารถเป็นแนวคิดภาษาอื่นได้ นี่คือรูปแบบ Extended Backus Naur สำหรับไวยากรณ์ (ข้อความที่ตัดตอนมาสำหรับคำสั่ง):

statement:
        labeled-statement
        expression-statement <-- can be zero or more expressions
        compound-statement
        selection-statement
        iteration-statement
        jump-statement
        declaration-statement
        try-block

เราสามารถเห็นแนวคิดอื่น ๆ ที่ถือว่าเป็นข้อความสั่งใน C ++

  • expression-statement s เป็นการอธิบายตนเอง (คำแถลงอาจประกอบด้วยนิพจน์ที่เป็นศูนย์หรือมากกว่าอ่านไวยากรณ์อย่างระมัดระวังมันเป็นเรื่องยาก)
  • caseตัวอย่างเช่นคำสั่งที่มีข้อความ
  • เลือกคำสั่ง s มีif if/else,case
  • ย้ำคำสั่ง s มีwhile, do...while,for (...)
  • กระโดดงบ s มีbreak, continue, return(สามารถกลับแสดงออก)goto
  • declaration-statementคือชุดของการประกาศ
  • ลองบล็อกคือคำสั่งที่แสดงถึงtry/catchบล็อก
  • และอาจมีไวยากรณ์น้อยลง

นี่เป็นข้อความที่ตัดตอนมาซึ่งแสดงส่วนของนิพจน์:

expression:
        assignment-expression
        expression "," assignment-expression
assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression
  • นิพจน์เป็นหรือมีการมอบหมายบ่อยครั้ง
  • เงื่อนไขการแสดงออก (เสียงทำให้เข้าใจผิด) หมายถึงการใช้งานของผู้ประกอบการ ( +, -, *, /, &, |, &&, ||, ... )
  • การแสดงออก - เอ่อ? throwข้อคือการแสดงออกเกินไป

0

งบเป็นประโยคที่สมบูรณ์ทางไวยากรณ์ การแสดงออกไม่ได้ ตัวอย่างเช่น

x = 5

อ่านว่า "x ได้รับ 5" นี่เป็นประโยคที่สมบูรณ์ รหัส

(x + 5)/9.0

อ่าน "x plus 5 ทั้งหมดหารด้วย 9.0" นี่ไม่ใช่ประโยคที่สมบูรณ์ คำสั่ง

while k < 10: 
    print k
    k += 1

เป็นประโยคที่สมบูรณ์ ขอให้สังเกตว่าส่วนหัวของห่วงไม่ได้; "ขณะที่ k <10" เป็นประโยคย่อย


whileคือการแสดงออกคือบางภาษาเช่น Scala คุณกำลังสร้างไวยากรณ์ที่สับสนขณะพิมพ์ ดูคำตอบของฉัน
Shelby Moore III

นี่คือ while loop ในสกาล่า: tutorialspoint.com/scala/scala_while_loop.htm การวนลูปพร้อมเพรดิเคตและไม่มีเนื้อหาใด ๆ ที่ไม่ได้เป็นประโยคที่สมบูรณ์ทางไวยากรณ์ มันไม่ได้แสดงออกอย่างเต็มรูปแบบ คุณต้องการร่างกายเพื่อให้มันเป็นนิพจน์
ncmathsadist

A whileกับร่างกายยังคงแสดงออกในสกาล่า มันอาจจะเป็นคำสั่งถ้ามันสร้างผลข้างเคียงซึ่งสิ่งที่คำตอบ downvoted หนักของฉันอนุญาต (การแสดงออกยังสามารถเป็นคำสั่ง) คำตอบของฉันคือคำตอบที่ถูกต้องเพียงข้อเดียว ขออภัยที่ผู้อ่านทุกคนที่ไม่เข้าใจ
Shelby Moore III

คุณหมายถึงอะไรโดยสมบูรณ์ทางไวยากรณ์? ใน C (x + 5)/9.0สามารถยืนอยู่คนเดียวอย่างแน่นอนในฐานะคำสั่ง นอกจากนี้หากดำเนินการทางไวยากรณ์แล้วคุณหมายถึงโปรแกรมที่ถูกต้อง C ไม่อนุญาตให้ใช้คำสั่งแบบสแตนด์อะโลนเป็นโปรแกรมเดี่ยว
Akangka

เสร็จสมบูรณ์ทางไวยากรณ์: ถือเป็นประโยคที่สมบูรณ์
ncmathsadist

0

นี่คือฤดูร้อนของหนึ่งในคำตอบที่ง่ายที่สุดที่ฉันพบ

ตอบโดย Anders Kaseorg เป็นครั้งแรก

คำสั่งคือบรรทัดของโค้ดที่สมบูรณ์ซึ่งดำเนินการบางอย่างในขณะที่นิพจน์คือส่วนใด ๆ ของโค้ดที่ประเมินเป็นค่า

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

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

http://www.quora.com/Python-programming-language-1/Whats-the-difference-between-a-statement-and-an-expression-in-Python


0

พื้นฐานความเป็นจริงของแนวคิดเหล่านี้คือ:

นิพจน์ : หมวดหมู่ประโยคที่มีอินสแตนซ์ที่สามารถประเมินค่าได้

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

นอกเหนือจากบริบทเริ่มต้นสำหรับ FORTRAN ในช่วงต้นทศวรรษที่ผ่านมาทั้งคำจำกัดความของการแสดงออกและข้อความในคำตอบที่ยอมรับนั้นผิดอย่างเห็นได้ชัด:

  • การแสดงออกสามารถเป็นตัวถูกดำเนินการ unvaluated ไม่มีการสร้างคุณค่าจากสิ่งเหล่านั้น
    • นิพจน์ย่อยในการประเมินที่ไม่เข้มงวดสามารถประเมินค่าไม่ได้แน่นอน
      • ภาษา C ส่วนใหญ่มีกฎการประเมินการลัดวงจรที่เรียกว่าข้ามการประเมิน subexpression บางอย่างโดยไม่มีการเปลี่ยนแปลงผลสุดท้ายแม้จะมีผลข้างเคียง
    • C และบางภาษาที่มีลักษณะคล้าย C มีความคิดเกี่ยวกับตัวถูกดำเนินการที่ไม่ได้ประเมินค่าซึ่งอาจมีการกำหนดอย่างเป็นบรรทัดฐานในข้อกำหนดภาษา โครงสร้างดังกล่าวใช้เพื่อหลีกเลี่ยงการประเมินผลอย่างแน่นอนดังนั้นข้อมูลบริบทที่เหลืออยู่ (เช่นประเภทหรือข้อกำหนดการจัดตำแหน่ง) สามารถแยกความแตกต่างแบบคงที่โดยไม่ต้องเปลี่ยนพฤติกรรมหลังจากการแปลโปรแกรม
      • ตัวอย่างเช่นการแสดงออกที่ใช้เป็นตัวถูกดำเนินการของsizeofผู้ประกอบการจะไม่เคยประเมิน
  • คำสั่งไม่มีส่วนเกี่ยวข้องกับการสร้างบรรทัด พวกเขาสามารถทำอะไรมากกว่านิพจน์ขึ้นอยู่กับข้อกำหนดของภาษา
    • Modern Fortran ในฐานะผู้สืบทอดโดยตรงของ FORTRAN เก่ามีแนวคิดของคำสั่งที่ปฏิบัติการได้และคำสั่งที่ไม่สามารถดำเนินการได้
    • ในทำนองเดียวกัน C ++ กำหนดประกาศเป็นหมวดหมู่ย่อยระดับบนสุดของหน่วยการแปล การประกาศใน C ++ เป็นคำสั่ง (สิ่งนี้ไม่เป็นความจริงใน C. )นอกจากนี้ยังมีคำสั่ง expressionเช่นคำสั่งปฏิบัติการของ Fortran
    • เพื่อความสนใจของการเปรียบเทียบกับนิพจน์เฉพาะคำสั่ง "ปฏิบัติการ" มีความสำคัญ แต่คุณไม่สามารถเพิกเฉยต่อความจริงที่ว่าข้อความทั่วไปได้ถูกสร้างขึ้นเพื่อสร้างหน่วยการแปลในภาษาที่จำเป็นดังกล่าวแล้ว อย่างที่คุณเห็นนิยามของหมวดหมู่นั้นแตกต่างกันมาก (อาจ) ทรัพย์สินทั่วไปที่เก็บรักษาไว้ในหมู่ภาษาเหล่านี้คือข้อความคาดว่าจะถูกตีความตามลำดับคำศัพท์ (สำหรับผู้ใช้ส่วนใหญ่จากซ้ายไปขวาและจากบนลงล่าง)

(BTW ฉันต้องการเพิ่มคำตอบที่เกี่ยวข้องกับวัสดุที่เกี่ยวกับ C เพราะฉันจำไม่ได้ว่า DMR มีความคิดเห็นเช่นนั้นหรือไม่ดูเหมือนจะไม่มีเหตุผลอื่นที่จะรักษาความซ้ำซ้อนของฟังก์ชันในการออกแบบของ C : โดยเฉพาะเครื่องหมายจุลภาคเทียบกับข้อความ)

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

อย่างไรก็ตามเป็นที่น่าสงสัยว่าเราต้องการหมวดหมู่เฉพาะของ "ข้อความ" ในภาษาโปรแกรมทั่วไป:

  • งบไม่รับประกันว่าจะมีความสามารถทางความหมายมากกว่านิพจน์ในการออกแบบปกติ
    • หลายภาษาประสบความสำเร็จในการละทิ้งแนวคิดเรื่องงบเพื่อให้การออกแบบโดยรวมสะอาดเรียบร้อยและสอดคล้องกัน
      • ในภาษาดังกล่าวนิพจน์สามารถทำทุกอย่างที่คำสั่งแบบเก่าสามารถทำได้: เพียงแค่วางผลลัพธ์ที่ไม่ได้ใช้เมื่อมีการประเมินผลนิพจน์โดยการออกจากผลลัพธ์ที่ไม่ได้ระบุอย่างชัดเจน (เช่นใน R n RS Scheme) หรือมีค่าพิเศษ (ในฐานะ ค่าของประเภทหน่วย) ไม่สามารถผลิตได้จากการประเมินผลนิพจน์ปกติ
      • กฎของคำสั่งการประเมินผลของคำศัพท์สามารถถูกแทนที่ด้วยตัวดำเนินการควบคุมลำดับที่ชัดเจน (เช่นbeginใน Scheme) หรือน้ำตาล syntactic ของโครงสร้าง monadic
      • กฎคำสั่งคำศัพท์ของ "ข้อความ" ชนิดอื่น ๆ สามารถได้รับมาเป็นส่วนขยายของประโยค (ตัวอย่างเช่นใช้แมโครที่ถูกสุขลักษณะ) เพื่อรับฟังก์ชั่นทางไวยากรณ์ที่คล้ายกัน (และสามารถทำอะไรได้มากกว่า )
    • ในทางตรงกันข้ามแถลงการณ์ไม่สามารถมีกฎเกณฑ์ดั้งเดิมเช่นนั้นได้เพราะพวกเขาไม่ได้เขียนถึงการประเมิน: ไม่มีความคิดทั่วไปของ "การประเมินสถานะย่อย" (แม้ว่าจะมีฉันสงสัยว่าอาจมีอะไรมากกว่าคัดลอกและวางจากกฎที่มีอยู่ของการประเมินผลของการแสดงออก)
      • โดยทั่วไปภาษาที่รักษาข้อความสั่งจะมีนิพจน์เพื่อแสดงการคำนวณและมีหมวดหมู่ย่อยระดับบนสุดของคำสั่งที่เก็บรักษาไว้เพื่อการประเมินผลนิพจน์สำหรับหมวดหมู่ย่อยนั้น ตัวอย่างเช่น C ++ มีคำสั่ง expression-statementเป็นหมวดหมู่ย่อยและใช้กฎการประเมินผลนิพจน์ที่ถูกทิ้งค่าเพื่อระบุกรณีทั่วไปของการประเมินผลแบบนิพจน์ทั้งหมดในบริบทดังกล่าว บางภาษาเช่น C # เลือกที่จะปรับแต่งบริบทเพื่อลดความซับซ้อนของกรณีการใช้งาน แต่มันจะขยายข้อกำหนดมากขึ้น
  • สำหรับผู้ใช้ภาษาโปรแกรมความสำคัญของคำสั่งอาจทำให้พวกเขาสับสนมากขึ้น
    • การแยกกฎของนิพจน์และข้อความในภาษาต้องใช้ความพยายามมากขึ้นในการเรียนรู้ภาษา
    • การตีความคำสั่งที่ไร้เดียงสาซ่อนความคิดที่สำคัญกว่า: การประเมินการแสดงออก (นี่อาจเป็นปัญหาได้มากที่สุด)
      • แม้การประเมินผลของการแสดงออกเต็มรูปแบบในงบเป็นข้อ จำกัด กับคำศัพท์คำสั่งย่อยไม่ได้ (จำเป็น) ในที่สุดผู้ใช้ควรเรียนรู้สิ่งนี้นอกเหนือจากกฎใด ๆ ควบคู่ไปกับข้อความ (พิจารณาว่าจะทำให้มือใหม่ได้รับจุดที่++i + ++iไม่มีความหมายใน C. )
      • ภาษาบางภาษาเช่น Java และ C # มีข้อ จำกัด เพิ่มเติมเกี่ยวกับลำดับของการประเมินผลของนิพจน์ย่อยที่จะอนุญาตให้ใช้โดยไม่ใช้กฎการประเมินผล มันอาจเป็นปัญหาได้มากกว่าเดิม
        • ดูเหมือนว่าเกินความจริงสำหรับผู้ใช้ที่ได้เรียนรู้แนวคิดของการประเมินผลการแสดงออกแล้ว นอกจากนี้ยังสนับสนุนให้ชุมชนผู้ใช้ทำตามแบบจำลองจิตที่เบลอของการออกแบบภาษา
        • มันขยายข้อมูลจำเพาะภาษามากขึ้น
        • มันเป็นอันตรายต่อการปรับให้เหมาะสมโดยการขาดการแสดงออกของ nondeterminism ในการประเมินผลก่อนที่จะมีการแนะนำแบบดั้งเดิมที่ซับซ้อนมากขึ้น
      • ภาษาบางภาษาเช่น C ++ (โดยเฉพาะ C ++ 17) ระบุบริบทที่ละเอียดยิ่งขึ้นของกฎการประเมินเพื่อประนีประนอมปัญหาข้างต้น
        • มันขยายตัวสเปคภาษามาก
        • สิ่งนี้ขัดกับความเรียบง่ายของผู้ใช้ทั่วไป ...

เหตุใดจึงต้องแถลง อย่างไรก็ตามประวัติศาสตร์นั้นยุ่งเหยิงไปหมดแล้ว ดูเหมือนว่านักออกแบบภาษาส่วนใหญ่ไม่ได้เลือกอย่างระมัดระวัง

ยิ่งไปกว่านั้นมันยังทำให้ผู้ที่ชื่นชอบระบบบางประเภท (ที่ไม่คุ้นเคยกับประวัติ PL) ความเข้าใจผิดที่ว่าระบบประเภทนั้นจะต้องมีสิ่งสำคัญที่ต้องทำเกี่ยวกับการออกแบบกฎที่สำคัญยิ่งขึ้นในความหมายการปฏิบัติการ

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

ตัวอย่างเช่นคนเน้นธรรมชาติดีพิมพ์เป็นอาร์กิวเมนต์กลางกับการรักษาแบบดั้งเดิมของต undelimited แม้ว่าข้อสรุปที่ค่อนข้างเหมาะสมและข้อมูลเชิงลึกเกี่ยวกับฟังก์ชั่นแต่งจะ OK ( แต่ก็ยังไกลเกินไปไร้เดียงสาที่จะสาระสำคัญ ) เรื่องนี้ไม่ได้เสียงเพราะมันโดยสิ้นเชิงไม่สนใจวิธีการด้าน "ช่อง" ในทางปฏิบัติเช่น_Noreturn any_of_returnable_typesการ (C11) Falsumเพื่อเข้ารหัส และการพูดอย่างเคร่งครัดเครื่องจักรนามธรรมที่มีสภาวะที่คาดเดาไม่ได้นั้นไม่เหมือนกับ "คอมพิวเตอร์ที่ล้มเหลว"


0

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

Wikipedia กำหนดคำว่าทำนองเดียวกัน

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

สังเกตเห็นคำสั่งหลัง (แม้ว่าจะเป็น "โปรแกรม" ในกรณีนี้มีความผิดพลาดทางเทคนิคเพราะทั้ง C และ Java ปฏิเสธโปรแกรมที่ไม่มีข้อความใด ๆ )

Wikipedia กำหนดคำว่านิพจน์เป็น

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

อย่างไรก็ตามนี่คือเท็จเพราะใน Kotlin throw new Exception("")เป็นนิพจน์ แต่เมื่อประเมินแล้วมันจะส่งข้อยกเว้นออกไปโดยไม่ส่งคืนค่าใด ๆ

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

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

มันคือการรวมกันของหนึ่งหรือมากกว่าหนึ่งค่าคงที่ตัวแปรฟังก์ชั่นและผู้ประกอบการที่การแปลภาษาการเขียนโปรแกรม (ตามกฎเฉพาะของความสำคัญและการสมาคม) และคำนวณเพื่อผลิต ("กลับ" ในสภาพแวดล้อม stateful) ค่าอื่น

แต่ปัญหาอยู่ในภาษาการเขียนโปรแกรม C เนื่องจากฟังก์ชั่น execute บางอย่างเช่นนี้

void executeSomething(void){
    return;
}

คือexecuteSomething()การแสดงออกหรือมันคือคำสั่งหรือไม่? ตามคำจำกัดความของฉันมันเป็นคำสั่งเพราะตามที่กำหนดไว้ในไวยากรณ์อ้างอิง C ของ Microsoft

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

แต่หน้าเดียวกันอย่างชัดเจนบ่งชี้ว่าไวยากรณ์ดังกล่าวเป็นนิพจน์


-6

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

การแสดงออกมีประเภทอื่น ๆ นอกเหนือจากประเภทด้านล่างคือมันมีค่า คำสั่งมีหน่วยหรือประเภทด้านล่าง

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

เห็นได้ชัดว่า a @pragmaหรือ a /*comment*/ไม่มีประเภทจึงแตกต่างจากข้อความสั่ง ดังนั้นคำสั่งประเภทเดียวที่จะไม่มีผลข้างเคียงจะไม่ใช่การดำเนินการ การไม่ดำเนินการจะมีประโยชน์ในฐานะตัวแทนสำหรับผลข้างเคียงในอนาคตเท่านั้น การกระทำอื่นใดอันเนื่องมาจากคำสั่งจะเป็นผลข้างเคียง คอมไพเลอร์คำใบ้อีกครั้งเช่น@pragmaไม่ใช่คำสั่งเพราะมันไม่มีประเภท


2
ความแตกต่างไม่เกี่ยวกับประเภทของการแสดงออก ประโยคที่กำหนดโดยวากยสัมพันธ์นั้นไม่มีหลายประเภทในหลายภาษา แม้ว่าฉันจะไม่คัดค้านการกำหนดประเภทของคำศัพท์ดังกล่าวในทางทฤษฎีการรักษาที่แตกต่างกันใน@pragmaหรือ/*comment*/มีเหตุผล
FrankHB

-11

ส่วนใหญ่ได้อย่างแม่นยำคำสั่งจะต้องมี"ผลข้างเคียง" (กล่าวคือเป็นความจำเป็น ) และการแสดงออกต้องมีค่าประเภท (เช่นไม่ชนิดล่าง)

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


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

เรามาดูกันว่าวิกิพีเดียต้องพูดอะไรในเรื่องนี้

https://en.wikipedia.org/wiki/Statement_(computer_science)

ในการเขียนโปรแกรมคอมพิวเตอร์คำสั่งเป็นองค์ประกอบแบบสแตนด์อโลนที่เล็กที่สุดของภาษาการเขียนโปรแกรมที่จำเป็นซึ่งแสดงถึงการกระทำบางอย่างที่จะดำเนินการ

หลายภาษา (เช่น C) สร้างความแตกต่างระหว่างคำสั่งและคำจำกัดความด้วยคำสั่งที่มีรหัสที่ปฏิบัติการได้และคำจำกัดความที่ประกาศตัวระบุในขณะที่การแสดงออกประเมินค่าเพียง


5
คำสั่งไม่จำเป็นต้องมีผลข้างเคียง ยกตัวอย่างเช่นในหลามpassเป็นคำสั่ง มันเป็นแบบไม่มี op และไม่ได้ประเมินอะไรเลย
Matthew Schinckel

9
-1 นี่มันผิด คำสั่งไม่จำเป็นต้องมีผลข้างเคียง ดูในส่วน 1.5 ของภาษา C # ข้อมูลจำเพาะ ไม่เพียง แต่ไม่ได้ระบุว่าข้อความต้องมีผลข้างเคียง แต่ยังแสดงรายการหลายข้อความที่สามารถไม่มีผลข้างเคียง
NullUserException

2
@NullUserException ฉันอ่านส่วนนั้น การประกาศ, การแสดงออก, การเลือก, การวนซ้ำและคำสั่งกระโดดอาจสร้างผลข้างเคียงทั้งหมด แต่ถ้ามีการแสดงออก RT ก็ไม่ได้เป็นคำสั่ง ฉันรู้ว่าสเปคนั้นเท่ากับการแสดงออกด้วยข้อความ แต่คำถามนี้ถามถึงความแตกต่างระหว่างพวกเขา ดังนั้นทั้งคำถามไม่มีคำตอบหรือคุณกำลังใช้ข้อมูลจำเพาะ C # อย่างแท้จริง คำตอบที่ได้รับการโหวตสูงสุดพยายามพูดในสิ่งที่ฉันทำ แต่ "ทำอะไรบางอย่าง" นั้นไม่มีความหมาย "ผลข้างเคียง" เป็นวิธีที่มีความหมายในการพูดว่า "ทำอะไร" เราต้องคิดไม่ใช่แค่สำรอก
Shelby Moore III

13
@ShelbyMooreIII คุณพูดถูก เอกสารอย่างเป็นทางการเป็นที่ไม่ถูกต้อง Marc Gravell และจอนเป้าบินที่มีความเป็นไปได้มากที่สุดเคารพ C # โปสเตอร์ใช้งานอยู่บน SO ด้านนอกของเอริค Lippert เป็นผิด ผมและคนอื่น ๆ ทุกคนที่ downvoted คุณและแสดงความคิดเห็นทางด้านซ้ายอธิบายตำแหน่งของเรามีความผิด คุณพูดถูก คุณเป็นคนเดียวเท่านั้นที่รู้ว่าพวกเขากำลังพูดถึงอะไรเพราะคุณฉลาดกว่าพวกที่เหลือทั้งหมด
NullUserException

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