Sự khác biệt giữa ngôn ngữ biên dịch và thông dịch là gì?


118

Sau khi đọc một số tài liệu về chủ đề này, tôi vẫn không chắc sự khác biệt giữa ngôn ngữ biên dịch và ngôn ngữ thông dịch là gì. Tôi được cho biết đây là một trong những điểm khác biệt giữa Java và JavaScript. Ai đó vui lòng giúp tôi hiểu nó?

Câu trả lời:


165

Sự khác biệt giữa ngôn ngữ biên dịch và thông dịch là gì?

Sự khác biệt không nằm ở ngôn ngữ; nó đang được thực hiện .

Sau khi đưa nó ra khỏi hệ thống của tôi, đây là một câu trả lời:

  • Trong một triển khai đã biên dịch, chương trình gốc được dịch thành các lệnh máy gốc, được thực thi trực tiếp bởi phần cứng.

  • Trong một triển khai được thông dịch, chương trình gốc được dịch sang một thứ khác. Một chương trình khác, được gọi là "trình thông dịch", sau đó kiểm tra "thứ gì đó khác" và thực hiện bất kỳ hành động nào được yêu cầu. Tùy thuộc vào ngôn ngữ và cách triển khai của nó, có nhiều dạng khác nhau của "cái gì đó khác". Từ phổ biến hơn đến ít phổ biến hơn, "cái gì đó khác" có thể là

    • Hướng dẫn nhị phân cho một máy ảo, thường được gọi là bytecode , như được thực hiện trong Lua, Python, Ruby, Smalltalk và nhiều hệ thống khác (cách tiếp cận đã được phổ biến vào những năm 1970 bởi UCSD P-system và UCSD Pascal)

    • Biểu diễn dạng cây của chương trình gốc, chẳng hạn như cây cú pháp trừu tượng, như được thực hiện cho nhiều trình thông dịch nguyên mẫu hoặc giáo dục

    • Một đại diện được mã hóa của chương trình nguồn, tương tự như Tcl

    • Các ký tự của chương trình nguồn, như đã được thực hiện trong MINT và TRAC

Một điều làm phức tạp vấn đề là có thể dịch (biên dịch) bytecode thành các lệnh máy gốc . Do đó, một triển khai intepreted thành công cuối cùng có thể có được một trình biên dịch. Nếu trình biên dịch chạy động, thì nó thường được gọi là trình biên dịch đúng lúc hoặc trình biên dịch JIT. JIT đã được phát triển cho Java, JavaScript, Lua và tôi dám chắc rằng nhiều ngôn ngữ khác. Tại thời điểm đó, bạn có thể có một triển khai kết hợp trong đó một số mã được thông dịch và một số mã được biên dịch.


7
Thưa ông, tôi có những câu hỏi sau 1. "Cái gì đó khác" được viết bằng ngôn ngữ nào? 2. Và trong ngữ cảnh của JavaScript, "cái gì đó khác" có khác nhau từ trình duyệt này sang trình duyệt khác không? 3. Giả sử, tập lệnh của tôi đang chạy trong Google Chrome và Internet Explorer, nó có được diễn giải giống nhau trong cả hai trình duyệt không?
JavaHopper

@Norman đó là một lời giải thích tuyệt vời. Tuy nhiên, đây là một số nhầm lẫn mà tôi vẫn còn. Trong triển khai đã biên dịch, chương trình gốc được chuyển đổi thành các lệnh máy gốc. Làm thế nào mà? Chẳng hạn, tôi nghĩ C sau khi biên dịch sẽ tạo ra mã lắp ráp, mã này dù sao cũng cần phải được lắp ráp bởi một trình hợp dịch gốc vào mã máy của máy bên dưới. Vậy điều đó khác gì với một máy ảo (python hoặc JVM, v.v.) hoạt động tương tự trong trường hợp ngôn ngữ được thông dịch?
qre0ct

58

Java và JavaScript là một ví dụ khá tồi để chứng minh sự khác biệt này , vì cả hai đều là ngôn ngữ thông dịch . Java (được thông dịch) và C (hoặc C ++) (được biên dịch) có thể là một ví dụ tốt hơn.

Tại sao lại có văn bản bị sọc? Như câu trả lời này đã chỉ ra một cách chính xác, thông dịch / biên dịch là về việc triển khai cụ thể một ngôn ngữ, không phải về ngôn ngữ riêng lẻ . Mặc dù các câu như "C là một ngôn ngữ biên dịch" nói chung là đúng, nhưng không có gì ngăn cản ai đó viết một trình thông dịch ngôn ngữ C. Trên thực tế, các thông dịch viên cho C có tồn tại .

Về cơ bản, mã đã biên dịch có thể được thực thi trực tiếp bởi CPU của máy tính. Có nghĩa là, mã thực thi được chỉ định bằng ngôn ngữ "bản địa" của CPU (hợp ngữ ).

Tuy nhiên, mã của các ngôn ngữ được thông dịch phải được dịch trong thời gian chạy từ bất kỳ định dạng nào sang các lệnh máy CPU. Bản dịch này được thực hiện bởi một thông dịch viên.

Một cách nói khác là các ngôn ngữ thông dịch mã được dịch sang các lệnh của máy theo từng bước trong khi chương trình đang được thực thi, trong khi các ngôn ngữ biên dịch mã đã được dịch trước khi thực thi chương trình.


8
Java được thông dịch? Từ wikipedia: "Các ứng dụng Java thường được biên dịch thành bytecode (tệp lớp) có thể chạy trên bất kỳ Máy ảo Java (JVM) nào bất kể kiến ​​trúc máy tính."
Personman

6
@Personman về mặt kỹ thuật vẫn được "hiểu" là JVM đang thực thi mã, không phải bản thân hệ điều hành. Nó thực sự là một sự khác biệt về ngữ nghĩa nữa, như người ta có thể nói rằng sự phức tạp của các hệ điều hành hiện đại làm cho sự khác biệt về cơ bản không liên quan đến hầu hết các tình huống. Bạn đang nói về sự khác biệt giữa hệ điều hành chạy ứng dụng và hệ điều hành chạy ứng dụng đang chạy mã.
GrayWizardx

5
Tôi cho rằng ý bạn là bản thân các tệp lớp được thông dịch bởi máy ảo Java. Điều đó là hợp lý, nhưng nguồn java thực sự được biên dịch sang Java VM bytecode. Bạn có thể xây dựng một Máy Java vật lý không yêu cầu máy ảo thông dịch nó thành mã máy của kiến ​​trúc khác. Vì vậy, có vẻ chính xác hơn khi nói rằng Java được biên dịch. Tuy nhiên, đây là một ví dụ điển hình về cách thức phân biệt khó hiểu và tùy tiện. Rốt cuộc, C được biên dịch là do CPU thông dịch, phải không?
Nhân viên

13
Java là một ví dụ khá tệ về ngôn ngữ biên dịch hoặc thông dịch vì nó về cơ bản là cả hai. Nếu tôi định so sánh, tôi sẽ sử dụng C và Lisp để tránh bất kỳ sự nhầm lẫn nào.
Bill the Lizard

7
@stakx - trên thực tế, các mã bytecodes của Java thường được trình biên dịch JIT biên dịch thành mã gốc. Cách duy nhất để có được hành vi thông dịch thuần túy là tắt trình biên dịch JIT một cách rõ ràng khi JVM được khởi chạy.
Stephen C

15

Đây là sự khác biệt cơ bản giữa ngôn ngữ biên dịch và thông dịch viên.

Ngôn ngữ biên dịch

  • Nhận toàn bộ chương trình dưới dạng đầu vào duy nhất và chuyển đổi nó thành mã đối tượng được lưu trữ trong tệp.
  • Mã đối tượng trung gian được tạo
  • ví dụ: C, C ++
  • Các chương trình đã biên dịch chạy nhanh hơn vì quá trình biên dịch được thực hiện trước khi thực thi.
  • Yêu cầu bộ nhớ nhiều hơn do việc tạo mã đối tượng.
  • Lỗi được hiển thị sau khi toàn bộ chương trình được biên dịch
  • Mã nguồn --- Trình biên dịch --- Mã máy --- Đầu ra

Ngôn ngữ thông dịch viên:

  • Nhận lệnh đơn làm đầu vào duy nhất và thực hiện các lệnh.
  • Mã đối tượng trung gian KHÔNG được tạo
  • ví dụ: Perl, Python, Matlab
  • Các chương trình được thông dịch chạy chậm hơn vì quá trình biên dịch và thực thi diễn ra đồng thời.
  • Yêu cầu bộ nhớ ít hơn.
  • Lỗi được hiển thị cho mọi chỉ dẫn.
  • Mã nguồn --- Trình thông dịch --- Đầu ra

5

Nói chung, một trình biên dịch đọc mã máy tính ngôn ngữ cấp cao hơn và chuyển đổi nó thành mã p hoặc mã máy gốc. Một trình thông dịch chạy trực tiếp từ mã p hoặc mã được thông dịch chẳng hạn như Basic hoặc Lisp. Thông thường, mã đã biên dịch chạy nhanh hơn, nhỏ gọn hơn nhiều và đã tìm thấy tất cả các lỗi cú pháp và nhiều lỗi tham chiếu bất hợp pháp. Mã được thông dịch chỉ tìm thấy các lỗi như vậy sau khi ứng dụng cố gắng diễn giải mã bị ảnh hưởng. Mã được thông dịch thường tốt cho các ứng dụng đơn giản chỉ được sử dụng một lần hoặc nhiều nhất là một vài lần, hoặc thậm chí có thể để tạo mẫu. Mã biên dịch tốt hơn cho các ứng dụng nghiêm túc. Đầu tiên một trình biên dịch lấy toàn bộ chương trình, kiểm tra lỗi, biên dịch nó và sau đó thực thi nó. Trong khi đó, một trình thông dịch thực hiện điều này từng dòng một, vì vậy nó chiếm một dòng, kiểm tra lỗi,

Nếu bạn cần thêm thông tin, chỉ cần Google cho "sự khác biệt giữa trình biên dịch và trình thông dịch".


3
Umm, không chắc bạn lấy đâu ra một số điều này ngoài hai câu lệnh đầu tiên. Điều này về mặt kỹ thuật đã đúng vài thế hệ trước với nhiều ngôn ngữ được thông dịch, nhưng tùy thuộc vào nền tảng và sự chú ý đến từng chi tiết, có thể có mã được thông dịch hoạt động gần hoặc cũng như mã được biên dịch cho các hoạt động nhất định.
GrayWizardx

Hãy nhớ rằng các ngôn ngữ như Java, C # và JavaScript gần như đang tràn ngập toàn bộ thế giới lập trình ngày nay, sẽ không công bằng khi nói rằng "Mã biên dịch tốt hơn cho các ứng dụng nghiêm túc."
Sisir

2

Đó là một sự khác biệt rất rõ ràng, và trên thực tế nói chung không phải là thuộc tính của chính ngôn ngữ, mà là của chương trình bạn đang sử dụng để thực thi mã bằng ngôn ngữ đó.

Tuy nhiên, hầu hết các ngôn ngữ được sử dụng chủ yếu dưới dạng này hay dạng khác, và vâng, về cơ bản, Java luôn được biên dịch, trong khi javascript về cơ bản luôn được thông dịch.

Biên dịch mã nguồn là chạy một chương trình trên đó tạo ra một tệp nhị phân, có thể thực thi được, khi chạy, có hành vi được xác định bởi nguồn. Ví dụ: javac biên dịch các tệp .java của người-readbale thành tệp .class có thể đọc được bằng máy.

Để diễn giải mã nguồn, hãy chạy một chương trình trên đó tạo ra hành vi được xác định ngay lập tức mà không tạo tệp trung gian. Ví dụ: khi trình duyệt web của bạn tải stackoverflow.com, nó sẽ diễn giải một loạt javascript (bạn có thể xem bằng cách xem nguồn trang) và tạo ra rất nhiều hiệu ứng đẹp mà các trang này có - ví dụ: upvoting hoặc trình thông báo nhỏ thanh ngang trên cùng.


Trong khi Java lần đầu tiên chuyển sang mã bytecode và chỉ trong khi thực thi JVM mới chuyển nó thành mã máy; có chính xác không khi nói rằng nó được biên dịch và không được giải thích?
Sisir

1
Tôi đoán bạn có thể nói rằng Java bytecode được thông dịch, chắc chắn, nhưng không ai viết Java bytecode. Bản thân Java thường được biên dịch thành bytecode.
Personman

2

Ngôn ngữ thông dịch được thực thi tại thời điểm chạy theo các hướng dẫn như trong kịch bản shell và ngôn ngữ biên dịch là ngôn ngữ được biên dịch (được thay đổi thành ngôn ngữ Assembly, mà CPU có thể hiểu được) và sau đó được thực thi như trong c ++.


0

Như những người khác đã nói, biên dịchthông dịch là cụ thể cho việc triển khai một ngôn ngữ lập trình; chúng không cố hữu trong ngôn ngữ. Ví dụ, có C phiên dịch viên.

Tuy nhiên, chúng ta có thể (và trong thực tế thì có) phân loại các ngôn ngữ lập trình dựa trên cách triển khai phổ biến nhất (đôi khi là chuẩn) của nó. Ví dụ, chúng tôi nói C được biên dịch.

Đầu tiên, chúng ta phải xác định mà không có trình thông dịch và trình biên dịch không rõ ràng:

Trình thông dịch cho ngôn ngữ X là một chương trình (hoặc một máy hoặc chỉ một loại cơ chế nào đó nói chung) thực hiện bất kỳ chương trình p nào được viết bằng ngôn ngữ X sao cho nó thực hiện các hiệu ứng và đánh giá kết quả theo quy định của đặc tả của X .

Một trình biên dịch từ X đến Y là một chương trình (hoặc một cái máy, hoặc chỉ một số loại cơ chế nói chung) mà dịch bất kỳ chương trình p từ một số ngôn ngữ X vào một chương trình ngữ nghĩa tương đương p' trong một số ngôn ngữ Y theo cách như vậy mà giải thích p ' với một thông dịch viên cho Y sẽ mang lại kết quả tương tự và có những ảnh hưởng tương tự như giải thích p với một thông dịch viên cho X .

Lưu ý rằng theo quan điểm của lập trình viên, CPU là trình thông dịch máy cho ngôn ngữ máy bản địa tương ứng của chúng.

Bây giờ, chúng ta có thể phân loại dự kiến ​​các ngôn ngữ lập trình thành 3 loại tùy thuộc vào cách triển khai phổ biến nhất của nó:

  • Ngôn ngữ biên dịch cứng: Khi các chương trình được biên dịch hoàn toàn sang ngôn ngữ máy. Trình thông dịch duy nhất được sử dụng là CPU. Ví dụ: Thông thường, để chạy một chương trình bằng C, mã nguồn được biên dịch sang ngôn ngữ máy, sau đó được thực thi bởi CPU.
  • Ngôn ngữ thông dịch: Khi không có biên dịch nào của chương trình gốc sang ngôn ngữ máy. Nói cách khác, không có mã máy mới nào được tạo ra; chỉ mã máy hiện có mới được thực thi. Một thông dịch khác với CPU cũng phải được sử dụng (thường là một chương trình) .example: Trong việc thực hiện kinh điển của Python, mã nguồn được biên dịch đầu tiên Python bytecode và sau đó rằng bytecode được thực hiện bởi CPython, một chương trình thông dịch viên cho Python bytecode .
  • Ngôn ngữ biên dịch mềm: Khi sử dụng trình thông dịch không phải CPU mà còn có các phần của chương trình gốc có thể được biên dịch sang ngôn ngữ máy. Đây là trường hợp của Java, trong đó mã nguồn được biên dịch thành bytecode trước và sau đó, bytecode có thể được thông dịch bởi Java Interpreter và / hoặc được biên dịch thêm bởi trình biên dịch JIT.

Đôi khi, các ngôn ngữ biên dịch mềm và cứng được quy chiếu để biên dịch đơn giản, do đó C #, Java, C, C ++ được cho là được biên dịch.

Trong phân loại này, JavaScript từng là một ngôn ngữ thông dịch, nhưng đó là cách đây nhiều năm. Ngày nay, nó được biên dịch JIT sang ngôn ngữ máy mẹ đẻ trong hầu hết các triển khai JavaScript chính, vì vậy tôi muốn nói rằng nó thuộc các ngôn ngữ biên dịch mềm.

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.