Mảng trong C++Khai báo, Khởi tạo & Con trỏ (Ví dụ)

⚡ Tóm tắt thông minh

Một mảng trong C++ Mảng là một tập hợp các phần tử cùng kiểu dữ liệu được lưu trữ trong các vị trí bộ nhớ liền kề. Ở đây, bạn sẽ học cách khai báo, khởi tạo và truy cập mảng, các loại mảng, cũng như ưu điểm và nhược điểm của chúng.

  • 📚 Những gì nó là: Mảng lưu trữ nhiều giá trị cùng kiểu trong một biến.
  • 🔢 Tờ khai: Khai báo một mảng với kiểu dữ liệu, tên và kích thước, ví dụ như int nums[5];.
  • 🎯 Lập chỉ mục: Các phần tử của mảng được truy cập bằng chỉ số, bắt đầu từ 0.
  • 🧩 Khởi tạo: Bạn có thể thiết lập giá trị mảng khi khai báo bằng cách sử dụng dấu ngoặc nhọn { }.
  • ⚖️ Sự đánh đổi: Mảng cho phép truy cập nhanh theo chỉ mục nhưng có kích thước cố định.
  • 🤖 Hỗ trợ từ AI: Các công cụ AI như GitHub Copilot tạo ra các vòng lặp mảng và logic ngay lập tức.

Mảng trong C++

Mảng là gì?

Mảng là một cấu trúc dữ liệu lưu trữ tuần tự các phần tử có cùng kiểu dữ liệu. MỘT C++ mảng có kích thước cố định.

Bạn có thể xem mảng là tập hợp các biến có kiểu dữ liệu tương tự. Thay vì khai báo từng biến và gán cho nó một giá trị riêng lẻ, bạn có thể khai báo một biến (mảng) và cộng giá trị của các biến khác nhau vào biến đó. Mỗi giá trị gia tăng vào mảng được xác định bằng một chỉ mục.

Tại sao chúng ta cần mảng?

Mảng rất quan trọng trong bất kỳ ngôn ngữ lập trình nào. Chúng cung cấp một cách thuận tiện hơn để lưu trữ các biến hoặc tập hợp dữ liệu có kiểu dữ liệu tương tự cùng nhau thay vì lưu trữ chúng riêng biệt. Mỗi giá trị của mảng sẽ được truy cập riêng biệt.

Khai báo một mảng trong C++

Khai báo mảng trong C++ liên quan đến việc nêu rõ loại cũng như số phần tử được lưu trữ trong mảng. Cú pháp:

type array-Name [ array-Size ];

Quy tắc khai báo mảng một chiều trong C++.

  • Kiểu: Kiểu là loại phần tử được lưu trữ trong mảng và nó phải hợp lệ C++ loại dữ liệu.
  • Tên mảng: Tên mảng là tên được gán cho mảng.
  • Kích thước mảng: Kích thước mảng là số phần tử được lưu trữ trong mảng. Nó phải là số nguyên và lớn hơn 0.

Ví dụ, bạn có thể tạo một mảng tên là age và lưu trữ tuổi của 5 học sinh như sau:

int age[5];

Mảng age sẽ lưu trữ 5 số nguyên đại diện cho độ tuổi của các học sinh khác nhau.

Khởi tạo mảng

Khởi tạo mảng là quá trình gán/lưu trữ các phần tử vào một mảng. Việc khởi tạo có thể được thực hiện trong một câu lệnh hoặc từng câu lệnh một. Lưu ý rằng phần tử đầu tiên trong mảng được lưu ở chỉ mục 0, trong khi phần tử cuối cùng được lưu ở chỉ mục n-1, trong đó n là tổng số phần tử trong mảng.

Trong trường hợp mảng tuổi, phần tử đầu tiên sẽ được lưu ở chỉ mục 0, trong khi phần tử cuối cùng sẽ được lưu ở chỉ mục 4.

Chúng ta hãy sử dụng mảng age để chứng minh cách khởi tạo mảng có thể được thực hiện:

int age[5] = {19, 18, 21, 20, 17};

Tổng số phần tử trong { } không thể vượt quá giá trị được nêu trong [ ]. Phần tử 19 ở chỉ số 0, 18 ở chỉ số 1, 21 ở chỉ số 2, 20 ở chỉ số 3 và 17 ở chỉ mục 4. Nếu bạn không nêu rõ số phần tử sẽ được lưu trữ trong mảng trong [ ], thì mảng sẽ chỉ đủ lớn để chứa các phần tử được thêm vào trong { }. Ví dụ:

int age[] = {19, 18, 21, 20, 17};

Câu lệnh trên sẽ tạo ra mảng giống hệt như mảng trước đó. Bạn cũng có thể gán một phần tử cho một mảng bằng chỉ mục của nó. Ví dụ:

age[3] = 20;

Câu lệnh trên sẽ lưu trữ giá trị 20 tại chỉ mục 3 của mảng có tên age. Điều này có nghĩa là 20 sẽ là 4th phần tử của mảng.

Các loại mảng

Có hai loại C++ mảng:

  • Mảng một chiều
  • Mảng đa chiều
  • Con trỏ tới một mảng

Mảng một chiều

Đây là một mảng trong đó các mục dữ liệu được sắp xếp tuyến tính chỉ theo một chiều. Nó thường được gọi là mảng 1-D. Cú pháp:

datatype array-name[size];
  • Tên mảng là tên của mảng.
  • Kích thước là số phần tử được lưu trữ trong mảng.

Ví dụ:

#include <iostream>
using namespace std;

int main()
{
	int age[5] = { 19, 18, 21, 20, 17 };
	for (int x = 0; x < 5; x++)
	{
		cout <<age[x]<<"\n";
	}
}

Đầu ra:

Mảng một chiều

Đây là ảnh chụp màn hình của mã:

Mảng một chiều

Code Giải thích:

  1. Bao gồm tệp tiêu đề iostream trong mã của chúng tôi. Nó sẽ cho phép chúng ta đọc và ghi vào bảng điều khiển.
  2. Bao gồm không gian tên std để sử dụng các lớp và hàm của nó mà không cần gọi nó.
  3. Gọi hàm main() để thêm logic của chương trình vào bên trong.
  4. Bắt đầu phần thân của hàm main().
  5. Khai báo một mảng có tên age để lưu trữ 5 số nguyên. 5 số nguyên cũng đã được khởi tạo.
  6. Tạo một biến số nguyên x bằng vòng lặp for.
  7. Sự bắt đầu của phần thân vòng lặp for.
  8. Sử dụng biến vòng lặp x để lặp lại các giá trị của tuổi mảng và in chúng trên bảng điều khiển. “\n” là ký tự dòng mới và in thành dòng mới sau mỗi lần lặp.
  9. Phần cuối của cơ thể vòng lặp for.
  10. Phần cuối của hàm main().

Mảng đa chiều

Đây là một mảng trong đó các mục dữ liệu được sắp xếp để tạo thành một mảng các mảng. Mảng nhiều chiều có thể có số chiều bất kỳ, nhưng phổ biến nhất là mảng hai chiều và mảng ba chiều. Cú pháp:

datatype array-name[d1][d2][d3]...[dn];

Tên mảng là tên của mảng sẽ có n chiều. Ví dụ:

Mảng hai chiều

Mảng 2 chiều lưu trữ dữ liệu trong danh sách với mảng 1 chiều. Đây là ma trận có hàng và cột. Để khai báo mảng 2 chiều, hãy sử dụng cú pháp sau:

type array-Name [ x ][ y ];

Loại phải hợp lệ C++ kiểu dữ liệu. Xem mảng 2D dưới dạng bảng, trong đó x biểu thị số hàng trong khi y biểu thị số cột. Điều này có nghĩa là bạn xác định từng phần tử trong mảng 2D bằng cách sử dụng dạng a[x][y], trong đó x là số hàng và y là số cột chứa phần tử đó.

Đây là một ví dụ về cách khởi tạo mảng 2D:

int a[2][3] = {  
   {0, 2, 1} ,   /*  row at index 0 */
   {4, 3, 7} ,   /*  row at index 1 */
   };

Trong ví dụ trên, chúng ta có một mảng 2D có thể được xem dưới dạng ma trận 2×3. Có 2 hàng và 3 cột. Phần tử 0 có thể được truy cập dưới dạng a[0][1] vì nó nằm ở giao điểm của hàng được lập chỉ mục 0 và cột được lập chỉ mục 1. Phần tử 3 có thể được truy cập dưới dạng a[1][2] vì nó nằm ở giao điểm của hàng được lập chỉ mục 1 và cột được lập chỉ mục 2.

Lưu ý rằng chúng tôi chỉ cần thêm dấu ngoặc nhọn để phân biệt các hàng phần tử khác nhau. Việc khởi tạo cũng có thể được thực hiện như sau:

int a[2][3] = {0, 2, 1, 4, 3, 7};
   };

Sau đây C++ Ví dụ minh họa cách khởi tạo và duyệt một mảng 2 chiều:

#include <iostream>
using namespace std;
int main() 
{
	// a 2x3 array
	int a[3][2] = { {0, 2}, {1, 4}, {3, 7} };

	// traverse array elements

	for (int i=0; i<3; i++)
		for (int j=0; j<2; j++) 
		
		{
			cout << "a[" <<i<< "][" <<j<< "]: ";
			cout << a[i][j] << endl;
		}
	return 0;
}

Đầu ra:

Mảng hai chiều

Đây là ảnh chụp màn hình của đoạn mã trên:

Mảng hai chiều

Code Giải thích:

  1. Bao gồm tệp tiêu đề iostream trong mã của chúng tôi. Nó sẽ cho phép chúng ta đọc và ghi vào bảng điều khiển.
  2. Bao gồm không gian tên std để sử dụng các lớp và hàm của nó mà không cần gọi nó.
  3. Gọi hàm main() trong đó mã sẽ được thêm vào.
  4. Bắt đầu phần thân của hàm main().
  5. Một bình luận. các C++ trình biên dịch sẽ bỏ qua điều này.
  6. Khai báo mảng 2D gồm 3 hàng và 2 cột. Các mục cũng đã được thêm vào mảng.
  7. Một bình luận. các C++ trình biên dịch sẽ bỏ qua điều này.
  8. Tạo một biến tôi sử dụng vòng lặp for. Biến này sẽ lặp qua các chỉ mục hàng của mảng.
  9. Tạo biến j bằng vòng lặp for. Biến này sẽ lặp qua các chỉ mục cột của mảng.
  10. Bắt đầu phần thân của vòng lặp.
  11. In giá trị của biến i và j ra màn hình điều khiển bên trong dấu ngoặc vuông trên màn hình điều khiển.
  12. In ra giá trị được lưu tại chỉ mục [i][j] của mảng a.
  13. Kết thúc phần thân của vòng lặp.
  14. Hàm main() sẽ trả về một giá trị nguyên nếu chương trình chạy tốt.
  15. Phần cuối của hàm main().

Mảng ba chiều

Mảng 3D là một mảng gồm nhiều mảng. Mỗi phần tử trong mảng 3D được xác định bởi một bộ 3 chỉ mục. Để truy cập các phần tử của mảng 3D, chúng ta sử dụng ba vòng lặp for. Ví dụ:

#include<iostream>
using namespace std;
void main()
{
	int a[2][3][2] = {{{4, 8},{2, 4},{1, 6}}, {{3, 6},{5, 4},{9, 3}}};
	cout << "a[0][1][0] = " << a[0][1][0] << "\n";
	cout << "a[0][1][1] = " << a[0][1][1] << "\n";
}

Đầu ra:

Mảng ba chiều

Đây là ảnh chụp màn hình của mã:

Mảng ba chiều

Code Giải thích:

  1. Bao gồm tệp tiêu đề iostream trong mã của chúng tôi. Nó sẽ cho phép chúng ta đọc và ghi vào bảng điều khiển.
  2. Bao gồm không gian tên std để sử dụng các lớp và hàm của nó mà không cần gọi nó.
  3. Gọi hàm main() để thêm logic của chương trình vào bên trong.
  4. Bắt đầu phần thân của hàm main().
  5. Khai báo một mảng 3D có tên là kích thước 2x3x2. Các giá trị của mảng cũng đã được khởi tạo.
  6. Truy cập mục được lưu trữ tại chỉ mục [0] [1] [0] của mảng và in nó trên bảng điều khiển.
  7. Truy cập mục được lưu trữ tại chỉ mục [0] [1] [1] của mảng và in nó trên bảng điều khiển.
  8. Phần cuối của hàm main().

Con trỏ tới một mảng

A con trỏ là một biến chứa địa chỉ. Ngoài việc sử dụng con trỏ để lưu trữ địa chỉ của một biến, chúng ta có thể sử dụng nó để lưu trữ địa chỉ của một ô mảng. Tên của mảng liên tục trỏ đến phần tử đầu tiên của nó. Hãy xem xét tuyên bố được đưa ra dưới đây:

int age[5];

Age là một con trỏ tới $age[0], địa chỉ của phần tử đầu tiên của một mảng có tên age. Hãy xem xét ví dụ sau:

#include <iostream>
using namespace std;
int main()
{
	int *john;

	int age[5] = { 19, 18, 21, 20, 17 };

	john = age;

	cout << john << "\n";

	cout << *john;
	
}

Đầu ra:

Con trỏ tới một mảng

Lưu ý rằng giá trị đầu tiên của kết quả đầu ra ở trên có thể trả về một giá trị khác tùy thuộc vào địa chỉ được gán cho phần tử đầu tiên của mảng trong bộ nhớ máy tính của bạn.

Đây là ảnh chụp màn hình của mã:

Con trỏ tới một mảng

Code Giải thích:

  1. Bao gồm tệp tiêu đề iostream trong mã của chúng tôi. Nó sẽ cho phép chúng ta đọc và ghi vào bảng điều khiển.
  2. Bao gồm không gian tên std để sử dụng các lớp và hàm của nó mà không cần gọi nó.
  3. Gọi hàm main() để thêm logic của chương trình vào bên trong.
  4. Bắt đầu phần thân của hàm main().
  5. Khai báo một biến con trỏ có tên *john.
  6. Khai báo một mảng số nguyên có tên age để lưu trữ 5 số nguyên. Các giá trị của số nguyên cũng đã được khởi tạo.
  7. Gán biến john giá trị địa chỉ của mục được lưu trữ trong chỉ mục đầu tiên của mảng tuổi.
  8. In giá trị của biến john, là địa chỉ của mục được lưu trong chỉ mục đầu tiên của mảng age.
  9. In giá trị đầu tiên được lưu trong mảng age.
  10. Phần cuối của hàm main().

Tên mảng có thể được sử dụng làm con trỏ không đổi và ngược lại cũng đúng. Điều này có nghĩa là bạn có thể truy cập giá trị được lưu trữ ở chỉ mục 3 của tuổi mảng bằng *(age + 3). Ví dụ:

#include <iostream>
using namespace std;

int main() {
	// an array of 5 elements.
	int age[5] = { 19, 18, 21, 20, 17 };
	int *p;

	p = age;

	// output array values

	cout << "Using pointer: " << endl;

	for (int x=0; x<5; x++) {
		cout << "*(p + " << x << ") : ";
		cout << *(p + x) << endl;
	}
	cout << "Using age as address: " << endl;

	for (int x = 0; x < 5; x++) {
		cout << "*(age + " << x << ") : ";
		cout << *(age + x) << endl;
	}

	return 0;
}

Đầu ra:

Con trỏ tới một mảng

Đây là ảnh chụp màn hình của mã:

Con trỏ tới một mảng

Code Giải thích:

  1. Bao gồm tệp tiêu đề iostream trong mã của chúng tôi. Nó sẽ cho phép chúng ta đọc và ghi vào bảng điều khiển.
  2. Bao gồm không gian tên std để sử dụng các lớp và hàm của nó mà không cần gọi nó.
  3. Gọi hàm main() và bắt đầu phần thân của hàm main().
  4. Một bình luận. các C++ trình biên dịch sẽ bỏ qua điều này.
  5. Khai báo một mảng có tên age để lưu trữ 5 số nguyên.
  6. Tạo một con trỏ số nguyên p.
  7. Gán p giá trị địa chỉ của phần tử đầu tiên của tuổi mảng.
  8. Một bình luận. các C++ trình biên dịch sẽ bỏ qua điều này.
  9. In ra một số văn bản trên bảng điều khiển.
  10. Tạo một số nguyên x bằng cách sử dụng vòng lặp for. { đánh dấu sự bắt đầu phần thân của vòng lặp for.
  11. In ra các giá trị của x kết hợp với một số văn bản khác trên bảng điều khiển.
  12. In ra các giá trị của *(p + x) trên bảng điều khiển.
  13. Kết thúc phần thân của vòng lặp for.
  14. In ra một số văn bản trên bảng điều khiển.
  15. Tạo một biến x bằng cách sử dụng vòng lặp for. { đánh dấu sự bắt đầu của phần thân vòng lặp for.
  16. In ra các giá trị của x từ 0 đến 4 cùng với một số văn bản khác.
  17. In ra các giá trị của *(age + x).
  18. Kết thúc phần thân của vòng lặp for.
  19. Trả về giá trị nếu chương trình chạy thành công.
  20. Phần cuối của hàm main().

Truy cập các giá trị của một mảng

Các phần tử của một mảng được truy cập bằng cách sử dụng các chỉ số tương ứng của chúng. Chỉ số của phần tử được truy cập được thêm vào trong dấu ngoặc vuông [ ] ngay sau tên mảng. Ví dụ:

int john = age[2];

Trong ví dụ trên, chúng ta chỉ đơn giản nói rằng tuổi của John được lưu trữ ở chỉ mục 2 của mảng có tên age. Điều này có nghĩa là tuổi của John là 3rd giá trị trong tuổi mảng. Đây là một bản hoàn chỉnh C++ ví dụ cho thấy cách truy cập và in ra giá trị này:

#include<iostream>
using namespace std;
int main()
{
	int age[5] = { 19, 18, 21, 20, 17 };
	int john = age[2];
	cout << "The age of John is:"<<john;
}

Đầu ra:

Truy cập các giá trị của một mảng

Đây là ảnh chụp màn hình của mã:

Truy cập các giá trị của một mảng

Code Giải thích:

  1. Bao gồm tệp tiêu đề iostream trong mã của chúng tôi. Nó sẽ cho phép chúng ta đọc và ghi vào bảng điều khiển.
  2. Bao gồm không gian tên std để sử dụng các lớp và hàm của nó mà không cần gọi nó.
  3. Gọi hàm main() trong đó mã sẽ được thêm vào.
  4. Bắt đầu phần thân của hàm main().
  5. Khai báo một mảng có tên age để lưu trữ 5 phần tử số nguyên.
  6. Truy cập giá trị được lưu trữ tại chỉ mục 2 của tuổi mảng và lưu trữ giá trị của nó trong một biến có tên john.
  7. In giá trị của biến john trên bảng điều khiển cùng với văn bản khác.

Ưu điểm của mảng trong C++

Sau đây là những ưu/lợi ích của việc sử dụng Array trong C++:

  • Các phần tử mảng có thể được duyệt qua dễ dàng.
  • Dễ dàng thao tác dữ liệu mảng.
  • Các phần tử mảng có thể được truy cập ngẫu nhiên.
  • Mảng tạo điều kiện tối ưu hóa mã; do đó, chúng ta có thể thực hiện nhiều công việc với ít mã hơn.
  • Dễ dàng sắp xếp dữ liệu mảng.

Nhược điểm của mảng trong C++

  • Một mảng có kích thước cố định; do đó, chúng tôi không thể thêm các phần tử mới vào nó sau khi khởi tạo.
  • Việc phân bổ nhiều bộ nhớ hơn yêu cầu sẽ dẫn đến lãng phí dung lượng bộ nhớ và việc phân bổ ít bộ nhớ hơn có thể gây ra sự cố.
  • Số lượng phần tử được lưu trữ trong một mảng phải được biết trước.

Câu Hỏi Thường Gặp

Một mảng trong C++ Đây là một tập hợp các phần tử cùng kiểu dữ liệu được lưu trữ trong các vị trí bộ nhớ liền kề. Nó cho phép bạn lưu trữ và truy cập nhiều giá trị bằng một tên biến và một chỉ mục.

Khai báo một mảng với kiểu dữ liệu, tên và kích thước trong dấu ngoặc vuông, ví dụ như int numbers[5];. Điều này dành chỗ cho năm số nguyên trong bộ nhớ.

Truy cập một phần tử bằng chỉ số của nó trong dấu ngoặc vuông, ví dụ như numbers[0] cho phần tử đầu tiên. Chỉ số mảng bắt đầu từ 0 và tăng dần đến kích thước trừ đi một.

Khởi tạo một mảng khi khai báo bằng dấu ngoặc nhọn, ví dụ: int nums[3] = {1, 2, 3};. Bạn cũng có thể gán giá trị sau đó bằng chỉ số, ví dụ: nums[0] = 5;.

C++ Hỗ trợ mảng một chiều cho các danh sách đơn giản, và mảng đa chiều như mảng hai chiều cho các bảng hoặc lưới giá trị.

Mảng cung cấp khả năng truy cập chỉ mục nhanh và lưu trữ dữ liệu hiệu quả, nhưng chúng có kích thước cố định được thiết lập khi khai báo và không thể tăng kích thước sau khi khởi tạo.

Các trợ lý AI như GitHub Copilot tạo ra các khai báo mảng, viết vòng lặp để điền hoặc tìm kiếm trong mảng và đề xuất cách khắc phục lỗi truy cập chỉ mục ngoài phạm vi khi bạn nhập liệu.

Đúng vậy. Các công cụ hỗ trợ bởi AI sẽ phát hiện lỗi truy cập ngoài phạm vi, lỗi lệch một đơn vị và mảng chưa được khởi tạo, đồng thời đề xuất các giải pháp thay thế an toàn hơn như std::vector cho dữ liệu động.

Tóm tắt bài viết này với: