Nối tiếp nội dung phần 1, phần 2 giáo trình Lập trình căn bản sẽ cung cấp tới người học nội dung kiến thức về: Kiểu dữ liệu quan trọng; Các thao tác trên tệp như: tạo một tệp mới, ghi dữ liệu từ bộ nhớ lên tệp, đọc dữ liệu từ tệp vào bộ nhớ,… Mời các bạn cùng tham khảo giáo trình.
lOMoARcPSD|16991370 CHƢƠNG 6: KIỂU CẤU TRÚC, KIỂU HỢP Để lƣu trữ xử lý thơng tin máy tính ta có biến mảng Mỗi biến lƣu đƣợc giá trị Mảng tập hợp nhiều biến có kiểu giá trị tên mảng Cấu trúc xem nhƣ mở rộng khái niệm biến mảng, cho phép lƣu trữ xử lý dạng thông tin phức tạp Khái niệm cấu trúc C có nhiều nét tƣơng tự nhƣ khái niệm ghi pascal hay foxpro Cấu trúc công cụ mạnh để mô tả xử lý cấu trúc liệu phức tạp toán quản lý, điển hình nhƣ tốn quản lý sinh viên,khi sinh viên đƣợc xem nhƣ cấu trúc gồm thành phần nhƣ họ tên, quê quán, tuổi, địa chỉ,… 6.1 Kiểu cấu trúc 6.1.1 Định nghĩa kiểu cấu trúc Khi định nghĩa kiểu cấu trúc ta cần ra: tên kiểu cấu trúc thành phần Việc đƣợc thực theo mẫu sau: Mẫu 1: struct tên kiểu cấu trúc { Khai báo thành phần }; thành phần cấu trúc biến, mảng cấu trúc khác mà kiểu đƣợc định nghĩa từ trƣớc Ví dụ 6.1: struct que_quan { char xa[20], huyen[20], tinh[20]; } ; Thiết kế kiểu cấu trúc có tên que_quan gồm ba thành phần: xa, huyen, tinh có kiểu liệu kiểu mảng ký tự struct sinh_vien { 101 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 char ho_ten[30]; int tuoi; float diem; struct que_quan dia_chi; }; Thiết kế kiểu cấu trúc có tên sinh_viên gồm bốn thành phần: thành phần thứ có tên ho_ten mảng char, thành phần thứ hai tuoi có kiểu int, thành phần thứ ba diem có kiểu float thành phần cuối dia_chi, cấu trúc có kiểu que_quan đƣợc định nghĩa trƣớc Chú ý: Có thể dùng tốn tử typedef để định nghĩa kiểu cấu trúc nhƣ sau: Mẫu 2: typedef struct { Khai báo thành phần } tên kiểu cấu trúc; Ví dụ 6.2 Các kiểu cấu trúc que_quan sinh_vien định nghĩa nhƣ sau: typedef struct { char xa[20], huyen[20], tinh[20]; } que_quan; typedef struct { char ho_ten[30]; int tuoi; float diem; que_quan dia_chi; } sinh_vien; 102 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 6.1.2 Khai báo biến cấu trúc Khai báo biến cấu trúc đƣợc thực theo mẫu sau: Mẫu 1: struct tên kiểu cấu trúc danh sách tên biến cấu trúc; Ví dụ 6.3: struct sinh_vien sv1, sv2; cho ta hai biến cấu trúc sv1 sv2 Cả hai đƣợc xây dựng theo kiểu sinh_viên đƣợc định nghĩa ví dụ 6.1 Mẫu 2: Cho phép vừa thiết kế kiểu cấu trúc vừa khai báo biến cấu trúc struct tên kiểu cấu trúc { Khai báo thành phần } danh sách tên biến cấu trúc; Ví dụ 6.4: Các biến cấu trúc sv1 sv2 đƣợc xây dựng theo cách sau: struct sinh_vien { char ho_ten[30]; int tuoi; float diem; struct que_quan dia_chi; } sv1, sv2; kiểu cấu trúc que_quan đƣợc định nghĩa nhƣ ví dụ 6.1 Mẫu 3: Vừa định nghĩa kiểu cấu trúc vừa khai báo biến cấu trúc nhƣ trên, ta khơng cần tên kiểu cấu trúc nhƣ sau struct { Khai báo thành phần } danh sách tên biến cấu trúc; Ví dụ 6.5: Các cấu trúc sv1, sv2 khai báo nhƣ sau: 103 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 struct { char ho_ten[30]; int tuoi; float diem; struct que_quan dia_chi; } sv1, sv2; với kiểu cấu trúc que_quan đƣợc định nghĩa nhƣ ví dụ 6.1 Sự khác mẫu mẫu 3: mẫu việc xây dựng đƣợc biến cấu trúc ta cịn tạo đƣợc kiểu cấu trúc Kiểu đƣợc sử dụng để khai báo biến cấu trúc khác Cịn mẫu khai báo biến cấu trúc, tức thực đƣợc phần công việc mẫu Chú ý: Nếu dùng typedef để định nghĩa kiểu cấu trúc, khai báo biến cấu trúc có kiểu định nghĩa ta cần dùng tên kiểu (bỏ từ khóa struct) Ví dụ kiểu cấu trúc que_quan đƣợc định nghĩa nhƣ ví dụ 6.2 biến cấu trúc dịa_chi khai báo ví dụ 6.4 6.5 nhƣ sau: struct sinh_vien { char ho_ten[30]; int tuoi; float diem; que_quan dia_chi; } sv1, sv2; 6.1.3 Truy nhập tới thành phần cấu trúc Từ chƣơng đầu, ta quen với việc sử dụng biến, phần tử mảng câu lệnh Các thành phần cấu trúc đóng vai trị nhƣ biến, phần tử mảng Do phép tốn thực đƣợc biến, phần tử mảng thực đƣợc thành phần Câu lệnh dùng cho biến, phần tử mảng dùng đƣợc cho thành phần cấu trúc Để truy nhập đến thành phần cấu trúc ta sử dụng cách sau: 104 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 tên cấu trúc1.tên cấu trúc2 tên cấu trúcn.tên thành phần Ví dụ 6.6: Biến cấu trúc sv1 đƣợc khai báo ví dụ 6.4 có thành phần sau: sv1.ho_ten sv1.tuoi sv1.dia_chi.xa sv1.dia_chi.huyen sv1.dia_chi.tinh Chú ý: Để truy nhập tới thành phần cấu trúc ta phải tên thành phần mà cịn phải liệt kê tên cấu trúc chứa thành phần Điều gây công tẻ nhạt viết chƣơng trình Ta rút gọn việc truy nhập đến thành phần cấu trúc cách dùng thị #define nhƣ sau: #define tên tên cấu trúc1.tên cấu trúc2 tên cấu trúcn Khi đó, truy nhập đến thành phần biến cấu trúc ta không cần phải tên cấu trúc1.tên cấu trúc2 tên cấu trúcn mà thay vào ta viết tên Ví dụ 6.7: Sử dụng #define #define ht sv1.ho_ten #define sv1.tuoi t #define đc sv1.dia_chi Khi viết ht tức viết sv1.ho_ten, viết t tức viết sv1.tuoi, tƣơng tự đc.xã tƣơng đƣơng với sv1.dia_chi.xa 6.1.4 Sử dụng cấu trúc Cách sử dụng kiểu cấu trúc nhƣ kiểu liệu số (int, float…) khác điểm sau: - Để nhập liệu cho thành phần cấu trúc ta thực giống nhƣ nhập liệu cho biến/mảng - Khi có trỏ cấu trúc trỏ tới đối tƣợng cấu trúc ta truy nhập đến thành phần cấu trúc thông qua trỏ nhƣ sau: Cách 1: tên trỏ -> thành phần Cách 2: (*tên trỏ).thành phần 105 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 Ví dụ 6.8: Giả sử ta có khai báo struct sinh_vien sv, *p; sau dùng phép gán p = &sv; cách viết sau tƣơng đƣơng: sv1.ho_ten tƣơng đƣơng với p ->ho_ten hay (*p).ho_ten Ví dụ 6.9: Viết chƣơng trình nhập vào thơng tin sinh viên gồm thành phần họ tên, tuổi, điểm trung bình, địa Sau in thơng tin sinh viên hình #include “stdio.h” #include “conio.h” void main() { typedef struct { char xa[20], huyen[20], tinh[20]; } que_quan; struct sinh_vien { char ho_ten[30]; int tuoi; float diem; que_quan dia_chi; } sv; float x; printf(“Nhap thong tin ve sinh viên\n”); printf(“Nhap ho ten sinh viên\n”); fflush(stdin); gets(sv.ho_ten); 106 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 printf(“Nhap tuoi sinh vien\n”); scanf(“%d”, &sv.tuoi); printf(“Nhap diem trung binh sinh vien\n”); scanf(“%f”,&sv.diem); printf(“Nhap dia chi sinh vien\n”); printf(“Nhap xa:”); gets(sv.dia_chi.xa); printf(“Nhap huyen:”); gets(sv.dia_chi.huyen); printf(“Nhap tinh:”); gets(sv.dia_chi.tinh); printf(“In thông tin ve sinh vien man hinh\n”); printf(“Ho ten \t tuoi \t diem trung binh \t dia chi”); printf(“%6s\t%d\t%f\t %s %s %s”,sv.ho_ten, sv.tuoi, sv.diem_tb, sv.dia_chi.xa, sv.dia_chi.huyen, sv.dia_chi.tinh); getch(); } 6.1.5 Mảng cấu trúc Là mảng mà phần tử mảng có kiểu kiểu cấu trúc Giả sử kiểu cấu trúc sinh_viên đƣợc định nghĩa tên Khi khai báo: struct sinh_vien sv, danh_sach[100]; cho biến cấu trúc sv kiểu sinh_vien mảng cấu trúc danh_sach Mảng danh_sach gồm 100 phần tử, phần tử cấu trúc kiểu sinh_vien Chú ý: không cho phép sử dụng phép toán lấy địa thành phần thực phần tử mảng cấu trúc Chẳng hạn không cho phép viết &danh_sách[i].diem kiểu diem thực kiểu diem ngun cho phép Ví dụ 6.10: Viết chƣơng trình nhập vào thông tin lớp gồm n sinh viên, sinh viên cấu trúc gồm thành phần họ tên, tuổi, điểm trung bình, địa Sau in thơng tin sinh viên hình #include “stdio.h” #include “conio.h” 107 Downloaded by nguyenphuong Phuong nguyen (Kimphuongrio@gmail.com) lOMoARcPSD|16991370 void main() { struct sinh_vien { char ho_ten[30], dia_chi[30]; int tuoi; float điem; } lop[100]; float x; int n,i; printf(“Nhap so sinh vien:”); scanf(“%d”,&n); for (i = 1;itiep = p->tiep; - Giải phóng nhớ phần tử cần xóa 6.3.3.5 Chèn phần tử vào danh sách Có hai kiểu chèn chèn phần tử vào sau phần tử danh sách kiểu thứ hai chèn phần. .. lại, có phần tử B danh sách trỏ p lƣu giữ địa phần tử B ta nối phần tử A vào trƣớc phần tử đứng sau phần tử B danh sách phép gán q -> tiep = p -> tiep (hay nói cách khác phần tử A chứa địa phần