ฉันถามเกี่ยวกับ c # แต่ฉันคิดว่ามันเหมือนกันในภาษาอื่น ๆ ส่วนใหญ่
ใครบ้างมีคำจำกัดความที่ดีของการแสดงออกและงบและสิ่งที่แตกต่างกันคืออะไร?
ฉันถามเกี่ยวกับ c # แต่ฉันคิดว่ามันเหมือนกันในภาษาอื่น ๆ ส่วนใหญ่
ใครบ้างมีคำจำกัดความที่ดีของการแสดงออกและงบและสิ่งที่แตกต่างกันคืออะไร?
คำตอบ:
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 เป็นภาษาทั้งหมดที่ไม่มีคำสั่งทางประโยค แต่มีเพียงการแสดงออก แม้แต่คลาสลูปที่มีโครงสร้างและรูปแบบที่มีเงื่อนไขก็ยังถือว่าเป็นนิพจน์และพวกมันก็มีคุณค่า - แต่ไม่ใช่สิ่งที่น่าสนใจมาก
callfunc(x = 2);
ผ่านx
ไปไม่ได้callfunc
2
ถ้าx
เป็นลอย, จะถูกเรียกว่าไม่callfunc(float)
callfunc(int)
และใน C ++ ถ้าคุณผ่านx=y
ไปfunc
และfunc
ใช้อ้างอิงและการเปลี่ยนแปลงมันเปลี่ยนแปลงไม่ได้x
y
where
ประโยคใน Haskell ถือเป็นนิพจน์ไม่ใช่คำแถลง learnyouahaskell.com/syntax-in-functions#where
where
เป็นส่วนหนึ่งของการประกาศฟังก์ชั่นไม่ใช่การแสดงออกหรือคำสั่ง
โปรดทราบว่าใน C "=" เป็นจริงตัวดำเนินการซึ่งทำสองสิ่ง:
นี่คือส่วนแยกจากไวยากรณ์ ANSI C คุณจะเห็นได้ว่า C ไม่มีคำสั่งประเภทต่าง ๆ มากมาย ... ส่วนใหญ่ของคำสั่งในโปรแกรมคือคำสั่งการแสดงออกเช่นการแสดงออกด้วยเครื่องหมายอัฒภาคในตอนท้าย
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
expression_statement
: ';'
| expression ';'
;
การแสดงออกเป็นสิ่งที่ส่งกลับค่าในขณะที่คำสั่งไม่ได้
ตัวอย่าง:
1 + 2 * 4 * foo.bar() //Expression
foo.voidFunc(1); //Statement
เรื่องใหญ่ระหว่างสองเรื่องนี้คือคุณสามารถโยงนิพจน์เข้าด้วยกันในขณะที่งบไม่สามารถถูกผูกมัดได้
foo.voidFunc(1);
เป็นนิพจน์ที่มีค่าเป็นโมฆะ while
และif
เป็นงบ
return
ถือว่าเป็นสถานะ
คุณสามารถค้นหาได้จากวิกิพีเดียแต่นิพจน์ได้รับการประเมินเป็นค่าบางค่าในขณะที่งบไม่มีค่าที่ประเมิน
ดังนั้นการแสดงออกสามารถใช้ในงบ แต่ไม่ใช่วิธีอื่น ๆ
โปรดทราบว่าบางภาษา (เช่น Lisp และฉันเชื่อว่า Ruby และอีกหลายภาษา) ไม่ได้แยกความแตกต่างของคำสั่งกับการแสดงออก ... ในภาษาดังกล่าวทุกอย่างเป็นการแสดงออกและสามารถถูกล่ามโซ่กับการแสดงออกอื่น ๆ
สำหรับคำอธิบายของความแตกต่างที่สำคัญในการจัดองค์ประกอบ (ความสามารถในการแสดงออก) ของคำศัพท์และคำพูดการอ้างอิงที่ฉันโปรดปรานคือเอกสารรางวัลทัวริงของ John Backus การเขียนโปรแกรมสามารถปลดปล่อยจากสไตล์ของ von Neumann ได้หรือไม่? .
ภาษาที่จำเป็น (Fortran, C, Java, ... ) เน้นข้อความสำหรับการจัดโครงสร้างโปรแกรมและมีการแสดงออกเป็นความคิดหลัง ภาษาหน้าที่เน้นการแสดงออก หมดจดภาษาทำงานได้มีประสิทธิภาพเช่นการแสดงออกกว่างบก็จะถูกกำจัดออกไปโดยสิ้นเชิง
นิพจน์สามารถถูกประเมินเพื่อรับค่าในขณะที่ statement ไม่คืนค่า ( เป็นโมฆะประเภท)
นิพจน์การเรียกใช้ฟังก์ชันสามารถถูกพิจารณาว่าเป็นข้อความสั่งของหลักสูตร แต่ถ้าสภาพแวดล้อมการดำเนินการมีตัวแปรในตัวพิเศษเพื่อเก็บค่าที่ส่งคืนจะไม่มีวิธีเรียกคืน
ภาษาเชิงคำสั่งต้องใช้ขั้นตอนทั้งหมดเพื่อเป็นรายการของคำสั่ง Expression-oriented languages ซึ่งอาจเป็นภาษาที่ใช้งานได้ทั้งหมดคือรายการของนิพจน์หรือในกรณีของ LISP ซึ่งเป็น S-expression แบบยาวหนึ่งรายการที่แสดงรายการของนิพจน์
แม้ว่าทั้งสองประเภทสามารถเขียนได้ แต่นิพจน์ส่วนใหญ่สามารถเขียนได้โดยพลการตราบเท่าที่ประเภทนั้นตรงกัน ข้อความแต่ละประเภทมีวิธีการเขียนข้อความอื่น ๆ ของตนเองหากสามารถทำได้ทั้งหมด Foreach และถ้า statement ต้องการทั้ง stat เดียวหรือว่า subordinate statement ทั้งหมดจะอยู่ใน block statement หนึ่งอันถัดไปยกเว้นว่า substatements จะอนุญาตให้มี substatements ของตัวเอง
งบสามารถรวมถึงการแสดงออกซึ่งการแสดงออกไม่ได้รวมงบใด ๆ แม้ว่าจะมีข้อยกเว้นอย่างหนึ่งก็คือการแสดงออกแลมบ์ดาซึ่งหมายถึงฟังก์ชั่นและสามารถรวมฟังก์ชั่นใดก็ได้ที่สามารถยกเว้นในกรณีที่ภาษาไม่อนุญาตให้มีการ จำกัด แลมบ์ดาเท่านั้น
ในภาษาที่ใช้นิพจน์คุณต้องมีเพียงนิพจน์เดียวสำหรับฟังก์ชั่นเนื่องจากโครงสร้างการควบคุมทั้งหมดส่งคืนค่า (จำนวนมากส่งคืน NIL) ไม่จำเป็นต้องมีคำสั่ง return เนื่องจากนิพจน์ที่ประเมินค่าล่าสุดในฟังก์ชันคือค่าที่ส่งคืน
null
)? จะไม่void
เหมือนหน่วยประเภทมากขึ้น(แต่มีค่าเดียวไม่สามารถเข้าถึงได้)?
void
เป็นชนิดที่การกลับมาของฟังก์ชั่นที่ไม่เคยผลตอบแทน (เช่นฟังก์ชั่นที่throw
s ข้อผิดพลาด) มันเป็นประเภทด้านล่าง มิฉะนั้นvoid
จะเป็นประเภทของหน่วย คุณถูกต้องที่คำสั่งที่ไม่สามารถแยกออกมีประเภทหน่วย แต่คำสั่งที่สามารถแยกออกเป็นประเภทด้านล่าง เนื่องจากทฤษฎีบท Halting เรามักจะไม่สามารถพิสูจน์ได้ว่าฟังก์ชั่นไม่ได้แตกต่างดังนั้นฉันคิดว่าหน่วยเป็นนิยาย null
ประเภทด้านล่างไม่สามารถมีค่าจึงไม่สามารถมีค่าเดียวของ
null
ค่าเป็นจริงpseudovalueแสดงถึงว่ามีการอ้างอิงหมายถึงบางสิ่งบางอย่างที่ไม่มีอยู่
เพียงแค่: การแสดงออกประเมินค่าเป็นคำสั่งไม่ได้
{}
เป็นคำสั่ง การใส่คำนั้นด้วยคำพูดที่ทำให้ตกใจไม่เปลี่ยนแปลง งบเป็นโครงสร้างประโยคด้วยความหมาย ไม่มีสิ่งดังกล่าวเป็น "ชั้นความหมาย" - คุณดูเหมือนจะหมายถึงการดำเนินการ คุณบอกว่าคุณพยายามที่จะแม่นยำ แต่คุณล้มเหลว การร้องเรียนของคุณเกี่ยวกับ "ความไม่รู้ของผู้ลงคะแนนเสียง" นั้นเป็นโฆษณาที่บริสุทธิ์ คุณไม่มีข้อมูลเกี่ยวกับสภาพจิตใจของผู้ลงคะแนนเสียง
{}
ถูกกำหนดให้เป็นคำสั่งในข้อมูลจำเพาะภาษา C #
บางสิ่งเกี่ยวกับภาษาที่ใช้นิพจน์:
สำคัญที่สุด: ทุกสิ่งคืนค่า
ไม่มีความแตกต่างระหว่างวงเล็บปีกกาและวงเล็บปีกกาสำหรับการกำหนดบล็อกโค้ดและนิพจน์เนื่องจากทุกอย่างเป็นนิพจน์ สิ่งนี้ไม่ได้ป้องกันการกำหนดขอบเขตศัพท์: แม้ว่าสามารถกำหนดตัวแปรท้องถิ่นสำหรับนิพจน์ที่คำจำกัดความของมันมีอยู่และคำสั่งทั้งหมดที่มีอยู่ภายในนั้นตัวอย่างเช่น
ในภาษาที่ใช้นิพจน์ทุกอย่างจะส่งคืนค่า ในตอนแรกมันอาจจะแปลกไปหน่อย - อะไรจะ(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
)
คำสั่งเป็นกรณีพิเศษของการแสดงออกหนึ่งที่มี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>
)
คำตอบอื่น ๆ จำนวนมากบ่งบอกว่าคุณไม่สามารถโยงประโยคอย่างที่คุณสามารถทำได้ด้วยการแสดงออก แต่ฉันไม่แน่ใจว่าแนวคิดนี้มาจากไหน เราสามารถคิดว่าการ;
ที่ปรากฏขึ้นหลังจากงบเป็นผู้ประกอบการมัดไบนารีการสองแสดงออกของประเภทและรวมไว้ในการแสดงออกครั้งเดียวของชนิดvoid
void
งบ -> คำแนะนำในการติดตาม
นิพจน์ตามลำดับ-> การประเมินผลที่คืนค่า
ข้อความนั้นเป็นเหมือนขั้นตอนหรือคำสั่งในอัลกอริทึมผลลัพธ์ของการดำเนินการคำสั่งคือการทำให้ตัวชี้คำสั่งเกิดขึ้นจริง (เรียกว่าในแอสเซมเบลอร์)
การแสดงออกไม่ได้หมายถึงและสั่งการดำเนินการตั้งแต่แรกเห็นวัตถุประสงค์ของพวกเขาคือการประเมินและส่งกลับค่า ในภาษาการเขียนโปรแกรมที่จำเป็นการประเมินผลของนิพจน์มีคำสั่ง แต่มันเป็นเพียงเพราะรูปแบบความจำเป็น แต่มันไม่ได้เป็นสาระสำคัญของพวกเขา
ตัวอย่างของข้อความ:
for
goto
return
if
(ทั้งหมดนี้แสดงถึงความก้าวหน้าของบรรทัด (คำสั่ง) ของการดำเนินการไปยังอีกบรรทัดหนึ่ง)
ตัวอย่างของการแสดงออก:
2+2
(มันไม่ได้หมายความถึงความคิดของการดำเนินการ แต่จากการประเมินผล)
คำสั่ง ,
คำสั่งเป็นแบบเอกสารประกอบขั้นตอนการดำเนินการที่มีการสร้างโปรแกรม 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;}
:)
ฉันชอบความหมายของstatement
คำว่าตรรกะอย่างเป็นทางการ มันเป็นสิ่งที่เปลี่ยนแปลงสถานะของตัวแปรหนึ่งตัวหรือมากกว่าในการคำนวณทำให้สามารถใช้คำสั่งจริงหรือเท็จเกี่ยวกับคุณค่าของมัน
ฉันเดาว่าจะมีความสับสนในโลกแห่งการคำนวณและวิทยาศาสตร์โดยทั่วไปเมื่อมีคำศัพท์หรือคำใหม่มาใช้คำที่มีอยู่คือ 'repurposed' หรือผู้ใช้ไม่รู้คำศัพท์ที่มีอยู่เป็นที่ยอมรับหรือเหมาะสมสำหรับสิ่งที่อธิบาย
ฉันไม่พอใจกับคำตอบใด ๆ ที่นี่ ฉันดูไวยากรณ์ของ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 ++
case
ตัวอย่างเช่นคำสั่งที่มีข้อความif
if/else
,case
while
, do...while
,for (...)
break
, continue
, return
(สามารถกลับแสดงออก)goto
try/catch
บล็อกนี่เป็นข้อความที่ตัดตอนมาซึ่งแสดงส่วนของนิพจน์:
expression:
assignment-expression
expression "," assignment-expression
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
+
, -
, *
, /
, &
, |
, &&
, ||
, ... )throw
ข้อคือการแสดงออกเกินไปงบเป็นประโยคที่สมบูรณ์ทางไวยากรณ์ การแสดงออกไม่ได้ ตัวอย่างเช่น
x = 5
อ่านว่า "x ได้รับ 5" นี่เป็นประโยคที่สมบูรณ์ รหัส
(x + 5)/9.0
อ่าน "x plus 5 ทั้งหมดหารด้วย 9.0" นี่ไม่ใช่ประโยคที่สมบูรณ์ คำสั่ง
while k < 10:
print k
k += 1
เป็นประโยคที่สมบูรณ์ ขอให้สังเกตว่าส่วนหัวของห่วงไม่ได้; "ขณะที่ k <10" เป็นประโยคย่อย
while
กับร่างกายยังคงแสดงออกในสกาล่า มันอาจจะเป็นคำสั่งถ้ามันสร้างผลข้างเคียงซึ่งสิ่งที่คำตอบ downvoted หนักของฉันอนุญาต (การแสดงออกยังสามารถเป็นคำสั่ง) คำตอบของฉันคือคำตอบที่ถูกต้องเพียงข้อเดียว ขออภัยที่ผู้อ่านทุกคนที่ไม่เข้าใจ
(x + 5)/9.0
สามารถยืนอยู่คนเดียวอย่างแน่นอนในฐานะคำสั่ง นอกจากนี้หากดำเนินการทางไวยากรณ์แล้วคุณหมายถึงโปรแกรมที่ถูกต้อง C ไม่อนุญาตให้ใช้คำสั่งแบบสแตนด์อะโลนเป็นโปรแกรมเดี่ยว
นี่คือฤดูร้อนของหนึ่งในคำตอบที่ง่ายที่สุดที่ฉันพบ
ตอบโดย Anders Kaseorg เป็นครั้งแรก
คำสั่งคือบรรทัดของโค้ดที่สมบูรณ์ซึ่งดำเนินการบางอย่างในขณะที่นิพจน์คือส่วนใด ๆ ของโค้ดที่ประเมินเป็นค่า
สามารถรวมนิพจน์“ แนวนอน” เป็นนิพจน์ขนาดใหญ่โดยใช้โอเปอเรเตอร์ในขณะที่งบสามารถรวม“ แนวตั้ง” ได้โดยการเขียนทีละอันหรือด้วยการสร้างบล็อก
ทุกนิพจน์สามารถใช้เป็นข้อความสั่งได้ (ซึ่งผลกระทบคือเพื่อประเมินนิพจน์และละเว้นค่าผลลัพธ์) แต่คำสั่งส่วนใหญ่ไม่สามารถใช้เป็นนิพจน์ได้
พื้นฐานความเป็นจริงของแนวคิดเหล่านี้คือ:
นิพจน์ : หมวดหมู่ประโยคที่มีอินสแตนซ์ที่สามารถประเมินค่าได้
คำให้การ : หมวดหมู่ประโยคที่มีอินสแตนซ์ซึ่งอาจเกี่ยวข้องกับการประเมินผลของนิพจน์และค่าผลลัพธ์ของการประเมิน (ถ้ามี) ไม่สามารถรับประกันได้
นอกเหนือจากบริบทเริ่มต้นสำหรับ FORTRAN ในช่วงต้นทศวรรษที่ผ่านมาทั้งคำจำกัดความของการแสดงออกและข้อความในคำตอบที่ยอมรับนั้นผิดอย่างเห็นได้ชัด:
sizeof
ผู้ประกอบการจะไม่เคยประเมิน(BTW ฉันต้องการเพิ่มคำตอบที่เกี่ยวข้องกับวัสดุที่เกี่ยวกับ C เพราะฉันจำไม่ได้ว่า DMR มีความคิดเห็นเช่นนั้นหรือไม่ดูเหมือนจะไม่มีเหตุผลอื่นที่จะรักษาความซ้ำซ้อนของฟังก์ชันในการออกแบบของ C : โดยเฉพาะเครื่องหมายจุลภาคเทียบกับข้อความ)
(เหตุผลต่อไปนี้ไม่ใช่คำตอบที่ตรงกับคำถามเดิม แต่ฉันรู้สึกว่าจำเป็นต้องชี้แจงสิ่งที่ตอบแล้ว)
อย่างไรก็ตามเป็นที่น่าสงสัยว่าเราต้องการหมวดหมู่เฉพาะของ "ข้อความ" ในภาษาโปรแกรมทั่วไป:
begin
ใน Scheme) หรือน้ำตาล syntactic ของโครงสร้าง monadic++i + ++i
ไม่มีความหมายใน C. )เหตุใดจึงต้องแถลง อย่างไรก็ตามประวัติศาสตร์นั้นยุ่งเหยิงไปหมดแล้ว ดูเหมือนว่านักออกแบบภาษาส่วนใหญ่ไม่ได้เลือกอย่างระมัดระวัง
ยิ่งไปกว่านั้นมันยังทำให้ผู้ที่ชื่นชอบระบบบางประเภท (ที่ไม่คุ้นเคยกับประวัติ PL) ความเข้าใจผิดที่ว่าระบบประเภทนั้นจะต้องมีสิ่งสำคัญที่ต้องทำเกี่ยวกับการออกแบบกฎที่สำคัญยิ่งขึ้นในความหมายการปฏิบัติการ
อย่างจริงจังการให้เหตุผลขึ้นอยู่กับประเภทไม่ได้เลวร้ายในหลายกรณี แต่โดยเฉพาะอย่างยิ่งไม่สร้างสรรค์ในหนึ่งพิเศษนี้ แม้แต่ผู้เชี่ยวชาญก็สามารถทำสิ่งที่ผิดพลาดได้
ตัวอย่างเช่นคนเน้นธรรมชาติดีพิมพ์เป็นอาร์กิวเมนต์กลางกับการรักษาแบบดั้งเดิมของต undelimited แม้ว่าข้อสรุปที่ค่อนข้างเหมาะสมและข้อมูลเชิงลึกเกี่ยวกับฟังก์ชั่นแต่งจะ OK ( แต่ก็ยังไกลเกินไปไร้เดียงสาที่จะสาระสำคัญ ) เรื่องนี้ไม่ได้เสียงเพราะมันโดยสิ้นเชิงไม่สนใจวิธีการด้าน "ช่อง" ในทางปฏิบัติเช่น_Noreturn any_of_returnable_types
การ (C11) Falsum
เพื่อเข้ารหัส และการพูดอย่างเคร่งครัดเครื่องจักรนามธรรมที่มีสภาวะที่คาดเดาไม่ได้นั้นไม่เหมือนกับ "คอมพิวเตอร์ที่ล้มเหลว"
ในภาษาโปรแกรมเชิงคำสั่งบล็อกรหัสถูกกำหนดเป็นรายการของคำสั่ง กล่าวอีกนัยหนึ่งคำสั่งคือส่วนหนึ่งของไวยากรณ์ที่คุณสามารถใส่ไว้ในบล็อกโค้ดโดยไม่ทำให้เกิดข้อผิดพลาดทางไวยากรณ์
Wikipedia กำหนดคำว่าทำนองเดียวกัน
ในการเขียนโปรแกรมคอมพิวเตอร์คำสั่งคือหน่วยไวยากรณ์ของภาษาการเขียนโปรแกรมที่จำเป็นซึ่งแสดงถึงการกระทำบางอย่างที่จะดำเนินการ โปรแกรมที่เขียนด้วยภาษาดังกล่าวจะเกิดขึ้นตามลำดับของคำสั่งอย่างน้อยหนึ่งคำ
สังเกตเห็นคำสั่งหลัง (แม้ว่าจะเป็น "โปรแกรม" ในกรณีนี้มีความผิดพลาดทางเทคนิคเพราะทั้ง C และ Java ปฏิเสธโปรแกรมที่ไม่มีข้อความใด ๆ )
Wikipedia กำหนดคำว่านิพจน์เป็น
การแสดงออกในภาษาการเขียนโปรแกรมเป็นนิติบุคคลที่อาจได้รับการประเมินเพื่อกำหนดมูลค่าของมัน
อย่างไรก็ตามนี่คือเท็จเพราะใน Kotlin throw new Exception("")
เป็นนิพจน์ แต่เมื่อประเมินแล้วมันจะส่งข้อยกเว้นออกไปโดยไม่ส่งคืนค่าใด ๆ
ในภาษาการเขียนโปรแกรมแบบสแตติกทุกนิพจน์มีชนิด อย่างไรก็ตามคำจำกัดความนี้ไม่ทำงานในภาษาการเขียนโปรแกรมแบบไดนามิก
โดยส่วนตัวแล้วฉันกำหนดนิพจน์เป็นส่วนหนึ่งของไวยากรณ์ที่สามารถประกอบกับตัวดำเนินการหรือการเรียกใช้ฟังก์ชันเพื่อให้ได้นิพจน์ที่ใหญ่กว่า สิ่งนี้คล้ายกับคำอธิบายการแสดงออกโดย Wikipedia:
มันคือการรวมกันของหนึ่งหรือมากกว่าหนึ่งค่าคงที่ตัวแปรฟังก์ชั่นและผู้ประกอบการที่การแปลภาษาการเขียนโปรแกรม (ตามกฎเฉพาะของความสำคัญและการสมาคม) และคำนวณเพื่อผลิต ("กลับ" ในสภาพแวดล้อม stateful) ค่าอื่น
แต่ปัญหาอยู่ในภาษาการเขียนโปรแกรม C เนื่องจากฟังก์ชั่น execute บางอย่างเช่นนี้
void executeSomething(void){
return;
}
คือexecuteSomething()
การแสดงออกหรือมันคือคำสั่งหรือไม่? ตามคำจำกัดความของฉันมันเป็นคำสั่งเพราะตามที่กำหนดไว้ในไวยากรณ์อ้างอิง C ของ Microsoft
คุณไม่สามารถใช้ค่า (ไม่มีอยู่) ของนิพจน์ที่มีประเภทเป็นโมฆะในทางใดทางหนึ่งและไม่สามารถแปลงนิพจน์โมฆะ (โดยนัยหรือโดยชัดแจ้ง) เป็นประเภทใดก็ได้ยกเว้นโมฆะ
แต่หน้าเดียวกันอย่างชัดเจนบ่งชี้ว่าไวยากรณ์ดังกล่าวเป็นนิพจน์
เพื่อปรับปรุงและตรวจสอบคำตอบก่อนหน้าของฉันคำจำกัดความของคำภาษาการเขียนโปรแกรมควรจะอธิบายจากทฤษฎีประเภทวิทยาการคอมพิวเตอร์เมื่อใช้
การแสดงออกมีประเภทอื่น ๆ นอกเหนือจากประเภทด้านล่างคือมันมีค่า คำสั่งมีหน่วยหรือประเภทด้านล่าง
จากสิ่งนี้มันตามมาว่าคำสั่งจะมีผลกระทบใด ๆ ในโปรแกรมเมื่อมันสร้างผลข้างเคียงเพราะมันไม่สามารถส่งคืนค่าหรือมันจะส่งกลับค่าประเภทหน่วยที่ไม่สามารถกำหนดได้ (ในบางภาษาเช่น ของ C void
) หรือ (เช่นใน Scala) สามารถจัดเก็บไว้สำหรับการประเมินความล่าช้าของคำสั่ง
เห็นได้ชัดว่า a @pragma
หรือ a /*comment*/
ไม่มีประเภทจึงแตกต่างจากข้อความสั่ง ดังนั้นคำสั่งประเภทเดียวที่จะไม่มีผลข้างเคียงจะไม่ใช่การดำเนินการ การไม่ดำเนินการจะมีประโยชน์ในฐานะตัวแทนสำหรับผลข้างเคียงในอนาคตเท่านั้น การกระทำอื่นใดอันเนื่องมาจากคำสั่งจะเป็นผลข้างเคียง คอมไพเลอร์คำใบ้อีกครั้งเช่น@pragma
ไม่ใช่คำสั่งเพราะมันไม่มีประเภท
@pragma
หรือ/*comment*/
มีเหตุผล
ส่วนใหญ่ได้อย่างแม่นยำคำสั่งจะต้องมี"ผลข้างเคียง" (กล่าวคือเป็นความจำเป็น ) และการแสดงออกต้องมีค่าประเภท (เช่นไม่ชนิดล่าง)
ประเภทของคำสั่งที่เป็นประเภทหน่วย แต่เนื่องจากลังเลหน่วยทฤษฎีบทเป็นนิยายเพื่อช่วยให้พูดประเภทด้านล่าง
Void
ไม่ใช่ประเภทด้านล่างที่แม่นยำ (ไม่ใช่ประเภทย่อยของประเภทที่เป็นไปได้ทั้งหมด) มันมีอยู่ในภาษาที่ไม่ได้มีระบบการพิมพ์เสียงสมบูรณ์ ที่อาจฟังดูเป็นคำหยาบคาย แต่ความสมบูรณ์เช่นคำอธิบายประกอบความแปรปรวนมีความสำคัญอย่างยิ่งต่อการเขียนซอฟต์แวร์แบบขยายได้
เรามาดูกันว่าวิกิพีเดียต้องพูดอะไรในเรื่องนี้
https://en.wikipedia.org/wiki/Statement_(computer_science)
ในการเขียนโปรแกรมคอมพิวเตอร์คำสั่งเป็นองค์ประกอบแบบสแตนด์อโลนที่เล็กที่สุดของภาษาการเขียนโปรแกรมที่จำเป็นซึ่งแสดงถึงการกระทำบางอย่างที่จะดำเนินการ
หลายภาษา (เช่น C) สร้างความแตกต่างระหว่างคำสั่งและคำจำกัดความด้วยคำสั่งที่มีรหัสที่ปฏิบัติการได้และคำจำกัดความที่ประกาศตัวระบุในขณะที่การแสดงออกประเมินค่าเพียง
pass
เป็นคำสั่ง มันเป็นแบบไม่มี op และไม่ได้ประเมินอะไรเลย