2010-05-06 38 views
6

Dưới đây là giá trị hợp lệ và không hợp lệ như được hiển thị và ý nghĩa của chúng. Khi nào một tình huống như thế sẽ nảy sinh khi viết đoạn mã này.Nhà điều hành tăng và giảm

++x = 5;  // legal 
--x = 5;  // legal 
x++ = 5;  // illegal 
x-- = 5;  // illegal 
+0

thể trùng lặp của http://stackoverflow.com/questions/1860461/why-is-i-i-1-unspecified-behavior –

+1

Bài tập về nhà? Câu hỏi kiểm tra? –

+0

Không thực sự cả hai. Chỉ tò mò muốn biết. – ckv

Trả lời

13

Toán tử postfix (x ++/x--) không trả về giá trị (giá trị bạn có thể gán).

Họ trả về một giá trị tạm thời mà là một bản sao của giá trị của biến trước khi thay đổi

Giá trị là một rvalue, vì vậy bạn có thể viết:

y = x++ và nhận được giá trị cũ của x

+0

Bạn nên thêm mã như vậy sẽ không bao giờ được sử dụng. –

+2

@Bruno: Tại sao không? Đó là toàn bộ điểm cho toán tử tăng sau. –

7

Tất cả những giá trị này sửa đổi giá trị của x nhiều hơn một lần giữa các điểm chuỗi và do đó hành vi không xác định, bạn nên cẩn thận tránh. Tôi không thấy sự khác biệt giữa "hợp pháp" và "bất hợp pháp" xuất hiện - vì hành vi là hợp pháp, bất kỳ hành vi nào (bao gồm gửi các loại email đến Bộ trưởng Ngoại giao) đều hoàn toàn phù hợp với Tiêu chuẩn.

5

Giả sử câu hỏi là về các nhà điều hành được xây dựng trong ++--, không có tuyên bố nào là hợp pháp.

Hai chữ cái đầu tiên là cũng được tạo thành, nghĩa là chúng chỉ đơn thuần là compilable vì kết quả tăng tiền tố là lvalue. Hai số cuối cùng là hình thành không chính xác, vì kết quả tăng thêm hậu tố không phải là một rvalue, đó là lý do tại sao bạn không thể gán cho nó.

Tuy nhiên, ngay cả hai trường hợp đầu tiên không hợp pháp theo nghĩa là chúng tạo ra hành vi không xác định. Nó là bất hợp pháp để sửa đổi cùng một đối tượng nhiều hơn một lần mà không có một điểm chuỗi can thiệp. (Lưu ý rằng, các trình biên dịch được phép từ chối biên dịch mã được tạo đúng cũng tạo ra hành vi không xác định, có nghĩa là ngay cả cặp đầu tiên có thể chứng minh là không tương thích).

9

Do cả toán tử =() và toán tử ++() có thể bị quá tải, không thể nói mã nào không biết gì về loại toán tử đang được áp dụng.

+1

Tò mò về lý do tại sao điều này bị giảm giá - người đàn ông có điểm hợp lệ. Tôi hy vọng rằng OP là giao dịch ints, nhưng không có loại được đề cập. – Puppy

+0

Tôi tin rằng nó thậm chí có thể là điều này không dẫn đến hành vi không xác định nếu x là một loại không vô hướng. –

+0

@DeadMG: Mọi người downvote những điều khi họ không nghĩ về họ hoặc nghĩ rằng họ quá "ưa thích" hoặc "pedantic". –

1

Thành thật mà nói, bạn không bao giờ nên viết điều đó. Postincrement và pre-increment (và decrements) chỉ nên được sử dụng một mình. Chúng chỉ là công thức cho sự nhầm lẫn.

+2

Nếu bạn chỉ sử dụng chúng theo cách riêng của mình, thì số gia tăng bài đăng là một toán tử vô giá trị. –

+0

Tôi nghĩ rằng khi DeadMG nói "riêng của họ", anh ta có nghĩa là không làm nhiệm vụ kép. Anh ta không có ý định loại trừ những thứ như 'if (x ++) {/*...*/}' v.v. Đúng, DeadMG? –

+0

Tôi hoàn toàn có ý định loại trừ chúng. Postincrement và pre-increment là cú pháp đường, không tốt khi thực sự được sử dụng trong một biểu thức. Nếu bạn tuyệt vọng cần điều này, làm điều đó bằng tay, để cho trình biên dịch biến nó thành dạng khác. Nhưng tôi không thấy trong điều kiện có thể bạn có thể cần nó anyway. – Puppy

1

Nơi duy nhất tôi có thể nghĩ về tình huống như vậy sẽ xảy ra là với toán tử quá tải của toán tử ++ và toán tử =. Thậm chí sau đó, định nghĩa không rõ ràng. Những gì bạn đang nói về cơ bản là thêm một đến x, sau đó gán 5 cho nó. Một câu hỏi sẽ nảy sinh như tại sao bạn cần tăng x trước khi gán 5 cho nó? Lời giải thích duy nhất có thể là nếu bạn có một số loại lớp mà toán tử ++ bằng cách nào đó tăng bộ đếm nội bộ, sau đó gán. Không có ý tưởng tại sao một điều như vậy là cần thiết mặc dù.

2

++x--x cả hai cung cấp cho bạn lại x (sau khi được tăng/giảm). Tại thời điểm đó bạn có thể làm những gì bạn muốn với nó, bao gồm gán nó một giá trị mới.

x++x-- cả cung cấp cho bạn trở lại những gì x (chỉ trước nó được tăng lên/giảm đi).Thay đổi giá trị này làm cho không có ý nghĩa nhiều hơn là thay đổi giá trị trả về bất kỳ chức năng bình thường của:

obj->getValue() += 3; // pointless