2008-11-13 23 views
8

Tôi luôn tự hỏi tại sao một thao tác đơn giản và cơ bản như hoán đổi nội dung của hai biến này lại không được tích hợp cho nhiều ngôn ngữ.Tại sao toán tử trao đổi/trao đổi không tồn tại trong các ngôn ngữ mệnh lệnh hoặc OO như C/C++/C#/Java ...?

Đây là một trong những bài tập lập trình cơ bản nhất trong các lớp khoa học máy tính; nó được sử dụng nhiều trong nhiều thuật toán (ví dụ: phân loại); mỗi bây giờ và sau đó người ta cần nó và người ta phải sử dụng một biến tạm thời hoặc sử dụng một khuôn mẫu/chức năng chung.

Nó thậm chí là một hướng dẫn máy cơ bản trên nhiều bộ vi xử lý, để lược đồ tiêu chuẩn với một biến tạm thời sẽ được tối ưu hóa.

Nhiều toán tử ít rõ ràng hơn đã được tạo, như toán tử gán (ví dụ: + =, có thể được tạo để phản ánh hướng dẫn tích lũy máy, ví dụ: thêm rìu, bx) hoặc ?? toán tử trong C#.

Vì vậy, lý do là gì? Hay nó thực sự tồn tại, và tôi luôn luôn bỏ lỡ nó?

+0

Câu hỏi hay. Tôi cũng đã tự hỏi về điều này, mặc dù các câu trả lời có ý nghĩa. – pro3carp3

+1

Câu lệnh SWAP * có * tồn tại trong QBasic. – dan04

+0

Thú vị hơn macro 'hoán đổi hai biến' sẽ là một hành vi giống như toán tử dấu phẩy, nhưng giá trị của nó là toán hạng đầu tiên. Hãy tưởng tượng các nhà điều hành đã được viết là "=:" (Tôi thực sự không biết ký hiệu nào sẽ là tốt). Sau đó, "x = (y =: y = x)" sẽ hoán đổi x và y. Các ứng dụng khác sẽ là, ví dụ: "return (y =: y + = 4)" sẽ tương tự về mặt khái niệm với toán tử post-increment, nhưng tăng thêm 4 chứ không phải là một. – supercat

Trả lời

11

Theo kinh nghiệm của tôi, nó không phải là cần thiết thông thường trong các ứng dụng thực tế, ngoài các thuật toán phân loại đã được đề cập và đôi khi trong phần cứng cấp thấp chọc, vì vậy theo quan điểm của tôi, nó có một mục đích quá đặc biệt để có một ngôn ngữ có mục đích chung.

Như đã đề cập, không phải tất cả các bộ xử lý đều hỗ trợ nó như một lệnh (và nhiều bộ xử lý không hỗ trợ nó cho các đối tượng lớn hơn một từ). Vì vậy, nếu nó được hỗ trợ với một số ngữ nghĩa bổ sung hữu ích (ví dụ như là một hoạt động nguyên tử) sẽ rất khó để hỗ trợ trên một số bộ vi xử lý, và nếu nó không có ngữ nghĩa bổ sung thì nó chỉ là (ít khi được sử dụng) đường synatatic.

Các nhà điều hành (+ = etc) được hỗ trợ bởi vì chúng phổ biến hơn trong các chương trình thực tế - và do đó đường syntacic chúng cung cấp hữu ích hơn, và cũng như tối ưu hóa - hãy nhớ ngày C từ cuối những năm 60/đầu những năm 70, và tối ưu hóa trình biên dịch không phải là nâng cao (và các máy ít có khả năng hơn, vì vậy bạn không muốn tối ưu hóa độ dài đi qua anyway).

Paul

+0

Câu trả lời hay. Nhưng có nhiều thuật toán hơn trong đó nó được sử dụng: thuật toán Fisher-Yales (phiên bản hiện đại), thuật toán Steinhaus-Johnson-Trotter, Ma trận-Tranposition. Và trong những chuyên ngành hơn, nơi nó được sử dụng làm đối số cho việc giảm độ phức tạp của không gian. Tôi thừa nhận rằng đây là những trường hợp đặc biệt. –

+1

"đây là những trường hợp đặc biệt" Chính xác. –

+0

Trình biên dịch tối ưu hóa vẫn có thể sử dụng hướng dẫn trao đổi gốc bất cứ khi nào nó phát hiện mẫu, vì vậy nó thậm chí không cần thiết cho các trường hợp chuyên biệt được trích dẫn. –

0

Bạn làm có XOR operator mà không một biến thay thế cho loại nguyên thủy ...

+0

Điều đó có thể gây ra lỗi nếu hai điều bạn đang trao đổi có cùng vị trí lưu trữ. Nó sẽ không cho chúng ra. Tôi cũng đã được nói rằng trên các bộ vi xử lý hiện đại, nó ít hiệu quả hơn là chỉ sử dụng một biến tạm thời. –

3

Đó là một ví dụ sử dụng rộng rãi trong các khóa học khoa học máy tính, nhưng tôi hầu như không bao giờ thấy mình cần nó trong mã thực - trong khi tôi sử dụng + = rất thường xuyên.

Có, trong phân loại nó sẽ là tiện dụng - nhưng bạn không có xu hướng cần phải thực hiện phân loại chính mình, do đó, số lượng sử dụng thực tế trong mã nguồn sẽ vẫn còn khá thấp.

+0

Trao đổi hai giá trị không phải là phổ biến, nhưng nó khá phổ biến để muốn lưu trữ và đọc một lvalue cùng một lúc. Theo một nghĩa nào đó, đó là những gì mà toán tử postfix ++ và - làm (chúng làm một cửa hàng có giá trị được sửa đổi, nhưng giá trị được truyền cho phần còn lại của biểu thức là giá trị được cập nhật trước). – supercat

-1

Tôi nghĩ rằng họ chỉ quên thêm :-) Có, không phải tất cả các CPU đều có loại hướng dẫn này, vậy thì sao? Chúng tôi có nhiều thứ khác mà hầu hết các CPU không có hướng dẫn để tính toán. Nó sẽ dễ dàng hơn/rõ ràng hơn và cũng nhanh hơn (bằng nội tại) nếu chúng ta có nó !!!

+0

Sẽ không nhất thiết phải nhanh hơn - trình biên dịch có thể trực tuyến cuộc gọi để hoán đổi (và tôi sẽ tưởng tượng một số đã làm) nếu nó thực sự là hiệu suất quan trọng. –

+0

Điều gì về phần cứng cơ bản, nếu nó có XCHG hoặc lệnh tương tự, trao đổi sẽ được thực hiện mà không cần một biến tạm thời và nó sẽ thực thi nhanh hơn. Có nhiều nội tại hơn là nội tuyến! – Malkocoglu

+0

... và có nhiều thứ để tối ưu hóa hơn so với nội tuyến. Các trình biên dịch có khả năng tìm ra khi một sự hoán đổi xảy ra (nó không phải là * khó xác định một biến tạm thời và sử dụng XCHG thay thế). – Imagist

4

C++ không có hoán đổi.

#include <algorithm> 
#include <cassert> 

int 
main() 
{ 
    using std::swap; 
    int a(3), b(5); 
    swap(a, b); 
    assert(a == 5 && b == 3); 
} 

Ngoài ra, bạn cũng có thể chuyên swap cho các loại tùy chỉnh!

+2

Đây chỉ là một chức năng được xác định. Ý tôi là, tại sao nó không được tích hợp trực tiếp. –

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