[Programming in C#] Bài 5: Mảng và các lớp, phương thức trong C#

1. Mảng (Array)
a. Giới thiệu về mảng

- Trong chương trình đôi khi chúng ta cần thực hiện lưu trữ một loạt các thông tin có cùng kiểu dữ liệu để làm điều này thường chúng ta sẽ phải khai báo rất nhiều biến tương ứng với mỗi một thông tin như vậy. Việc quản lý số lượng lớn các biến gây ra rất nhiều khó khăn. Để giải quyết các khó khăn này thì C# cũng như các ngôn ngữ lập trình khác cung cấp một kiểu cấu trúc dữ liệu cho phép quản lý các biến có cùng tên, cùng kiểu dữ liệu. Đó là mảng.
- Mảng là một tập hợp hữu hạn các phần tử có cùng kiểu dữ liệu. Có thể coi mảng là một cách quản lý danh sách các biến có cùng kiểu dữ liệu.
- Để khai báo mảng trong C# chúng ta sử dụng cú pháp:
[Kiểu dữ liệu] [ ] … [ ] [tên mảng];
Trong đó:
[Kiểu dữ liệu]: là bất kì một kiểu dữ liệu nào được hỗ trợ trong C#.
[Tên mảng]: là một định danh để phân biệt các mảng với các biến, các đối tượng khác.
Số lượng các cặp dấu [ ] : chỉ ra chiều của mảng.
Nếu có 1 dấu [ ] thì mảng là mảng 1 chiều.
Nếu có 2 dấu [ ] thì mảng là mảng 2 chiều.
Nếu có 3 dấu [ ] thì mảng là mảng 3 chiều.
……………….
Nếu có n dấu [ ] thì mảng là mảng n chiều.
VD: khai báo mảng 1 chiều lưu trữ phần tử nguyên có tên là x.

int[] x;
  • Khởi tạo mảng: là quá trình khai báo số lượng các phần tử của mảng và gán giá trị cho các phần tử đó.
    Để khởi tạo mảng trong C# chúng ta có các cách như sau:

    * Khai báo và chỉ ra số phần tử của mảng.

    Cú pháp:
    [Kiểu dữ liệu] [ ] [tên mảng] = new [Kiểu dữ liệu] [số lượng phần tử];
    VD: khai báo một mảng số nguyên lưu trữ 20 phần tử.
int[] x = new int[20];

* Khai báo sau đó mới khởi tạo số phần tử của mảng.

[Kiểu dữ liệu] [ ] [tên mảng];
[tên mảng] = new [kiểu dữ liệu] [số phần tử];
VD: khai báo một mảng số nguyên lưu trữ 20 phần tử.

int[] x;
x = new int[20];

* Khai báo, chỉ ra số lượng các phần tử mảng và gán các giá trị ban đầu cho các phần tử mảng.

int[] x = new int[5] { 5, -7, 8, 1, 9 };


* Khai báo, ko chỉ ra số lượng các phần tử mảng và gán giá trị cho các phần tử của mảng.

- Truy cập các phần tử mảng: một mảng là một danh sách các phần tử có cùng kiểu dữ liệu, các phần tử đó được đánh số thứ tự bắt đầu từ 0 đến n-1 (Trong đó n là số phần tử của mảng).
Như vậy để truy cập đến 1 phần tử của mảng thì chúng ta sử dụng một số nguyên để chỉ ra số thứ tự của phần tử đó trong mảng, phần tử nguyên này được gọi là chỉ số (index).
Cú pháp tổng quát để truy cập đến phần tử thứ i của mảng là:
[tên mảng] [i-1];
VD: gán giá trị -9 cho phần tử thứ 3 của mảng.

x[2] = -9;
  • Duyệt qua các phần tử mảng.
    Kể từ khi mảng là một tập hợp các hữu hạn phần tử do đó để duyệt qua các phần tử mảng thường chúng ta sử dụng vòng lặp for.
    VD: in danh sách các phần tử mảng x ở trên.
Console.WriteLine("Danh sach cac phan tu trong mang:");
for (int i = 0; i < 5; i++)
    Console.Write(x[i] + "\t");

b. Các kiểu mảng
Có 3 kiểu mảng trong C#:
- Mảng 1 chiều (single-dimension array): mảng 1 chiều là một mảng các phần tử. Mảng 1 chiều được khai báo chỉ bao gồm 1 cặp dấu [ ].
- Mảng nhiều chiều (multi-dimension array): mảng nhiều chiều là mảng có số chiều từ 2 trở lên (có từ 2 cặp [ ] trở lên).
VD về sử dụng mảng 2 chiều: mảng 2 chiều thường được sử dụng để lưu trữ các thông tin dạng bảng. VD: lưu trữ bảng điểm của 1 sinh viên.
Một sinh viên có nhiều môn học (tối đa 5 môn học), mỗi môn học có thể có nhiều điểm số (VD: tối đa là 3 điểm).
Để lưu trữ thông tin này chúng ta dùng mảng 2 chiều như sau:

// Khai báo một mảng 2 chiều 5 dòng và 3 cột để lưu
// trữ danh sách bảng điểm của 1 sinh viên.
float[,] diem = new float[5, 3];

// Nhập danh sách điểm cho sinh viên.
Console.WriteLine("Nhap diem cho sinh vien");
for (int i = 0; i < 5; i++)
{
    Console.WriteLine("Nhap diem cho mon thu {0}", i + 1);
    for (int j = 0; j < 3; j++)
    {
        Console.Write("Nhap diem thu {0}: ", j + 1);
        diem[i, j] = float.Parse(Console.ReadLine());
    }
}
// In danh sách điểm cho sinh viên trên dạng bảng.
Console.WriteLine("\n\tDiem1\tDiem2\tDiem3\n");
for (int i = 0; i < 5; i++)
{
    Console.Write("Mon{0}\t", i + 1);
    for (int j = 0; j < 3; j++)
        Console.Write(diem[i, j] + "\t");
    Console.WriteLine();
}


- Mảng nhọn (jagged array): mảng nhọn là một mảng của các mảng, trong đó kích thước của mỗi một mảng có thể khác nhau. Mảng nhọn cho phép chúng ta sử dụng bộ nhớ một cách tiết kiệm hơn.
VD: về việc sử dụng mảng nhọn áp dụng cho trường hợp dùng mảng để lưu trữ danh sách điểm của một sinh viên (một sinh viên có tối đa 5 môn học) và mỗi môn học có thể có một hoặc nhiều điểm.

// Khai báo mảng jagged.
float[][] diem = new float[5][] {new float[] {9},
new float[] {1,4,4,6},
new float[] {3,3,5},
new float[] {2,7},
new float[] {10}};

// Duyệt qua các phần tử của mảng jagged.
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < diem[i].Length; j++)
        Console.Write(diem[i][j] + "\t");
    Console.WriteLine();
}

Console.ReadLine();

c. Lớp mảng
- Trong C# thì tất cả mọi thứ đều là đối tượng.
- Như vậy mảng cũng là một đối tượng.
- Để hỗ trợ cho việc thao tác với các mảng thì C# cung cấp cho chúng ta một lớp mà có các phương thức, các thuộc tính để chúng ta sử dụng và thao tác với mảng.
- Lớp này có tên là Array nằm trong namespace có tên System.
- Lớp này cung cấp các phương thức tĩnh để chúng ta có thể thực hiện một số các thao tác cơ bản trên mảng như:

* Sắp xếp: Sort.
* Tìm kiếm: IndexOf (hàm này thực hiện tìm kiếm một phần tử x trong mảng y, hàm trả về -1 nếu ko tìm thấy x trong mảng y và trả về vị trí của phần tử x trong mảng y nếu tìm thấy).
* Đảo ngược các phần tử: Reverse.