1 00:00:07,360 --> 00:00:09,360 [Powered by Google Translate] Chúng ta hãy nói về mảng. 2 00:00:09,360 --> 00:00:12,780 Vậy tại sao chúng tôi muốn sử dụng mảng? 3 00:00:12,780 --> 00:00:17,210 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. 4 00:00:17,210 --> 00:00:21,270 Nó có vẻ hợp lý để có 5 biến riêng biệt. 5 00:00:21,270 --> 00:00:24,240 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. 6 00:00:24,240 --> 00:00:30,700 Các biến chúng ta sẽ có được int ID0, id1 int, và như vậy. 7 00:00:30,700 --> 00:00:34,870 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 8 00:00:34,870 --> 00:00:36,870 cho mỗi trong các ID sinh viên. 9 00:00:36,870 --> 00:00:39,710 Nếu chúng ta muốn kiểm tra mà học sinh xảy ra được trong CS50, 10 00:00:39,710 --> 00:00:43,910 đầ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. 11 00:00:43,910 --> 00:00:48,070 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 12 00:00:48,070 --> 00:00:54,430 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. 13 00:00:54,430 --> 00:00:57,560 >> Ngay sau khi bạn nghe thấy rằng chúng ta cần phải sao chép và dán, 14 00:00:57,560 --> 00:01:00,440 bạn nên bắt đầu nghĩ rằng có một giải pháp tốt hơn. 15 00:01:00,440 --> 00:01:05,360 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? 16 00:01:05,360 --> 00:01:09,570 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, 17 00:01:09,570 --> 00:01:14,260 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. 18 00:01:14,260 --> 00:01:19,600 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 19 00:01:19,600 --> 00:01:22,040 chương trình để làm điều này đối với các ID 0 đến 6. 20 00:01:22,040 --> 00:01:26,120 Vâng bây giờ bạn nhận ra bạn có 100 ID sinh viên. 21 00:01:26,120 --> 00:01:30,770 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, 22 00:01:30,770 --> 00:01:33,760 và sao chép và dán bất kỳ logic cho những ID mới. 23 00:01:33,760 --> 00:01:38,380 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. 24 00:01:38,380 --> 00:01:42,240 Nhưng nếu bạn không biết bao nhiêu học sinh có thực sự đang có? 25 00:01:42,240 --> 00:01:47,320 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ì. 26 00:01:47,320 --> 00:01:50,250 Uh oh. Điều này sẽ không làm việc rất tốt. 27 00:01:50,250 --> 00:01:53,820 Chương trình của bạn chỉ hoạt động đối với một số hằng số sinh viên. 28 00:01:53,820 --> 00:01:57,520 >> Giải quyết tất cả những vấn đề này là vẻ đẹp của các mảng. 29 00:01:57,520 --> 00:01:59,930 Vì vậy, một mảng là gì? 30 00:01:59,930 --> 00:02:04,480 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, 31 00:02:04,480 --> 00:02:09,960 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. 32 00:02:09,960 --> 00:02:14,030 Một mảng là chỉ là một khối lớn của bộ nhớ. Có bấy nhiêu thôi. 33 00:02:14,030 --> 00:02:17,770 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 34 00:02:17,770 --> 00:02:20,740 bộ nhớ đủ lớn để chứa 10 số nguyên riêng biệt. 35 00:02:29,930 --> 00:02:33,410 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 36 00:02:33,410 --> 00:02:37,180 là một khối liên tục của 40 byte trong bộ nhớ. 37 00:02:42,660 --> 00:02:46,280 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, 38 00:02:46,280 --> 00:02:49,200 nó vẫn chỉ là một khối lớn của bộ nhớ. 39 00:02:49,200 --> 00:02:51,840 Các ký hiệu đa chiều chỉ là một sự tiện lợi. 40 00:02:51,840 --> 00:02:55,640 Nếu bạn có 3 mảng đa chiều 3 các số nguyên, 41 00:02:55,640 --> 00:03:00,650 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. 42 00:03:00,650 --> 00:03:05,460 Tổng số các số nguyên là 3 lần 3, và mỗi số nguyên chiếm 4 byte. 43 00:03:05,460 --> 00:03:07,750 >> Chúng ta hãy xem xét một ví dụ cơ bản. 44 00:03:07,750 --> 00:03:10,660 Chúng ta có thể thấy ở đây 2 cách khác nhau của các mảng tuyên bố. 45 00:03:15,660 --> 00:03:18,580 Chúng ta sẽ có nhận xét 1 trong số họ cho chương trình để biên dịch 46 00:03:18,580 --> 00:03:20,900 kể từ khi chúng ta khai báo x hai lần. 47 00:03:20,900 --> 00:03:25,140 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. 48 00:03:25,140 --> 00:03:28,560 Cả hai của những dòng này khai báo một mảng của N kích thước, 49 00:03:28,560 --> 00:03:30,740 nơi chúng tôi đã # define N là 10. 50 00:03:30,740 --> 00:03:34,460 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 51 00:03:34,460 --> 00:03:37,250 và sử dụng số nguyên đó như là một số phần tử trong mảng của chúng tôi. 52 00:03:37,250 --> 00:03:41,960 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 53 00:03:41,960 --> 00:03:49,000 tưởng tượng biến; x0, x1, x2, và cứ thế tăng lên xN-1. 54 00:03:57,270 --> 00:04:00,840 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 55 00:04:00,840 --> 00:04:02,090 bên trong cho các vòng. 56 00:04:02,090 --> 00:04:09,660 Khi chúng tôi viết một cái gì đó như x [3], tôi sẽ chỉ đọc như x khung 3, 57 00:04:09,660 --> 00:04:13,090 bạn có thể nghĩ về nó như yêu cầu x3 tưởng tượng. 58 00:04:13,090 --> 00:04:17,519 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, 59 00:04:17,519 --> 00:04:22,630 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, 60 00:04:22,630 --> 00:04:25,660 mà là một tổng chỉ số N. 61 00:04:25,660 --> 00:04:28,260 >> Để suy nghĩ về việc làm thế nào điều này thực sự hoạt động 62 00:04:28,260 --> 00:04:31,260 hãy nhớ rằng mảng là một khối lớn của bộ nhớ. 63 00:04:31,260 --> 00:04:37,460 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ớ. 64 00:04:37,460 --> 00:04:41,360 Vì vậy, x0 đề cập đến 4 byte đầu tiên của khối. 65 00:04:45,810 --> 00:04:49,230 X [1] đề cập đến 4 byte kế tiếp và như vậy. 66 00:04:49,230 --> 00:04:53,760 Đ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. 67 00:04:55,660 --> 00:04:59,840 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 68 00:04:59,840 --> 00:05:03,460 chỉ 1.600 byte sau khi sự bắt đầu của x. 69 00:05:03,460 --> 00:05:08,780 Ở đâ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. 70 00:05:08,780 --> 00:05:13,170 >> Trước khi di chuyển trên, nó rất quan trọng để nhận ra rằng trong C 71 00:05:13,170 --> 00:05:17,080 không có thực thi của chỉ số mà chúng tôi sử dụng trong mảng. 72 00:05:17,080 --> 00:05:23,180 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] 73 00:05:23,180 --> 00:05:26,060 hoặc thậm chí x [-5]. 74 00:05:26,060 --> 00:05:28,240 Chỉ số này thậm chí không có được một số. 75 00:05:28,240 --> 00:05:30,630 Nó có thể là bất kỳ biểu hiện tùy ý. 76 00:05:30,630 --> 00:05:34,800 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. 77 00:05:34,800 --> 00:05:40,340 Đâ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, 78 00:05:40,340 --> 00:05:43,350 và sau đó sử dụng i là chỉ số cho mảng. 79 00:05:43,350 --> 00:05:46,160 Bằng cách này bạn có hiệu quả vòng lặp trên toàn bộ mảng, 80 00:05:46,160 --> 00:05:50,600 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. 81 00:05:50,600 --> 00:05:53,920 >> Trong lần đầu tiên cho vòng lặp, tôi bắt đầu từ 0, 82 00:05:53,920 --> 00:05:58,680 và do đó, nó sẽ chỉ định vị trí 0 trong mảng, giá trị 0 lần 2. 83 00:05:58,680 --> 00:06:04,370 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. 84 00:06:04,370 --> 00:06:10,170 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 85 00:06:10,170 --> 00:06:13,370 giá trị N-1 lần 2. 86 00:06:13,370 --> 00:06:17,810 Vì vậy, chúng tôi đã tạo một mảng với 10 số đầu tiên, ngay cả. 87 00:06:17,810 --> 00:06:21,970 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, 88 00:06:21,970 --> 00:06:24,760 nhưng mà có thể đã được đưa ra thứ này đi. 89 00:06:24,760 --> 00:06:30,210 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. 90 00:06:30,210 --> 00:06:33,600 >> Hãy thử chạy chương trình với cả hai loại tờ khai mảng 91 00:06:33,600 --> 00:06:36,330 và có một cái nhìn tại đầu ra của chương trình. 92 00:06:51,450 --> 00:06:57,020 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. 93 00:06:57,020 --> 00:07:02,230 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 94 00:07:02,230 --> 00:07:05,040 mà là nói 10.000. 95 00:07:05,040 --> 00:07:07,430 Cách xa hơn cuối của mảng. 96 00:07:14,700 --> 00:07:17,210 Rất tiếc. Có lẽ bạn đã nhìn thấy điều này trước đây. 97 00:07:17,210 --> 00:07:20,440 Một lỗi phân khúc có nghĩa là chương trình của bạn đã bị rơi. 98 00:07:20,440 --> 00:07:24,430 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. 99 00:07:24,430 --> 00:07:27,870 Ở đây chúng ta chạm vào 10.000 địa điểm vượt ra ngoài bắt đầu x, 100 00:07:27,870 --> 00:07:31,920 mà rõ ràng là một nơi trong bộ nhớ, chúng ta không nên được chạm vào. 101 00:07:31,920 --> 00:07:37,690 Vì vậy, hầu hết chúng ta có lẽ sẽ không vô tình đặt 10.000 thay vì N, 102 00:07:37,690 --> 00:07:42,930 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 103 00:07:42,930 --> 00:07:46,830 trong điều kiện vòng lặp như trái ngược với ít hơn N. 104 00:07:46,830 --> 00:07:50,100 Hãy nhớ rằng một mảng chỉ có chỉ số từ 0 đến N-1, 105 00:07:50,100 --> 00:07:54,510 điều đó có nghĩa rằng chỉ số N là vượt quá kết thúc của mảng. 106 00:07:54,510 --> 00:07:58,050 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. 107 00:07:58,050 --> 00:08:01,950 Trong thực tế, lỗi này là để phổ biến mà nó có tên riêng của nó, 108 00:08:01,950 --> 00:08:03,970 ra bởi 1 lỗi. 109 00:08:03,970 --> 00:08:05,970 >> Đó là những điều cơ bản. 110 00:08:05,970 --> 00:08:09,960 Vì vậy, sự khác biệt lớn giữa 2 loại tờ khai mảng là gì? 111 00:08:09,960 --> 00:08:13,960 Một khác biệt là khối lớn của bộ nhớ đi. 112 00:08:13,960 --> 00:08:17,660 Trong tuyên bố đầu tiên, mà tôi sẽ gọi các loại khung-mảng, 113 00:08:17,660 --> 00:08:20,300 mặc dù điều này không có nghĩa là một tên thông thường, 114 00:08:20,300 --> 00:08:22,480 nó sẽ đi trên stack. 115 00:08:22,480 --> 00:08:27,450 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. 116 00:08:27,450 --> 00:08:32,480 Đ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, 117 00:08:32,480 --> 00:08:36,419 trong khi đó như bạn explicitily phải gọi miễn phí trên các mảng con trỏ 118 00:08:36,419 --> 00:08:38,010 hoặc người nào khác bạn có một rò rỉ bộ nhớ. 119 00:08:38,010 --> 00:08:42,750 Ngoài ra, các mảng khung không phải là thực sự là một biến. 120 00:08:42,750 --> 00:08:45,490 Điều này là quan trọng. Nó chỉ là một biểu tượng. 121 00:08:45,490 --> 00:08:49,160 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. 122 00:08:49,160 --> 00:08:52,970 Đ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, 123 00:08:52,970 --> 00:08:56,240 mặc dù điều này là hoàn toàn hợp lệ với các kiểu con trỏ. 124 00:08:56,240 --> 00:08:58,270 >> Các loại con trỏ là một biến. 125 00:08:58,270 --> 00:09:01,510 Đố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ớ. 126 00:09:01,510 --> 00:09:06,060 Biến x chính nó được lưu trữ trong ngăn xếp và chỉ là một con trỏ đơn, 127 00:09:06,060 --> 00:09:08,620 nhưng khối lớn của bộ nhớ được lưu trữ trên heap. 128 00:09:08,620 --> 00:09:11,010 X biến trên stack chỉ lưu trữ địa chỉ 129 00:09:11,010 --> 00:09:14,010 khối lớn của bộ nhớ trên heap. 130 00:09:14,010 --> 00:09:17,370 Một ý nghĩa của điều này là với kích thước của nhà điều hành. 131 00:09:17,370 --> 00:09:22,480 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ớ, 132 00:09:22,480 --> 00:09:24,620 một cái gì đó giống như 40 byte, 133 00:09:24,620 --> 00:09:26,920 nhưng nếu bạn yêu cầu kích thước của loại con trỏ của mảng, 134 00:09:26,920 --> 00:09:32,740 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. 135 00:09:32,740 --> 00:09:36,530 Sử dụng các loại mảng con trỏ, nó là không thể trực tiếp yêu cầu 136 00:09:36,530 --> 00:09:38,530 kích thước của khối lớn của bộ nhớ. 137 00:09:38,530 --> 00:09:42,530 Đ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 138 00:09:42,530 --> 00:09:46,980 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ó. 139 00:09:46,980 --> 00:09:51,490 >> 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. 140 00:09:51,490 --> 00:09:56,130 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. 141 00:10:11,220 --> 00:10:14,470 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. 142 00:10:14,470 --> 00:10:18,120 Đây chỉ là một giới thiệu về những gì bạn có thể làm với mảng. 143 00:10:18,120 --> 00:10:20,990 Họ xuất hiện trong hầu hết mọi chương trình bạn viết. 144 00:10:20,990 --> 00:10:24,390 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 145 00:10:24,390 --> 00:10:26,710 từ đầu của video. 146 00:10:26,710 --> 00:10:29,960 >> Tên tôi là Rob Bowden, và đây là CS50.