Sự khác biệt giữa lập trình bắt buộc, thủ tục và cấu trúc là gì?


85

Bằng cách nghiên cứu xung quanh (sách, Wikipedia, các câu hỏi tương tự về SE, v.v.) tôi đã hiểu rằng lập trình mệnh lệnh là một trong những mô hình lập trình chính, nơi bạn mô tả một loạt các lệnh (hoặc câu lệnh) để máy tính thực thi (vì vậy bạn rất đẹp nhiều thứ để nó thực hiện các hành động cụ thể, do đó tên "bắt buộc"). Càng xa càng tốt.

Mặt khác, lập trình thủ tục là một loại cụ thể (hoặc tập hợp con) của lập trình mệnh lệnh, trong đó bạn sử dụng các thủ tục (nghĩa là các hàm) để mô tả các lệnh mà máy tính sẽ thực hiện.

Câu hỏi đầu tiên : Có một ngôn ngữ lập trình mệnh lệnh không phải là thủ tục không? Nói cách khác, bạn có thể lập trình mệnh lệnh mà không cần thủ tục không?

Cập nhật : Câu hỏi đầu tiên này dường như được trả lời. Một ngôn ngữ CÓ THỂ là bắt buộc mà không cần thủ tục hoặc cấu trúc. Một ví dụ là ngôn ngữ hội thuần túy.

Sau đó, bạn cũng có lập trình Cấu trúc, dường như là một loại (hoặc tập hợp con) khác của lập trình mệnh lệnh, xuất hiện để loại bỏ sự phụ thuộc vào câu lệnh GOTO.

Câu hỏi thứ hai : sự khác biệt giữa lập trình thủ tục và cấu trúc là gì? Bạn có thể có cái này mà không có cái kia, và ngược lại? Chúng ta có thể nói lập trình thủ tục là một tập hợp con của lập trình có cấu trúc, như trong hình ảnh không?

nhập mô tả hình ảnh ở đây

Câu trả lời:


52

Nhiều thuật ngữ có thể được sử dụng lại (thường được sử dụng sai) về các ngôn ngữ lập trình, đặc biệt là các ngôn ngữ không phải là ngôn ngữ hướng đối tượng.

Dưới đây là một số mô tả nhỏ về các điều khoản.

  1. Lập trình bắt buộc - Ngày xưa, khi lập trình được lắp ráp rộng rãi, mã sẽ có hàng tấn GOTO. Ngay cả các ngôn ngữ cấp cao hơn như FORTRAN và BASIC cũng bắt đầu sử dụng cùng một nguyên thủy. Trong mô hình lập trình này, toàn bộ chương trình là một thuật toán đơn hoặc chức năng hoàn chỉnh được viết tuyến tính - từng bước một. Đây là phong cách bắt buộc . Hiểu rằng người ta thực sự có thể viết công việc cấp bách hoàn toàn xấu ngay cả trong ngôn ngữ C hiện đại, nhưng nó khá dễ dàng để tổ chức mã bằng các ngôn ngữ cấp cao hơn.

  2. Lập trình có cấu trúc và mô đun - Thông thường chúng ta sẽ có thể sử dụng thuật ngữ thay thế cho nhau nhưng với sự khác biệt tinh tế. Khi các ngôn ngữ cấp cao hơn bắt đầu trở nên phong phú hơn, người ta nhận ra rằng tất cả các đơn vị công việc nên được chia thành các phần nhỏ hơn - đó là khi các chức năng ra đời và lập trình trở thành một hệ thống phân cấp các chức năng và nhiều cấp độ thấp hơn có thể được sử dụng lại.

    • Lập trình có cấu trúc là bất kỳ chương trình nào khi chức năng được chia thành các đơn vị như for loop, while loop, if... thencấu trúc khối vv.
    • Ngoài ra, ở đây một đoạn mã (hàm) có thể được sử dụng lại.
    • Trong lập trình mô-đun , người ta có thể tạo ra một dạng gói vật lý - tức là một đoạn mã có thể được vận chuyển; đó là mục đích khá chung và có thể sử dụng lại. Đây được gọi là mô-đun của các yếu tố được biên dịch cùng nhau.
    • Vì vậy, người ta khó có thể thấy các chương trình mô-đun không có cấu trúc và ngược lại; định nghĩa kỹ thuật là khác nhau tinh tế nhưng mã chủ yếu có cấu trúc có thể được thực hiện theo mô-đun và cách khác.
  3. Sau đó đến "lập trình hướng đối tượng" được xác định rõ trong văn học. Hiểu rằng lập trình hướng đối tượng một dạng lập trình có cấu trúc theo định nghĩa. Tên mới cho tất cả các mã dựa trên chức năng đó là mã có cấu trúc nhưng KHÔNG hướng đối tượng thường được gọi là lập trình thủ tục.

    • Vì vậy, về cơ bản mã có cấu trúc trong đó các hàm (hoặc thủ tục) chiếm ưu thế trên dữ liệu được gọi là thủ tục trong khi biểu diễn dựa trên lớp và đối tượng được gọi là hướng đối tượng. Cả hai theo định nghĩa cũng là mô-đun.

Nhiều người nghĩ - tất cả các chương trình có cấu trúc (có thể bỏ qua dựa trên Object) là lập trình bắt buộc; Tôi đoán điều này chỉ là do thiếu định nghĩa rõ ràng về lập trình mệnh lệnh - nhưng nó đã sai. Bạn đang làm lập trình có cấu trúc khi bạn không làm nhiều việc bắt buộc! Nhưng tôi vẫn có thể viết rất nhiều chức năng cũng như rất nhiều câu lệnh goto bên trong chương trình C hoặc FORTRAN để trộn.

Để được cụ thể cho câu hỏi của bạn:

Câu hỏi đầu tiên : Ngôn ngữ lắp ráp thuần túy là ngôn ngữ bắt buộc KHÔNG có cấu trúc hoặc thủ tục. (Có từng bước điều khiển diễn giải không có nghĩa là thủ tục - nhưng phân chia chức năng thành các chức năng là điều tạo nên một thủ tục ngôn ngữ).

  • hiệu chỉnh * Hầu hết các hình thức lắp ráp hiện đại DO đều hỗ trợ sử dụng các chức năng. Trên thực tế, mọi thứ có thể ở mã cấp cao ĐÃ tồn tại ở mức thấp để hoạt động. Mặc dù đó là cách thực hành tốt hơn nhiều để tạo mã thủ tục, nhưng có thể viết cả mã thủ tục và mã bắt buộc. Không giống như cái sau, nó dễ bảo trì và dễ hiểu hơn (tránh mã spaghetti khủng khiếp). Tôi nghĩ rằng có các kịch bản shell / bash phù hợp hơn với giải thưởng là hoàn toàn bắt buộc, nhưng ngay cả khi đó, hầu hết đều có chức năng, các nhà phát triển chắc chắn hiểu giá trị của chúng là bao nhiêu.

Câu hỏi thứ hai : Lập trình thủ tục là một HÌNH THỨC của lập trình có cấu trúc.


THÊM

  • Theo một số phân loại, phân loại chính là Tuyên bố (hoặc ngôn ngữ chức năng) so với mệnh lệnh. Ngôn ngữ khai báo cho phép tính toán mà không mô tả luồng điều khiển của nó trong khi mệnh lệnh là nơi xác định luồng điều khiển rõ ràng (từng bước). Dựa trên sự phân loại này, lập trình mệnh lệnh, đối với một số người có thể là một tập hợp siêu lập trình có cấu trúc, mô đun và OO. Xem điều này: Lập trình chức năng so với OOP

  • Sau khi định hướng đối tượng, đã có những mô hình lập trình khác được phát minh: Xem tại đây để biết thêm chi tiết: Sự khác biệt giữa định hướng theo khía cạnh, hướng đối tượng và lập trình hướng vai trò là gì?


1
Vì vậy, bạn sẽ nói rằng lập trình thủ tục nhất thiết cũng là lập trình có cấu trúc, trong khi điều ngược lại là không đúng (mặc dù thường là như vậy)?
Daniel Scocco

2
Vâng, tôi sẽ nói như vậy.
Dipan Mehta

1
Trong câu trả lời của tôi, tôi đã định nghĩa mệnh lệnh so với cấu trúc - trong đó lập trình mệnh lệnh được viết chỉ bằng cách thực hiện từng bước và không có cấu trúc. Tuy nhiên, theo một số định nghĩa có một phân loại khác; đây là sự phân loại giữa Tuyên bố (hoặc ngôn ngữ chức năng) so với mệnh lệnh. Các ngôn ngữ khai báo cho phép tính toán mà không mô tả luồng điều khiển của nó trong đó bắt buộc là nơi xác định luồng điều khiển rõ ràng (từng bước). Dựa trên sự phân loại này, lập trình mệnh lệnh, đối với một số người có thể là một tập hợp siêu cấu trúc. Một số không hoàn toàn theo định nghĩa đó.
Dipan Mehta

Tôi có một ý kiến ​​khác, liên quan đến định nghĩa về lập trình có cấu trúc. Lập trình có cấu trúc và lập trình mô đun không giống nhau. Xin vui lòng xem định nghĩa ở cuối ghi chú này. Liên kết tương tự cho thấy Trình biên dịch ** là ngôn ngữ lập trình có cấu trúc **! Tham khảo cho định nghĩa của STP: en.wikipedia.org/wiki/Sturationured_programming - Emmad Kareem
NoChance

Là "dạng vật lý của gói" ... một tệp, hoặc một thư mục / kho lưu trữ các tệp? (Hoặc là không, và đó là một cái gì đó khác.)
n611x007

4

Câu hỏi đầu tiên: Có, nhiều ngôn ngữ hướng đối tượng thuần túy đủ điều kiện. Mặc dù chúng có các phương thức rất gần với các hàm, nhưng chúng xem các phương thức này theo các thông điệp và không cho chúng đủ trọng lượng để gọi ngôn ngữ theo thủ tục.

Câu hỏi thứ hai: Sự khác biệt thường ở một phạm vi khác nhau. Bạn có thể có một hàm với các câu lệnh goto ở khắp mọi nơi, sẽ theo kiểu thủ tục, nhưng không phải là lập trình có cấu trúc. Mặt khác, hầu hết các ngôn ngữ OO đều hỗ trợ và khuyến khích lập trình có cấu trúc, nhưng không phải lập trình theo thủ tục.

Lập trình thủ tục mô tả thứ tự toàn cầu của chương trình. Các chương trình thủ tục là những chương trình được hiểu một cách hiệu quả nhất bằng cách nhìn vào biểu đồ cuộc gọi của chúng. Lập trình cấu trúc là một thuộc tính cục bộ, nó được áp dụng cho việc sử dụng if và while trái ngược với goto.

Như vậy, hai thuộc tính này không khớp nhau, bạn có thể có một thuộc tính mà không có thuộc tính kia.


1
Bài kiểm tra litmus duy nhất để trở thành Thủ tục là ngôn ngữ chứa các thủ tục (hàm hoặc phương thức ) và là Bắt buộc, nghĩa là. không khai báo. Điều này có nghĩa là hầu hết các ngôn ngữ OO không có chức năng thuần túy sẽ là Thủ tục.
dietbuddha

1
@dietbuddha: Theo định nghĩa này, Haskell sẽ đủ điều kiện là ngôn ngữ thủ tục thông qua việc sử dụng các đơn nguyên. Tôi yêu cầu một sự phụ thuộc nhất định vào các thủ tục để tạo ra một thủ tục ngôn ngữ.
thiton

Tôi không biết rõ về Haskell, nhưng tôi nghĩ Haskell là một ngôn ngữ chức năng thuần túy vì nó bao bọc các tác dụng phụ trong Monads.
dietbuddha

2
Chà, một số người cho rằng Haskell không hoàn toàn hoạt động vì nó cho phép mọi tương tác với thế giới bên ngoài (hoặc vì một phần mở rộng GHC , unsafePerformIOcho phép phá hoại). Những người khác nói đùa rằng Haskell là ngôn ngữ lập trình mệnh lệnh yêu thích của họ. Nhưng thực tế là, một mức độ rất lớn của mã Haskell sống tách biệt khỏi IO, không sử dụng các sơ hở không chuẩn để lén tác dụng phụ và hoàn toàn là chức năng.

1
@thiton Tôi không đồng ý. Monads là các cấu trúc chức năng quá; chúng chỉ trông bắt buộc do đường cú pháp của Haskell ("ký hiệu"). Khi bạn desugar monads, bản chất chức năng của chúng trở nên rõ ràng. Ngược lại, các ngôn ngữ OO thực sự bắt buộc: cốt lõi của chúng là dựa trên việc thực hiện tuần tự các câu lệnh.
Andres F.

2

hầu hết các ngôn ngữ phổ biến trong 50 năm qua đã được thiết kế xung quanh kiến ​​trúc máy tính phổ biến, được gọi là kiến trúc Von Neumann , sau một trong những người sáng lập ra nó, John von Neumann.

Những ngôn ngữ này được gọi là ngôn ngữ bắt buộc.

Trong máy tính von Neumaan, cả dữ liệu và chương trình được lưu trữ trong cùng một bộ nhớ. CPU thực hiện các lệnh là tách biệt với bộ nhớ. Do đó, các hướng dẫn và dữ liệu phải được truyền từ bộ nhớ đến CPU. Kết quả hoạt động trong CPU phải được chuyển trở lại bộ nhớ. Gần như tất cả các máy tính kỹ thuật số được xây dựng từ những năm 1940 đều dựa trên kiến ​​trúc von Neumaan.


1
+1 không chắc chắn điều này có liên quan gì đến câu hỏi, nhưng đó là một câu trả lời thú vị.
Chuck Conway

2
Gì? Đâu là phần về mệnh lệnh so với thủ tục, v.v.?
bbqchickenrobot 8/03/2015

Tôi nghĩ vấn đề ở đây là ngụy biện về cấu trúc chương trình (Bắt buộc, Tuyên bố, Thủ tục, Hướng đối tượng, Chức năng, v.v.) là các cấu trúc ngôn ngữ và tất cả các chương trình cuối cùng được xử lý trên các máy kiến ​​trúc Von Neumann. Điều này tương tự như nói tất cả các ngôn ngữ Turing Complete là tương đương.
ChuckCottrill

2

Tôi sợ rằng không có câu trả lời nào được đưa ra cho đến nay nắm bắt được cốt lõi của các khái niệm này.

Bắt buộc, thủ tục và cấu trúc không phải là thuộc tính loại trừ lẫn nhau, chúng chỉ tập trung vào một khía cạnh duy nhất của logic mô hình hóa.

Bắt buộc là phần đối lập của khai báo Bắt buộc về cơ bản có nghĩa là bạn nói cho máy tính biết phải làm gì bằng cách thực hiện một loạt các hướng dẫn mà bạn cung cấp. Mặt khác, một chương trình khai báo cho biết những gì cần đạt được . Nói cách khác, xác định các bước so với xác định một kết quả.

Lập trình thủ tục đề cập đến khả năng của bộ xử lý (cả phần cứng hoặc trình thông dịch) để gói các hướng dẫn thành các hợp chất, nhảy đến một hợp chất như vậy và quay trở lại điểm sau khi nhảy khi hợp chất được thực thi. Điều này nghe có vẻ tầm thường và theo tiêu chuẩn ngày nay, nhưng bạn cần một số hỗ trợ cơ bản trong máy trước khi bạn có thể làm điều này: khả năng nhảy, một số ngăn xếp để đẩy một địa chỉ trên đó có thể được bật lên và nhảy tới sau và con trỏ ngăn xếp. Bộ vi xử lý sớm cung cấp tính năng này nhưng bạn có thể tưởng tượng một bộ xử lý nguyên thủy chỉ có khả năng thực hiện các hướng dẫn được cung cấp cho nó một cách tuần tự, như băng đục lỗ hoặc bộ xử lý thẻ đục lỗ.

Lập trình có cấu trúc là bước tiếp theo từ khả năng chuyển sang hướng dẫn khác. Cuối cùng, mọi thứ bắt đầu nhảy, nhưng nếu bạn có thể có các bước nhảy có điều kiện, bạn có thể xây dựng các câu lệnh điều khiển cơ bản như if-then, for, while, lặp lại - cho đến khi và chuyển đổi. Áp dụng những cái đó được gọi là lập trình có cấu trúc.

Trong bất kỳ môi trường lập trình hiện đại nào, bạn sẽ có tất cả những điều trên theo ý của bạn và coi chúng là điều hiển nhiên để chúng tôi không nói về chúng như vậy nữa. Các thuộc tính khác biệt giữa các ngôn ngữ từ lâu đã chuyển sang mô hình cấp cao hơn như lập trình hướng đối tượng và lập trình chức năng.

Lập trình khai báo vẫn chưa phổ biến, chủ yếu vì nó sẽ luôn là miền cụ thể, ít nhất là ở một mức độ nào đó. Bạn không thể có một ngôn ngữ khai báo mục đích chung. Đây là lý do tại sao chúng ta vẫn bị mắc kẹt với cái gọi là ngôn ngữ thế hệ thứ 3, trong đó lập trình khai báo hoặc "mô hình hóa" sẽ được coi là thế hệ thứ 4.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.