Bước sang bài này, bạn sẽ đi tới một khái niệm mới nhưng bạn sẽ cảm thấy vừa lạ mà vừa quen đồng thời cũng không kém phần quan trọng và sẽ được sử dụng thường xuyên trong lập trình. Nội dung mình muốn đề cập hôm nay là mảng một chiều trong C++.
Mảng một chiều là gì?
Trước khi đi vào khái niệm, mình sẽ đặt ra một bài toán như sau và bạn sẽ tìm cách giải quyết vấn đề đó nhé.
Bài toán
Bạn sẽ làm thế nào nếu có bài toán yêu cầu bạn nhập giá trị cho 100 biến số nguyên, sau đó thực hiện tính tổng giá trị của 100 biến số nguyên vừa nhập?
Có lẽ với những kiến thức trước giờ, bạn sẽ phải cặm cụi khai báo lần lượt 100 biến có kiểu int. Sau đó lại lần lượt viết 200 dòng lệnh nhập/xuất để nhập giá trị cho 100 biến int đó. Cuối cùng viết một dòng tính tổng dài lê thê với 100 biến. Hix, với cách làm này thì mình bao dài và bao mỏi luôn ????, mới nghĩ thôi đã không muốn làm rồi phải không nào?
Nhưng bạn ạ, thực tế có những bài như thế đấy (thậm chí hơn thế nhiều) chứ không phải đặt ra cho vui đâu. Vậy thì trong trường hợp như vậy, chúng ta sẽ giải quyết bài toán này như thế nào? Chắc chắn là chúng ta sẽ cần một giải pháp khác để tổ chức và lưu trữ giá trị thuận tiện hơn, dễ quản lý hơn. Và một trong những giải pháp đó là sử dụng mảng một chiều để tổ chức và lưu trữ nhiều giá trị.
Mảng một chiều là gì?
Như bạn đã biết, mỗi biến dữ liệu chỉ có thể biểu diễn một giá trị. Do đó nếu gặp bài toán như trên thì sẽ rất bất tiện, vì vậy hầu hết các ngôn ngữ lập trình đều thiết kế một kiểu dữ liệu chuyên dụng cho những trường hợp này, đó là kiểu mảng.
Và mảng thực chất là một biến được cấp phát bộ nhớ liên tục và bao gồm nhiều biến thành phần. Các thành phần của mảng là tập hợp các biến có cùng kiểu dữ liệu và cùng tên. Và đây chính là giải pháp để giải quyết bài toán trên.
Hình minh hoạ ở trên là ví dụ của mảng một chiều. Lẽ ra mình sẽ đề cập đến địa chỉ ô nhớ này nọ nhưng ngẫm lại thấy không cần thiết ở thời điểm này. Đề cập đến điều này sẽ chỉ làm bạn rối hơn mà thôi vì vậy mình sẽ lược qua phần đó, sau này ổn và làm quen rồi thì bạn sẽ tự tìm hiểu lại được bản chất tổ chức lưu trữ của mảng trên bộ nhớ như thế nào. Còn bây giờ bạn chỉ cần hình dung “mảng một chiều là một dãy các biến nằm liền kề và liên tiếp nhau” là đủ rồi.
Khai báo và sử dụng mảng một chiều
Khai báo mảng một chiều
Có 02 cách hay được sử dụng để khai báo mảng một chiều
Cách 1: Khai báo tường minh
Đây là cách khai báo hay được sử dụng, với cách khai báo này bạn cần chỉ rõ kích thước mảng (số lượng phần tử của mảng). Cú pháp như sau:
➤ Ví dụ: Khai báo mảng một chiều các số nguyên có tên là a gồm 100 phần tử như sau:
Cách 2: Khai báo không tường minh
Với cách khai báo này, bạn không cần phải chỉ rõ kích thước của mảng. Bên cạnh đó, bạn còn có thể gán giá trị ban đầu cho mảng. Cú pháp như sau:
➤ Lưu ý: Các giá trị được gán phải nằm trong cặp dấu ngoặc móc {}, các phần tử được ngăn cách nhau bởi dấu phẩy và giá trị được gán phải đúng với kiểu dữ liệu của mảng.
➤ Ví dụ: Khai báo mảng được gán sẵn giá trị ban đầu như sau:
Trong ví dụ trên, mình khai báo 03 mảng khác nhau, mỗi mảng đều được khởi gán các giá trị ban đầu. Chẳng hạn như mảng a có kiểu int được gán sẵn 08 giá trị, mỗi giá trị đều phù hợp với kiểu int của mảng a và ngăn cách nhau bởi dấu phẩy.
Tới đây bạn đã hiểu được phần nào về mảng chưa? Và đã “lờ mờ” hiểu được cách giải quyết bài toán ở trên chưa? Chắc là hiểu rồi phải không nào? Với cách khai báo mảng như vậy thì việc khai báo 100 phần tử như bài toán ở trên sẽ hết sức đơn giản và sẽ giống như cách 1. Và như vậy, bạn đã giải quyết được một vấn đề của bài toán rồi đấy.
Sử dụng mảng một chiều
Bạn hãy quan sát hình ảnh bên dưới để nắm cách truy xuất các phần tử trong mảng.
Mỗi một phần tử trong mảng nằm liền kề nhau và gồm 02 thành phần: giá trị và vị trí của phần tử đó trong mảng. Muốn truy xuất được giá trị của một phần tử nào đó trong mảng, bạn cần phải nắm được vị trí của phần tử đó trong mảng, phần tử đầu tiên nằm ở vị trí 0.
Truy xuất giá trị phần tử của mảng
Để hiểu rõ hơn về cách thức truy xuất giá trị của các phần tử trong mảng, bạn hãy thử viết đoạn chương trình sau nhé:
Đoạn chương trình trên chỉ đơn giản là khai báo một mảng a, đồng thời gán sẵn 07 giá trị ban đầu cho mảng a. Sau đó chúng ta chỉ làm một việc đơn giản là xuất giá trị của phần tử thứ 3 trên mảng a ra màn hình. Nếu viết đúng và chạy thử thì bạn sẽ nhận được kết quả như thế này:
Đến đây bạn đã hiểu cách thức truy xuất giá trị của các phần tử trong mảng a chưa nào? Phần tử đầu tiên nằm ở vị trí 0 sẽ có giá trị là 3, cứ liên tiếp như vậy thì phần tử nằm ở vị trí 3 sẽ có giá trị là 2.
Và để giúp bạn hiểu rõ hơn về cách sử dụng mảng, mình sẽ minh hoạ thêm 03 phần nữa: nhập, xuất và thao tác trên mảng. Với các phần này, mình sẽ vận dụng lại kiến thức về vòng lặp và hàm đã học trong các phần trước để thực hiện, vì vậy nếu quên thì bạn hãy xem đã lại nhé.
Nhập mảng
Đầu tiên mình sẽ hướng dẫn bạn cách nhập dữ liệu cho một mảng đã nhé. Để cho tiện sử dụng lại cho sau này, mình sẽ viết thành một hàm nhập mảng như sau:
Đoạn code trên, mình viết một hàm có tên là nhapMang. Hàm này có 02 tham số đầu vào là một mảng a và biến số nguyên n. Ở đây bạn lưu ý một chút nhé, mảng a được truyền vào làm tham số nhưng lại là truyền địa chỉ vì vậy mặc định xem như là truyền tham chiếu. Do đó mọi thay đổi giá trị của mảng a đều sẽ được lưu giữ mang ra bên ngoài hàm mà không cần thêm dấu &. Biến n được truyền vào để giúp bạn xác định số lượng phần từ mà bạn muốn nhập giá trị trong mảng a.
Do mảng một chiều a chứa nhiều phần tử, do đó để tiện cho việc nhập mảng thì mình sẽ sử dụng một vòng lặp (dòng 6) để nhập cho lần lượt từng phần tử trong mảng. Bạn hãy để ý biến chạy i của vòng lặp, ở đây mình tận dụng luôn biến chạy i làm chỉ số vị trí của phần tử trong mảng (dòng 8).
Xuất mảng
Tương tự như nhập mảng, mình cũng sẽ xây dựng một hàm để xuất giá trị của các phần tử trong mảng ra màn hình.
Đoạn code này chắc mình sẽ không cần giải thích lại đâu nhỉ. Bởi nếu bạn hiểu hàm nhapMang thì hàm xuatMang cũng tương tự mà thôi.
Thao tác trên mảng
Cuối cùng, để giúp bạn hiểu hơn về mảng một chiều, mình sẽ minh hoạ cách giải quyết bài toán đặt ra ở trên. Ở đây, mình cũng sẽ viết một hàm tính tổng như sau:
Bạn có nhận xét gì không nhỉ? Có điểm chung giữa các hàm này là đều sử dụng một vòng lặp để duyệt qua các phần tử của mảng. Mỗi một phần tử được truy xuất bởi vị trí thứ i, và đây cũng là cách để mình tính tổng từng phần tử trong mảng đấy. Thao tác với mảng chính là việc bạn sẽ quản lý vòng lặp mảng như thế nào mà thôi.
Dưới đây là cấu trúc của toàn bộ chương trình cho bạn nào muốn tham khảo.
Tổng kết
Mảng một chiều là một cấu trúc dữ liệu cực kỳ quan trọng trong lập trình, vì vậy bạn hãy cố gắng học và hiểu được nó nhé. Bài viết này mình viết để các bạn mới có thể nắm được ngay phần cơ bản nên cũng chưa thật sự lột tả được bản chất tổ chức dữ liệu của mảng. Nhưng kinh nghiệm trong nhiều năm giảng dạy, mình nhận thấy càng nói về khía cạnh tổ chức lưu trữ trên bộ nhớ thì càng làm các bạn mới học khó hiểu và nản. Do đó mình cố ý lược bớt phần đó mà sẽ đề cập trong một chủ đề nâng cao, khi mà bạn đã có kiến thức cơ bản rồi thì bạn sẽ dễ hiểu hơn.