Bài Array Mảng Bài học phần trước, giúp bạn hiểu thêm cách sử dụng pointer Bạn cảm thấy có chút khó khăn việc sử dụng pointers? Bạn không tránh khỏi việc dùng chúng đâu! Các pointers sử dụng thường xuyên C, nói với bạn điều này! Trong học này, học cách tạo biến số type "array" hay gọi mảng Các mảng sử dụng thường xuyên C tiện lợi việc xếp chuỗi giá trị Bài học bắt đầu vài lời giải thích cách hoạt động arrays nhớ Tôi nhận thấy việc mở đầu với kiến thức phần nhớ vô quan trọng: Nó giúp bạn hiểu phương thức hoạt động Một lập trình viên hiểu điều họ làm, điều đảm bảo chương trình viết chạy ổn định hơn, bạn nghĩ sao? Các arrays nhớ “Arrays dãy biến số type, chứa vùng nhớ liên tục.” Lời giải thích giống từ điển phải không? Rõ ràng hơn, mảng chứa số lượng lớn biến số type (long, int, char, double ) Mỗi mảng có kích thước xác định Nó tạo 2, 3, 10, 150, 2500 cases (ô, slots), tùy theo tùy chọn bạn Biểu đồ sau mảng kích thước ô nhớ, địa 1600 : Khi bạn yêu cầu tạo mảng kích thước ô nhớ, chương trình yêu cầu hệ điều hành quyền sử dụng ô nhớ ô phải nằm kề nhau, có nghĩa ô sau ô trước Giống trên, địa nằm nối tiếp nhau: 1600, 1601, 1602, 1603 "khoảng trống" Cuối cùng, ô mảng chứa số type Nếu mảng có type int, ô mảng chứa số type int Không thể tạo mảng lúc chứa giá trị type int double Tóm lại, sau điều buộc phải ghi nhớ: Khi mảng (array) tạo ra, sử dụng vùng liên tục nhớ: ô nhớ nằm liên tục kề Tất ô (case) mảng phải type Một array type int chứa số dạng int, chứa số dạng khác Cách tạo mảng (array) Bắt đầu, xem làm để tạo mảng chứa giá trị int: C code: int array[4] ; Vậy thôi, ta cần thêm vào dấu ngoặc vuông [ ] số lượng ô mà bạn muốn chứa mảng Không có giới hạn (tùy theo dung lượng nhớ máy tính) Vậy bây giờ, làm cách đưa giá trị vào case mảng? Rất đơn giản, cần viết array[số_thứ_tự_của_case] Chú ý: mảng số 0! Mảng chứa giá trị int có ô với số thứ tự 0, 1, 2, Không có ô số array cases! Các bạn hay nhầm lẫn đây, nhớ kĩ Nếu muốn thêm vào mảng giá trị giống biểu đồ trên, viết: C code: int array[4] ; array[0] = 10; array[1] = 23; array[2] = 505; array[3] = 8; Vậy mối quan hệ mảng pointer ? Nếu bạn viết array pointer Đó pointer vào ô mảng Test : C code: int array[4] ; printf ("%d", array); Kết quả, ta nhận ô địa mảng: Console: 1600 Nếu bạn ghi thứ tự ô mảng vào ngoặc vuông [ ], bạn nhận giá trị ô đó: C code: int array[4]; printf ("%d", array[0]); Console: 10 Tương tự với ô khác Nhắc lại bạn viết array, pointer, sử dụng kí tự * để có giá trị ô đầu tiên: C code: int array[4]; printf ("%d", *array); Console: 10 Và nhận giá trị ô với *(array+1) (địa array+1) Cả dòng code sau hoạt động tương tự nhau: C code: array[1] // Cho gia tri cua o thu (o dau tien viet la [0]) *(array+ 1) // Tuong tu: cho gia tri o thu Nói rõ hơn, bạn viết array[0], giống bạn yêu cầu giá trị tìm thấy địa array + (ở ví dụ 1600) Nếu bạn viết array[1], bạn nhận giá trị địa array + (1601 ví dụ) Và tương tự với trường hợp lại Dynamic array(mảng động) Ngôn ngữ C tồn nhiều versions Version trước đây, gọi C99, cho phép tạo dynamic array, có nghĩa mảng với kích thước khai báo biến số: C code: int kichThuoc = 5; int array[kichThuoc]; Cách viết không thông dụng compiler, nhiều chương trình chạy đến dòng thứ dừng lại Từ đầu đến giờ, hướng dẫn bạn ngôn ngữ C89 nên tuyệt đối không dùng dòng code thứ Vậy là, bạn không viết biến số đặt ngoặc vuông để khai báo kích thước mảng, kể biến số số (constant)! Một mảng phải có kích thước xác định, có nghĩa khai báo bạn phái ghi rõ ràng kích thước mảng số: C code: int array[5] ; Vậy lại cấm tạo mảng với kích thước phụ thuộc vào biến số? Tôi bảo đảm với bạn: điều thực hiện! C89 Nhưng để thực điều này, dùng kĩ thuật khác (chắc chắn, đảm bảo chạy điều kiện) gọi phân bổ động (dynamic allocation) Chúng ta học sau Liệt kê giá trị mảng (array) Bây muốn hiển thị giá trị ô mảng Tôi sử dụng số lượng printf với số ô mảng Nhưng phải viết nhiều lần printf, điều thật nhàm chán (hãy tưởng tượng đến trường hợp mảng chứa 8000 giá trị) Vì vậy, tốt sử dụng vòng lặp Và vòng lặp for tiện lợi việc này: C code: int main (int argc, char *argv[ ]) { int array[4], i = 0; array[0] = 10; array[1] = 23; array[2] = 505; array[3] = 8; for (i = ; i < ; i++) { printf ("%d\n", array[i]); } return 0; } Console: 10 23 505 Vòng lặp chạy dọc ô mảng nhờ vào biến số i (các nhà lập trình thường dùng i, biến số thông dụng để chạy dọc mảng) Cách đặc biệt thông dụng, ta để biến số dấu [ ] Những biến số tuyệt đối cấm sử dụng việc tạo mảng (để khai báo kích thước), phép sử dụng để "di chuyển" mảng, có nghĩa để hiển thị giá trị! Trong ví dụ trên, đặt biến số i, tăng dần từ 0, 1, Như vậy, hiển thị giá trị array[0], array[1], array[2] array[3]! Cần ý không nên hiển thị giá trị array[4]! Một array ô có số thứ tự 0, 1, 2, Nếu bạn thử hiển thị giá trị array[4], hiển thị số không xác định, lỗi đẹp Hệ điều hành dừng chương trình lại cố ý xâm nhập vào địa không cho phép Khởi tạo giá trị mảng Bạn biết cách di chuyển mảng, điều có nghĩa bạn khởi tạo mảng với giá trị tất ô việc sử dụng vòng lặp! Bạn đạt trình độ cần thiết thực điều C code: int main (int argc, char *argv[ ]) { int array[4], i = 0; // Khoi tao cac gia tri array for (i = ; i < ; i++) { array[i] = 0; } // Hien thi cac gia tri de kiem tra for (i = ; i < ; i++) { printf ("%d\n", array[i]); } return 0; } Console: 0 0 : Một cách khác để khởi tạo giá trị Bạn cần biết cách khác để khởi tạo giá trị mảng thủ công C Bằng cách viết giá trị ngoặc nhọn { }, cách dầu phẩy “,” : array[4] = { giaTri1, giaTri2, giaTri3, giaTri4}; C code: int main (int argc, char *argv[ ]) { int array[4] = {0, 0, 0, 0}, i = 0; for (i = ; i < ; i++) { printf ("%d\n", array[i]); } return 0; } Console: 0 0 Mặt khác, lợi ích cách làm là, bạn cần khai báo giá trị ô đầu tiên, ô lại tự động nhận giá trị 0: Cụ thể, viết: C code: int array[4] = {10, 23}; // Gia tri nhap vao: 10, 23, 0, Ô nhận giá trị 10, ô thứ nhận giá trị 23, ô lại nhận giá trị Vậy làm cách để khai báo tất ô với giá trị 0? Bạn cần khai báo ô giá trị 0, sau ô lại nhận giá trị C code: int array[4] = {0} // Khai bao array voi tat ca cac o gia tri Kỹ thuật hoạt động với kích thước (có thể thực array 100 ô nữa) Chú ý, thường gặp lỗi int array[4] = {1}; Dòng code thêm vào giá trị sau: 1, 0, 0, Nhiều bạn nghĩ dòng code khởi tạo mảng với tất giá trị 1, vậy, để làm điều bạn cần sử dụng vòng lặp Tạo function để liệt kê giá trị mảng Bạn biết cách hiển thị nội dung mảng Vậy bạn không thử viết chương trình để thực điều này? Như bạn tìm hiểu cách đưa array vào function Chúng ta cần gửi hai parameter vào function: array (địa array) thứ hai kích thước nó! Và function bạn có khả hoạt động với array khác đưa vào Chúng ta cần biến số kichThuocArray Bạn biết array xem pointer Vì vậy, đưa array vào function giống thực với pointer: C code: // Prototype cua function hien thi void hienThi (int *array, int kichThuocArray); int main (int argc, char *argv[ ]) { int array[4] = {10, 15, 3}; // Chung ta hien thi noi dung cua array hienThi (array, 4); return 0; } void hienThi (int *array, int kichThuocArray) { int i; for (i = ; i < kichThuocArray ; i++) { printf ("%d\n", array[i]); } } Console 10 15 Function không khác nhiều so với function học trước Chúng ta đưa vào parameter pointer type int (array), sau kích thước array (rất quan trọng để biết vòng lặp dừng lại!) Nội dung array hiển thị qua function nhờ vào vòng lặp Cần ghi thêm cách khác để đưa mảng vào function: C code: void hienThi (int array[ ], int kichThuocArray) hoạt động tương tự trên, việc sử dụng dấu ngoặc vuông cho phép người đọc code hiểu rõ: function cần mảng Có thể hạn chế nhầm lẫn function cần trỏ biến Tôi thường sử dụng cách viết thứ hai để đưa mảng vào function, bạn nên thực giống Và cách viết không cần khai báo kích thước ngoặc vuông Một vài tập thực hành! Tôi lúc có nhiều tập cho bạn luyện tập ! Các bạn nên tự viết function làm việc với array Tôi đưa đề cho bạn thực hành, code, bạn tự viết lấy Hãy đặt câu hỏi, có thắc mắc Bài tập Tạo function tongArray để tính tổng giá trị chứa (sử dụng return để trả giá trị) Và để giúp bạn hiểu rõ hơn, prototype function cần viết: C code: int tongArray (int array[ ], int kichthuocArray); Bài tập Tạo function trungBinhArray để tính trung bình giá trị chứa Prototype: C code: double trungBinhArray (int array[ ], int kichThuocArray); Bài tập Tạo function copyArray để chép nội dung array sang array khác Prototype: C code: void copyArray (int array1[ ], int array2[ ], int kichThuoc); Bài tập Viết function maximumArray có nhiệm vụ so sánh tất giá trị chứa bên array với giaTriMax Nếu có giá trị lớn biến số giaTriMax đưa vào, chuyển thành Prototype: C code: void maximumArray (int array[ ], int kichThuoc, int giaTriMax); VD: array {1,5,7,8,5,2,3} max=5, chuyển thành {1,5,0,0,5,2,3} Bài tập Bài tập khó hẳn tập bạn hoàn toàn có khả thực Hãy viết function sapXepArray xếp lại giá trị bên theo thứ tự tăng dần C code: void sapXepArray (int array[ ], int kichThuoc); VD: array {1,5,7,8,5,2,3} chuyển thành {1,2,3,5,5,7,8} Hãy viết file array.c chứa tất functions cần thiết file array.h chứa prototypes functions Nào bắt đầu làm việc ! Nếu bạn qua học pointer khác bạn vượt qua Tôi không nghĩ học gây khó khăn cho bạn Bạn nên nhớ hai điều quan trọng sau: Đừng quên array bắt đầu số thứ tự (không phải 1) Khi bạn đưa array vào function, gửi kèm theo kích thước array Và cho bạn tin vui, bạn có đủ trình độ để làm việc với chuỗi kí tự Bạn đưa chuỗi kí tự vào nhớ, ví dụ việc yêu cầu họ tên người dùng Và học sau học cách làm việc với chuỗi kí tự !