2014-07-23 18 views
27

Trong khi chơi đùa với các nhà điều hành ++, tôi đã cố gắng để viết như sau:Toán tử ++ (hoặc -) trả về cái gì?

++i++; 

tôi mong đợi này để biên dịch lúc đầu, nhưng tôi nhận được một lỗi biên dịch:

The operand of an increment or decrement operator must be a variable, property or indexer.

sau đó tôi đã cố gắng viết ++(i++) để giúp trình biên dịch hiểu những gì tôi có nghĩa là nhưng nó cũng (không ngạc nhiên) đã không làm việc.

Vì vậy, tôi tự hỏi điều gì sẽ trả lại cho nhà khai thác ++? Với các lỗi biên dịch Tôi nhận tôi đã mong ++i để không trở về một int đại diện cho giá trị của i tăng lên, nhưng điều đó cũng không phải là trường hợp kể từ khi tôi có thể làm i = (++i) + 1 với thành công ...

Bất kỳ ai có bất cứ ý tưởng tại sao Nhà điều hành ++ không thể bị xích?

Ngoài ra, (++i).GetType() trả lại System.Int32.

+0

Bạn nên nhìn vào C++ hành quá tải có thể nó sẽ xóa mọi thứ lên http://stackoverflow.com/questions/4421706/operator-overloading –

+0

Chỉ cần tò mò, không (++ i) ++ biên dịch? Tôi không có VS trước mặt tôi, vì vậy tôi không thể kiểm tra. – RLH

+0

Không, không. Bởi vì '+ + i' trả về giá trị của' i' được tăng lên và không phải là biến. (Từ những gì tôi vừa học được: P) – Bun

Trả lời

45

Trong C# Các ++ operator trả về giá trị trước (đối với i++) hoặc sau (đối với ++i) incrementing.

Lỗi mà bạn thấy là do nhà điều hành đó CHỈ có thể được sử dụng trên biến số , thuộc tính hoặc chỉ mục. Lý do là vì mục đích của nhà điều hành là tăng biến đang được tham chiếu. Bạn không thể sử dụng nó trên một biểu thức hoặc loại khác. Điều gì sẽ (9++) làm gì?

Bạn mong đợi (i++)++ tương đương với i++; i++. Nhưng i++ trả lại giá trị và số tăng nội bộ i. Vì bạn không thể áp dụng toán tử ++ cho giá trị chuỗi không thể thực hiện được.

Sự khác biệt trong C++ là ++ tiền tố điều hành mất một tài liệu tham khảo như một đầu vào, và trả về một tham khảo giá trị ban đầu, vì vậy bạn có thể chuỗi các nhà điều hành vì nó chỉ sử dụng con trỏ thay vì của một giá trị. Nhà điều hành postfix trả về một giá trị và do đó không thể bị xiềng xích.

+0

Phần đó về so sánh C#/C++ rất thú vị (không phải phần còn lại của câu trả lời là không), và có lẽ là nguồn gốc của sự hiểu lầm của tôi. Cảm ơn rất nhiều. – Bun

+0

@Bun Rất vui khi được trợ giúp. –

+3

Cũng được bao gồm bởi [câu trả lời này nhiều hơn rộng rãi của Eric Lippert] (http://stackoverflow.com/a/3346729/60761) –

17

Kết quả của các nhà điều hành ++ hoặc --giá trị của biến, bất động sản, hoặc indexer, và không biến, bất động sản, hoặc indexer riêng của mình.

Bạn không thể tăng gấp đôi biến số như (i++)++ vì lý do tương tự mà bạn không thể tự tăng giá trị như 100++.

+0

Wow Tôi không thể tin rằng tôi đã không nghĩ về điều đó. Cảm ơn bạn rất nhiều vì đã giải thích rõ ràng. – Bun

4

Nếu tôi có thể mượn thuật ngữ từ C hoặc C++, toán tử ++ ở đây trả về "giá trị r". Giá trị r không ánh xạ tới một loại ngôn ngữ, đó là một mẹo cú pháp để phân biệt những gì có thể gán (có thể sửa đổi) và cái gì không.

Thứ mà bạn có thể tìm thấy ở bên trái của thao tác gán được gọi là giá trị l (giá trị bên trái) và những thứ bạn có thể tìm thấy ở bên phải của bài tập là "r-values"). Toán tử ++ phải hoạt động trên một giá trị l, vì nó cần gán cho nó. Tuy nhiên, biểu thức trả lại phải là một giá trị r, bởi vì nó sẽ không có ý nghĩa để làm i++ = 4 trong C#, giống như nó sẽ không có ý nghĩa để làm foo.Bar() = 4 hoặc 1 = 5.

C# không có giá trị hoặc giá trị mỗi lần, nhưng nó giới hạn những gì có thể được tìm thấy ở phía bên trái của một nhiệm vụ cho các biến, thuộc tính và hoạt động của chỉ mục. Điều này, không phải ngẫu nhiên, cũng là những gì bạn có thể sử dụng toán tử ++.

+1

Câu trả lời hay. Tôi lưu ý rằng bạn đúng khi nói rằng C# không sử dụng thuật ngữ "rvalue"/"lvalue" hơi khó hiểu. Thay vào đó, C# phân loại tất cả các biểu thức thành một trong: * giá trị, biến, không gian tên, kiểu, nhóm phương thức, hàm rỗng, hàm ẩn danh, thuộc tính, chỉ mục, sự kiện và gọi phương thức trả về void *. (Khởi tạo mảng, mặc dù chúng trông giống như biểu thức, về mặt kỹ thuật không phải là biểu thức.) –

1

Tôi nhận thấy rằng bạn không thể sử dụng ++ trước hoặc sau biểu thức.

Khi bạn sử dụng:

++(i++); 

bạn đang làm một cái gì đó như:

++(<expression>) 

Trình biên dịch giải quyết các biểu hiện đầu tiên và sau đó nó sẽ tăng kết quả của biểu thức và những âm thanh điên. Toán hạng ++ hoạt động bằng cách tăng một biến ngay lập tức không có kết quả của một biểu thức.

Cách biểu thức lập trình được đánh giá? Ngữ pháp của ngôn ngữ (BNF) http://people.cis.ksu.edu/~schmidt/301s11/Lectures/bnfT.html

Dưới đây là một ví dụ về việc sử dụng đúng đắn về toán hạng này ++

int i = 0, j = 0; 
int sum = i++ + j++; 
//result sum = 0, i = 1, j = 1 

này toán hạng ++ là lộn xộn, vì làm 3 điều cùng một lúc (đọc, increment, chuyển nhượng). Cá nhân tôi không sử dụng trong các biểu thức lớn, chẳng hạn như ví dụ trên: i++ + j++. Nhưng tôi vẫn sử dụng nó trong vòng lặp for-loop hoặc while-by của chính nó.

Thậm chí một biểu thức ngắn như i = j++; là một mớ hỗn độn. Giữ mã của bạn đơn giản và dễ hiểu. Khái niệm tương tự có thể được viết như sau:

i = j; 
j++; //or j+=1; 
Các vấn đề liên quan