Bài giảng Ngôn ngữ lập trình C - Chương IV: Mảng và con trỏ

4.1. Mảng

2 Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật

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ác phần tử của mảng được lưu trữ trong một khối gồm

các ô nhớ liên tục nhau, có cùng tên (cũng là tên của mảng)

nhưng phân biệt với nhau ở chỉ số. Chỉ số này xác định vị trí

của nó trong mảng.

pdf 28 trang phuongnguyen 7140
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Ngôn ngữ lập trình C - Chương IV: Mảng và con trỏ", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Ngôn ngữ lập trình C - Chương IV: Mảng và con trỏ

Bài giảng Ngôn ngữ lập trình C - Chương IV: Mảng và con trỏ
4.1. Mảng 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật2
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ác phần tử của mảng được lưu trữ trong một khối gồm
các ô nhớ liên tục nhau, có cùng tên (cũng là tên của mảng)
nhưng phân biệt với nhau ở chỉ số. Chỉ số này xác định vị trí
của nó trong mảng.
Mảng được chia ra làm 2 loại: mảng một chiều và mảng
nhiều chiều (mảng 2 chiều trở lên).
Mảng
4.1.1 Mảng một chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật3
A) Khai báo mảng:
Lưu ý: số_phần_tử ( kích thước của mảng) phải được xác định 
ngay tại thời điểm khai báo và phải là hằng số.
Ví dụ: 
int A[100]; //khai báo mảng số nguyên A gồm 100 phần tử.
Kiểu_dữ_liệu Tên_mảng [số_phần_tử] ;
4.1.1 Mảng một chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật4
B) Truy xuất dữ liệu trong mảng:
Truy xuất các phần tử của mảng theo cú pháp:
Trong đó chỉ_số là số nguyên bắt đầu từ 0 đến n-1, với n là 
kích thước của mảng.
Ví dụ: Mảng A có 4 phần tử, phần tử thứ 2 là A[1]= - 7
Tên_mảng[chỉ_số]
Chỉ số 0 1 2 3
Mảng A 4 -7 3 2
Phần tử A[0] A[1] A[2] A[3]
4.1.1 Mảng một chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật5
C) Khởi tạo giá trị cho mảng một chiều khi khai báo: 
Ví dụ 1: Khởi tạo giá trị cho tất cả các phần tử của mảng:
int A[5]={1,5,-8,7,0};
Ví dụ 2: Khởi tạo vài giá trị đầu của mảng, các phần tử sau mặc 
định bằng 0: int A[5]={2,4,1};
Ví dụ 3: Khởi tạo giá trị 0 cho tất cả các phần tử:
int A[5]={0};
Ví dụ 4: Khởi tạo mảng mà không khai báo kích thước:
int A[]={1,5,-8}; 
Khi đó mảng A sẽ có kích thước bằng 3 vì nó có 3 phần tử.
Kiểu_dữ_liệu Tên_mảng[số_phần_tử] = { giá_tri_1, giá_trị_2,};
Trong đó, giá_trị_1, giá_trị_2, là các giá trị tương ứng
được khởi tạo cho từng phần tử của mảng theo đúng thứ tự. Số
lượng các giá trị không được vượt quá kích thước của mảng.
4.1.1 Mảng một chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật6
D) Dùng mảng một chiều làm tham số hàm:
Việc truyền một phần tử đơn lẻ vào hàm thì hoàn toàn
giống với truyền một biến vào hàm.
Đối với trường hợp muốn truyền toàn bộ mảng cho hàm thì
ta cần phải khai báo mảng là tham số hình thước của hàm.
Ví dụ: int Max(int A[12], kich_thuoc); 
Lưu ý:
- Có thể không cần ghi kích thước mảng trong phần khai
báo tham số hàm, ví dụ: int Max(int A[], kich_thuoc); ).
- Khi gọi hàm và truyền mảng thì ta chỉ ghi tên mảng mà
không có cặp ngoặc [] ,ví dụ: Gọi hàm Max ở ví dụ trên,
truyền tham số là mảng int B[12] , kích_thước là 12 như sau:
Max( B, 12) ;
Ví dụ: Dùng mảng một chiều làm tham số hàm 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật7
Kết quả khi chạy chương trình :
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
4.1.2 Mảng hai chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật8
Dạng đơn giản nhất và thông dụng nhất của mảng nhiều
chiều là mảng hai chiều. Một mảng hai chiều là mảng chứa các
mảng một chiều.
Để cho dễ hiểu người ta thường biểu diễn mảng hai chiều
dưới dạng một ma trận gồm các hàng và các cột. Tuy nhiên, về
mặt vật lý thì các phần tử của mảng hai chiều vẫn được lưu
trong một khối nhớ liên tục nhau.
A) Khai báo mảng hai chiều:
Khi đó kích thước mảng sẽ là tích (số_hàng*số_cột)
Ví dụ: 
float A[3][4]; /*Mảng số thực A gồm 12 phần tử được chia
thành 3 hàng, 4 cột*/
Kiểu_dữ_liệu Tên_mảng[số_hàng][số_cột] ;
4.1.2 Mảng hai chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật9
B) Truy xuất các phần tử của mảng:
Mỗi phần tử của mảng có dạng:
Trong đó, chỉ_số_hàng có giá trị từ 0 đến (số_hàng -1)và
chỉ_số_cột có giá trị từ 0 đến (số_cột - 1).
Ví dụ: Mảng int A[3][2] được minh họa như hình dưới:
Tên_mảng[chỉ_số_hàng][chỉ_số_cột]
Chỉ số (0, 0) (0, 1) (1, 0) (1, 1) (2, 0) (2, 1)
Mảng A
Phần tử A[0][0] A[0][1] A[1][0] A[1][1] A[2][0] A[2][1]
0 1
0 6 2
1 -9 0
2 1 5
4.1.2 Mảng hai chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật10
6 2
-9 0
1 5
C) Khởi tạo giá trị cho mảng hai chiều khi khai báo:
Thứ tự các phần tử của mảng A[i][j] sẽ được khởi tạo theo
thứ tự như sau:
Ví dụ 1: Khởi tạo mảng số nguyên A[3][2] giống mảng 1 chiều:
int A[3][2] = {2, 7, 9, 0, 4, -3};
0 1  j-1
0
1
i-1
4.1.2 Mảng hai chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật11
Ví dụ 2: Khởi tạo theo từng dòng (hàng), các phần tử của mỗi
dòng sẽ nằm trong một cặp dấu {}:
int A[3][2]={{2, 7}, {9, 0}, {4,-3}};
Ví dụ 3: Khởi tạo giá trị cho vài phần tử ở đầu mảng, các phần tử
còn lại sẽ tự động nhận giá trị 0:
int A[3][2]={{2, 7}, {9}, {4,-3}};
Ví dụ 4: Khởi tạo giá trị 0 cho tất cả các phần tử của mảng:
int A[3][2]={0};
Ví dụ 5: Khởi tạo giá trị cho mảng mà không bao gồm khai báo
chiều thứ nhất hay số hàng ( chiều thứ hai hay số cột bắt buộc
phải có):
int A[][2]={{2, 7}, {9, 0}, {4,-3}};
4.1.2 Mảng hai chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật11
D) Mảng hai chiều làm tham số cho hàm:
Tương tự như mảng một chiều, mảng hai chiều cũng có
thể được dùng làm tham số cho hàm.
Khi khai báo một tham số là mảng hai chiều, cần phải chỉ
rõ số phần tử của các chiều, tuy nhiên số phần tử của chiều đầu
tiên có thể vắng.
Ví dụ về mảng hai chiều 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật13
Kết quả chạy chương trình:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật14
A) Khái niệm
Con trỏ là một biến lưu trữ địa chỉ của một biến khác.
Nghĩa là, giá trị của con trỏ là địa chỉ của một ô nhớ trong bộ
nhớ.
Con trỏ thường được sử dụng trong những trường hợp:
- Được sử dụng bên trong hàm để truy xuất đến giá trị
của các biến nằm bên ngoài hàm.
- Truyền mảng và chuỗi từ một hàm đến một hàm khác.
- Cần cấp phát vùng nhớ động giúp quản lí và sử dụng bộ
nhớ một cách hiệu quả.
- Xây dựng các cấu trúc dữ liệu như cây, danh sách liên
kết,
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật15
B) Khai báo và sử dụng con trỏ
Cú pháp khai báo:
Trong đó, Kiểu_dữ_liệu là kiểu của biến mà con trỏ
muốn trỏ đến. Dấu ‘*’ là kí hiệu con trỏ chỉ áp dụng duy nhất
cho biến nằm ngay sau nó.
Trước khi sử dụng con trỏ chúng ta phải chỉ rõ địa chỉ của
ô nhớ mà nó trỏ đến bằng cách gán như sau:
Với ‘&’ là toán tử lấy địa chỉ của biến được đặt trước tên biến.
Ngoài ra, có thể khởi tạo cho con trỏ bằng giá trị 0 (hay NULL).
Một con trỏ có giá trị NULL không trỏ tới ô nhớ nào cả, nó khác
với con trỏ chưa khởi tạo.
Kiểu_dữ_liệu *Tên_con_trỏ ;
Tên_con_trỏ = &tên_biến ;
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật16
Lưu ý:
- Địa chỉ của một ô nhớ là một số nguyên không dấu, nên
kiểu dữ liệu của biến con trỏ sẽ là kiểu số nguyên
- Con trỏ được sử dụng trong hai trường hợp: sử dụng
chính giá trị của con trỏ và sử dụng giá trị của ô nhớ mà con
trỏ đang trỏ tới.
- Biến con trỏ có thể được sử dụng trong các biểu thức
giống như các biến thông thường.
- Trong trường hợp muốn truy xuất đến giá trị tại ô nhớ
mà con trỏ đang trỏ tới, ta sử dụng toán tử ‘*’ đặt trước biến
con trỏ( trừ trường hợp con trỏ có giá trị NULL để tránh lỗi khi
chạy chương trình).
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật17
C) Các phép toán số học trên con trỏ
C chỉ cho phép một số phép toán số học được thực hiện
trên con trỏ gồm: +, -, ++,--, +=, -=.
Bên cạnh các phép toán số học, chúng ta còn có thể thực
hiện các phép so sánh giữa hai con trỏ như: ==, !=, >, >=, <, <=
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật18
D) Cấp phát vùng nhớ động cho con trỏ
 Bằng các hàm trong hay 
- void *malloc( S ); Cấp phát vùng nhớ có kích thước S bytes
và trả về địa chỉ của vùng nhớ đó. Nếu không đủ bộ nhớ hàm trả
về giá trị NULL.
- void *calloc( N, S ); Cấp phát mảng động có N phần tử, mỗi
phần tử có kích thước S bytes và trả về địa chỉ của vùng nhớ đó.
- void *realloc(void *ptr, S); Cấp lại vùng nhớ với kích
thước S bytes cho biến con trỏ ptr, đồng thời chép dữ liệu vào
vùng nhớ mới.
 Bằng toán tử new : 
BiếnConTrỏ = new KiểuDL[Số_phần_tử];
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật19
Ví dụ: int *p1, *p2;
- Cấp động 1 biến kiểu int : 
p1 = (int *) malloc( sizeof(int) );
p1 = new int;
- Cấp động 1 mảng 10 phần tử: 
p2 = (int*) calloc(10, sizeof(int) );
p2 = new int[10];
4.2 Con trỏ 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật20
E) Xóa biến động
Giải phóng vùng nhớ động đã cấp phát cho biến con trỏ:
 Dùng hàm: free (Biếncontrỏ);
 Dùng toán tử: delete Biếncontrỏ;
Ví dụ:
free(p1);
delete p1;
Ví dụ 1: Minh họa về con trỏ
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật21
Kết quả khi chạy chương trình:
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
Ví dụ 2: Sử dụng biến con trỏ để hàm trả về nhiều giá trị
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật22
Kết quả khi chạy chương trình: Hàm init trả về 2 giá trị cho x và y
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
4.3 Con trỏ và mảng 
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật23
Mảng và con trỏ luôn có mối quan hệ mật thiết với nhau.
Tên mảng chứa địa chỉ của phần tử đầu tiên của mảng, tức là
mảng làm việc giống như con trỏ luôn trỏ đến phần tử đầu tiên.
Vì thế, phép gán biến con trỏ cho một biến mảng là hoàn toàn
hợp lệ. Tuy nhiên biến con trỏ có thể được gán một địa chỉ khác,
tức là giá trị của nó có thể thay đổi. Trong khi đó, biến mảng
luôn luôn trỏ đến một vùng nhớ cố định do đó phép gán biến
mảng cho biến con trỏ là không hợp lệ.
Ví dụ : Cộng hằng số vào mảng
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật24
Kết quả khi chạy chương trình:
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
Bài tập luyện tập
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật25
Bài 1: Viết chương trình nhập giá trị cho dãy số thực gồm n phần
tử ( n<=100). Tìm và in ra chỉ số của các phần tử có giá trị nhỏ
nhất trong dãy.
Bài 2: Nhập một dãy n số nguyên (n < 50) và một số nguyên x.
Loại khỏi dãy những phần tử có giá trị bằng x.
Bài 3: Tính tổng bình phương các phần tử của dãy số nguyên gồm
n phần tử (n<=20).
Bài 4: Sắp xếp một dãy số nguyên gồm n phần tử (n<=40) theo thứ
tự tăng dần. Chèn thêm một số nguyên x nhập từ bàn phím vào dãy
sao cho dãy vẫn tăng dần. Xuất dãy mới ra màn hình.
Bài tập luyện tập
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật26
Bài 5: Viết chương trình nhập dữ liệu cho mảng int A[m][n] với
m, n <= 10.
a) Xuất mảng A ra màn hình.
b) Tìm giá trị lớn nhất trong A.
c) Dòng nào của A có tổng các phần tử là lớn nhất.
d) Sắp xếp từng dòng của A theo thứ tự tăng dần.
e) Sắp xếp mảng A theo thứ tự giảm dần.
Bài tập luyện tập
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật27
Bài 6: Cho hai ma trận số nguyên A và B có kích thước m hàng, n 
cột (m, n<=100). Viết chương trình:
a) Nhập/xuất dữ liệu cho hai ma trận.
b) Tính tổng của hai ma trận.
c) Tìm phần tử lớn nhất và nhỏ nhất của ma trận A.
d) Có bao nhiêu phần tử là số âm trong ma trận B.
e) Sắp xếp ma trận A theo thứ tự tăng dần.
f) Xuất ra màn hình ma trận chuyển vị của B
g) Tìm phần tử nhỏ nhất trong tất cả các phần tử của hai ma trận
Bài tập luyện tập
Khoa CNTT - Bài giảng THĐC - Khối ngành kỹ thuật28
Bài 7: Cho ma trận A vuông cấp n (n<=8) với các phần tử là số
nguyên. Viết chương trình theo các yêu cầu sau:
a) Nhập/xuất A .
b) Tính tổng các phần tử nằm ngoài đường chéo chính ?
c) Tìm giá trị lớn nhất trên đường chéo chính ?
d) Có bao nhiêu phần tử là số âm nằm trên đường chéo phụ ?
e) Ma trận A có đối xứng hoặc phản đối xứng hay không ?
f) Tính detA ?
g) Tính rank(A) ?

File đính kèm:

  • pdfbai_giang_ngon_ngu_lap_trinh_c_chuong_iv_mang_va_con_tro.pdf