2015-08-01 26 views
5

Để trao đổi với số nguyên, A và B, điều này dường như làm việc trong C,Tại sao "A = A + B - (B = A)" giá trị hoán đổi trong C?

A = A + B - (B = A); 

Tại sao công việc này? Và nếu điều này làm việc trong mọi điều kiện, điều này có thể được sử dụng để rút ngắn bất kỳ thuật toán thường được triển khai nào khác không?

+3

Nó hoạt động trùng hợp trên nhiều triển khai, tuy nhiên, hành vi của mã này không được xác định theo tiêu chuẩn. – Marian

+4

Hơn nữa, nó chỉ ẩn biến tạm thời trong phần 'B = A'. Nó không thực sự đơn giản hóa bất cứ điều gì. IMHO nó làm xấu đi khả năng đọc của mã. –

+3

Liên quan: [Tại sao biểu thức a = a + b - (b = a) đưa ra cảnh báo điểm chuỗi trong C++?] (Http: // stackoverflow.com/questions/13317684/why-do-the-expression-aabba-give-a-sequence-point-cảnh báo-in-c), [Tại sao a = (a + b) - (b = a) là lựa chọn không hợp lệ để hoán đổi hai số nguyên?] (http://stackoverflow.com/questions/20800684/why-is-a-ab-baa-bad-choice-for-swapping-two-integers). –

Trả lời

5

Trên thực tế nó gọi hành vi undefined theo standards-

C99 §6.5: “2. Giữa điểm chuỗi trước đó và tiếp theo, đối tượng phải có giá trị được lưu trữ được sửa đổi nhiều nhất một lần bằng cách đánh giá biểu thức. Hơn nữa, giá trị trước khi được chỉ đọc để xác định giá trị được lưu trữ.”

2

Bạn không nên dựa vào mã như vậy để làm việc vì nó dựa trên thực tế là nó được xử lý từ trái sang phải.

Bất kỳ triển khai nào không thực hiện như vậy sẽ làm cho lỗi không thành công. Bạn nên tránh viết mã không hoạt động trong mọi trường hợp trên tất cả các nền tảng và không phải là trình biên dịch độc lập, hoặc dựa vào những thứ không được ghi chép cũng như không được xác định rõ.

Vậy tại sao nó hoạt động nếu bạn đi từ trái sang phải: Giả sử A = 1 và B = 3
A = A + B - (B = A);
A = 1 + 3 - (1) = 3
Việc gán B xảy ra khi tôi rời() Điểm mấu chốt là chỉ khi xử lý từ trái sang phải, việc gán B đến A sẽ diễn ra sau.

Khi xử lý từ phải sang trái cùng ví dụ: A = A + B - (B = A);
A = 1 + 1 - (1) = 1
Bây giờ, việc gán B đang diễn ra trước.

Một lần nữa, bạn không nên dựa vào mã không rõ ràng cho người đọc những gì đang xảy ra, và đó là trình biên dịch phụ thuộc mà đây là trường hợp ở đây.

1

Đây chỉ là 'ngắn' hơn so với tiêu chuẩn/cách rõ ràng để làm điều đó, trong số dòng/dấu chấm phẩy được sử dụng.

  • Nó giới thiệu thêm hoạt động mà có thể không cho phép tối ưu hóa bởi trình biên dịch
  • xấu đi khả năng đọc (như đã đề cập bởi DR)
  • (ab) sử dụng hành vi phi tiêu chuẩn (như đã đề cập bởi Marion), điều này có thể khiến nó không thành công với một số trình biên dịch

Bạn không bao giờ nên sử dụng nó.

Các vấn đề liên quan