Tại sao các ngôn ngữ yêu cầu dấu ngoặc đơn xung quanh các biểu thức khi được sử dụng cùng với if if và


67

Ngôn ngữ như C, Java, và C ++ tất cả các yêu cầu ngoặc xung quanh toàn bộ một biểu khi được sử dụng trong một if, whilehoặc switch.

if (true) {
    // Do something
}

như trái ngược với

if true {
    // Do something
}

Điều này có vẻ kỳ lạ với tôi vì dấu ngoặc đơn là dư thừa. Trong ví dụ này, truelà một biểu thức riêng của nó. Dấu ngoặc không biến đổi ý nghĩa của nó theo bất kỳ cách nào tôi biết. Tại sao cú pháp kỳ lạ này tồn tại và tại sao nó lại phổ biến như vậy? Có một lợi ích cho nó mà tôi không biết?


20
Pascal không yêu cầu dấu ngoặc đơn (vì nó yêu cầu a THEN).
JimmyB

30
Python, Ruby thì không.
smci

31
Tôi tin rằng C sử dụng dấu ngoặc đơn vì dấu ngoặc nhọn là tùy chọn cho một thân câu lệnh. Hoặc có lẽ một cách tốt hơn để nói rằng niềng răng không phải là một phần của iftuyên bố, họ chỉ tạo ra một tuyên bố ghép.
Fred Larson

7
Đi, thú vị, yêu cầu niềng răng nhưng không phải dấu ngoặc đơn.
Kos

25
Câu hỏi là một chút tautological. Tại sao hố ga tròn bao phủ tất cả các vòng? Tại sao tất cả anh em là nam? Tại sao tất cả các ngôn ngữ yêu cầu paren đều yêu cầu parens? Nắp hố ga tròn là định nghĩa; anh em là nam theo định nghĩa; Các ngôn ngữ yêu cầu parens yêu cầu parens theo định nghĩa.
Eric Lippert

Câu trả lời:


155

Cần phải có một số cách để biết nơi điều kiện kết thúc và chi nhánh bắt đầu. Có nhiều cách khác nhau để làm điều đó.

Trong một số ngôn ngữ, không có điều kiện nào cả , ví dụ như trong Smalltalk, Self, Drameak, Io, Ioke, Seph và Fancy. Phân nhánh có điều kiện được thực hiện đơn giản như một phương thức bình thường như bất kỳ phương pháp nào khác. Phương thức này được thực hiện trên các đối tượng booleans và được gọi trên boolean. Theo cách đó, điều kiện chỉ đơn giản là người nhận phương thức và hai nhánh là hai đối số, ví dụ như trong Smalltalk:

aBooleanExpression ifTrue: [23] ifFalse: [42].

Trong trường hợp, bạn quen thuộc hơn với Java, điều này tương đương với các điều sau:

aBooleanExpression.ifThenElse(() -> 23, () -> 42);

Trong họ ngôn ngữ Lisp, tình huống tương tự: điều kiện chỉ là các hàm bình thường (thực ra là macro) và đối số thứ nhất là điều kiện, đối số thứ hai và thứ ba là các nhánh, vì vậy chúng chỉ là đối số hàm bình thường, và có không có gì đặc biệt cần thiết để phân định chúng:

(if aBooleanExpression 23 42)

Một số ngôn ngữ sử dụng từ khóa làm dấu phân cách, ví dụ Algol, Ada, BASIC, Pascal, Modula-2, Oberon, Oberon-2, Active Oberon, Hợp phần Pascal, Zonnon, Modula-3:

IF aBooleanExpression THEN RETURN 23 ELSE RETURN 42;

Trong Ruby, bạn có thể sử dụng từ khóa hoặc dấu phân cách biểu thức (dấu chấm phẩy hoặc dòng mới):

if a_boolean_expression then 23 else 42 end

if a_boolean_expression; 23 else 42 end

# non-idiomatic, the minimum amount of whitespace required syntactically
if a_boolean_expression
23 else 42 end

# idiomatic, although only the first newline is required syntactically
if a_boolean_expression
  23
else
  42
end

Go yêu cầu các nhánh phải là các khối và không cho phép các biểu thức hoặc câu lệnh, điều này làm cho các dấu ngoặc nhọn bắt buộc. Do đó, dấu ngoặc đơn không bắt buộc, mặc dù bạn có thể thêm chúng nếu bạn muốn; Perl6 và Rust tương tự nhau về vấn đề này:

if aBooleanExpression { return 23 } else { return 42 }

Một số ngôn ngữ sử dụng các ký tự không chữ và số khác để phân định điều kiện, ví dụ: Python:

if aBooleanExpression: return 23
else: return 42

Điểm mấu chốt là: bạn cần một số cách để biết nơi điều kiện kết thúc và nhánh bắt đầu. Có nhiều cách để làm như vậy, dấu ngoặc đơn chỉ là một trong số đó.


8
Tổng quan rất tốt.
Peter - Tái lập Monica

2
tất nhiên trong một ngôn ngữ mà các biểu thức trần không phải là một câu lệnh (ví dụ như một cái gì đó như BASIC cũ hơn trong đó một giá trị được tính phải được gán cho một biến hoặc được truyền cho một số câu lệnh khác) hoặc khi không có toán tử tiền tố nào bạn luôn có thể để xác định kết thúc của một biểu thức và bắt đầu một tuyên bố nào. Tôi chắc chắn có thể thấy một biến thể BASIC quản lý mà không có dấu phân cách ở cuối câu lệnh IF.
Periata Breatta

4
Ngoài ra, vì C được thiết kế vào những năm 70 và tính toán rất tốn kém, việc thêm một chút dấu ngoặc đơn có thể sẽ giúp trình phân tích cú pháp dễ viết hơn một chút.
Machado

4
Re: Lisp: "thực sự, macro". Trong thực tế IF là một hình thức đặc biệt trong Scheme và CL (chỉ để hoàn thiện).
coredump

1
@Leushenko: Và, ví dụ, trong MISC, mặc định là lười biếng, tất cả các hình thức có điều kiện chỉ là các chức năng bình thường, không phải là macro cũng như các hình thức đặc biệt. (Thật vậy, AFAIR, MISC không có hình thức đặc biệt nào?)
Jörg W Mittag

70

Dấu ngoặc đơn chỉ không cần thiết nếu bạn sử dụng dấu ngoặc nhọn.

if true ++ x;

Ví dụ trở nên mơ hồ mà không có họ.


28
@RobertHarvey - Dấu ngoặc đơn được yêu cầu bởi hầu hết mọi ngôn ngữ tôi biết. Chắc chắn C và họ hàng của nó. OP đang hỏi tại sao họ được yêu cầu - và đó là vì ngôn ngữ sẽ trở nên mơ hồ.
Telastyn

25
Ngay trên đỉnh đầu của tôi, không cần phải có dấu ngoặc đơn iftrong: cơ bản, lắp ráp, python, bash / zsh, tcl, batch, brainfuck hoặc mã máy. Thiếu dấu ngoặc đơn chỉ làm cho ifmơ hồ nếu ngôn ngữ đã được thiết kế để phụ thuộc vào chúng.
candied_orange 7/11/2016

12
Tôi ngạc nhiên khi không ai đề cập đến phiên bản hợp lý và dễ đọc nhất - trong Pascal (bao gồm Delphi) if Condition then ....
Ulrich Gerhardt

18
Đi là một ví dụ tốt về làm ngược lại. Nó làm cho niềng răng {}bắt buộc và do đó không yêu cầu parens xung quanh biểu hiện. Không chỉ không yêu cầu parens mà nếu tôi nhớ chính xác việc thêm parens sẽ gây ra lỗi biên dịch - chúng bị cấm
slebetman

10
@Eiko Hãy để tôi nói lại. Ví dụ trong câu trả lời là mơ hồ về mặt cú pháp , mặc dù nó không rõ ràng về mặt ngữ nghĩa (như bạn đã lưu ý). Nhưng vì giai đoạn phân tích cú pháp xảy ra trước khi phân tích ngữ nghĩa, trình phân tích cú pháp sẽ gặp phải sự mơ hồ - và nó phải đưa ra một phỏng đoán không xác định hoặc thất bại. Nếu (vì bất kỳ lý do nào) trình phân tích cú pháp chọn không thất bại, bộ phân tích ngữ nghĩa sẽ hoạt động với cây kết quả, bất kể đó là gì. Tôi chưa thấy trình biên dịch trong đó trình phân tích ngữ nghĩa sẵn sàng yêu cầu trình phân tích cú pháp lặp lại các cây con và đưa ra một lựa chọn khác ở cấu trúc mơ hồ về mặt cú pháp.
Theodoros Chatzigiannakis 7/11/2016

21

Dấu ngoặc đơn trong một ifcâu lệnh không có cùng ý nghĩa với dấu ngoặc đơn được sử dụng trong biểu thức số học. Dấu ngoặc trong biểu thức số học được sử dụng để nhóm các biểu thức lại với nhau. Dấu ngoặc trong một ifcâu lệnh được sử dụng để phân định biểu thức boolean; nghĩa là, để phân biệt biểu thức boolean với phần còn lại của ifcâu lệnh.

Trong một ifcâu lệnh, dấu ngoặc đơn không thực hiện chức năng nhóm (mặc dù, trong ifcâu lệnh, bạn vẫn có thể sử dụng dấu ngoặc đơn để nhóm các biểu thức số học. Tập hợp dấu ngoặc ngoài sau đó dùng để phân định toàn bộ biểu thức boolean). Làm cho chúng yêu cầu đơn giản hóa trình biên dịch, vì trình biên dịch có thể dựa vào các dấu ngoặc đơn luôn ở đó.


Tôi không thấy cách nó đơn giản hóa trình biên dịch. Quy tắc `IF '(' biểu thức ')' tuyên bố` không đơn giản hơn IF primary_expression statement. Lưu ý rằng sau này là rõ ràng như nhau.
user58697

@ user58697: Không, chỉ có cái sau có sự mơ hồ trong đó toán tử postfix primary_expressionkhông thể được phân biệt với toán tử tiền tố trên câu lệnh biểu thức. Để sao chép câu trả lời của Telastyn , if true ++ x;. Ngoài ra, nếu các câu lệnh trống tồn tại, if a & f;có thể là một câu lệnh rỗng và nhị phân &bên trong điều kiện hoặc là một unary &khi bắt đầu câu lệnh. Nhưng khi khớp dấu ngoặc đơn, có chính xác một trận đấu cho phần mở đầu (
MSalters

@MSalters Một toán tử postfix không phân tích cú pháp chính. Một biểu thức chính là một trong những IDENTIFIER, CONSTANT, STRING_LITERAL'(' expression ')'.
dùng58697

@ user58697: Bạn dường như có một ngôn ngữ cụ thể trong tâm trí. Và dường như có một quy tắc rằng các dấu ngoặc đơn là không cần thiết nếu và chỉ khi các điều kiện là "IDENTIFIER, CONSTANT hoặc STRING_LITITH". Tôi không chắc điều đó làm cho mọi thứ dễ dàng hơn.
MSalters

16

Như những người khác đã chỉ ra một phần điều này là do thực tế là các biểu thức cũng là các câu lệnh hợp lệ và trong trường hợp một khối chỉ với một câu lệnh bạn có thể bỏ dấu ngoặc. Điều này có nghĩa là sau đây là mơ hồ:

if true
    +x;

Bởi vì nó có thể được hiểu là:

if (true + x) {}

thay vì:

if (true) {+x;}

Một số ngôn ngữ (ví dụ Python) cho phép bạn tránh dấu ngoặc đơn nhưng vẫn có điểm đánh dấu điều kiện cuối:

nếu đúng : + x

Tuy nhiên, bạn đúng khi chúng ta có thể định nghĩa một ngôn ngữ không bao giờ yêu cầu dấu ngoặc đơn: một ngôn ngữ mà một biểu thức không phải là một câu lệnh hợp lệ sẽ không có vấn đề này.

Thật không may, điều này có nghĩa là những thứ như:

 ++x;
 functionCall(1,2,3);

sẽ không phải là câu lệnh hợp lệ, vì vậy bạn phải giới thiệu một số cú pháp kỳ lạ để có thể thực hiện các hành động đó mà không cần tạo biểu thức. Một cách đơn giản để làm điều này là chỉ cần thêm biểu thức bằng một điểm đánh dấu như [statement]:

[statement] ++x;
[statement] functionCall(1,2,3);

Bây giờ sự mơ hồ biến mất vì bạn phải viết:

if true
    [statement] ++x;

Nhưng như bạn có thể thấy, tôi không thấy một ngôn ngữ như vậy được phổ biến rộng rãi vì đặt dấu ngoặc đơn xung quanh một ifđiều kiện (hoặc :cuối cùng) sẽ tốt hơn nhiều sau đó đặt một điểm đánh dấu như vậy cho mọi tuyên bố biểu thức.


Lưu ý : việc sử dụng [statement]điểm đánh dấu chỉ là cú pháp đơn giản nhất tôi có thể nghĩ ra. Tuy nhiên, bạn có thể có hai cú pháp hoàn toàn khác biệt cho các biểu thức và câu lệnh không có sự mơ hồ giữa chúng mà không yêu cầu một điểm đánh dấu như vậy. Vấn đề là: ngôn ngữ sẽ vô cùng kỳ lạ vì phải làm những điều tương tự trong một biểu thức hoặc một tuyên bố bạn phải sử dụng một cú pháp hoàn toàn khác.

Một điều mà nói đến cái tâm có hai cú pháp riêng biệt mà không có một dấu hiệu rõ ràng như vậy sẽ được, ví dụ: lực lượng báo cáo sử dụng biểu tượng unicode (nên thay vì forbạn muốn sử dụng một số biến thể unicode của các chữ cái f, or), trong khi biểu thức được Chỉ ASCII.


2
Một ngôn ngữ thực sự tồn tại sử dụng một dấu hiệu câu lệnh biểu thức như vậy: Nếu bạn muốn đánh giá một biểu thức cho các tác dụng phụ của nó, bạn cần phải rõ ràng discardgiá trị của nó trong Nim . Tuy nhiên, điều đó chỉ được thực hiện vì an toàn loại, không phải vì lý do cú pháp.
amon

@amon Nice, tôi không biết về điều đó. Dù sao, như tôi đã nói, điểm đánh dấu không thực sự cần thiết, đó chỉ là một cách đơn giản để đạt được sự khác biệt đó mà không phát minh ra các cú pháp không trực quan.
Bakuriu

1
@amon - nhiều biến thể BASIC cũng có sự tách biệt nghiêm ngặt giữa các biểu thức và câu lệnh. Biểu thức chỉ được phép ở những nơi mà giá trị sẽ thực sự được sử dụng (ví dụ: các phép gán biến, các câu lệnh như PRINT thực hiện một hành động, v.v.). Các thủ tục không được sử dụng để tính toán một giá trị được gọi bằng một từ khóa (thường là "GỌI", mặc dù ít nhất một biến thể tôi biết về việc sử dụng "PROC") có tiền tố tên của chúng. Và như vậy. BASIC thường phân định kết thúc của biểu thức trong câu lệnh IF bằng "THEN", nhưng tôi không thể thấy lý do kỹ thuật nào mà yêu cầu không thể bỏ được.
Periata Breatta

1
Có một ngôn ngữ rất phổ biến trong thập niên 80 có các khối không có dấu ngoặc, dấu ngoặc, dấu hai chấm hoặc dấu khác và chấp nhận các biểu thức như các câu lệnh ở khắp mọi nơi và một số câu lệnh hoạt động như các biểu thức (toán tử ghép như + = và ++). Nó rất tệ, có một bộ xử lý câm trước trình biên dịch ( ?ví dụ như simbol trong thực tế là một hàm sau PP). Không có ;. Chắc chắn, nó cần một điểm đánh dấu cho dòng tiếp tục, nhưng điều này không được khuyến khích. harbour.github.io/doc/clc53.html#if-cmd . Trình biên dịch nhanh và đơn giản (được tạo bằng Bison / Flex).
Maniero

@bigown Họ đạt được điều đó bằng cách sử dụng một cú pháp riêng cho các điều kiện logic, vì vậy, về cơ bản, các điều kiện cho if, whileecc bị giới hạn so với các biểu thức chung được sử dụng trong các ngôn ngữ khác. Chắc chắn: nếu bạn có nhiều hơn hai loại cú pháp (như tuyên bố, biểu thức, biểu thức logic, biểu hiện pha cà phê, ...), bạn có thể giao dịch một số tự do.
Bakuriu

10

Thông thường các ngôn ngữ gia đình C yêu cầu các dấu ngoặc đơn này, nhưng không phổ biến.

Một trong những thay đổi cú pháp đáng chú ý hơn Perl 6 là họ sửa đổi ngữ pháp để bạn không cần phải cung cấp cho các ngoặc xung quanh if, forvà điều kiện tuyên bố tương tự. Vì vậy, một cái gì đó như thế này là hoàn toàn hợp lệ trong Perl 6:

if $x == 4 {
    ...
}

như là

while $queue.pop {
    ...
}

Tuy nhiên, vì chúng chỉ là các biểu thức mà bạn có thể đặt dấu ngoặc đơn xung quanh chúng nếu bạn muốn, trong trường hợp đó chúng chỉ là các nhóm thông thường thay vì một phần bắt buộc của cú pháp như trong C, C #, Java, v.v.

Rust có cú pháp tương tự Perl 6 trong bộ phận này:

if x == 4 {
    ...
}

Đối với tôi, có vẻ như một tính năng của các ngôn ngữ lấy cảm hứng từ C hiện đại hơn là nhìn vào những thứ như thế này và tự hỏi về việc loại bỏ chúng.


Mặc dù câu trả lời của bạn cung cấp một số cái nhìn sâu sắc về các ngôn ngữ khác, nó không trả lời "Tại sao cú pháp kỳ lạ này tồn tại và tại sao nó lại phổ biến như vậy?"

Bạn khá đúng. Tôi đã thực sự tìm cách thêm ngữ cảnh vào câu hỏi, đây không phải là điều dễ làm trong nền tảng này. Tôi đoán cuối cùng nếu tôi đưa ra câu trả lời cho câu hỏi đó là "chỉ vì, vì không có lý do kỹ thuật nào mà ngữ pháp không thể chấp nhận khi không có chúng". Nhưng đó không phải là một câu trả lời rất hữu ích.
Matthew Walton

Trong Perl 5 có cả hai. Đối với các if cấu trúc bình thường hoặc vòng lặp với BLOCK, cần có các parens, ví dụ như trong if ( $x == 4 ) { ... }hoặc foreach my $foo ( @bar ) { ... }. Khi ký hiệu postfix được sử dụng, các parens là tùy chọn, như trong return unless $foo;hoặc ++$x while s/foo/bar/g;.
simbabque

6

Có một khía cạnh mà tôi ngạc nhiên là không có câu trả lời nào hiện có.

C, và nhiều dẫn xuất C và ngoại hình, có một điểm đặc biệt ở chỗ giá trị của một phép gán là giá trị được gán. Một hậu quả của điều này là một bài tập có thể được sử dụng trong đó giá trị được mong đợi.

Điều này cho phép bạn viết những thứ như

if (x = getValue() == 42) { ... }

hoặc là

if (x == y = 47) { ... }

hoặc là

unsigned int n = 0 /* given m == SOME_VALUE */;
while (n < m && *p1++ = *p2++) { n++; }

(được coi là hoàn toàn while (n < m && *p1++ = *p2++ != 0) { n++; }vì C coi không phải là số 0 là sự thật; tình cờ, tôi nghĩ đó chỉ là về strncpy () trong thư viện chuẩn C)

hoặc thậm chí

if (x = 17);

và nó là tất cả hợp lệ. Không phải tất cả các kết hợp hợp lệ về mặt cú pháp đều nhất thiết hữu ích (và các trình biên dịch hiện đại cảnh báo cụ thể về các bài tập bên trong các điều kiện, bởi vì đó là một lỗi phổ biến), nhưng một số trong đó thực sự hữu ích.

Phân tích các câu lệnh như vậy có thể sẽ khó khăn hơn nhiều nếu không có cách rõ ràng nào để xác định nơi biểu thức điều kiện bắt đầu và kết thúc.

Dấu ngoặc đơn đã được sử dụng để phân định tên hàm khỏi các đối số hàm, vì vậy tôi đoán rằng chúng có vẻ giống như một lựa chọn tự nhiên cũng để phân định từ khóa khỏi đối số từ khóa.

Chắc chắn, các cú pháp thay thế có thể được xác định để làm điều tương tự. Nhưng làm như vậy sẽ làm tăng sự phức tạp, đặc biệt là trong trình phân tích cú pháp mà sau đó sẽ cần phải xử lý hai bộ cú pháp khác nhau cho phần lớn cùng một điều. Quay lại khi C đang được thiết kế, sức mạnh tính toán (cả về khả năng xử lý số, bộ nhớ làm việc và khả năng lưu trữ) là vô cùng hạn chế; bất cứ điều gì làm giảm sự phức tạp với ít hoặc không mất chi phí cho khả năng đọc gần như chắc chắn là một sự thay đổi đáng hoan nghênh.

Sử dụng dấu ngoặc đơn có vẻ hơi cổ xưa ngày nay, nhưng nó không giống như việc cho ai đó quen thuộc với ngôn ngữ này, nó làm suy yếu khả năng đọc so với một số cú pháp khác có khả năng diễn đạt những điều tương tự.


5

Lý do chủ yếu là lịch sử.

Vào thời điểm trình biên dịch C đầu tiên được viết, các máy tính có trình biên dịch ram, cpu và trình biên dịch rất hạn chế, trong đó văn bản bằng cách viết bằng tay với một vài công cụ để giúp người viết trình biên dịch. Do đó, các quy tắc phức tạp đã tốn kém để thực hiện trong một trình biên dịch. C ++, C #, Java, v.v ... đều được thiết kế để người lập trình C dễ học, do đó không có những thay đổi không cần thiết nào được thực hiện.

Trong 'c like' ngôn ngữ có điều kiện ( if, while, etc) không yêu cầu blockmã tắt rõ ràng , bạn chỉ có thể sử dụng một câu lệnh đơn giản.

if (a == d) doIt()

hoặc bạn có thể kết hợp các câu lệnh lại với nhau compound statementbằng cách đặt chúng vào{}

Chúng tôi thích trình biên dịch để tìm lỗi chúng tôi mắc phải và đưa ra như một thông báo lỗi chúng tôi có thể hiểu.


3

Cả Java và C ++ đều được phát triển sau khi C trở thành ngôn ngữ lập trình rất phổ biến. Một xem xét trong thiết kế của mỗi ngôn ngữ đó là nó sẽ thu hút các lập trình viên C và muốn các lập trình viên sử dụng ngôn ngữ mới. (Tôi là một trong những lập trình viên C mà họ đã thành công.) Ngoài ra, C ++ được thiết kế để (gần như) có thể hoán đổi với mã C. Để hỗ trợ những mục tiêu này, cả C ++ và Java thông qua nhiều cú pháp của C, bao gồm ngoặc xung quanh các điều kiện của if, whileswitchbáo cáo.

Do đó, lý do tại sao tất cả các ngôn ngữ này yêu cầu dấu ngoặc đơn xung quanh các điều kiện của các câu lệnh đó là vì C có, và câu hỏi thực sự là tại sao C yêu cầu các dấu ngoặc đơn đó.

Nguồn gốc của ngôn ngữ C được mô tả trong bài viết này của Dennis Ritchie, một trong những tác giả chính của sự phát triển của nó (một số thậm chí có thể nói tác giả chính của sự phát triển của nó). Như đã nói trong bài báo đó, C ban đầu được phát triển vào đầu những năm 1970 như là một ngôn ngữ lập trình hệ thống cho các máy tính có không gian cực kỳ hạn chế trong bộ nhớ chính. Người ta mong muốn có một ngôn ngữ ở cấp độ cao hơn ngôn ngữ lắp ráp, nhưng được cung cấp các tài nguyên sẵn có để làm việc, việc dễ dàng phân tích ngôn ngữ cũng rất quan trọng. Yêu cầu dấu ngoặc đơn sẽ giúp việc xác định mã có điều kiện tương đối dễ dàng.

Người ta cũng có thể suy luận rằng khả năng viết chương trình sử dụng ít ký tự hơn được coi là một lợi thế và hai dấu ngoặc đơn chiếm ít không gian hơn từ khóa THENđược sử dụng trong FORTRAN và các ngôn ngữ cấp cao khác tại thời điểm đó; trong thực tế, vì các dấu ngoặc đơn cũng có thể thay thế các khoảng trắng dưới dạng các ký hiệu phân cách, nên if(a==b)có bốn ký tự ngắn hơn IF a==b THEN.

Trong mọi trường hợp, một số cân bằng phải được đặt ra giữa việc con người có thể đọc, viết và hiểu các chương trình được viết bằng C dễ dàng như thế nào, trình biên dịch có thể phân tích và biên dịch các chương trình được viết bằng C dễ dàng như thế nào và bao nhiêu kilobyte (!) sẽ được yêu cầu cả cho nguồn chương trình và trình biên dịch. Và dấu ngoặc đơn xung quanh các điều kiện của if, whilevà các switch tuyên bố là cách mọi người chọn để đạt được sự cân bằng đó trong thiết kế của C.

Bằng chứng là trong một số câu trả lời khác, một khi bạn loại bỏ các trường hợp cụ thể theo đó C được phát triển, tất cả các dạng cú pháp thay thế đã được sử dụng cho các điều kiện của các ngôn ngữ lập trình khác nhau. Vì vậy, các dấu ngoặc đơn thực sự đi đến một quyết định thiết kế được đưa ra bởi một số người dưới những ràng buộc nhất định tại một thời điểm nhất định trong lịch sử.


Tôi không chắc chắn công bằng khi nói rằng C ++ được thiết kế theo cách "để thu hút những lập trình viên sử dụng ngôn ngữ mới". Ghi nhớ C với các lớp học ?
một CVn

@ MichaelKjorling Phải thừa nhận rằng, các nhà phát triển Java đã rõ ràng hơn nhiều về "wooing". Nhưng lưu ý rằng bài báo được liên kết trích dẫn, vì một lý do tại sao Stroustrup chọn bắt đầu với C làm cơ sở cho ngôn ngữ của mình, rằng C được sử dụng rộng rãi. Một cách mà điều này cung cấp một động lực để gần gũi với C là bởi vì mã hiện tại có thể dễ dàng được điều chỉnh (như tôi đã nêu) - nhưng các lập trình viên hiện tại cũng có thể dễ dàng thích nghi.
David K

@ MichaelKjorling Tôi cho rằng cách diễn đạt ban đầu của câu trả lời của tôi cho thấy rằng "wooing" là một yếu tố lớn hơn trong thiết kế ngôn ngữ so với thực tế. Tôi đã chỉnh sửa câu trả lời để cố gắng làm rõ rằng đó chỉ là một điều được đưa vào thiết kế ngôn ngữ.
David K

3

Nhiều người ở đây cho rằng nếu không có dấu ngoặc đơn thì cú pháp sẽ mơ hồ và ngụ ý rằng đây sẽ là một tình huống xấu hoặc thậm chí là không thể.

Trong thực tế, ngôn ngữ có rất nhiều cách để đối phó với sự mơ hồ. Ưu tiên toán tử chỉ là một ví dụ của chủ đề này.

Không, sự mơ hồ không phải là lý do cho dấu ngoặc đơn. Tôi đoán người ta có thể chỉ cần tạo một phiên bản C không yêu cầu dấu ngoặc đơn xung quanh điều kiện (do đó làm cho chúng là tùy chọn) và vẫn tạo mã hợp lệ trong mọi trường hợp. Ví dụ về if a ++ b;có thể được hiểu là tương đương với if (a) ++b;hoặc if (a++) b;, bất cứ điều gì có vẻ phù hợp hơn.

Câu hỏi tại sao Dennis Ritchie chọn làm () bắt buộc (và do đó đặt ra meme này cho nhiều ngôn ngữ dẫn xuất) là một ngôn ngữ. Tôi đoán khái niệm nói rõ rằng điều kiện là một biểu thức chứ không phải là một mệnh lệnh là cha đẻ của ý nghĩ.

Và trên thực tế, C được thiết kế để có thể phân tích cú pháp bằng cách sử dụng trình phân tích cú pháp một lần. Sử dụng cú pháp với dấu ngoặc đơn bắt buộc xung quanh điều kiện hỗ trợ khía cạnh này.


Tôi thấy một downvote về câu trả lời của tôi. Xin vui lòng giải thích trong một bình luận những gì bạn không thích về nó. Có lẽ tôi có thể cải thiện nó sau đó.
Alfe

0

Dấu ngoặc đơn xung quanh các ifđiều kiện không bắt buộc trong Fortran, Cobol, PL / 1, Algol, Algo-68, Pascal, Modula, XPL, PL / M, MPL, ... hoặc bất kỳ ngôn ngữ nào khác có thentừ khóa. thenphục vụ để phân định conditiontừ sau statement.

Dấu ngoặc đóng trong C vv có chức năng như then, và dấu mở là chính thức dự phòng.

Nhận xét trên áp dụng cho các ngôn ngữ phân tích truyền thống.


Fortran không yêu cầu dấu ngoặc đơn trong tất cả các phiên bản IF của nó, bao gồm cả phiên bản cấu trúc.
Lấy
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.