Để hiểu rõ hơn về việc khởi tạo mảng (array) và con trỏ tới mảng trong C++, mời bạn đọc tiếp bài viết dưới đây của Mytour. Nếu bạn chưa đọc phần 1, hãy tham khảo để có cái nhìn toàn diện về khái niệm mảng trong C++.
Nội dung:
1. Khởi Tạo Mảng trong C++
2. Sử dụng Con Trỏ tới Mảng
1. Bắt Đầu với Khởi Tạo Mảng trong C++
Cách khai báo mảng đơn giản nhất là sử dụng cú pháp int n[] = { 2, 4, 8 };
Tuy nhiên, khi chúng ta chỉ khai báo mảng như int n[3];, chưa có giá trị cụ thể nào được gán cho các phần tử. Chỉ là chúng ta đã chỉ định rằng mảng sẽ chứa 3 số nguyên.
Để mảng có ý nghĩa, chúng ta cần gán giá trị cho từng phần tử một trong mảng.
Thiết lập giá trị cho n[0] là 2;
Thiết lập giá trị cho n[1] là 4;
Thiết lập giá trị cho n[2] là 8;
Tương tự như cách chúng ta gán giá trị cho các biến thông thường.
Khai báo và gán giá trị cho x, y, z là 2, 4, 8 lần lượt.
Gán giá trị 2 cho x.
Gán giá trị 4 cho y.
Gán giá trị 8 cho z.
Có hai cách để bắt đầu một mảng, đó là:
Khai báo và gán giá trị cho mảng n với các phần tử 2, 4, 8.
Hoặc bạn có thể khai báo mảng trước, sau đó gán giá trị cho từng phần tử trong mảng.
Khai báo mảng n với 3 phần tử.
Gán giá trị 2 cho phần tử đầu tiên của mảng n.
Gán giá trị 4 cho phần tử thứ hai của mảng n.
Gán giá trị 8 cho phần tử thứ ba của mảng n.
Để dễ hiểu, hãy tưởng tượng n[0], n[1], và n[2] như là những biến riêng lẻ chúng ta đã sử dụng trước đây.
Tương tự như một biến, một mảng có thể chứa dữ liệu của bất kỳ kiểu nào.
Khai báo mảng f chứa các số thực với giá trị khởi tạo là 1.1, 1.4, 1.5.
Ở đây, f là mảng của kiểu dữ liệu float.
- Ví dụ 1:
Để minh họa, chúng ta sẽ xem ví dụ về việc tính điểm trung bình của 3 học sinh. Ở đây, điểm[0], điểm[1], điểm[2] tương ứng với số điểm của học sinh thứ nhất, thứ hai và thứ ba.
#include
int main(){
Sử dụng namespace std;
int điểm[3];
float trung_bình;
cout << 'Nhập số điểm của học sinh thứ nhất: ';
cin >> điểm[0];
cout << 'Nhập số điểm của học sinh thứ hai: ';
cin >> điểm[1];
cout << 'Nhập số điểm của học sinh thứ ba: ';
cin >> điểm[2];
trung bình = ( điểm[0] + điểm[1] + điểm[2] )/ 3.0;
cout << 'Điểm trung bình := ' << trung bình << endl;
trả về 0;
}
Kết quả đầu ra:
Nhập điểm của học sinh thứ nhất
23
Nhập điểm của học sinh thứ hai
25
Nhập điểm của học sinh thứ ba
31
Điểm trung bình: 26.3333
Trong ví dụ này, chúng ta thao tác với mảng một cách tương tự như xử lý các biến thông thường. Đồng thời, cần lưu ý đến hai điểm:
- Giá trị trung bình phải là kiểu dữ liệu float vì giá trị trung bình của số nguyên cũng có thể là float.
- Khi tính điểm số trung bình, tổng của các số phải chia cho 3.0 thay vì 3, để đảm bảo giá trị điểm trung bình là kiểu float.
- Ví dụ 2: Trong ví dụ này, chúng ta sử dụng vòng lặp:
#include
int main(){
sử dụng namespace std;
int n[10]; /* khai báo n là mảng của 10 số nguyên */
int i,j;
/* khởi tạo các phần tử của n */
for ( i = 0; i<10; i++=''>
{
cout < 'nhập='' giá='' trị='' của='' n['=''>< i=''><><>
cin >> n[i];
}
/* in các giá trị của phần tử mảng */
for (j = 0; j < 10;='' j++=''>
{
cout < 'n['=''>< j=''>< ']=' << n[j] << endl;
}
Trả về 0;
}
- Kết quả đầu ra có dạng:
Nhập giá trị của n[0]
23
Nhập giá trị của n[1]
25
Nhập giá trị của n[2]
31
Nhập giá trị của n[3]
1
Nhập giá trị của n[4]
33
Nhập giá trị của n[5]
35
Nhập giá trị của n[6]
76
Nhập giá trị của n[7]
47
Nhập giá trị của n[8]
74
Nhập giá trị của n[9]
45
n[0] = 23
n[1] = 25
n[2] = 31
n[3] = 1
n[4] = 33
n[5] = 35
n[6] = 76
n[7] = 47
n[8] = 74
n[9] = 45
Trong chương trình trên, mã khá đơn giản, I và j bắt đầu từ 0 vì chỉ số mảng bắt đầu từ 0 và tăng lên 9 (cho 10 phần tử). Vì vậy i và j chỉ tăng lên đến 9 chứ không phải 10 (i <10 và j <10). Vì vậy, trong đoạn mã trên, n [i] sẽ là n [0], n [1], n [2], ...., n [9].
Ngoài ra trong ví dụ này chúng ta thấy có 2 vòng lặp. Trong vòng lặp for đầu tiên, chúng ta lấy các giá trị của phần tử khác nhau của từng mảng một. Trong vòng lặp thứ 2, chúng ta in các giá trị của phần tử mảng.
Trong lần lặp đầu tiên, giá trị của i là 0, vì vậy n[i] là n[0]. Vì vậy bằng cách viết cin >> n[i];, người dùng sẽ được yêu cầu nhập giá trị của n[0]. Tương tự trong lần lặp thứ 2, giá trị của i sẽ là 1 và n [i] sẽ là n [1]. Vì vậy cin >> n[i]; sẽ được sử dụng để nhập giá trị từ người dùng cho n[1], ... . Giá trị của i sẽ tăng lên 9 và các chỉ số của mảng (0,1,2, ..., 9).
Mảng được cấp phát bộ nhớ một cách liên tục. Nếu địa chỉ của phần tử đầu tiên trong mảng số nguyên là X, thì địa chỉ của phần tử thứ hai sẽ là X + 4 (vì kích thước của số nguyên là 4 byte), và phần tử thứ ba sẽ là X + 4 + 4, ... . Bộ nhớ của mảng được phân bổ liên tục và có kết cấu gần gũi nhau.
2. Sử dụng con trỏ với mảng
Chúng ta sẽ tìm hiểu cách sử dụng con trỏ với mảng. Trước khi đi sâu, hãy giả sử chúng ta đã có một con trỏ sẵn có.
Nếu bạn chưa biết, con trỏ là một biến giữ địa chỉ của một biến khác. Ví dụ, nếu biến y trỏ đến biến x, thì giá trị của y sẽ là địa chỉ của x.
Tương tự, nếu một biến y trỏ đến một mảng n, có nghĩa là giá trị của y là địa chỉ của phần tử đầu tiên trong mảng, tức là n[0]. Điều này có nghĩa là y là con trỏ tới mảng n. Tên của mảng chính là con trỏ đến phần tử đầu tiên trong mảng.
Nếu p là con trỏ tới mảng tuổi, thì p (hoặc tuổi) trỏ đến tuổi[0].
int tuổi[50];
int *p;
p = tuổi;
Trong đoạn mã trên, gán địa chỉ của phần tử đầu tiên trong mảng tuổi cho p. Vì p trỏ đến phần tử đầu tiên của mảng tuổi, *p chính là giá trị của phần tử đầu tiên trong mảng.
Vì *p đề cập đến phần tử mảng đầu tiên, *(p+1) và *(p+2) tương ứng với các phần tử thứ 2 và thứ 3, ... . Vì vậy *p là tuổi[0], *(p + 1) là tuổi[1], *(p + 2) là tuổi[2], ....
Tương tự, *tuổi là tuổi[0] (giá trị của tuổi), *(tuổi+1) là tuổi[1] (giá trị của tuổi+1), *(tuổi+2) là tuổi[2] (giá trị của tuổi+2), ... .
Dưới đây là một số kiến thức về con trỏ đến mảng trong C++. Cùng xem ví dụ sau để hiểu rõ hơn về cách sử dụng con trỏ đến mảng:
#include
int main(){
float n[5] = { 20.4, 30.0, 5.8, 67, 15.2 }; /* khai báo n là mảng của 5 số thực */
float *p; /* p là con trỏ kiểu float */
int i;
p = n; /* p trỏ đến mảng n */
/* in giá trị của từng phần tử trong mảng */
for (i = 0; i < 5; i++){
std::cout < '*(p + '<< i <<')=' << *(p + i) << std::endl;/* *(p+i) là giá trị của (p+0),(p+1)...*/
}
Trả về 0;
}
Kết quả đầu ra có dạng:
*(p + 0) = 20.4
*(p + 1) = 30
*(p + 2) = 5.8
*(p + 3) = 67
*(p + 4) = 15.2
Vì p đang trỏ đến phần tử đầu tiên của mảng, nên *p hoặc *(p+0) tương ứng với giá trị tại p[0] hoặc giá trị tại phần tử đầu tiên của p. Tương tự, *(p+1) tương ứng với giá trị tại p[1]. *(p+3) và *(p+4) tương ứng với giá trị tại p[3] và p[4].
Ví dụ trên là sự kết hợp của nhiều khái niệm. Cuối cùng, in địa chỉ của mảng và giá trị của từng phần tử trong mảng.
#include
int main(){
int n[4] = { 20, 30, 5, 67 }; /* khai báo n là mảng của 4 số nguyên*/
int *p; /*con trỏ */
int i;
p = n; /*p trỏ tới mảng n*/
/* in địa chỉ của mảng */
std::cout << ' địa chỉ của mảng n = ' << p << std::endl; /*p trỏ tới mảng tức là lưu trữ địa chỉ của phần tử đầu tiên của mảng*/
/* in địa chỉ các phần tử của mảng */
for (i = 0; i < 4; i++ )
{
std::cout << ' địa chỉ của n['<< i <<'] = ' << &n[i] << std::endl;
}
trả về 0;
}
đầu ra có dạng:
địa chỉ của mảng n = 0xfffe2c0c
địa chỉ của n[0] = 0xfffe2c0c
địa chỉ của n[1] = 0xfffe2c10
địa chỉ của n[2] = 0xfffe2c14
địa chỉ của n[3] = 0xfffe2c18
trong ví dụ trên, địa chỉ của phần tử đầu tiên của n và p giống nhau. ngoài ra chúng ta in các giá trị của các phần tử khác nhau của mảng bằng cách sử dụng (p + 1), (p + 2) và (p + 3).
như vậy trong bài viết mảng (array) trong C++ (phần 1) trên đây, Mytour vừa giới thiệu cho bạn về khởi tạo mảng cũng như con trỏ tới mảng trong C++. trong bài viết mảng (array) trong C++ (phần 3) tiếp theo, Mytour sẽ giới thiệu tiếp cho bạn về cách truyền toàn bộ mảng trong hàm, cũng như vòng lặp for-each là gì.
' ]=''>{C}{C}{C}{C}{C}
}
trả về 0;
}
đầu ra có dạng:
địa chỉ của mảng n = 0xfffe2c0c
địa chỉ của n[0] = 0xfffe2c0c
địa chỉ của n[1] = 0xfffe2c10
địa chỉ của n[2] = 0xfffe2c14
địa chỉ của n[3] = 0xfffe2c18
trong ví dụ trên, địa chỉ của phần tử đầu tiên của n và p là giống nhau. Ngoài ra, chúng ta in giá trị của các phần tử khác nhau của mảng bằng cách sử dụng (p + 1), (p + 2) và (p + 3).
Vậy nên, trong bài viết về mảng trong C++ (phần 1) trên đây, Mytour vừa hướng dẫn về cách khởi tạo mảng cũng như con trỏ tới mảng trong C++. Trong bài viết mảng trong C++ (phần 3) tiếp theo, Mytour sẽ giới thiệu chi tiết về cách truyền toàn bộ mảng trong hàm cũng như giới thiệu về vòng lặp for-each là gì. Hãy đón đọc mảng trong C phần 3 để hiểu rõ hơn về nội dung này.