2013-03-27 20 views
9

Sự khác nhau thực tế giữa việc sử dụng các mô-đun với câu lệnh use hoặc các tệp riêng biệt với câu hỏi include là gì? Ý tôi là, nếu tôi có một chương trình con được sử dụng rất nhiều trong một chương trình: khi nào hoặc tại sao tôi nên đặt nó vào trong một mô-đun hoặc chỉ viết nó vào một tệp riêng và bao gồm nó trong mọi phần khác của chương trình mà nó cần phải đã sử dụng?Sự khác biệt giữa INCLUDE và các mô-đun trong Fortran

Ngoài ra, sẽ tốt hơn nếu bạn viết tất cả các chương trình con dự định đi vào một mô-đun trong các tệp riêng biệt và sử dụng include bên trong mô-đun? Đặc biệt nếu mã trong các chương trình con là dài, để giữ cho mã được tổ chức tốt hơn (theo cách đó tất cả các chương trình con được đóng gói trong mod, nhưng nếu tôi phải chỉnh sửa một thì tôi không cần phải đi qua mê cung mã).

Trả lời

16

Sự khác biệt về khái niệm giữa hai bản đồ với các khác biệt thực tế rất quan trọng.

Dòng INCLUDE hoạt động ở cấp nguồn - nó hoàn thành việc bao gồm văn bản đơn giản ("câm"). Trong trường hợp không có bất kỳ giải thích bộ xử lý đặc biệt nào của "filename" (không yêu cầu thực sự là một tệp) trong dòng include thì nguồn hoàn chỉnh có thể dễ dàng được lập trình theo cách thủ công cùng với trình lập trình và không có gì khác biệt -so-bao giờ trong ngữ nghĩa của nguồn. Nguồn được bao gồm không có cách giải thích thực sự trong sự cô lập - nghĩa của nó hoàn toàn phụ thuộc vào ngữ cảnh trong đó dòng bao gồm tham chiếu đến nguồn được bao gồm xuất hiện.

Mô-đun hoạt động ở cấp độ thực thể cao hơn nhiều của chương trình, tức là ở cấp độ trình biên dịch đang xem xét những điều mà nguồn thực sự mô tả. Một mô-đun có thể được biên dịch trong sự cô lập của người sử dụng hạ lưu của nó và một khi nó đã được biên dịch trình biên dịch biết chính xác những gì các mô-đun có thể cung cấp cho chương trình.

Thông thường những gì ai đó đang sử dụng bao gồm các dòng là hy vọng cần làm là những mô-đun nào thực sự là được thiết kế để làm.

Ví dụ vấn đề:

  • Bởi vì khai báo thực thể có thể được trải rộng trên nhiều báo cáo các đối tượng được mô tả bởi nguồn bao gồm có thể không được những gì bạn mong đợi. Hãy xem xét các nguồn sau đây để được bao gồm:

    INTEGER :: i

    Trong cách ly nó trông như thế này tuyên bố tên i như một vô hướng số nguyên (hoặc có lẽ một hàm Ai biết được?!). Bây giờ xem xét phạm vi sau đây bao gồm trên:

    INCLUDE "source from above"
    DIMENSION :: i(10,10)

    i bây giờ là một cấp bậc hai mảng! Có lẽ bạn muốn làm cho nó một POINTER? Một ALLOCATABLE? Một đối số giả? Có lẽ điều đó dẫn đến lỗi, hoặc có lẽ đó là nguồn hợp lệ! Ném nhập ngầm vào hỗn hợp để thực sự kết hợp những niềm vui tiềm năng.

    Một thực thể được xác định trong mô-đun là "hoàn toàn" do mô-đun xác định. Các thuộc tính cụ thể cho phạm vi sử dụng có thể được thay đổi (VOLATILE, khả năng truy cập, vv), nhưng thực thể cơ bản vẫn giữ nguyên. Các xung đột tên được gọi một cách rõ ràng và có thể dễ dàng làm việc xung quanh với mệnh đề đổi tên trên câu lệnh USE.

  • Fortran có các hạn chế về thứ tự tuyên bố (các câu lệnh đặc tả phải đi trước các câu lệnh thực thi, v.v.). Nguồn được bao gồm cũng phải chịu các hạn chế đó, một lần nữa là trong ngữ cảnh bao gồm, không phải là điểm của định nghĩa nguồn.

    Trộn lẫn với sự mơ hồ nguồn giữa các định nghĩa hàm tuyên bố (phần đặc tả) và câu lệnh gán (phần thực thi) đối với một số thông báo lỗi hoàn toàn bị nghi ngờ hoặc chấp nhận sự im lặng của trình biên dịch mã sai.

    Có các yêu cầu về nơi câu lệnh USE tham chiếu đến một mô-đun xuất hiện, nhưng nguồn cho đơn vị chương trình mô-đun thực tế hoàn toàn độc lập với điểm sử dụng của nó.

  • Ưa thích có một số trạng thái toàn cầu được chia sẻ trên các quy trình liên quan và bạn muốn sử dụng bao gồm? Hãy để tôi giới thiệu bạn với các khối phổ biến và khái niệm liên kết cơ bản về liên kết chuỗi ...

    Liên kết chuỗi là một sự cố không may xảy ra khi triển khai bộ vi xử lý Fortran cơ bản sớm là lỗi thời gian lỗi, không linh hoạt.

    Biến mô-đun tạo các khối chung và các tệ nạn liên quan của chúng hoàn toàn không cần thiết.

  • Nếu bạn đang sử dụng các dòng bao gồm, hãy lưu ý rằng bạn không thực sự bao gồm nguồn của thủ tục thường được sử dụng (gợi ý trong đoạn đầu tiên của bạn sẽ dẫn đến một cú pháp lỗi cú pháp từ trình biên dịch) . Những gì bạn thường làm là bao gồm nguồn mô tả giao diện của quy trình. Đối với bất kỳ thủ tục không tầm thường nào, nguồn mô tả giao diện khác với nguồn hoàn chỉnh của thủ tục - ngụ ý rằng bây giờ bạn cần phải duy trì hai biểu diễn nguồn của cùng một thứ. Đây là một gánh nặng bảo trì dễ bị lỗi.

    Như đã đề cập - các trình biên dịch tự động thu được kiến ​​thức về giao diện của một thủ tục mô-đun (kiến thức biên dịch là "rõ ràng" vì nó thực sự thấy mã của thủ tục - do đó thuật ngữ "giao diện rõ ràng"). Không cần lập trình viên làm gì hơn nữa. Hệ quả là các chương trình con bên ngoài không nên được sử dụng ở tất cả trừ khi có những lý do rất tốt để trái (có lẽ là sự tồn tại của phụ thuộc quá mức hoặc quá rộng) - điểm khởi đầu cơ bản cần được đặt mọi thứ trong mô-đun hoặc chương trình chính.

Các áp phích khác đã đề cập đến lợi ích của tổ chức mã nguồn trong mô-đun, bao gồm kiểm soát khả năng truy cập chi tiết thực hiện nội bộ.

Tôi chấp nhận có sử dụng hợp lệ các dòng INCLUDE theo đoạn thứ hai của câu hỏi - nơi các mô-đun lớn trở nên khó sử dụng. F2008 đã giải quyết vấn đề này với các mô-đun con, cũng mang lại một số lợi ích khác. Một khi chúng trở nên được hỗ trợ rộng rãi bao gồm các công việc xung quanh nên bị bỏ rơi.

Sử dụng hợp lệ thứ hai là khắc phục sự thiếu hỗ trợ của ngôn ngữ cho kỹ thuật lập trình chung (những mẫu cung cấp trong C++) - tức là nơi các loại đối tượng tham gia vào hoạt động có thể thay đổi. để làm trên các đối tượng đó về cơ bản giống nhau. Nó có thể là một thập kỷ hoặc lâu hơn trước khi ngôn ngữ sắp xếp.

+0

Vì vậy, không có bất lợi trong việc tách các chương trình con trong các tập tin khác nhau và sau đó sử dụng bao gồm bên trong các mô-đun, phải không? Tôi chưa bao giờ nghe nói về submodules trước đây. – Nordico

+1

Tôi chỉ xem xét nếu tôi có các tệp nguồn rất lớn hoặc là một phần của quá trình di chuyển nguồn cũ. Nếu có thể, trước tiên tôi sẽ xem xét việc phá vỡ mô-đun thành một số mô-đun "con" sau đó được tổng hợp cùng với các câu lệnh USE trong mô-đun chính. Tuy nhiên, với các phụ thuộc kiểu thủ tục/thủ tục phức tạp và/hoặc với cách mà các hoạt động trợ năng PUBLIC/PRIVATE của Fortran hoạt động, việc sử dụng các mô-đun con có thể không phải lúc nào cũng có thể. Bạn có thể thấy rằng việc ghép nguồn cho một mô-đun cùng với các dòng INCLUDE gây nhầm lẫn một số hệ thống xây dựng. – IanH

6

Đặt thủ tục vào các mô-đun và sử dụng các mô-đun đó làm cho giao diện của thủ tục rõ ràng. Nó cho phép trình biên dịch Fortran kiểm tra tính nhất quán giữa các đối số thực tế trong một cuộc gọi và các đối số giả của quy trình. Điều này bảo vệ chống lại một loạt các sai lầm lập trình viên. Giao diện rõ ràng cũng cần thiết cho một số tính năng "nâng cao" nhất định của Fortran> = 90; ví dụ, đối số tùy chọn hoặc từ khóa. Nếu không có giao diện rõ ràng, trình biên dịch sẽ không tạo ra cuộc gọi chính xác. Chỉ bao gồm một tệp không cung cấp những lợi thế này.

+1

Tôi muốn tiếp tục, tôi không nghĩ rằng có bất kỳ lý do chính đáng nào để sử dụng bao gồm tệp. –

+0

@HighPerformanceMark: Chương trình chung của người nghèo? – eriktous

+1

Giống như tôi đã viết * Tôi không biết bất kỳ lý do chính đáng nào để sử dụng bao gồm các tệp *. Nhưng đó là một ý kiến ​​ –

3

Câu trả lời của M.S.B. thật tuyệt vời và có lẽ là lý do quan trọng nhất để thích các mô-đun hơn bao gồm. Tôi muốn thêm một vài suy nghĩ nữa.

Sử dụng mô-đun sẽ giảm kích thước nhị phân đã biên dịch của bạn nếu đó là thứ quan trọng đối với bạn. Mô-đun được biên dịch một lần và khi bạn use, bạn đang tải biểu tượng mô-đun đó để sử dụng mã. Khi bạn include một tệp, bạn thực sự đang chèn mã mới vào thường trình của mình. Nếu bạn sử dụng include rất nhiều, nó có thể làm cho tệp nhị phân của bạn lớn và cũng làm tăng thời gian biên dịch của bạn.

Bạn cũng có thể sử dụng các mô-đun để mã hóa kiểu OOP giả trong Fortran 90 thông qua việc sử dụng thông minh các chức năng công khai và riêng tư và các loại do người dùng xác định trong một mô-đun. Ngay cả khi bạn không muốn làm điều đó, nó cung cấp một cách tốt đẹp để nhóm các chức năng hợp lý thuộc về nhau.

Các vấn đề liên quan