2012-01-12 84 views
42

Có rất nhiều thông tin mâu thuẫn về điều này. Trong khi một số người nói rằng C# được biên dịch (vì nó được biên dịch thành IL và sau đó là mã gốc khi chạy), những người khác nói rằng nó được hiểu là nó cần .NET. EN Wiki nói:C# được diễn giải một phần hay thực sự được biên soạn?

Nhiều giải thích ngôn ngữ đầu tiên được biên soạn với một số hình thức ảo đang máy, sau đó được một trong hai giải thích hoặc biên soạn trong thời gian chạy để mã gốc.

Vì vậy, tôi khá bối rối. Bất cứ ai có thể giải thích rõ ràng điều này?

+0

thể trùng lặp của [Liệu C# Interpreted hoặc biên soạn?] (Http://stackoverflow.com/questions/2777242/is-c-sharp-interpreted-or-compiled) –

Trả lời

47

C# được biên dịch thành IL, bởi trình biên dịch C#.

IL này sau đó được biên dịch chỉ trong thời gian (JIT) khi cần thiết, sang ngôn ngữ lắp ráp gốc của máy chủ. Nó sẽ có thể viết một thời gian chạy NET mà giải thích IL thay vì mặc dù. Ngay cả khi điều này đã được thực hiện, tôi vẫn cho rằng C# là một ngôn ngữ được biên dịch.

+3

Nhưng tại sao nó lại sau đó được nhiều người lập trình coi là ngôn ngữ intepreted? – user970696

+9

Cá nhân tôi chưa từng nghe ai gọi C# là ngôn ngữ thông dịch. – jrummell

+8

Có lẽ chúng chỉ bị nhầm lẫn hoặc thông báo sai. Hoặc có thể tôi đã sai :-) – Simon

9

Look đây: http://msdn.microsoft.com/library/z1zx9t92

Source code viết bằng C# được biên dịch thành một ngôn ngữ trung gian (IL) mà phù hợp với đặc điểm kỹ thuật CLI.

(...)

Khi chương trình C# được thực thi, hội đồng được nạp vào CLR, mà có thể có những hành động khác nhau dựa trên các thông tin trong manifest. Sau đó, nếu các yêu cầu bảo mật được đáp ứng, CLR thực hiện chỉ trong thời gian (JIT) biên dịch để chuyển đổi mã IL thành các hướng dẫn máy gốc .

+0

Cảm ơn, vì vậy nếu tôi không hiểu chính xác, những rắc rối với intepretes có thể đến từ máy ảo (CRM) cần thiết, tuy nhiên nó không phải là intepreter đúng sự thật. – user970696

0

C# là ngôn ngữ có thể kết hợp.

Probbably, tôi lặp lại, probbably, như tôi đã gặp quá những loại ý kiến, thực tế là ai đó nghĩ rằng có một Interpreter cho ngôn ngữ C#, là do các loại dự án như

C# Interpreter Console

hoặc, ví dụ, nổi tiếng

LinqPAD

nơi bạn có thể viết chỉ dòng mã và thực hiện chúng, mang lại nghĩ rằng đó là Python giống như ngôn ngữ, là không đúng. Nó biên dịch những dòng này và thực hiện chúng, giống như một ngôn ngữ lập trình thông thường (từ quan điểm luồng công việc).

+1

cảm ơn bạn. Nhưng vẫn còn, C++ và C# cả hai sẽ được biên dịch ngôn ngữ từ quan điểm đó. Nhưng tôi nghĩ rằng nó không phải là rõ ràng như với C + + trực tiếp biên dịch mã nguồn gốc trong khi với NET của nó chỉ CIL. – user970696

+1

C#, như đã được trả lời ở đây, lần đầu tiên được biên dịch thành Intermidiate Language, và chỉ sau khi được biên dịch trong mã máy máy cụ thể. Có lý do khiến Eric Lippert trả lời http://stackoverflow.com/questions/7875253/what-is-the-purpose-of-a-stack-why-do-we-need-it-msil/7877736#7877736 để hiểu lý do đằng sau điều đó. – Tigran

25

Ngôn ngữ được biên dịch thuần túy có một số lợi thế. Tốc độ, như một quy tắc, và thường làm việc thiết lập kích thước. Một ngôn ngữ được diễn giải hoàn toàn có một số ưu điểm. Tính linh hoạt của việc không cần một giai đoạn biên dịch rõ ràng cho phép chúng tôi chỉnh sửa tại chỗ và dễ dàng di chuyển dễ dàng hơn.

Ngôn ngữ được ghép nối phù hợp với nền tảng trung bình trong trường hợp này.Đó là lý do một mình lý do tại sao chúng ta có thể nghĩ về một ngôn ngữ jitted như được biên dịch hoặc giải thích tùy thuộc vào vị trí mà chúng tôi quan tâm đến việc đạt được, và định kiến ​​của chúng tôi đối với một hay khác.

C# cũng có thể được biên dịch vào lần chạy đầu tiên, như xảy ra trong ASP.NET, làm cho nó gần như được diễn giải trong trường hợp đó (mặc dù nó vẫn được biên dịch sang IL và sau đó được trích xuất trong trường hợp này). Chắc chắn, nó có khá nhiều lợi thế của việc giải thích trong trường hợp này (so sánh với VBScript hoặc JScript được sử dụng trong ASP cổ điển), cùng với nhiều lợi thế của việc biên dịch.

Nghiêm túc, không có ngôn ngữ nào được biên dịch, ngôn ngữ thông dịch hoặc biên dịch. Chúng tôi có thể NGen C# để mã nguồn gốc (mặc dù nếu nó làm một cái gì đó như tự động tải một hội đồng, nó vẫn sẽ sử dụng IL và jitting). Chúng tôi có thể viết một intepretter cho C hoặc C + + (một số người đã làm như vậy). Tuy nhiên, trong trường hợp sử dụng phổ biến nhất của nó, C# được biên dịch thành IL, sau đó được trích xuất, không hoàn toàn là định nghĩa cổ điển về giải thích và cũng không được biên dịch.

+0

Tôi đồng ý với 'không có ngôn ngữ nào được diễn giải, ngôn ngữ được biên dịch hoặc biên soạn'. Tôi đã nhìn thấy một chút về python mà lần đầu tiên được biên dịch để 'byteCode' và sau đó tại thời gian chạy' byteCode' được giải thích bởi người giải thích của hệ điều hành tương ứng. Thực tế này chỉ thêm vào sự ngạc nhiên của tôi gây ra bởi các định nghĩa của các ngôn ngữ biên dịch, biên soạn và diễn giải. – RBT

+0

Các ngôn ngữ JIT có thể nhanh hơn bản địa. Bạn biết rằng điều cụ thể gcc có, nơi nó xuất ra một tệp đo lường hiệu suất khi chạy và sau đó nạp lại dữ liệu đó vào gcc để biên dịch một nhị phân được tối ưu hóa nhiều hơn? JVM và CLR đều làm điều đó liên tục. –

4

Trước hết, hãy hiểu định nghĩa về diễn giải và biên dịch.

"Compile" (when referring to code) có nghĩa là dịch mã từ ngôn ngữ này sang ngôn ngữ khác. Thông thường từ mã nguồn có thể đọc được của con người vào mã máy mà trình xử lý mục tiêu có thể ... xử lý.

"Interpret" (when referring to code) CSONG nghĩa là dịch mã từ ngôn ngữ này sang ngôn ngữ khác. Nhưng lần này nó thường được sử dụng để đi từ mã nguồn có thể đọc được của con người vào một mã trung gian được thực hiện bởi một máy ảo mà diễn giải nó thành mã máy.

Chỉ cần được rõ ràng đang
Nguồn -> Compiler -> Mã Máy
Source code -> Compiler -> Byte Code -> Interpreter -> Mã Máy

Bất kỳ ngôn ngữ có thể, về mặt lý thuyết, hãy interpreted hoặc compiled. Thông thường Java được biên dịch thành bytecode được giải thích bởi máy ảo Java thành mã máy. C# thường được diễn dịch thành bytecode được biên dịch bởi CLR, thời gian chạy ngôn ngữ chung, một máy ảo khác.

Và cho đến nay toàn bộ điều là một mánh lới quảng cáo tiếp thị. Thuật ngữ "diễn giải" đã được thêm vào (hoặc ít nhất, tăng mức sử dụng) để giúp hiển thị mức độ gọn gàng của just-in-time compiling. Nhưng họ có thể vừa sử dụng "biên soạn". Sự khác biệt là một nghiên cứu về ngôn ngữ tiếng Anh và xu hướng kinh doanh hơn là bất kỳ điều gì về bản chất kỹ thuật.

+4

Trong thông dịch viên, không có mã máy nào được tạo khi chạy, chỉ có mã máy hiện tại được thực thi. Theo tiêu chuẩn đó, hoàn toàn không chính xác để tham khảo Thời gian chạy ngôn ngữ chung như một thông dịch viên. –

2

C# là cả hai được diễn giải và biên dịch trong suốt cuộc đời. C# được biên dịch thành một ngôn ngữ ảo được hiểu bởi một máy ảo.

Sự nhầm lẫn bắt nguồn từ khái niệm mờ của "Ngôn ngữ được biên dịch".

"Ngôn ngữ biên soạn" là một từ khóa sai, theo nghĩa nào đó, vì được biên dịch hoặc giải thích không phải là thuộc tính của ngôn ngữ mà là thời gian chạy.

ví dụ: Bạn có thể viết một thông dịch viên C nhưng mọi người thường gọi nó là "Ngôn ngữ biên dịch", bởi vì các bản cài đặt C biên dịch thành mã máy, và ngôn ngữ được thiết kế với sự biên dịch trong tâm trí.

+2

Không, máy tính để bàn .NET VM (gọi là Common Language Runtime) có trình biên dịch JIT, không có trình thông dịch. Ngược lại, .NET Microframework, được tìm thấy trên các thiết bị nhúng nhỏ có thể thậm chí không hỗ trợ sửa đổi mã thời gian chạy, thực sự giải thích IL. –

+0

http://en.wikipedia.org/wiki/Common_Language_Runtime – ajfabbri

+0

Nguồn -> (trình biên dịch) -> Ngôn ngữ trung gian -> (phiên dịch) -> Mã gốc. Tôi đang xem JIT như một thông dịch viên tối ưu hóa. Về cơ bản nó là "bộ nhớ đệm" ở lớp thông dịch. Bạn có thể gọi cả hai bước trình biên dịch nếu bạn muốn. – ajfabbri

8

Nếu bạn cảm thấy, đã học hoặc là trường học cũ, EXE được biên dịch sẽ chuyển từ mã nguồn sang mã máy thì C# được diễn giải. Nếu bạn nghĩ rằng được biên dịch có nghĩa là chuyển đổi mã nguồn thành mã khác, chẳng hạn như mã byte, thì hãy chuyển đổi mã nguồn của nó.Đối với tôi, bất cứ thứ gì cần xử lý thời gian chạy để làm việc trong hệ điều hành mà nó được xây dựng để được giải thích.

+0

Chúng tôi không hỏi ý kiến ​​và "đối với tôi" là một ý kiến. Đây không phải là một diễn đàn. –

0

C#, như Java, có bộ xử lý ngôn ngữ lai. Bộ vi xử lý lai thực hiện các công việc của cả giải thích và biên dịch.

7

Quá nhiều ngữ nghĩa và báo cáo dựa trên ý kiến.

Trước hết: C# không phải là ngôn ngữ diễn giải; CLR và JVM được coi là "runtimes" hoặc "middleware", nhưng cùng tên được áp dụng cho những thứ như Perl. Điều này tạo ra rất nhiều sự nhầm lẫn giữa những người có liên quan với tên.

Thuật ngữ "Phiên dịch" tham chiếu thời gian chạy thường có nghĩa là mã hiện tại diễn giải một số mã không phải là mã gốc. Có hai mô hình lớn: Phân tích cú pháp đọc mã nguồn thô và thực hiện các hành động logic; bytecode thực hiện đầu tiên biên dịch mã để một đại diện nhị phân không phải bản địa, đòi hỏi ít hơn nhiều chu kỳ CPU để giải thích.

Java ban đầu được biên dịch sang bytecode, sau đó đi qua một thông dịch viên; bây giờ, JVM đọc bytecode và chỉ trong thời gian biên dịch nó thành mã gốc. CIL cũng làm như vậy: CLR chỉ sử dụng trình biên dịch trong thời gian tới mã gốc.

Hãy xem xét tất cả các kết hợp của mã nguồn đang chạy, chạy bytecode, biên dịch thành bản gốc, chỉ trong thời gian biên dịch, chạy mã nguồn thông qua trình biên dịch đến đúng thời gian, v.v. Các ngữ nghĩa về việc liệu một ngôn ngữ được biên dịch hay giải thích trở thành vô nghĩa.

Ví dụ: nhiều ngôn ngữ thông dịch sử dụng tính năng biên dịch bytecode chỉ trong thời gian. C# biên dịch thành CIL, mà JIT biên dịch thành native; Ngược lại, Perl lập tức biên dịch một tập lệnh thành mã byte, sau đó chạy bytecode này thông qua một trình thông dịch. Bạn chỉ có thể chạy một assembly C# trong định dạng bytecode CIL; bạn chỉ có thể chạy tập lệnh Perl ở định dạng mã nguồn thô.

Trình biên dịch đơn giản cũng chạy rất nhiều thiết bị bên ngoài và bên trong. Thời gian chạy theo dõi việc thực hiện các chức năng khác nhau và sau đó điều chỉnh bố cục mã để tối ưu hóa các chi nhánh và tổ chức mã cho luồng thực thi cụ thể của nó. Điều đó có nghĩa là mã JIT có thể chạy nhanh hơn mã được biên dịch tự nhiên (như C++ thông thường, hoặc giống như C# chạy qua IL2CPP), vì JIT điều chỉnh chiến lược tối ưu hóa của nó thành trường hợp thực thi của mã khi nó chạy.

Chào mừng bạn đến với thế giới lập trình máy tính. Chúng tôi quyết định làm cho nó cực kỳ phức tạp, sau đó đính kèm các tên không mang tính mô tả vào mọi thứ. Mục đích là để tạo ra flamewars trên định nghĩa của các từ mà không có ý nghĩa thiết thực.

+0

JVM diễn dịch bytecode và sau đó biên dịch một số phương thức/vòng lặp thành mã gốc. Quá trình biên dịch này có thể diễn ra song song với cách giải mã bytecode và mã có thể được hoán đổi nóng. – Steves

+0

Tôi không thể tìm thấy một trích dẫn cho điều đó.Sự hiểu biết của tôi là JVM diễn dịch bytecode khi nó chạy bởi JIT - đó là: khi nó gặp bytecode nó chưa xử lý trong suốt quá trình chạy hiện tại, nó chạy nó thông qua JIT và thực hiện khối mã nguyên sinh kết quả. JIT và thực thi rẻ hơn so với việc giải mã bytecode và việc triển khai cả hai hệ thống là rất phức tạp. –

+0

Thanh toán, ví dụ: https://www.slideshare.net/ZeroTurnaround/vladimir-ivanovjvmjitcompilationoverview-24613146. Những gì bạn mô tả là những gì .NET làm. Những gì tôi mô tả là gì, v.d. Hotspot JVM làm và có nó khá phức tạp, đó là lý do tại sao nó được phát triển trong một thời gian. Bạn cần bytecode giải thích mã để lấy thông tin hồ sơ (suy nghĩ: nếu nhánh nào được dùng phần lớn thời gian, vv), được sử dụng trong trình biên dịch tối ưu hóa (nếu nhánh này không bao giờ được lấy, đừng chi tiêu quá nhiều tài nguyên để tối ưu hóa nó). – Steves

0

Vì máy tính chỉ có thể thực thi mã nhị phân, bất kỳ ngôn ngữ nào cũng sẽ dẫn đến việc tạo mã nhị phân tại một điểm hay điểm khác. Câu hỏi đặt ra là: ngôn ngữ có cho phép bạn tạo một chương trình trong mã nhị phân không? Nếu có, thì đó là một ngôn ngữ được biên dịch: theo định nghĩa "được biên dịch" trong "ngôn ngữ biên dịch" đề cập đến việc biên dịch thành mã nhị phân, không chuyển đổi thành một số mã trung gian. Nếu ngôn ngữ dẫn đến việc sản xuất mã trung gian như vậy cho một chương trình, nó sẽ cần một phần mềm bổ sung để thực hiện việc biên dịch nhị phân từ mã này: sau đó nó là một ngôn ngữ diễn giải. Có phải chương trình "được biên dịch" bởi C# có thể thực thi trực tiếp trên máy không có bất kỳ phần mềm nào khác được cài đặt trên máy này không? nếu không, thì đó là ngôn ngữ thông dịch. Đối với một ngôn ngữ thông dịch, nó là một thông dịch viên sẽ tạo ra mã nhị phân cơ bản, phần lớn thời gian theo một cách năng động vì cơ chế này là cơ sở cho sự linh hoạt của các ngôn ngữ đó. rem. : đôi khi nó không hiển nhiên vì trình thông dịch được đóng gói vào OS

+0

Theo định nghĩa này QBasic là một trình biên dịch. Đó rõ ràng là một crock. C# cũng là một ngôn ngữ thông dịch, với một số JITting ở đây và ở đó như là một tối ưu hóa. Chắc chắn, bạn có thể NGen. Net IL quá, nhưng bạn bị mất tối ưu hóa JITter có thể làm. Những gì bạn nhận được trong IL là danh sách dữ liệu được sử dụng để gửi các cuộc gọi vào các chương trình con, không có mã máy nào được tạo hoặc được thực thi trừ khi thời gian chạy thấy sử dụng nặng và thay thế các dữ liệu mã p bằng mã máy JITted để thay thế việc gửi đi cuộc gọi. – Bob77

1

Tôi tin rằng đây là một chủ đề khá cũ.

Từ quan điểm của tôi, mã được giải thích sẽ thông qua một thông dịch viên, từng dòng dịch và thực thi cùng một lúc. Giống như javascript ví dụ, nó là một mã giải thích, khi một dòng javascript chạy vào một lỗi, kịch bản sẽ chỉ phá vỡ.

Trong khi mã được biên dịch, nó sẽ trải qua một trình biên dịch, dịch tất cả mã sang một dạng mã khác cùng một lúc, mà không thực thi nó trước. Việc thực hiện là trong bối cảnh khác.

0

Nếu chúng tôi đồng ý với định nghĩa thông dịch «Trong khoa học máy tính, thông dịch viên là chương trình máy tính trực tiếp thực hiện, nghĩa là thực hiện, hướng dẫn được viết bằng ngôn ngữ lập trình hoặc kịch bản, mà không yêu cầu chúng được biên dịch vào chương trình ngôn ngữ máy. »không có nghi ngờ: C# không phải là một ngôn ngữ thông dịch.

Interpreter on Wikipedia