2016-09-23 20 views
7

Trong C và nhiều dẫn xuất của nó, i++ increments i và đánh giá với giá trị của i trước khi nó được tăng lên, và ++i increments i và đánh giá với giá trị của isau nó được tăng lên.Toán tử tăng trước nào phục vụ trong C?

Tôi có thể thấy lý do cho toán tử tăng cụ thể; nhiều bộ vi xử lý vào thời điểm đó có một opcode tăng đặc biệt nhanh hơn việc bổ sung và khái niệm "gia tăng" là một ý tưởng khác từ "thêm", theo lý thuyết có chúng được viết khác nhau có thể làm cho mã dễ đọc hơn.

Điều tôi không hiểu là cần cho nhà điều hành tăng trước. Không thể sử dụng thực tế cho nó được viết như thế này?

#This... 
x = i++; 
#becomes this: 
x = i; 
++i; 

Có lý do lịch sử mà tôi không biết, có thể không? Bạn không thể "vứt bỏ" các giá trị trả về của các toán tử trong các phiên bản nguyên thủy của C?

+0

Câu hỏi này có thể được chỉnh sửa để đưa nó vào phạm vi không? Tôi sẽ vui lòng chỉnh sửa câu trả lời của tôi và thêm một số bối cảnh lịch sử nhưng không có điểm tôi làm bất kỳ công việc nhiều hơn vào nó cho đến khi câu hỏi được đưa ra giữ. Tôi cũng cần biết các toán tử gia tăng nào đang được giải quyết (lý do chơi chữ). – Mick

+0

[Câu hỏi này đang được thảo luận về meta] (http://meta.stackoverflow.com/questions/335085/is-it-okay-to-delete-and-re-make-a-question-to-stop-everyone -hyperfocusing-on-a) và sau khi bị xóa ở đây đã được [yêu cầu lại ở dạng được làm rõ trên Lập trình viên] (http://programmers.stackexchange.com/questions/331870/origins-of-having-both-prefix- incrementi-và-postfix-increment-i-in-the). Để minh bạch trong khi các cuộc thảo luận này đang diễn ra, tôi đã hủy xóa nó ở đây và sẽ áp đặt khóa tạm thời (1 ngày). – Shog9

Trả lời

12

Một lý do là nó cho phép tạo mã hiệu quả mà không có bất kỳ giai đoạn tối ưu hóa ưa thích nào trong trình biên dịch, ided rằng các lập trình viên biết những gì anh ta (hoặc cô ấy) đã làm. Ví dụ, khi sao chép các nhân vật trong một bộ đệm khác, bạn có thể có:

register char *ptr1; 
register char *ptr2; 
... 
for (...) { 
    *ptr1++ = *ptr2++; /* post-increment */ 
} 

Một trình biên dịch mà tôi đã từng làm việc với (trên một máy tính mini độc quyền) sẽ tạo ra các hoạt động đăng ký sau cho công việc:

load $r1,*$a1++  // load $r1 from address in $a1 and increment $a1 
store $r1,*$a2++  // store $r1 at address in $a2 and increment $a2 

Tôi quên các opcodes thực tế. Trình biên dịch không chứa giai đoạn tối ưu hóa nhưng mã mà nó tạo ra rất chặt chẽ với điều kiện bạn hiểu trình biên dịch và kiến ​​trúc máy. Nó có thể làm điều này bởi vì kiến ​​trúc phần cứng có các chế độ giải quyết trước và giảm dần sau khi đăng ký cho cả thanh ghi địa chỉ và thanh ghi chung. Không có các chế độ địa chỉ tăng trước và sau giảm dần theo như tôi nhớ lại nhưng bạn có thể nhận được mà không cần đến chúng.

Tôi tin rằng máy tính mini DEC trên đó C ban đầu được phát triển có các chế độ địa chỉ như vậy. Máy mà tôi đã làm việc không được thực hiện bởi DEC nhưng kiến ​​trúc khá giống nhau.

Một giai đoạn tối ưu hóa đã được lên kế hoạch cho trình biên dịch. Tuy nhiên, nó chủ yếu được sử dụng bởi các lập trình viên hệ thống và khi họ thấy mã được tạo ra tốt như thế nào, việc thực hiện giai đoạn tối ưu hóa đã được lặng lẽ trì hoãn.

Lý do cơ bản cho thiết kế của C là cho phép tạo ra các trình biên dịch đơn giản và di động có thể tạo ra mã hiệu quả hợp lý với tối ưu hóa mã trung gian tối thiểu (hoặc không). Vì lý do này, các toán tử tăng và giảm và các toán tử gán phân phối đóng một vai trò quan trọng trong việc tạo mã nhỏ gọn và hiệu quả bằng các trình biên dịch C ban đầu. Họ không chỉ là cú pháp cú pháp như đề xuất của Niklaus Wirth et al.

-2

Vì vậy, bạn có thể, ví dụ, làm được điều này

While (++i < threshold) [do something]; 

và điều này ...

While (i++ < threshold) [do something]; 

hoặc bất kỳ một ngàn triển khai cụ thể khác mà cả hai sử dụng giá trị và tăng nó trong một tuyên bố duy nhất và nhận được kết quả khác nhau mong đợi

+0

Điều đó có vẻ rất cụ thể. Bạn có chắc đó là lý do lịch sử thực sự? – Schilcote

+0

Không có lý do lịch sử - chúng có các mục đích khác nhau. – NonCreature0714

+0

Đây là những biến thể thực sự thú vị. với ++ i BenPen