cấu trúc dữ liệu kiểu mảng là một kiểu dữ liệu có cấu trúc, bao gồm một tập hữu hạn các phần tử có cùng kiểu dữ liệu, có tên chung, được lưu trữ kế tiếp nhau trong bộ nhớ Kích thước của mảng được xác định ngay khi khai báo và là cố định Các phần tử trong mảng có tên chung là tên của mảng và được phân biệt với nhau thông qua chỉ số của chúng Mảng thường được dùng để lưu một dãy giá trị như: dãy số nguyên, dãy số thực, dãy kí tự, ma trận, …
Trang 1CHƯƠNG 4: CÁC KIỂU DỮ LIỆU CÓ CẤU TRÚC
BÀI GIẢNG HỌC PHẦN
KỸ THUẬT LẬP TRÌNH
Trang 2Nội dung
4.1 Kiểu mảng
4.2 Kiểu xâu ký tự
4.3 Kiểu cấu trúc
Trang 4Khái niệm mảng
• Là một kiểu dữ liệu có cấu trúc, bao gồm một tập hữu hạn các phần tử có cùng kiểu dữ liệu, có tên chung, được lưu trữ kế tiếp nhau trong bộ nhớ
• Kích thước của mảng được xác định ngay khi khai báo và là cố định
• Các phần tử trong mảng có tên chung là tên của mảng và được phân biệt với nhau thông qua chỉ số của chúng
• Mảng thường được dùng để lưu một dãy giá trị như: dãy số nguyên, dãy số thực, dãy kí tự, ma trận, …
Trang 5Khai báo và sử dụng mảng (1)
• Khai báo mảng:
kiểu_dữ_liệu tên_mảng[N1][N2]…[Nn]trong đó:
- kiểu_dữ_liệu: là kiểu dữ liệu của các phần tử mảng
- tên_mảng: tên biến mảng
- N1, N2, …, Nn: kích thước các chiều của mảng
Số phần tử của mảng: N1 * N2 * … * Nn
• Ví dụ:
- int a[10], b[20];
- float matran[10][20];
Trang 6Khai báo và sử dụng mảng (2)
• Có thể sử dụng chỉ thị #define để xác định kích thước các chiều của mảng
Trang 7Khai báo và sử dụng mảng (3)
• Kết hợp khởi tạo giá trị trong khai báo mảng:
- Khởi tạo giá trị cho mọi phần tử của mảng
Trang 8Khai báo và sử dụng mảng (4)
• Khai báo hằng kiểu mảng:
- Cách 1:
#define tên_mảng {giá_trị_1, …, giá_trị_n}
Không truy cập được vào các phần tử của mảng
- Cách 2:
const kiểu_dữ_liệu tên_mảng[N1] … [Nn] = {giá_trị_1, …, giá_trị_n}
Ví dụ:
const int hangmang1[4] = {10,20,25,40};
const float hangmang2[] = {4.5,9.25};
const float hangmang3[5] = {1.5,2,5};
Trang 9Khai báo và sử dụng mảng (5)
• Lưu trữ dữ liệu kiểu mảng:
- Các phần tử của mảng được lưu trữ tại các ô nhớ kế tiếp nhau trong bộ nhớ
- Kích thước bộ nhớ lưu trữ:
N1 * N2 * … * Nn * sizeof(kiểu_dữ_liệu)
- Các phần tử trong mảng được đánh chỉ số, phần tử đầu tiên có chỉ số là 0, phần tử thứ i có chỉ số là i-1
- Biến mảng lưu trữ địa chỉ của ô nhớ đầu tiên trong vùng nhớ được cấp phát
Trang 10 Các truy cập hợp lệ: a[0], a[1], a[2], a[3]
Các truy cập không hợp lệ: a[-2], a[-1], a[4], a[5],
…
Trang 12Các thao tác cơ bản trên mảng (1)
Trang 13Các thao tác cơ bản trên mảng (2)
• Nhập dữ liệu cho mảng từ bàn phím:
Sử dụng hàm scanf để nhập dữ liệu cho từng phần
tử của mảng
Ví dụ: int a[10];
Nhập dữ liệu cho phần tử a[1]: scanf("%d",&a[1]);
Nhập dữ liệu cho tất cả các phần tử của mảng: sử dụng cấu trúc lặp for
Trang 14Các thao tác cơ bản trên mảng (3)
• Nhập dữ liệu cho mảng từ bàn phím (tiếp):
Lưu ý: Phép lấy địa chỉ không áp dụng cho các phần tử
của mảng nhiều chiều (trừ trường hợp mảng 2 chiều gồm các số nguyên) cần sử dụng biến trung gian khi nhập dữ liệu cho mảng nhiều chiều
Trang 15Các thao tác cơ bản trên mảng (4)
• Xuất dữ liệu của mảng ra màn hình:
Sử dụng hàm printf để xuất dữ liệu từng phần tử của mảng ra màn hình
Trang 18• Viết chương trình nhập vào ma trận số nguyên (aij)mxn,
in lại các giá trị vừa nhập theo dạng ma trận, tính tổng các phần tử trong ma trận và thông báo kết quả ra màn hình
Trang 194.2 Kiểu xâu ký tự
• Khái niệm xâu ký tự
• Khai báo và sử dụng xâu ký tự
• Các hàm xử lý ký tự
• Các hàm xử lý xâu ký tự
• Một số chương trình với xâu ký tự
Trang 20Khái niệm xâu ký tự
• Là một kiểu dữ liệu có cấu trúc, bao gồm một dãy các ký tự liên tiếp, kết thúc bởi ký tự '\0' (null – mã ASCII là 0)
• Mỗi ký tự được lưu trong 1byte
• Độ dài xâu là số ký tự có trong xâu
• Xâu rỗng là xâu không có ký tự nào
• So sánh:
- Xâu ký tự & mảng ký tự
- 'A' và "A"
Trang 21Khai báo và sử dụng xâu ký tự (1)
• Khai báo xâu ký tự:
Trang 22Khai báo và sử dụng xâu ký tự (2)
• Khai báo hằng xâu ký tự:
Trang 23Khai báo và sử dụng xâu ký tự (3)
• Lưu trữ dữ liệu kiểu xâu ký tự:
- Các ký tự được lưu trữ tại các byte nhớ kế tiếp nhau trong bộ nhớ
Trang 24Khai báo và sử dụng xâu ký tự (4)
Trang 25Khai báo và sử dụng xâu ký tự (5)
• Lưu ý: - Không dùng phép gán giá trị cho xâu
- Không sử dụng hàm scanf() để nhập xâu chứa ký tự
cách
Trang 27- int iscntrl(int ch): kiểm tra xem ký tự có phải là ký
tự điều khiển hay không (mã ASCII [0,31])
- int isspace(int ch): kiểm tra xem ký tự có phải là ký
tự dấu cách (mã ASCII là 32) hay không
• Các ký tự đặc biệt: xuống dòng ('\n' - 10), đầu dòng
Trang 28Các hàm xử lý xâu ký tự (1)
• Khai báo tệp tiêu đề: #include <string.h>
• Các hàm:
- int strlen(char[] tên_xâu): trả về độ dài của xâu
- char[] strcpy(char[] xâu_đích, char[] xâu_nguồn): sao chép toàn bộ xâu_nguồn sang xâu_đích
Để sao chép tối đa n ký tự từ xâu_nguồn sang xâu_đích, sử dụng hàm:
char[] strncpy(char[] xâu_đích, char[] xâu_nguồn,
Trang 29Các hàm xử lý xâu ký tự (2)
• Các hàm: (tiếp)
- int strcmp(char[] xâu_1, char[] xâu_2): so sánh 2 xâu (có phân biệt ký tự in hoa – in thường), hàm trả về giá trị:
= 0 nếu 2 xâu bằng nhau
< 0 nếu xâu_1 < xâu_2
> 0 nếu xâu_1 > xâu_2
Nếu muốn so sánh 2 xâu, không phân biệt ký tự in hoa – in thường thì sử dụng hàm:
int stricmp(char[] xâu_1, char[] xâu_2)
- char[] strupr(char[] tên_xâu): trả về xâu chữ in hoa tương ứng
- char[] strlwr(char[] tên_xâu): trả về xâu chữ in
Trang 31in hoa tuong ung la '%c'!",c,toupper(c));
Trang 32printf("\nNhap xau ky tu s: ");gets(s);
printf("Do dai thuc cua xau la %d",strlen(s));
printf("\nXau chu in hoa tuong ung la: %s",strupr(s));
printf("\nXau chu in thuong tuong ung la: %s",strlwr(s)); printf("\nXau dao tuong ung la: %s",strrev(s));
return 0;
}
Trang 33Một số chương trình với xâu ký tự
• Viết chương trình cho phép người dùng nhập vào một xâu ký tự s, đếm số ký tự 'A' và 'a' có mặt trong
s, thay thế các ký tự đó bởi ký tự 'B' rồi đưa xâu mới
Trang 344.3 Kiểu cấu trúc
• Định nghĩa kiểu cấu trúc
• Khai báo biến cấu trúc
• Truy nhập đến các thành phần của cấu trúc
• Mảng cấu trúc
• Phép gán cấu trúc
Trang 35Định nghĩa kiểu cấu trúc
• Cú pháp:
struct tên_kiểu_cấu_trúc
{
khai_báo_các_thành_phần_trong_cấu_trúc; };
Trang 36Khai báo biến cấu trúc (1)
• Cú pháp:
struct tên_kiểu_cấu_trúc tên_biến_cấu_trúc;
Ví dụ:
struct ngaythang ngaysinh;
• Khi có nhiều biến cùng kiểu cấu trúc, có thể khai báo gộp với các tên biến viết ngăn cách bởi dấu ,
Ví dụ:
struct ngaythang ngaydi, ngayden;
• Có thể kết hợp khai báo và khởi tạo giá trị cho biến cấu trúc
Ví dụ:
struct ngaythang ngaysinh = {12,10,1988};
Trang 37Khai báo biến cấu trúc (2)
• Có thể kết hợp việc định nghĩa kiểu cấu trúc với khai báo biến cấu trúc theo cú pháp:
int thang;
int nam;} ngaydi,ngayden;
Trang 38Khai báo biến cấu trúc (3)
• Có thể sử dụng cú pháp sau để khai báo các biến cấu trúc: (bỏ tên_kiểu_cấu_trúc)
Trang 40Truy nhập đến các thành phần của cấu trúc
Trang 41• Lưu ý: Khi nhập dữ liệu cho mỗi phần tử trong mảng cấu trúc, cần nhập dữ liệu cho từng thành phần trong cấu trúc
Trang 42Phép gán cấu trúc (1)
• Khi các biến cấu trúc và các phần tử của mảng cấu trúc là cùng kiểu với nhau, có thể thực hiện các phép gán giá trị:
- Gán giá trị của biến cấu trúc này cho một biến cấu trúc khác
- Gán giá trị của biến cấu trúc cho phần tử mảng cấu trúc và ngược lại
- Gán giá trị của phần tử mảng cấu trúc này cho phần
tử mảng cấu trúc khác
Mỗi phép gán cấu trúc tương đương với một dãy phép gán các thành phần tương ứng cho nhau
Trang 45printf("Ma can bo: ");gets(dscb[i].macb);
printf("Ho ten: ");gets(dscb[i].hoten);