2012-03-13 31 views
5

Trong Matlab, tôi đã cố gắng để đưa các chức năng ẩn danh trong một mảng:Khi nào sử dụng mảng và khi nào sử dụng mảng ô?

>> a=[@(k)0.1/(k+1) @(k)0.1/(k+1)^0.501] 
??? Error using ==> horzcat 
Nonscalar arrays of function handles are not allowed; use cell arrays 
instead. 

Vì vậy, tôi tự hỏi những gì loại của các yếu tố được cho phép trong một mảng, và trong một mảng di động?

Ví dụ, tôi biết rằng trong một mảng, các phần tử có thể là số hoặc chuỗi. Còn gì nữa?

+0

Có thể liên quan - http://stackoverflow.com/questions/9055015/difference-between-accessing-cell-elements-using-and-curly-or-normal-brac/9055336#9055336 –

Trả lời

6

Trong ngắn: mảng di động là một không đồng nhất container, mảng thường là đồng nhất. Điều này có nghĩa rằng trong một mảng thường xuyên tất cả các phần tử có cùng loại, trong khi trong mảng ô, chúng có thể khác nhau. Bạn có thể đọc thêm về mảng ô here.

Sử dụng mảng tế bào khi:

  • Bạn có các loại khác nhau trong mảng của bạn
  • Bạn không chắc chắn liệu trong tương lai bạn có thể mở rộng nó với các loại khác
  • Bạn đang làm việc với các đối tượng có mẫu kế thừa
  • Bạn đang làm việc với một chuỗi các chuỗi - hầu như trong mọi trường hợp, nó thích hợp hơn là char (n, m)
  • Bạn có một mảng lớn, và bạn thường xuyên cập nhật một yếu tố duy nhất trong một chức năng - Do Matlabs copy-on-viết chính sách
  • Bạn đang làm việc có tay cầm chức năng (như @Pursuit giải thích)

thích thường xuyên mảng khi:

  • Tất cả các yếu tố có cùng loại
  • Bạn đang cập nhật toàn bộ mảng trong một shot - như Các hoạt động toán học.
  • Bạn muốn có loại an toàn
  • Bạn sẽ không thay đổi kiểu dữ liệu của mảng trong tương lai
  • Bạn đang làm việc với ma trận toán học.
  • Bạn đang làm việc với các đối tượng mà không có thừa kế

Nhiều lời giải thích về copy-on-viết:

Khi bạn truyền một mảng tới một hàm, một con trỏ/tham chiếu là thông qua.

function foo(x) 
    disp(x); 
end 

x= [1 2 3 4 5]; 
foo(x); %No copy is done here! A pointer is passed. 

Nhưng khi bạn thay đổi (hoặc một phần của nó), bản sao được tạo.

function foo(x) 
    x(4) = x(4) + 1; 
end 

x= [1 2 3 4 5]; 
foo(x); %x is being copied! At least twice memory amount is needed. 

Trong mảng ô, chỉ ô được sao chép.

function foo(x) 
    x{4} = x{4} + 1; 
end 

x= {1 2 3 4 5}; %Only x{4} will be copied 

Do đó, nếu bạn gọi hàm thay đổi một phần tử trên một mảng lớn, bạn đang tạo nhiều bản sao - làm cho bản sao chậm hơn. Nhưng trong một mảng tế bào, nó không phải là trường hợp.

+0

Cảm ơn! Tôi tự hỏi "Malab copy-on-write policy" là gì trong "Bạn có một mảng lớn, và bạn thường cập nhật một phần tử trong một hàm - Do chính sách sao chép-ghi-ghi Malab"? – Tim

+0

@Tim, tôi đã cập nhật câu trả lời của mình. –

3

Xử lý chức năng thực sự là ngoại lệ ở đây và lý do là cú pháp Matlab trở nên đáng ngạc nhiên nếu bạn cho phép hàm xử lý là một phần của mảng không phải ô. Ví dụ

a = @(x)x+1; 
a(2); %This returns 2 

Nhưng, nếu mảng của xử lý chức năng được hỗ trợ, sau đó

b = [@(x)x+1, @(x)x+2]; 
b(2);     %This would return @(x)x+2 
b(3) = @(x)x+3;  %This would extend the size of the array 

Vì vậy, sau đó sẽ này được phép?

a(2) = @(x)x+2;  %Would this extend the size of the previously scalar array 

Longwinded chỉnh sửa: Đây là tài liệu trong release notes accompanying release R14, đó là phiên bản đầu tiên cho phép các chức năng ẩn danh. Trước R14 bạn có thể tạo các hàm xử lý như các tham chiếu đến các hàm m-file và chúng có thể được đặt trong các mảng không phải ô. Chúng chỉ có thể được gọi bằng cách sử dụng feval (ví dụ: fnSin = @sin; output = feval(fnSin, pi)).

Khi chức năng ẩn danh được giới thiệu, Mathworks cập nhật cú pháp để cho phép quy ước gọi đơn giản hơn (ví dụ: fnSin = @sin; output = fnSin(pi)) có tác dụng gây ra sự mơ hồ khi sử dụng các mảng xử lý chức năng không phải ô. Dường như họ đã làm hết sức mình với ông nội hành vi mới này, nhưng những điều kiện ông nội đó đã hết hạn (đây là năm 2004).

+0

Cảm ơn! "Ông" là động từ nghĩa là gì? – Tim

+0

http://en.wikipedia.org/wiki/Grandfather_clause – Pursuit

2

Các mảng chỉ có thể lưu trữ dữ liệu với độ dài cố định. Ví dụ, double, single, char, logical, integer. Lý do là (tôi đoán) chúng được lưu trữ trực tiếp trong một khối bộ nhớ. Mặt khác, các ô được lưu trữ như một danh sách các con trỏ, mỗi con trỏ có thể trỏ đến một dữ liệu có kích thước khác nhau.

Đó là lý do tại sao mảng không thể lưu trữ chuỗi, xử lý chức năng, mảng và nhiều loại dữ liệu. Loại đó có thể có độ dài khác nhau. Ví dụ 'bla' có 3 byte, 'blabla' có 6 byte. Do đó nếu chúng được lưu trữ trong cùng một khối bộ nhớ, nếu bạn muốn thay đổi 'bla' thành 'blabla', bạn sẽ phải chuyển tất cả phần còn lại của bộ nhớ, điều này sẽ rất chậm và do đó nó không được xử lý.

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