2012-01-18 32 views
33

thể trùng lặp:
In C arrays why is this true? a[5] == 5[a]Tại sao tính năng này hoạt động? Vô lý truy cập mảng

Một người bạn của tôi đang học C++ cho lần đầu tiên, và đã gửi cho tôi đoạn này:

int foo[] = { 3, 38, 38, 0, 19, 21, 3, 11, 19, 42 }; 
char bar[] = " abcdefghijklmnopqrstuvwxyz-,.!?-_"; 
for (int i = 0; i < 10; ++i) { 
    std::cout << foo[i][bar]; 
} 

Tại một lướt qua, tôi đã nói với anh ta nó sẽ không hoạt động - tôi nghĩ nó sẽ không biên dịch, hoặc ít nhất sẽ dẫn đến vi phạm truy cập, vì foo không phải là một mảng hai chiều, mà ông ta trả lời rằng nó làm.

Tôi đã cố gắng cho bản thân mình, và điều ngạc nhiên của tôi, đoạn mã chạy hoàn toàn tốt đẹp. Câu hỏi đặt ra là: tại sao?

Theo logic, thông thường và thực hành tốt, cú pháp phải là bar[foo[i]].

Tôi xấu hổ khi thừa nhận rằng tôi không biết chuyện gì đang diễn ra. Điều gì làm cho cú pháp hợp lệ foo[i][bar] trong trường hợp này?

+16

Đây không phải là bản sao chính xác và câu trả lời khá thú vị. Nguyên nhân gốc rễ cho cả hai câu hỏi là như nhau, nhưng điều đó đúng với hàng trăm câu hỏi trên StackOverflow. –

+1

BTW: Tôi sẽ chỉ đồng ý với đầu ra nếu tôi làm những việc như thế này ... – stefaanv

+0

Thật thú vị, điều này thực sự có ý nghĩa nếu người ta đọc câu hỏi được liên kết, nhưng vẫn chính xác là phi logic như khi bạn don ' Tôi hiểu nó; phần phi logic chỉ đơn thuần là chuyển từ "làm thế nào để công việc này" thành "tại sao họ lại cho phép công việc này". –

Trả lời

35

Trong điều kiện đơn giản, việc tiếp cận của một phần tử mảng trong C (và trong C++, khi [] không bị quá tải) như sau:

x[i] = *(x + i) 

Vì vậy, với điều này và một chút của số học. ..

foo[i][bar] 
= (foo[i])[bar] 
= (*(foo + i))[bar] 
= *((*(foo + i)) + bar) 
= *(bar + (*(foo + i))) 
= bar[*(foo + i)] 
= bar[foo[i]] 

Không sử dụng "thực tế" này. Như bạn đã thấy, nó làm cho mã không thể đọc được, và mã không thể đọc được là không thể duy trì.

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