Tôi đang hỏi về c #, nhưng tôi cho rằng nó giống nhau ở hầu hết các ngôn ngữ khác.
Có ai có một định nghĩa tốt về biểu thức và phát biểu và sự khác biệt là gì?
Tôi đang hỏi về c #, nhưng tôi cho rằng nó giống nhau ở hầu hết các ngôn ngữ khác.
Có ai có một định nghĩa tốt về biểu thức và phát biểu và sự khác biệt là gì?
Câu trả lời:
Biểu hiện: Một cái gì đó đánh giá một giá trị. Ví dụ: 1 + 2 / x
Statement: Một dòng mã thực hiện điều gì đó. Ví dụ: GOTO 100
Trong các ngôn ngữ lập trình đa mục đích sớm nhất, như FORTRAN, sự khác biệt rất rõ ràng. Trong FORTRAN, một câu lệnh là một đơn vị thực thi, một việc mà bạn đã làm. Lý do duy nhất nó không được gọi là "đường" là vì đôi khi nó kéo dài nhiều dòng. Một biểu thức tự nó không thể làm bất cứ điều gì ... bạn phải gán nó cho một biến.
1 + 2 / X
là một lỗi trong FORTRAN, vì nó không làm gì cả. Bạn phải làm một cái gì đó với biểu hiện đó:
X = 1 + 2 / X
FORTRAN không có ngữ pháp như chúng ta biết ngày nay, ý tưởng đó đã được phát minh, cùng với Backus-Naur Form (BNF), như một phần định nghĩa của Algol-60. Vào thời điểm đó, sự phân biệt ngữ nghĩa ("có giá trị" so với "làm điều gì đó") được quy định theo cú pháp : một loại cụm từ là một biểu thức và một cụm từ khác là một câu lệnh và trình phân tích cú pháp có thể phân biệt chúng.
Các nhà thiết kế của các ngôn ngữ sau này đã làm mờ sự khác biệt: họ cho phép các biểu thức cú pháp thực hiện và họ cho phép các câu cú pháp có giá trị. Ví dụ ngôn ngữ phổ biến sớm nhất vẫn còn tồn tại là C. Các nhà thiết kế của C nhận ra rằng không có tác hại nào được thực hiện nếu bạn được phép đánh giá một biểu thức và vứt bỏ kết quả. Trong C, mọi biểu thức cú pháp có thể được tạo thành một câu lệnh chỉ bằng cách ghép một dấu chấm phẩy dọc theo cuối:
1 + 2 / x;
là một tuyên bố hoàn toàn hợp pháp mặc dù hoàn toàn không có gì sẽ xảy ra. Tương tự, trong C, một biểu thức có thể có tác dụng phụ .
1 + 2 / callfunc(12);
bởi vì callfunc
có thể làm điều gì đó hữu ích
Khi bạn cho phép bất kỳ biểu thức nào là một câu lệnh, bạn cũng có thể cho phép toán tử gán (=) bên trong các biểu thức. Đó là lý do tại sao C cho phép bạn làm những việc như
callfunc(x = 2);
Điều này đánh giá biểu thức x = 2 (gán giá trị của 2 cho x) và sau đó chuyển giá trị đó (2) cho hàm callfunc
.
Việc làm mờ các biểu thức và câu lệnh này xảy ra trong tất cả các dẫn xuất C (C, C ++, C # và Java), vẫn có một số câu lệnh (như while
) nhưng cho phép hầu hết mọi biểu thức được sử dụng làm câu lệnh (chỉ gán C #, các biểu thức gọi, tăng và giảm có thể được sử dụng làm câu lệnh; xem câu trả lời của Scott Wisniewski ).
Có hai "phạm trù cú pháp" (là tên kỹ thuật cho loại câu lệnh và biểu thức) có thể dẫn đến sự trùng lặp nỗ lực. Ví dụ: C có hai dạng điều kiện, dạng câu lệnh
if (E) S1; else S2;
và biểu thức
E ? E1 : E2
Và đôi khi mọi người muốn sao chép không có ở đó: ví dụ, trong tiêu chuẩn C, chỉ một câu lệnh có thể khai báo một biến cục bộ mới nhưng khả năng này đủ hữu ích để trình biên dịch GNU C cung cấp một phần mở rộng GNU cho phép một biểu thức khai báo một biểu thức biến cục bộ là tốt.
Các nhà thiết kế của các ngôn ngữ khác không thích loại trùng lặp này và họ đã sớm nhận ra rằng nếu các biểu thức có thể có tác dụng phụ cũng như các giá trị, thì sự phân biệt cú pháp giữa các câu và biểu thức không phải là tất cả hữu ích vì vậy họ đã loại bỏ nó . Haskell, Icon, Lisp và ML là tất cả các ngôn ngữ không có câu cú pháp, chúng chỉ có các biểu thức. Ngay cả các dạng vòng lặp có cấu trúc và các dạng có điều kiện được coi là các biểu thức và chúng có các giá trị nhưng không phải là các biểu thức rất thú vị.
callfunc(x = 2);
đi x
tới callfunc
, không 2
. Nếu x
là một float, callfunc(float)
sẽ được gọi, không callfunc(int)
. Và trong C ++, nếu bạn vượt qua x=y
để func
, và func
mất một tài liệu tham khảo và thay đổi nó, nó thay đổi x
, không phải y
.
where
mệnh đề trong haskell được coi là một biểu thức chứ không phải là một tuyên bố. learnyouahaskell.com/syntax-in-fifts#where
where
thực sự là một phần của khai báo hàm, không phải là biểu thức hoặc câu lệnh.
Lưu ý rằng trong C, "=" thực sự là một toán tử, thực hiện hai điều:
Đây là một trích xuất từ ngữ pháp ANSI C. Bạn có thể thấy rằng C không có nhiều loại câu lệnh khác nhau ... phần lớn các câu lệnh trong một chương trình là các câu lệnh biểu thức, nghĩa là một biểu thức có dấu chấm phẩy ở cuối.
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
expression_statement
: ';'
| expression ';'
;
Biểu thức là một cái gì đó trả về một giá trị, trong khi một câu lệnh thì không.
Ví dụ như:
1 + 2 * 4 * foo.bar() //Expression
foo.voidFunc(1); //Statement
Thỏa thuận lớn giữa hai bên là bạn có thể xâu chuỗi các biểu thức lại với nhau, trong khi các câu lệnh không thể được nối kết.
foo.voidFunc(1);
là một biểu thức có giá trị void. while
và if
là những tuyên bố.
return
nó được coi là một sự thay thế.
Bạn có thể tìm thấy điều này trên wikipedia , nhưng các biểu thức được ước tính theo một số giá trị, trong khi các câu lệnh không có giá trị được đánh giá.
Do đó, các biểu thức có thể được sử dụng trong các câu lệnh, nhưng không phải là cách khác.
Lưu ý rằng một số ngôn ngữ (như Lisp và tôi tin rằng Ruby và nhiều ngôn ngữ khác) không phân biệt tuyên bố và biểu thức ... trong các ngôn ngữ đó, mọi thứ đều là biểu thức và có thể được kết nối với các biểu thức khác.
Để giải thích về sự khác biệt quan trọng về khả năng kết hợp (tính chuỗi) của biểu thức so với câu lệnh, tài liệu tham khảo yêu thích của tôi là bài viết về giải thưởng Turing của John Backus, lập trình có thể được giải phóng khỏi phong cách von Neumann không? .
Các ngôn ngữ bắt buộc (Fortran, C, Java, ...) nhấn mạnh các câu lệnh để cấu trúc các chương trình và có các biểu thức như một kiểu suy nghĩ sau. Ngôn ngữ chức năng nhấn mạnh biểu thức. Các ngôn ngữ chức năng thuần túy có các biểu thức mạnh mẽ như vậy hơn các câu lệnh có thể được loại bỏ hoàn toàn.
Đơn giản là: một biểu thức ước lượng thành một giá trị, một câu lệnh thì không.
{}
là một tuyên bố. Đặt từ trong trích dẫn sợ hãi không thay đổi điều đó. Báo cáo là cấu trúc cú pháp với ngữ nghĩa. Không có thứ gọi là "lớp ngữ nghĩa" - bạn dường như đang đề cập đến việc thực thi . Bạn nói rằng bạn đang cố gắng chính xác, nhưng bạn đã thất bại ở đó. Khiếu nại của bạn về "sự thờ ơ của những người bỏ phiếu" là chủ đề quảng cáo thuần túy; bạn không có thông tin về trạng thái tinh thần của downvoters.
{}
được định nghĩa là một tuyên bố trong thông số ngôn ngữ C #.
Biểu thức có thể được ước tính để nhận giá trị, trong khi các câu lệnh không trả về giá trị (chúng thuộc loại void ).
Tất nhiên, các biểu thức gọi hàm cũng có thể được coi là câu lệnh, nhưng trừ khi môi trường thực thi có một biến tích hợp đặc biệt để giữ giá trị trả về, không có cách nào để lấy nó.
Các ngôn ngữ hướng phát biểu yêu cầu tất cả các thủ tục phải là một danh sách các câu lệnh. Các ngôn ngữ hướng biểu thức, có lẽ là tất cả các ngôn ngữ chức năng, là danh sách các biểu thức hoặc trong trường hợp của LISP, một biểu thức S dài biểu thị một danh sách các biểu thức.
Mặc dù cả hai loại có thể được soạn thảo, hầu hết các biểu thức có thể được soạn tùy ý miễn là các loại khớp với nhau. Mỗi loại câu lệnh có cách soạn thảo các câu lệnh khác, nếu chúng có thể làm tất cả. Foreach và nếu các câu lệnh yêu cầu một thống kê duy nhất hoặc tất cả các câu lệnh cấp dưới đi trong một khối câu lệnh, lần lượt từng câu lệnh, trừ khi các trạm biến áp cho phép các trạm biến áp riêng của chúng.
Các câu lệnh cũng có thể bao gồm các biểu thức, trong đó một biểu thức không thực sự bao gồm bất kỳ câu lệnh nào. Tuy nhiên, một ngoại lệ sẽ là biểu thức lambda, đại diện cho một hàm và do đó có thể bao gồm mọi thứ mà hàm có thể loại trừ trừ khi ngôn ngữ chỉ cho phép lambdas giới hạn, như lambdas biểu thức đơn của Python.
Trong ngôn ngữ dựa trên biểu thức, tất cả những gì bạn cần là một biểu thức cho một hàm vì tất cả các cấu trúc điều khiển trả về một giá trị (rất nhiều trong số chúng trả về NIL). Không cần câu lệnh return vì biểu thức được đánh giá cuối cùng trong hàm là giá trị trả về.
Void
không phải là loại dưới cùng. Xem câu trả lời của tôi .
null
)? Sẽ không void
giống với loại đơn vị hơn (nhưng với giá trị duy nhất không thể truy cập được)?
void
là kiểu trả về của hàm không bao giờ trả về (ví dụ: hàm throw
có lỗi), thì đó là kiểu dưới cùng . Nếu không thì void
là loại đơn vị . Bạn đúng rằng một câu lệnh không thể phân kỳ, có loại đơn vị. Nhưng một tuyên bố có thể phân kỳ là loại dưới cùng. Do Định lý dừng, chúng ta thường không thể chứng minh rằng một hàm không phân kỳ, vì vậy tôi nghĩ đơn vị là hư cấu. Loại dưới cùng không thể có một giá trị, vì vậy nó không thể có một giá trị duy nhất null
.
null
giá trị thực sự là một giả hành biểu thị rằng một tham chiếu đề cập đến một cái gì đó không tồn tại.
Một số điều về ngôn ngữ dựa trên biểu thức:
Quan trọng nhất: Mọi thứ trả về một giá trị
Không có sự khác biệt giữa dấu ngoặc nhọn và dấu ngoặc nhọn để phân định khối mã và biểu thức, vì mọi thứ đều là biểu thức. Điều này không ngăn chặn phạm vi từ vựng mặc dù: Một biến cục bộ có thể được xác định cho biểu thức chứa định nghĩa của nó và tất cả các câu lệnh chứa trong đó, ví dụ.
Trong một ngôn ngữ dựa trên biểu thức, mọi thứ trả về một giá trị. Điều này có thể hơi lạ lúc đầu - Điều gì (FOR i = 1 TO 10 DO (print i))
trở lại?
Một số ví dụ đơn giản:
(1)
trả lại 1
(1 + 1)
trả lại 2
(1 == 1)
trả lại TRUE
(1 == 2)
trả lại FALSE
(IF 1 == 1 THEN 10 ELSE 5)
trả lại 10
(IF 1 == 2 THEN 10 ELSE 5)
trả lại 5
Một vài ví dụ phức tạp hơn:
OpenADoor(), FlushTheToilet()
hoặc TwiddleYourThumbs()
sẽ trả về một số loại giá trị trần tục, chẳng hạn như OK, Xong hoặc Thành công.(FOR i = 1 TO 10 DO (print i))
, giá trị của vòng lặp for là "10", nó làm cho (print i)
biểu thức được ước tính 10 lần, mỗi lần trả về i dưới dạng một chuỗi. Lần cuối cùng thông qua trả lại 10
, câu trả lời cuối cùng của chúng tôiNó thường đòi hỏi một sự thay đổi nhỏ về tư duy để tận dụng tối đa ngôn ngữ dựa trên biểu thức, vì thực tế là mọi thứ đều là một biểu thức cho phép 'nội tuyến' rất nhiều thứ
Ví dụ nhanh:
FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO ( LotsOfCode )
là một sự thay thế hoàn toàn hợp lệ cho các biểu thức không dựa trên biểu thức
IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 FOR i = 1 TO TempVar DO ( LotsOfCode )
Trong một số trường hợp, bố cục mà mã dựa trên biểu thức cho phép tôi cảm thấy tự nhiên hơn nhiều
Tất nhiên, điều này có thể dẫn đến sự điên rồ. Là một phần của dự án sở thích bằng ngôn ngữ kịch bản dựa trên biểu thức có tên MaxScript, tôi đã xoay sở để đưa ra dòng quái vật này
IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
(
LotsOfCode
)
Một tuyên bố là một trường hợp đặc biệt của một biểu thức, một với void
kiểu. Xu hướng của các ngôn ngữ để đối xử với các câu lệnh khác nhau thường gây ra vấn đề, và sẽ tốt hơn nếu chúng được khái quát hóa đúng đắn.
Ví dụ, trong C #, chúng ta có Func<T1, T2, T3, TResult>
tập hợp các đại biểu chung quá tải rất hữu ích . Nhưng chúng ta cũng phải có một tương ứngAction<T1, T2, T3>
bộ , và lập trình chung có mục đích cao hơn liên tục phải được nhân đôi để đối phó với sự phân chia không may này.
Ví dụ tầm thường - một chức năng kiểm tra xem một tham chiếu có phải là null hay không trước khi gọi đến một chức năng khác:
TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
where TValue : class
{
return (value == null) ? default(TValue) : func(value);
}
Trình biên dịch có thể đối phó với khả năng TResult
là void
? Đúng. Tất cả những gì nó phải làm là yêu cầu trả về được theo sau bởi một biểu thức có kiểu void
. Kết quả của default(void)
sẽ là loại void
và func được truyền vào sẽ cần phải có dạng Func<TValue, void>
(tương đương với Action<TValue>
).
Một số câu trả lời khác ngụ ý rằng bạn không thể xâu chuỗi các câu như bạn có thể với các biểu thức, nhưng tôi không chắc ý tưởng này đến từ đâu. Chúng ta có thể nghĩ về ;
cái xuất hiện sau các câu lệnh như là một toán tử infix nhị phân, lấy hai biểu thức kiểu void
và kết hợp chúng thành một biểu thức kiểu duy nhất void
.
Báo cáo -> Hướng dẫn theo dõi
Biểu thức tuần tự -> Đánh giá trả về giá trị
Các câu lệnh về cơ bản giống như các bước, hoặc các hướng dẫn trong một thuật toán, kết quả của việc thực hiện một câu lệnh là sự hiện thực hóa của con trỏ lệnh (được gọi là trong trình biên dịch mã)
Biểu thức không ngụ ý và thứ tự thực hiện từ cái nhìn đầu tiên, mục đích của chúng là để đánh giá và trả về một giá trị. Trong các ngôn ngữ lập trình mệnh lệnh, việc đánh giá một biểu thức có một trật tự, nhưng đó chỉ là do mô hình mệnh lệnh, nhưng nó không phải là bản chất của chúng.
Ví dụ về Tuyên bố:
for
goto
return
if
(tất cả đều ngụ ý sự tiến bộ của dòng (câu lệnh) thực thi sang dòng khác)
Ví dụ về biểu thức:
2+2
(nó không ngụ ý ý tưởng thực hiện, nhưng đánh giá)
Tuyên bố ,
Một tuyên bố là một khối xây dựng theo thủ tục mà từ đó tất cả các chương trình C # được xây dựng. Một câu lệnh có thể khai báo một biến cục bộ hoặc hằng số, gọi một phương thức, tạo một đối tượng hoặc gán một giá trị cho một biến, thuộc tính hoặc trường.
Một loạt các câu lệnh được bao quanh bởi dấu ngoặc nhọn tạo thành một khối mã. Phần thân phương thức là một ví dụ về khối mã.
bool IsPositive(int number)
{
if (number > 0)
{
return true;
}
else
{
return false;
}
}
Các câu trong C # thường chứa các biểu thức. Một biểu thức trong C # là một đoạn mã chứa giá trị bằng chữ, tên đơn giản hoặc toán tử và toán hạng của nó.
Một biểu thức là một đoạn mã có thể được ước tính thành một giá trị, đối tượng, phương thức hoặc không gian tên duy nhất. Hai loại biểu thức đơn giản nhất là chữ và tên đơn giản. Một nghĩa đen là một giá trị không đổi không có tên.
int i = 5;
string s = "Hello World";
Cả i và s đều là các tên đơn giản xác định các biến cục bộ. Khi các biến đó được sử dụng trong một biểu thức, giá trị của biến được lấy và sử dụng cho biểu thức.
if(number >= 0) return true; else return false;
hoặc thậm chí tốt hơn bool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;}
:)
Tôi thích ý nghĩa của statement
logic chính thức của từ này. Đó là một thay đổi trạng thái của một hoặc nhiều biến trong tính toán, cho phép đưa ra tuyên bố đúng hoặc sai về giá trị của chúng.
Tôi đoán sẽ luôn có sự nhầm lẫn trong thế giới điện toán và khoa học nói chung khi thuật ngữ hoặc từ mới được giới thiệu, các từ hiện tại là 'được sử dụng lại' hoặc người dùng không biết gì về thuật ngữ hiện có, được thiết lập hoặc 'phù hợp' cho những gì họ đang mô tả
Tôi không thực sự hài lòng với bất kỳ câu trả lời ở đây. Tôi đã xem xét ngữ pháp cho C ++ (ISO 2008) . Tuy nhiên, có thể vì lợi ích của didactics và lập trình, các câu trả lời có thể đủ để phân biệt hai yếu tố (mặc dù thực tế có vẻ phức tạp hơn).
Một câu lệnh bao gồm 0 hoặc nhiều biểu thức, nhưng cũng có thể là các khái niệm ngôn ngữ khác. Đây là hình thức Extended Backus Naur cho ngữ pháp (trích đoạn phát biểu):
statement:
labeled-statement
expression-statement <-- can be zero or more expressions
compound-statement
selection-statement
iteration-statement
jump-statement
declaration-statement
try-block
Chúng ta có thể thấy các khái niệm khác được coi là câu lệnh trong C ++.
case
ví dụ như một tuyên bố có nhãnif
if/else
,case
while
, do...while
.for (...)
break
, continue
, return
(có thể trở lại biểu hiện),goto
try/catch
khốiĐây là một đoạn trích cho thấy phần biểu thức:
expression:
assignment-expression
expression "," assignment-expression
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
+
, -
, *
, /
, &
, |
,&&
, ||
, ...)throw
khoản là một biểu hiện quáCâu là những câu hoàn chỉnh về mặt ngữ pháp. Biểu hiện là không. Ví dụ
x = 5
đọc là "x được 5." Đây là một câu hoàn chỉnh. Mật mã
(x + 5)/9.0
đọc, "x cộng 5 tất cả chia cho 9.0." Đây không phải là một câu hoàn chỉnh. Tuyên bố
while k < 10:
print k
k += 1
là một câu hoàn chỉnh. Lưu ý rằng tiêu đề vòng lặp là không; "while k <10" là mệnh đề phụ.
while
là một biểu thức là một số ngôn ngữ như Scala. Bạn đang nhầm lẫn ngữ pháp với gõ. Xem câu trả lời của tôi .
while
với một cơ thể vẫn là một biểu hiện trong Scala. Nó cũng có thể là một tuyên bố nếu nó tạo ra các hiệu ứng phụ, điều mà câu trả lời bị đánh giá thấp của tôi cho phép (một biểu thức cũng có thể là một tuyên bố). Câu trả lời của tôi là duy nhất đúng. Xin lỗi tất cả những độc giả không thể hiểu.
(x + 5)/9.0
chắc chắn có thể đứng một mình như một tuyên bố. Ngoài ra, nếu hoàn thành về mặt ngữ pháp, bạn có nghĩa là một chương trình hợp lệ, C không cho phép các câu lệnh đứng một mình như một chương trình duy nhất.
Đây là tóm tắt của một trong những câu trả lời đơn giản nhất mà tôi tìm thấy.
ban đầu được trả lời bởi Anders Kaseorg
Một câu lệnh là một dòng mã hoàn chỉnh thực hiện một số hành động, trong khi một biểu thức là bất kỳ phần nào của mã đánh giá thành một giá trị.
Các biểu thức có thể được kết hợp giữa các chiều theo chiều ngang thành các biểu thức lớn hơn bằng cách sử dụng các toán tử, trong khi các câu lệnh chỉ có thể được kết hợp giữa các chiều dọc theo chiều dọc bằng cách viết lần lượt hoặc bằng các cấu trúc khối.
Mọi biểu thức có thể được sử dụng như một câu lệnh (có tác dụng là đánh giá biểu thức và bỏ qua giá trị kết quả), nhưng hầu hết các câu lệnh không thể được sử dụng làm biểu thức.
Cơ sở thực tế của các khái niệm này là:
Biểu thức : Một thể loại cú pháp có thể được đánh giá thành một giá trị.
Tuyên bố : Một loại cú pháp có thể hiện có thể liên quan đến các đánh giá của một biểu thức và giá trị kết quả của đánh giá (nếu có) không được đảm bảo.
Bên cạnh bối cảnh ban đầu của FORTRAN trong những thập niên đầu, cả hai định nghĩa về biểu thức và phát biểu trong câu trả lời được chấp nhận rõ ràng là sai:
sizeof
toán tử không bao giờ được đánh giá.(BTW, tôi muốn thêm [cần dẫn nguồn] vào câu trả lời liên quan đến các tài liệu về C vì tôi không thể nhớ liệu DMR có ý kiến như vậy hay không. Có vẻ như không có lý do gì để duy trì sự trùng lặp chức năng trong thiết kế của C : đáng chú ý là toán tử dấu phẩy so với các câu lệnh.)
(Lý do sau đây không phải là câu trả lời trực tiếp cho câu hỏi ban đầu, nhưng tôi cảm thấy cần phải làm rõ điều gì đó đã được trả lời ở đây.)
Tuy nhiên, điều đáng nghi ngờ là chúng ta cần một loại "tuyên bố" cụ thể trong các ngôn ngữ lập trình có mục đích chung:
begin
trong Lược đồ) hoặc đường cú pháp của các cấu trúc đơn âm.++i + ++i
vô nghĩa trong C.)Vậy tại sao lại tuyên bố? Dù sao, lịch sử đã là một mớ hỗn độn. Có vẻ như hầu hết các nhà thiết kế ngôn ngữ không cẩn thận lựa chọn của họ.
Tồi tệ hơn, nó thậm chí còn cung cấp cho một số người đam mê hệ thống loại (không đủ quen thuộc với lịch sử PL) một số quan niệm sai lầm rằng hệ thống loại phải có những điều quan trọng phải làm với các thiết kế quy tắc thiết yếu hơn về ngữ nghĩa hoạt động.
Nghiêm túc mà nói, lý luận tùy thuộc vào các loại không phải là xấu trong nhiều trường hợp, nhưng đặc biệt không mang tính xây dựng trong trường hợp đặc biệt này. Ngay cả các chuyên gia có thể làm hỏng mọi thứ lên.
Ví dụ, một người nào đó nhấn mạnh bản chất đánh máy tốt là đối số trung tâm chống lại cách đối xử truyền thống của các phần tiếp theo không bị giới hạn . Mặc dù kết luận có phần hợp lý và những hiểu biết về các hàm tổng hợp vẫn ổn ( nhưng vẫn còn quá ngây thơ đối với bản chất ), nhưng lập luận này không đúng vì nó hoàn toàn bỏ qua cách tiếp cận "kênh bên" trong thực tế như _Noreturn any_of_returnable_types
(trong C11) để mã hóa Falsum
. Và nói đúng ra, một cỗ máy trừu tượng với trạng thái không thể đoán trước không giống với "một chiếc máy tính bị sập".
Trong ngôn ngữ lập trình hướng câu lệnh, khối mã được định nghĩa là danh sách các câu lệnh. Nói cách khác, một câu lệnh là một phần cú pháp mà bạn có thể đặt bên trong một khối mã mà không gây ra lỗi cú pháp.
Wikipedia định nghĩa từ tương tự
Trong lập trình máy tính, một câu lệnh là một đơn vị cú pháp của một ngôn ngữ lập trình mệnh lệnh thể hiện một số hành động sẽ được thực hiện. Một chương trình được viết bằng ngôn ngữ như vậy được hình thành bởi một chuỗi gồm một hoặc nhiều câu lệnh
Lưu ý các tuyên bố sau. (mặc dù "một chương trình" trong trường hợp này là sai về mặt kỹ thuật vì cả C và Java đều từ chối một chương trình không chứa gì các câu lệnh.)
Wikipedia định nghĩa biểu thức từ là
Một biểu thức trong ngôn ngữ lập trình là một thực thể cú pháp có thể được đánh giá để xác định giá trị của nó
Tuy nhiên, điều này là sai, bởi vì trong Kotlin, throw new Exception("")
là một biểu thức nhưng khi được đánh giá, nó chỉ đơn giản là ném một ngoại lệ, không bao giờ trả lại bất kỳ giá trị nào.
Trong một ngôn ngữ lập trình gõ tĩnh, mỗi biểu thức có một loại. Định nghĩa này, tuy nhiên, không hoạt động trong một ngôn ngữ lập trình được gõ động.
Cá nhân, tôi định nghĩa một biểu thức là một phần cú pháp có thể được soạn thảo bằng một toán tử hoặc hàm gọi để mang lại một biểu thức lớn hơn. Điều này thực sự giống với giải thích về biểu thức của Wikipedia:
Nó là sự kết hợp của một hoặc nhiều hằng số, biến, hàm và toán tử mà ngôn ngữ lập trình diễn giải (theo các quy tắc ưu tiên và liên kết cụ thể của nó) và tính toán để tạo ra ("trả về", trong một môi trường có trạng thái)
Nhưng, vấn đề là ở ngôn ngữ lập trình C, được cung cấp một hàm thực thi Một cái gì đó như thế này:
void executeSomething(void){
return;
}
Là executeSomething()
một biểu thức hay nó là một tuyên bố? Theo định nghĩa của tôi, đó là một tuyên bố vì như được định nghĩa trong ngữ pháp tham chiếu C của Microsoft,
Bạn không thể sử dụng giá trị (không tồn tại) của một biểu thức có kiểu void theo bất kỳ cách nào, bạn cũng không thể chuyển đổi một biểu thức void (bằng cách chuyển đổi ngầm định hoặc rõ ràng) thành bất kỳ loại nào ngoại trừ void
Nhưng cùng một trang chỉ rõ rằng cú pháp như vậy là một biểu thức.
Để cải thiện và xác nhận câu trả lời trước của tôi, các định nghĩa về thuật ngữ ngôn ngữ lập trình nên được giải thích từ lý thuyết loại khoa học máy tính khi áp dụng.
Một biểu thức có một loại khác với loại Dưới cùng, tức là nó có một giá trị. Một tuyên bố có loại Đơn vị hoặc Dưới cùng.
Từ đó, một tuyên bố chỉ có thể có bất kỳ hiệu ứng nào trong chương trình khi nó tạo ra hiệu ứng phụ, bởi vì nó không thể trả về một giá trị hoặc nó chỉ trả về giá trị của loại Đơn vị không thể gán được (trong một số ngôn ngữ như một C void
) hoặc (chẳng hạn như trong Scala) có thể được lưu trữ để đánh giá chậm trễ của tuyên bố.
Rõ ràng a @pragma
hoặc a /*comment*/
không có loại và do đó được phân biệt với các câu lệnh. Do đó, loại tuyên bố duy nhất không có tác dụng phụ sẽ là không hoạt động. Không hoạt động chỉ hữu ích như một trình giữ chỗ cho các tác dụng phụ trong tương lai. Bất kỳ hành động nào khác do tuyên bố sẽ là một tác dụng phụ. Một lần nữa một gợi ý trình biên dịch, ví dụ @pragma
, không phải là một câu lệnh vì nó không có kiểu.
@pragma
hoặc /*comment*/
không nhất quán về mặt logic.
Chính xác nhất, một câu lệnh phải có "tác dụng phụ" (nghĩa là bắt buộc ) và một biểu thức phải có một loại giá trị (nghĩa là không phải là loại dưới cùng).
Các loại một tuyên bố là loại đơn vị, nhưng do Tạm dừng lý đơn vị là hư cấu để cho phép nói các loại đáy .
Void
không chính xác là loại dưới cùng (nó không phải là kiểu con của tất cả các loại có thể). Nó tồn tại trong các ngôn ngữ không có hệ thống âm thanh hoàn toàn . Điều đó nghe có vẻ giống như một tuyên bố hợm hĩnh, nhưng tính đầy đủ như chú thích phương sai rất quan trọng để viết phần mềm mở rộng.
Hãy xem Wikipedia nói gì về vấn đề này.
https://en.wikipedia.org/wiki/Statement_(computer_science)
Trong lập trình máy tính, một câu lệnh là phần tử độc lập nhỏ nhất của ngôn ngữ lập trình mệnh lệnh thể hiện một số hành động cần thực hiện.
Nhiều ngôn ngữ (ví dụ C) tạo ra sự khác biệt giữa các câu lệnh và định nghĩa, với một câu lệnh chỉ chứa mã thực thi và một định nghĩa khai báo một mã định danh, trong khi một biểu thức chỉ đánh giá một giá trị.
pass
là một tuyên bố. Nó là không có, và nó không đánh giá bất cứ điều gì.