วิธีการเทียบกับฟังก์ชั่นและขั้นตอน


107

คำถามง่าย ๆ แต่บ่อยครั้งที่ฉันได้ยินคำศัพท์สามคำที่นิยามด้วยความดุร้ายเช่นนี้

คำจำกัดความ "ถูกต้อง" ของ "ขั้นตอน", "วิธีการ", "ฟังก์ชั่น", "รูทีนย่อย" ฯลฯ คืออะไร?


4
คุณ
ลืม

1
@teresko: ฉันคิดว่า "subroutine" เป็นเรื่องธรรมดา
mk12

คำตอบ:


108

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

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

คุณอาจพูดว่าฟังก์ชั่นคืนค่า ฟังก์ชั่น C ต่อไปนี้จะไม่ส่งคืนค่า:

void f() { return; }

... แต่ฉันสงสัยว่าคุณจะพบใครก็ตามที่จะเรียกมันว่ากระบวนการ

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

ในความเป็นจริงคำว่า "การเขียนโปรแกรมตามขั้นตอน" หมายถึงภาษาทั้งชั้นรวมถึง C, Fortran และ Pascal เพียงหนึ่งในนั้นที่ใช้คำว่า "ขั้นตอน" ในความหมายอะไร

ดังนั้นสิ่งนี้ไม่สอดคล้องกันจริงๆ ข้อยกเว้นเพียงอย่างเดียวอาจเป็น "วิธีการ" ซึ่งดูเหมือนว่าจะใช้เกือบทั้งหมดกับภาษา OO หมายถึงฟังก์ชั่นที่เกี่ยวข้องกับวัตถุ แม้ว่าจะไม่สอดคล้องกันเสมอไป ตัวอย่างเช่น C ++ มักใช้คำว่า "member function" แทน method (แม้ว่าคำว่า "method" จะพุ่งเข้าไปในภาษา C ++ ในภาษาโปรแกรมเมอร์)

ประเด็นคือไม่มีสิ่งใดที่สอดคล้องกันจริงๆ มันสะท้อนให้เห็นถึงคำศัพท์เฉพาะที่ใช้ในทุกภาษา


นั่นคือสิ่งที่ฉันคิดว่าคำตอบคือ (ฉันควรจะเพิ่ม "subroutine" เป็นตัวแปรอื่นในการเข้าใจถึงปัญหาหลังเหตุการณ์) ฉันสามารถถามได้: ทำไมคุณไม่พบใครที่เรียกฟังก์ชัน C ว่า "กระบวนงาน" เพราะมันไม่ถูกต้องทางเทคนิคหรือเพราะคำว่า "ขั้นตอน" นั้นไม่ทันสมัย?
Django Reinhardt

7
โปรแกรมเมอร์ C ใช้คำว่า "function" เพียงเพราะผู้ออกแบบ C ใช้คำนั้น
Charles Salvia

15
อย่าปล่อยให้เด็กอาบน้ำ เพียงเพราะคำศัพท์ไม่ได้ใช้อย่างต่อเนื่องไม่ได้หมายความว่าคำต่าง ๆ ไม่มีความหมายที่แตกต่างกัน คำจำกัดความของ @ Bruce's และ @ Frank ได้รับการยอมรับอย่างกว้างขวางไม่ใช่เรื่องแปลก ความจริงที่ว่าความหมายไม่ใช่สากลเป็นสิ่งสำคัญ แต่มันก็ไม่ได้พิสูจน์ให้เห็นว่าการก้าวกระโดดไปสู่ ​​"การพูดในทางปฏิบัติมันไม่มีความแตกต่าง" (@Django)
LarsH

9
ชนิดของ double to C ++ ที่เรียกเมธอด "ฟังก์ชันสมาชิก", Java และ C # เรียกฟังก์ชัน "สแตติกเมธอด"
Jörg W Mittag

2
คำตอบของ Bruce คือคำตอบที่คุณควรเลือกหากคุณยังไม่คุ้นเคยกับการเขียนโปรแกรม คำจำกัดความของเขาจะถูกต้องอย่างแน่นอน 99% ของเวลา แต่ฉันกำลังมองหาคำตอบทางเทคนิค / เชิงทฤษฎีมากขึ้น บางครั้งโปรแกรมเมอร์รุ่นใหม่จะรู้จักเฉพาะโดเมนของตนเองและยืนยันว่ามีทั้งหมด ในความเป็นจริงมีโปรแกรมเมอร์ทำงานวันนี้ที่ยังคงใช้ภาษาที่เก่ากว่าและผู้ที่ไม่ "ผิด" สำหรับการใช้คำจำกัดความที่แตกต่างกัน นั่นคือสิ่งที่ฉันสนใจมากที่สุด
Django Reinhardt

67

ฟังก์ชั่นส่งกลับค่า แต่ขั้นตอนไม่ได้

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


8
ไม่ได้อยู่ภายในอย่างแน่นอน วิธีการคือฟังก์ชั่นหรือขั้นตอนใด ๆ ที่เป็นส่วนหนึ่งของชั้นเรียน
Scott Whitlock

8
ดังนั้น "กระบวนงานที่เก็บไว้" ใน SQL จึงไม่ส่งคืนค่าใด ๆ สิ่งที่เกี่ยวกับ "ขั้นตอน" ในบางอย่างเช่น Pascal? คำจำกัดความของคุณขึ้นอยู่กับแนวโน้มปัจจุบันหรือควรจะเป็นคำจำกัดความสากล ขอบคุณ!
Django Reinhardt

3
@Django: ใน Pascal ขั้นตอนไม่สามารถมีค่าตอบแทนและฟังก์ชั่นจะต้องมีค่าตอบแทน ในบางภาษาคำศัพท์อาจใช้อย่างเข้มงวดมากขึ้น
Bruce Alderman

1
FWIW, FORTRAN มี SUBROUTINE และ FUNCTIONs ตั้งแต่วันแรก ๆ ความแตกต่างที่ SUBROUTINE ไม่ส่งคืนค่า ฉันจำไม่ได้เกี่ยวกับ ALGOL ซึ่ง Pascal นั้นสืบเชื้อสายมาจาก
David Thornley

2
@ 3p1c_d3m0n เป็นความจริงที่แน่นอนว่าfunctionจะเติมเต็มทั้งบทบาทใน JS แต่ฟังก์ชั่น JS กลับคืนมาทั้งหมด undefinedเมื่อคำสั่งกลับไม่มีค่าค่าปริยาย เมื่อไม่มีการส่งคืนสินค้าล่ามจะเพิ่มคำสั่งส่งคืนโดยนัย ลึกลับ แต่อาจจะสอดคล้องกับคำนิยามที่ให้ไว้ที่นี่ นี่คือเหตุผลที่var x = function() {}();ถูกกฎหมายใน JS; หากไม่ใช่สำหรับการส่งคืนโดยปริยายสิ่งนี้จะต้องเป็นข้อผิดพลาดเนื่องจากเป็น Pascal
Semicolon

52

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

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

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

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

นิยามหลังนำไปสู่object = struct + closures correspondence


5
ดังนั้นวัตถุคือชุดของตัวแปรและชุดของการปิดเหนือตัวแปรทั่วไปเหล่านี้ โดยทั่วไปภาษาเชิงวัตถุมักจะมีการปิดและไม่มีใครรู้หรือไม่? มุมมองที่น่าสนใจ! +1
Giorgio

1
ฉันไม่เชื่อว่าวิธีการส่วนใหญ่ปิดเหนือสิ่งใด foo.doSomething()ไม่ได้เป็นแบบไม่มีพารามิเตอร์ มันมีหนึ่งพารามิเตอร์ (วัตถุfoo) ด้วยให้กับน้ำตาล syntactic การปิดจะสามารถอ้างอิงวัตถุได้โดยไม่จำเป็นต้องใช้พารามิเตอร์ดังกล่าว นั่นไม่ได้เป็นการบอกว่าวิธีการไม่สามารถปิดได้ แต่ส่วนใหญ่ไม่ใช่และการเป็น OO นั้นไม่เพียงพอสำหรับภาษาที่จะสนับสนุนการปิด
8bittree

3
foo.doSomething()ปิดfooตัวแปร ข้อความใด ๆ ในdoSomethingสามารถเข้าถึงfooผ่านthisหรือselfขึ้นอยู่กับภาษาของคุณ นี่คือคำจำกัดความของ "ปิด" คลาสใกล้กับตัวแปรสมาชิกดังนั้น (ละเว้น "what OO"), OO เพียงพอ เรื่องนี้เป็นที่รู้จักกันดีในวรรณคดี ...
Frank Shearar

1
เอ่อไม่ เห็นว่าเล็ก ๆ น้อย ๆfoo.ที่ด้านหน้าของfoo.doSomething()? นั่นคือคุณผ่านdoSomething()พารามิเตอร์ เพียงเพราะมันไม่ได้อยู่ในวงเล็บไม่ได้หมายความว่ามันไม่ใช่พารามิเตอร์ thisหรือselfภายในวิธีการที่น้ำตาลประโยคเพียงเพื่ออ้างอิงพารามิเตอร์ที่
8bittree

1
@ FrankShearar ฉันจะบอกว่ามีเพียงสองความแตกต่างที่ชัดเจนพอสมควรในการคำนวณ - ข้อมูลและคำแนะนำ แม้นั่นจะออกไปนอกหน้าต่างในกรณี (ผิดปกติ) ของรหัสแก้ไขตัวเอง ใน OO สิ่งที่โดยทั่วไปเรียกว่า "วิธีการ" (หรือ "ฟังก์ชั่นสมาชิก") ไม่จำเป็นต้องเป็นวิธีการหรือฟังก์ชั่นตามคำนิยามของคุณ - คำเหล่านี้ทั้งหมดในการใช้งานทั่วไปมีความหมายเหมือนกันกับความหมายทั่วไป "ฟังก์ชั่นที่ไม่บริสุทธิ์" ซึ่งมีอยู่ที่คุณกล่าวถึงเป็นเพียงคำอื่น ๆ (และยังเป็นคำพ้องความยาวที่ยืดยาวและใช้งานง่าย) สำหรับแนวคิดทั่วไปเดียวกันของ "คำแนะนำ"
Steve

14

บรูซมีคำตอบที่ดี ฉันจะเพิ่มความหมาย:

  • ขั้นตอนควร "ทำอะไรบางอย่าง" กับข้อโต้แย้งหรือทำให้เกิดผลข้างเคียงอื่น ๆ (เช่นprintf)
  • ฟังก์ชั่นควร (a) ตอบคำถามเกี่ยวกับข้อโต้แย้งหรือ (b) คำนวณค่าใหม่ตามข้อโต้แย้ง
  • ฟังก์ชั่นวิธีการควรตอบคำถามเกี่ยวกับสถานะของวัตถุ
  • วิธีการขั้นตอนควรเปลี่ยนสถานะของวัตถุ

คำตอบที่ดี! นอกจากนี้เพียงเล็กน้อย: A procedure should "do something" to the arguments- หรือทำให้เกิดผลข้างเคียงอื่น ๆ (เช่นprintf)
Allon Guralnek

1
@Allon โปรดทราบว่าprintfจะส่งคืนค่า - จำนวนอักขระที่พิมพ์ - ดังนั้นจึงเป็นฟังก์ชันทางเทคนิค
Sjoerd

@Sererd ฉันไม่เห็นด้วยที่printfมีค่า มันมีผลข้างเคียงที่เฉพาะเจาะจงนอกขอบเขตการร้องขอ: คือ I / O กับสิ่งที่เอาต์พุตมาตรฐานที่ควรจะเป็น ถึงแม้ว่าสกอตต์จะไม่แยกความแตกต่างนี้อย่างชัดเจนในฟังก์ชั่นการตั้งโปรแกรมการทำงานไม่ควรมีผลข้างเคียงและควรจะสามารถตอบคำถามราวกับว่าคุณมีข้อมูลจริงที่มันส่งคืน
อลัน

4

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

โดยทั่วไปฟังก์ชั่นคืนค่า แต่พวกเขาไม่จำเป็นต้อง

วิธีการเป็นข้อกำหนด OOP ทั่วไปในปัจจุบัน

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

ความแตกต่างที่ชัดเจนระหว่างข้อกำหนดเหล่านี้ขึ้นอยู่กับว่าคุณกำลังพูดคุยกับใคร!


2

80% ของความเชี่ยวชาญเกี่ยวข้องโดยตรงกับความคุ้นเคยกับระบบการตั้งชื่อ

95% ของผลิตภาพคือความสามารถในการระบุสิ่งที่มีประโยชน์ในขณะนี้แม้จะมีคำศัพท์ที่ใช้อธิบาย

ฉันอยากจะเรียกพวกเขาว่าวิธีการทั้งหมดใน c # ยกเว้นเมื่อฉันใช้ MSSQL เรามี sproc แต่แน่นอนตอนนี้เราใช้ Postgres และพวกเขาเรียกว่าฟังก์ชั่น


13
83.5% ของสถิติทั้งหมดถูกสร้างขึ้นในจุด ;-P
Django Reinhardt

1
ฉันต้องยอมรับฉันรู้สึกกระวนกระวายใจเมื่อได้ยินคนที่ขว้างปาคำว่า "วิธีการ" เมื่อทำงานในภาษาที่ไม่ใช่ OO ดูเหมือนว่าจะมีความสัมพันธ์อย่างมากกับการทำงานเป็นรหัสที่ไม่ใช่สำนวน
Racheet

ฉันใช้ 'วิธีการ' เมื่ออ้างถึงรหัส C เนื่องจากโปรแกรมเมอร์ OO จำนวนมากที่ฉันจัดการมีอาการทางจิตเมื่อได้ยินขั้นตอนข้อกำหนดและฟังก์ชั่น เพื่อความสนุกหากฉันต้องการยุ่งกับพวกเขาจริงๆฉันอาจแลกเปลี่ยนข้อตกลงแบบสุ่ม มันไม่ดีเลยอย่างเช่นเชิญนักโพลเจียนเข้าบ้านคุณ ... :)
mattnz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.