[Powered by Google Translate] Chúng ta hãy nói về mảng.
Vậy tại sao chúng tôi muốn sử dụng mảng?
Vâng chúng ta hãy nói rằng bạn có một chương trình mà cần để lưu trữ 5 ID sinh viên.
Nó có vẻ hợp lý để có 5 biến riêng biệt.
Vì lý do chúng ta sẽ thấy trong một chút, chúng tôi sẽ bắt đầu đếm từ 0.
Các biến chúng ta sẽ có được int ID0, id1 int, và như vậy.
Bất kỳ logic chúng ta muốn thực hiện trên một ID sinh viên sẽ cần phải được sao chép và dán
cho mỗi trong các ID sinh viên.
Nếu chúng ta muốn kiểm tra mà học sinh xảy ra được trong CS50,
đầu tiên chúng ta sẽ cần phải kiểm tra xem ID0 đại diện cho sinh viên trong khóa học.
Sau đó, làm tương tự cho học sinh tiếp theo, chúng tôi sẽ cần phải sao chép và dán mã cho ID0
và thay thế tất cả các lần xuất hiện của ID0 với id1 và như vậy cho id2, 3, và 4.
>> Ngay sau khi bạn nghe thấy rằng chúng ta cần phải sao chép và dán,
bạn nên bắt đầu nghĩ rằng có một giải pháp tốt hơn.
Bây giờ những gì nếu bạn nhận ra bạn không cần 5 ID sinh viên mà là 7?
Bạn cần phải đi trở lại mã nguồn của bạn và thêm vào id5 một, một id6,
và sao chép và dán logic để kiểm tra nếu các ID thuộc về các lớp học cho những 2 ID mới.
Không có gì là kết nối tất cả các ID với nhau, và vì vậy không có cách nào hỏi
chương trình để làm điều này đối với các ID 0 đến 6.
Vâng bây giờ bạn nhận ra bạn có 100 ID sinh viên.
Nó bắt đầu có vẻ ít hơn lý tưởng cần phải khai báo cho từng riêng trong các ID,
và sao chép và dán bất kỳ logic cho những ID mới.
Nhưng có lẽ chúng được xác định, và chúng tôi làm điều đó cho tất cả 100 học sinh.
Nhưng nếu bạn không biết bao nhiêu học sinh có thực sự đang có?
Chỉ có một số sinh viên n và chương trình của bạn phải yêu cầu người sử dụng n rằng những gì.
Uh oh. Điều này sẽ không làm việc rất tốt.
Chương trình của bạn chỉ hoạt động đối với một số hằng số sinh viên.
>> Giải quyết tất cả những vấn đề này là vẻ đẹp của các mảng.
Vì vậy, một mảng là gì?
Trong một số ngôn ngữ lập trình một loại mảng có thể có thể làm nhiều hơn một chút,
nhưng ở đây chúng tôi sẽ tập trung vào mảng dữ liệu cấu trúc cơ bản cũng giống như bạn sẽ thấy nó trong C.
Một mảng là chỉ là một khối lớn của bộ nhớ. Có bấy nhiêu thôi.
Khi chúng tôi nói rằng chúng tôi có một mảng 10 số nguyên, mà chỉ có nghĩa là chúng tôi có một số khối
bộ nhớ đủ lớn để chứa 10 số nguyên riêng biệt.
Giả sử rằng một số nguyên là 4 byte, điều này có nghĩa là một mảng của 10 số nguyên
là một khối liên tục của 40 byte trong bộ nhớ.
Ngay cả khi bạn sử dụng các mảng đa chiều, chúng tôi sẽ không đi vào đây,
nó vẫn chỉ là một khối lớn của bộ nhớ.
Các ký hiệu đa chiều chỉ là một sự tiện lợi.
Nếu bạn có 3 mảng đa chiều 3 các số nguyên,
sau đó chương trình của bạn sẽ thực sự chỉ coi đây như là một khối lớn của 36 byte.
Tổng số các số nguyên là 3 lần 3, và mỗi số nguyên chiếm 4 byte.
>> Chúng ta hãy xem xét một ví dụ cơ bản.
Chúng ta có thể thấy ở đây 2 cách khác nhau của các mảng tuyên bố.
Chúng ta sẽ có nhận xét 1 trong số họ cho chương trình để biên dịch
kể từ khi chúng ta khai báo x hai lần.
Chúng tôi sẽ xem xét một số sự khác biệt giữa 2 loại tờ khai trong một chút.
Cả hai của những dòng này khai báo một mảng của N kích thước,
nơi chúng tôi đã # define N là 10.
Chúng tôi có thể chỉ là một cách dễ dàng đã yêu cầu người sử dụng cho một số nguyên dương
và sử dụng số nguyên đó như là một số phần tử trong mảng của chúng tôi.
Giống như ví dụ thẻ sinh viên của chúng tôi trước, đây là loại giống như tuyên bố 10 hoàn toàn riêng biệt
tưởng tượng biến; x0, x1, x2, và cứ thế tăng lên xN-1.
Bỏ qua những dòng mà chúng ta khai báo các mảng, chú ý các dấu ngoặc vuông vẹn
bên trong cho các vòng.
Khi chúng tôi viết một cái gì đó như x [3], tôi sẽ chỉ đọc như x khung 3,
bạn có thể nghĩ về nó như yêu cầu x3 tưởng tượng.
Thông báo hơn so với một mảng của N kích thước, điều này có nghĩa rằng số bên trong dấu ngoặc đơn,
mà chúng ta sẽ gọi các chỉ số, có thể là bất cứ điều gì từ 0 đến N-1,
mà là một tổng chỉ số N.
>> Để suy nghĩ về việc làm thế nào điều này thực sự hoạt động
hãy nhớ rằng mảng là một khối lớn của bộ nhớ.
Giả sử rằng một số nguyên là 4 byte, toàn bộ mảng x là một khối 40 byte của bộ nhớ.
Vì vậy, x0 đề cập đến 4 byte đầu tiên của khối.
X [1] đề cập đến 4 byte kế tiếp và như vậy.
Điều này có nghĩa là bắt đầu của x là tất cả các chương trình bao giờ cần phải theo dõi.
Nếu bạn muốn sử dụng x [400], sau đó chương trình biết rằng điều này tương đương
chỉ 1.600 byte sau khi sự bắt đầu của x.
Ở đâu chúng tôi nhận được 1.600 byte từ? Đó là chỉ 400 lần 4 byte cho mỗi số nguyên.
>> Trước khi di chuyển trên, nó rất quan trọng để nhận ra rằng trong C
không có thực thi của chỉ số mà chúng tôi sử dụng trong mảng.
Khối lớn của chúng tôi là chỉ có 10 số nguyên dài, nhưng không có gì sẽ hét lên với chúng ta nếu chúng ta viết x [20]
hoặc thậm chí x [-5].
Chỉ số này thậm chí không có được một số.
Nó có thể là bất kỳ biểu hiện tùy ý.
Trong chương trình này, chúng tôi sử dụng các i biến từ vòng lặp để chỉ số vào mảng.
Đây là một mô hình rất phổ biến, vòng lặp từ i = 0 đến chiều dài của mảng,
và sau đó sử dụng i là chỉ số cho mảng.
Bằng cách này bạn có hiệu quả vòng lặp trên toàn bộ mảng,
và bạn có thể chỉ định cho mỗi vị trí trong mảng hoặc sử dụng nó cho một số tính toán.
>> Trong lần đầu tiên cho vòng lặp, tôi bắt đầu từ 0,
và do đó, nó sẽ chỉ định vị trí 0 trong mảng, giá trị 0 lần 2.
Sau đó, tôi gia tăng, và chúng tôi chỉ định vị trí đầu tiên trong mảng giá trị 1 lần 2.
Sau đó, tôi tăng một lần nữa và cứ thế tăng lên cho đến khi chúng ta gán vị trí N-1 trong mảng
giá trị N-1 lần 2.
Vì vậy, chúng tôi đã tạo một mảng với 10 số đầu tiên, ngay cả.
Có thể làm mềm mại sẽ có được một tên chút tốt hơn cho biến hơn x,
nhưng mà có thể đã được đưa ra thứ này đi.
Thứ hai vòng lặp for sau đó chỉ cần in các giá trị mà chúng tôi đã được lưu trữ bên trong của mảng.
>> Hãy thử chạy chương trình với cả hai loại tờ khai mảng
và có một cái nhìn tại đầu ra của chương trình.
Theo như chúng ta có thể thấy, chương trình hoạt động theo cùng một cách cho cả hai loại tờ khai.
Chúng ta hãy nhìn vào những gì sẽ xảy ra nếu chúng ta thay đổi vòng đầu tiên không dừng lại ở N
mà là nói 10.000.
Cách xa hơn cuối của mảng.
Rất tiếc. Có lẽ bạn đã nhìn thấy điều này trước đây.
Một lỗi phân khúc có nghĩa là chương trình của bạn đã bị rơi.
Bạn bắt đầu thấy những khi bạn chạm vào các vùng bộ nhớ bạn không nên chạm vào.
Ở đây chúng ta chạm vào 10.000 địa điểm vượt ra ngoài bắt đầu x,
mà rõ ràng là một nơi trong bộ nhớ, chúng ta không nên được chạm vào.
Vì vậy, hầu hết chúng ta có lẽ sẽ không vô tình đặt 10.000 thay vì N,
nhưng những gì nếu chúng ta làm một cái gì đó tinh tế hơn như nói viết ít hơn hoặc bằng N
trong điều kiện vòng lặp như trái ngược với ít hơn N.
Hãy nhớ rằng một mảng chỉ có chỉ số từ 0 đến N-1,
điều đó có nghĩa rằng chỉ số N là vượt quá kết thúc của mảng.
Chương trình không có thể sụp đổ trong trường hợp này, nhưng nó vẫn còn một lỗi.
Trong thực tế, lỗi này là để phổ biến mà nó có tên riêng của nó,
ra bởi 1 lỗi.
>> Đó là những điều cơ bản.
Vì vậy, sự khác biệt lớn giữa 2 loại tờ khai mảng là gì?
Một khác biệt là khối lớn của bộ nhớ đi.
Trong tuyên bố đầu tiên, mà tôi sẽ gọi các loại khung-mảng,
mặc dù điều này không có nghĩa là một tên thông thường,
nó sẽ đi trên stack.
Trong khi đó, trong lần thứ hai, mà tôi sẽ gọi kiểu con trỏ mảng, nó sẽ đi trên heap.
Điều này có nghĩa rằng khi trở về chức năng, các mảng khung sẽ tự động được deallocated,
trong khi đó như bạn explicitily phải gọi miễn phí trên các mảng con trỏ
hoặc người nào khác bạn có một rò rỉ bộ nhớ.
Ngoài ra, các mảng khung không phải là thực sự là một biến.
Điều này là quan trọng. Nó chỉ là một biểu tượng.
Bạn có thể nghĩ về nó như một hằng số mà trình biên dịch chọn cho bạn.
Điều này có nghĩa là chúng ta không thể làm một cái gì đó giống như x + + với các loại khung,
mặc dù điều này là hoàn toàn hợp lệ với các kiểu con trỏ.
>> Các loại con trỏ là một biến.
Đối với các loại con trỏ, chúng tôi có 2 khối riêng biệt của bộ nhớ.
Biến x chính nó được lưu trữ trong ngăn xếp và chỉ là một con trỏ đơn,
nhưng khối lớn của bộ nhớ được lưu trữ trên heap.
X biến trên stack chỉ lưu trữ địa chỉ
khối lớn của bộ nhớ trên heap.
Một ý nghĩa của điều này là với kích thước của nhà điều hành.
Nếu bạn yêu cầu kích thước của mảng khung, nó sẽ cung cấp cho bạn kích thước của các khối lớn của bộ nhớ,
một cái gì đó giống như 40 byte,
nhưng nếu bạn yêu cầu kích thước của loại con trỏ của mảng,
nó sẽ cho bạn kích thước của biến x chính nó, mà trên thiết bị này là khả năng chỉ 4 byte.
Sử dụng các loại mảng con trỏ, nó là không thể trực tiếp yêu cầu
kích thước của khối lớn của bộ nhớ.
Điều này thường không phải là nhiều hạn chế kể từ khi chúng tôi rất hiếm khi muốn kích thước
khối lớn của bộ nhớ, và chúng ta thường có thể tính toán nếu chúng ta cần nó.
>> Cuối cùng, các mảng khung xảy ra để cung cấp cho chúng tôi với một phím tắt để khởi tạo một mảng.
Chúng ta hãy xem làm thế nào chúng ta có thể viết 10 số nguyên đầu tiên ngay cả bằng cách sử dụng initilization tắt.
Với mảng con trỏ, không phải là có một cách để làm một phím tắt như thế này.
Đây chỉ là một giới thiệu về những gì bạn có thể làm với mảng.
Họ xuất hiện trong hầu hết mọi chương trình bạn viết.
Hy vọng rằng bạn có thể nhìn thấy một cách tốt hơn làm ví dụ ID của học sinh
từ đầu của video.
>> Tên tôi là Rob Bowden, và đây là CS50.