Chương 5 - Kiểu dữ liệu cấu trúc Chương 5 - Kiểu dữ liệu cấu trúc 1 Kiểu cấu trúc, hợp Kiểu cấu trúc, hợp Kiểu FILE Kiểu FILE Hàm main có tham số Hàm main có tham số Kiểu enum, struct, union Kiểu enum, struct, union Kiểu FILE Kiểu FILE Hàm main có tham số Hàm main có tham số
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Truy nhập đến các thành phần của Truy nhập đến các thành phần của structstruct• ten_bien_cau_truc.ten_thanh_phanten_bien_cau_truc.ten_thanh_phan• Ví dụ:Ví dụ:
– hs.hoten;hs.hoten;– hs.diem;hs.diem;
• Lưu ý:Lưu ý:– Khi nhập dữ liệu, không nên sử dụng toán tử & đối với Khi nhập dữ liệu, không nên sử dụng toán tử & đối với
các thành phần cấu trúc.các thành phần cấu trúc.– Có thể sử dụng #define để rút gọn “đường truy nhập” Có thể sử dụng #define để rút gọn “đường truy nhập”
đến các thành phần cấu trúc.đến các thành phần cấu trúc.– Có thể áp dụng phép gán cho các biến cấu trúc có Có thể áp dụng phép gán cho các biến cấu trúc có
} var_field;} var_field;Ví dụ:Ví dụ:struct date {struct date {
unsigned int unsigned int day : 5;day : 5; // khong duoc vuot qua 16 bits// khong duoc vuot qua 16 bitsunsigned unsigned month : 4;month : 4;int int year : 5;year : 5;
} x;} x;
Chương 5 - Kiểu dữ liệu cấu trúc8
Mảng có cấu trúcMảng có cấu trúc
• Là mảng mà các thành phần có kiểu cấu Là mảng mà các thành phần có kiểu cấu trúc.trúc.
Biến con trỏ chỉ đến một cấu trúc, để “cất” Biến con trỏ chỉ đến một cấu trúc, để “cất” địa chỉ của biến cấu trúc.địa chỉ của biến cấu trúc.struct ten_cautruc *ten_contro;struct ten_cautruc *ten_contro;
Truy xuất đến thành phần của cấu Truy xuất đến thành phần của cấu trúc bằng con trỏtrúc bằng con trỏ
Sử dụng phép toán kép: Sử dụng phép toán kép: ->->Ví dụ:Ví dụ:
printf(“\nHo ten hoc sinh: %s”,ptrhs->hoten);printf(“\nHo ten hoc sinh: %s”,ptrhs->hoten);printf(“\nDiem : %5.2f”,ptrhs->diem);printf(“\nDiem : %5.2f”,ptrhs->diem);
• Tương đương với:Tương đương với:printf(“\nHo ten hoc sinh: %s”,hs.hoten);printf(“\nHo ten hoc sinh: %s”,hs.hoten);printf(“\nDiem : %5.2f”,hs.diem);printf(“\nDiem : %5.2f”,hs.diem);
Chương 5 - Kiểu dữ liệu cấu trúc11
Các cấu trúc tự trỏCác cấu trúc tự trỏ
• Là cấu trúc có ít nhất một thành phần là con trỏ Là cấu trúc có ít nhất một thành phần là con trỏ chỉ đến bản thân cấu trúc.chỉ đến bản thân cấu trúc.
• Ví dụ:Ví dụ:• struct hocsinh{struct hocsinh{
– char hoten[20];char hoten[20];– float diem;float diem;– struct hocsinh *sau; //con tro chi toi hoc sinh tiep theo struct hocsinh *sau; //con tro chi toi hoc sinh tiep theo
trong danh sachtrong danh sach• }}
Chương 5 - Kiểu dữ liệu cấu trúc12
Danh sách liên kếtDanh sách liên kết• Ưu điểm so với mảng cấu trúc:Ưu điểm so với mảng cấu trúc:
– Linh họat: danh sách dài ngắn tùy ýLinh họat: danh sách dài ngắn tùy ý– Không bị lãng phí bộ nhớKhông bị lãng phí bộ nhớ
• Thành phần của một danh sách liên kết:Thành phần của một danh sách liên kết:– Vùng dữ liệu danh sáchVùng dữ liệu danh sách– Vùng liên kếtVùng liên kếttypedef struct kieu_dulieu{typedef struct kieu_dulieu{
<khai bao cac phan tu du lieu>;<khai bao cac phan tu du lieu>;<khai bao cac con tro lien ket>;<khai bao cac con tro lien ket>;
} bien_kieu_dulieu;} bien_kieu_dulieu;
Chương 5 - Kiểu dữ liệu cấu trúc13
Bài tập mẫuBài tập mẫu
• Xây dựng chương trình quản lý họ tên học sinh và điểm Xây dựng chương trình quản lý họ tên học sinh và điểm của từng người.của từng người.
– printf(“Khong du bo nho”);printf(“Khong du bo nho”);
Chương 5 - Kiểu dữ liệu cấu trúc14
Kiểu hợp (Union)Kiểu hợp (Union)
• Tương tự như biến cấu trúc.Tương tự như biến cấu trúc.• Khác nhau:Khác nhau:
– Các thành phần của biến union được cấp phát Các thành phần của biến union được cấp phát chung một vùng nhớ.chung một vùng nhớ.
– Độ dài của vùng nhớ đủ để chứa thành phần Độ dài của vùng nhớ đủ để chứa thành phần dài nhất trong union.dài nhất trong union.
• Một cấu trúc có thể có thành phần là union Một cấu trúc có thể có thành phần là union và ngược lại.và ngược lại.
Chương 5 - Kiểu dữ liệu cấu trúc15
Kiểu hợp (tt)Kiểu hợp (tt)• Việc định nghĩa một biến kiểu union, mảng các union, Việc định nghĩa một biến kiểu union, mảng các union,
con trỏ union, cũng như cách thức truy cập đến các con trỏ union, cũng như cách thức truy cập đến các thành phần của biến union được thực hiện hoàn toàn thành phần của biến union được thực hiện hoàn toàn tương tự như đối với biến cấu trúc.tương tự như đối với biến cấu trúc.
• Ví dụ:Ví dụ:• typedef union{typedef union{
– unsigned int ival;unsigned int ival;– float fval;float fval;– unsigned char ch[2];unsigned char ch[2];
• }val;}val; //do dai cua val bang do dai cua truong //do dai cua val bang do dai cua truong fval=4fval=4
• val a,b,x[10];val a,b,x[10];• a.ival=0xa1b2;a.ival=0xa1b2;• a.ch[0]=0xa1; a.ch[1]=0xb2;a.ch[0]=0xa1; a.ch[1]=0xb2;
Chương 5 - Kiểu dữ liệu cấu trúc16
Ví dụ minh họaVí dụ minh họa
Chương 5 - Kiểu dữ liệu cấu trúc17
Hàm main có tham sốHàm main có tham số• Các giá trị truyền cho tham số của hàm main sẽ Các giá trị truyền cho tham số của hàm main sẽ
được ghi sau tên chương trình khi gọi nó thực được ghi sau tên chương trình khi gọi nó thực hiện tại dấu nhắc của DOS.hiện tại dấu nhắc của DOS.
• Có hai tham số:Có hai tham số:– Tham số 1 (kiểu int): ghi nhận số giá trị mà ta đã nhập Tham số 1 (kiểu int): ghi nhận số giá trị mà ta đã nhập
vào khi cho thực hiện chương trình (bao gồm cả tên vào khi cho thực hiện chương trình (bao gồm cả tên chương trình)chương trình)• Các tham số này được xem như các chuỗi ký tựCác tham số này được xem như các chuỗi ký tự
– Tham số 2: mảng con trỏ ký tự (char *arr[]). Mảng này Tham số 2: mảng con trỏ ký tự (char *arr[]). Mảng này ghi nhận con trỏ trỏ vào vùng nhớ của các chuỗi giá ghi nhận con trỏ trỏ vào vùng nhớ của các chuỗi giá trị mà ta đã truyền cho chương trình.trị mà ta đã truyền cho chương trình.• Phần tử 0 sẽ chứa con trỏ chỉ đến vùng nhớ chứa tên Phần tử 0 sẽ chứa con trỏ chỉ đến vùng nhớ chứa tên
}}- Biên dịch ra file vidu.exeBiên dịch ra file vidu.exe- Chạy chương trình: Chạy chương trình: vidu 1 2 3vidu 1 2 3
Chương 5 - Kiểu dữ liệu cấu trúc19
Kiểu dữ liệu FILEKiểu dữ liệu FILE
• Khái niệm về File:Khái niệm về File:– là một loại dữ liệu có thể ghi lên đĩa để dùng là một loại dữ liệu có thể ghi lên đĩa để dùng
nhiều lần.nhiều lần.– Trong C, chỉ có 1 file, cấu trúc mỗi file có thể Trong C, chỉ có 1 file, cấu trúc mỗi file có thể
khác nhau.khác nhau.– Cấu trúc file tùy thuộc vào lúc ghi file (hàm ghi Cấu trúc file tùy thuộc vào lúc ghi file (hàm ghi
file)file)
Chương 5 - Kiểu dữ liệu cấu trúc20
Khai báo dữ liệu (FILE)Khai báo dữ liệu (FILE)
• Hàm cấp 1: hàm cấp thấp, làm việc thông qua Hàm cấp 1: hàm cấp thấp, làm việc thông qua số hiệu tập tin (file handle)số hiệu tập tin (file handle)
• Hàm cấp 2: xây dựng từ những hàm cấp 1, dễ Hàm cấp 2: xây dựng từ những hàm cấp 1, dễ sử dụng hơnsử dụng hơn– Dùng để đọc, ghi trên từng loại dữ liệu (số, chuỗi, ký Dùng để đọc, ghi trên từng loại dữ liệu (số, chuỗi, ký
tự, cấu trúc…)tự, cấu trúc…)– Làm việc thông qua con trỏ tập tinLàm việc thông qua con trỏ tập tin– Ví dụ:Ví dụ: FILE *f; FILE *f;
• Nhập xuất kiểu nhị phân:Nhập xuất kiểu nhị phân:– Dữ liệu ghi lên tập tin không bị thay đổiDữ liệu ghi lên tập tin không bị thay đổi– Mã kết thúc tập tin (ghi lên đĩa): -1Mã kết thúc tập tin (ghi lên đĩa): -1
• Nhập xuất kiểu văn bảnNhập xuất kiểu văn bản– Mã 10 (ký tư xuốn dòng) sẽ được ghi thành 2 ký tự Mã 10 (ký tư xuốn dòng) sẽ được ghi thành 2 ký tự
mã 13 và mã 10 (ngược lại khi đọc dữ liệu)mã 13 và mã 10 (ngược lại khi đọc dữ liệu)– Mã kết thúc tập tin: 26Mã kết thúc tập tin: 26
• Note:Note:– Sử dụng Sử dụng đúngđúng kiểu nhập và xuất cho mỗi tập tin. kiểu nhập và xuất cho mỗi tập tin.– Có một số hàm dùng chung cho cả hai kiểu nhập Có một số hàm dùng chung cho cả hai kiểu nhập
Các thao tác trên tập tinCác thao tác trên tập tin(dùng chung cho cả hai kiểu tập tin và văn bản)(dùng chung cho cả hai kiểu tập tin và văn bản)
• FILE *fopen(const char *ten_tap_tin, const FILE *fopen(const char *ten_tap_tin, const char *kieu);char *kieu);– Ý nghĩa:Ý nghĩa: mở một tập tin mở một tập tin
• Nếu thành công: trả về con trỏ FILE tương ứng với Nếu thành công: trả về con trỏ FILE tương ứng với file vừa mởfile vừa mở
• Nếu thất bại: trả về NULLNếu thất bại: trả về NULL– *ten_tap_tin: hằng chuỗi, hoặc con trỏ chỉ đến *ten_tap_tin: hằng chuỗi, hoặc con trỏ chỉ đến
vùng nhớ chứa tên tập tinvùng nhớ chứa tên tập tin– *kiểu: hằng chuỗi cho biết kiểu truy cập*kiểu: hằng chuỗi cho biết kiểu truy cập
Chương 5 - Kiểu dữ liệu cấu trúc24
KiểuKiểu Ý nghĩaÝ nghĩa““r”,”rt”r”,”rt” Đọc kiểu văn bản (file phải tồn tại)Đọc kiểu văn bản (file phải tồn tại)““w”,”wt”w”,”wt” Ghi kiểu văn bản (ghi mới)Ghi kiểu văn bản (ghi mới)““a”,”at”a”,”at” Ghi bổ sung kiểu văn bảnGhi bổ sung kiểu văn bản““r+”,”r+t”r+”,”r+t” Đọc/ghi kiểu văn bản (file phải tồn tại)Đọc/ghi kiểu văn bản (file phải tồn tại)““w+”,”w+t”w+”,”w+t” Đọc/ghi kiểu văn bản. (ghi mới)Đọc/ghi kiểu văn bản. (ghi mới)““a+”,”a+t”a+”,”a+t” Đọc/ghi bổ sung kiểu văn bảnĐọc/ghi bổ sung kiểu văn bản““rb”rb” Đọc kiểu nhị phân (file phải tồn tại)Đọc kiểu nhị phân (file phải tồn tại)““wb”wb” Ghi kiểu nhị phân (ghi mới)Ghi kiểu nhị phân (ghi mới)““ab”ab” Ghi bổ sung kiểu nhị phânGhi bổ sung kiểu nhị phân““r+b”r+b” Đọc/ghi kiểu nhị phân (file phải tồn tại)Đọc/ghi kiểu nhị phân (file phải tồn tại)““w+b”w+b” Đọc/ghi kiểu nhị phân. (ghi mới)Đọc/ghi kiểu nhị phân. (ghi mới)““a+b”a+b” Đọc/ghi bổ sung kiểu nhị phânĐọc/ghi bổ sung kiểu nhị phân
Chương 5 - Kiểu dữ liệu cấu trúc25
Các thao tác trên tập tin (tt)Các thao tác trên tập tin (tt)• int int fclosefclose (FILE *f)(FILE *f)
– Đóng tập tin được chỉ đến bởi con trỏ f.Đóng tập tin được chỉ đến bởi con trỏ f.– Thành công = 0, thất bại = EOFThành công = 0, thất bại = EOF
• int int fcloseallfcloseall (void)(void)– Đóng tất cả các tập tin đang mở.Đóng tất cả các tập tin đang mở.– Thành công = số tập tin đã đóng, thất bại = EOFThành công = số tập tin đã đóng, thất bại = EOF
• int int ff lushfflush (FILE *f)(FILE *f)– Làm sạch vùng đệm của tập tin được chỉ đến bởi Làm sạch vùng đệm của tập tin được chỉ đến bởi
con trỏ f.con trỏ f.– Thành công = 0, thất bại = EOFThành công = 0, thất bại = EOF
• int int ff lushallff lushall (void)(void)– Làm sạch vùng đệm của tất cả các tập tin đang Làm sạch vùng đệm của tất cả các tập tin đang
mở.mở.– Thành công = số tập tin đang mở, thất bại = EOFThành công = số tập tin đang mở, thất bại = EOF
Chương 5 - Kiểu dữ liệu cấu trúc26
Các thao tác trên tập tin (tt)Các thao tác trên tập tin (tt)
• int int unlinkunlink (const char *ten_tap_tin)(const char *ten_tap_tin)– Xóa một tập tin trên đĩa.Xóa một tập tin trên đĩa.– Thành công = 0, thất bại = EOFThành công = 0, thất bại = EOF
• int int renamerename (const char *ten_cu, const char (const char *ten_cu, const char ten_moi)ten_moi)– Đổi tên một tập tin trên đĩa.Đổi tên một tập tin trên đĩa.– Thành công = số tập tin đã đóng, thất bại = Thành công = số tập tin đã đóng, thất bại =
EOFEOF• int int feoffeof (FILE *f)(FILE *f)
– Cho giá trị khác 0 nếu ở cuối tập tin, ngược lại Cho giá trị khác 0 nếu ở cuối tập tin, ngược lại = 0.= 0.
Chương 5 - Kiểu dữ liệu cấu trúc27
Các hàm nhập xuấtCác hàm nhập xuất
• Nhập xuất ký tự (nhị phân và văn bản)Nhập xuất ký tự (nhị phân và văn bản)– Ghi ký tự lên tập tinGhi ký tự lên tập tin
• int int putcputc (int ch, FILE *f)(int ch, FILE *f)• int int fputcfputc (int ch, FILE *f)(int ch, FILE *f)• Ghi lên file f ký tự có mã = ch%256Ghi lên file f ký tự có mã = ch%256• Thành công = mã ký tự được ghi, thất bại = EOF(-Thành công = mã ký tự được ghi, thất bại = EOF(-
1)1)– Đọc ký tự từ tập tinĐọc ký tự từ tập tin
• int int getcgetc (FILE *f)(FILE *f)• int int fgetcfgetc (FILE *f)(FILE *f)• Đọc một ký tự từ file f.Đọc một ký tự từ file f.• Thành công = mã của ký tự đọc được, thất bại = Thành công = mã của ký tự đọc được, thất bại =
EOFEOF
Chương 5 - Kiểu dữ liệu cấu trúc28
Các hàm nhập xuất (tt)Các hàm nhập xuất (tt)• Nhập xuất chuỗi (cho kiểu văn bản)Nhập xuất chuỗi (cho kiểu văn bản)
– Ghi một chuỗiGhi một chuỗi• int int fputsfputs (const char *s, FILE *f)(const char *s, FILE *f)• Ghi một chuỗi được trỏ tới bới con trỏ s vào file fGhi một chuỗi được trỏ tới bới con trỏ s vào file f• Thành công = ký tự cuối cùng được ghi, thất Thành công = ký tự cuối cùng được ghi, thất
bại=EOFbại=EOF– Đọc một chuỗiĐọc một chuỗi
• char *char *fgetsfgets (const char *s, int n, FILE *f)(const char *s, int n, FILE *f)• Đọc một chuỗi từ file f và đưa vào vùng nhớ do s trỏ Đọc một chuỗi từ file f và đưa vào vùng nhớ do s trỏ
tớitới• Kết thúc khi đã đọc được n-1 ký tự, hoặc gặp ký tự Kết thúc khi đã đọc được n-1 ký tự, hoặc gặp ký tự
xuống dòng, hoặc gặp ký tự kết thúc filexuống dòng, hoặc gặp ký tự kết thúc file• Thất bại = NULLThất bại = NULL
Chương 5 - Kiểu dữ liệu cấu trúc29
Các hàm nhập xuất (tt)Các hàm nhập xuất (tt)• Đọc ghi dữ liệu theo khuôn dạng(cho kiểu văn Đọc ghi dữ liệu theo khuôn dạng(cho kiểu văn
bản)bản)– Ghi dữ liệu theo khuôn dạngGhi dữ liệu theo khuôn dạng
• int int fprintffprintf (FILE *f, const char *dacta, …)(FILE *f, const char *dacta, …)• … … là danh sách các đối số tương ứng với các đặc tảlà danh sách các đối số tương ứng với các đặc tả• Giống như hàm printf, dữ liệu sẽ được ghi lên fileGiống như hàm printf, dữ liệu sẽ được ghi lên file
– Đọc dữ liệu theo khuôn dạngĐọc dữ liệu theo khuôn dạng• fscanffscanf (FILE *f, const char *dacta, …)(FILE *f, const char *dacta, …)• … … là danh sách các đối số tương ứng với các đặc tảlà danh sách các đối số tương ứng với các đặc tả• Giống như hàm scanf, dữ liệu sẽ được đọc từ file f rồi Giống như hàm scanf, dữ liệu sẽ được đọc từ file f rồi
đưa vào các đối số tương ứngđưa vào các đối số tương ứng
Chương 5 - Kiểu dữ liệu cấu trúc30
Các hàm nhập xuất (tt)Các hàm nhập xuất (tt)
• Đọc ghi số nguyên (cho kiểu nhị phân)Đọc ghi số nguyên (cho kiểu nhị phân)– Ghi một số nguyênGhi một số nguyên
• int int putwputw (int n, FILE *f)(int n, FILE *f)• Ghi số nguyên n (2 byte) lên file fGhi số nguyên n (2 byte) lên file f• Thất bại=EOFThất bại=EOF
– Đọc một số nguyênĐọc một số nguyên• int *int *getwgetw (FILE *f)(FILE *f)• Đọc một số nguyên n (2 byte) từ file fĐọc một số nguyên n (2 byte) từ file f• Thất bại = EOFThất bại = EOF
Chương 5 - Kiểu dữ liệu cấu trúc31
Các hàm nhập xuất (tt)Các hàm nhập xuất (tt)
• Đọc ghi cấu trúc (cho kiểu nhị phân)Đọc ghi cấu trúc (cho kiểu nhị phân)– Ghi mẫu tin lên tập tinGhi mẫu tin lên tập tin
• int int fwritefwrite (void *ptr, int size, int n, FILE *f)(void *ptr, int size, int n, FILE *f)• Ghi Ghi nn mẫu tin có kích thước của mỗi mẫu tin là mẫu tin có kích thước của mỗi mẫu tin là sizesize lên file lên file
ff• Kết quả của hàm bằng số mẫu tin được ghi thật sựKết quả của hàm bằng số mẫu tin được ghi thật sự• ptrptr: con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi: con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi
– Đọc mẫu tin từ tập tinĐọc mẫu tin từ tập tin• int int freadfread (void *ptr, int size, int n, FILE *f)(void *ptr, int size, int n, FILE *f)• Đọc Đọc nn mẫu tin có kích thước của mỗi mẫu tin là mẫu tin có kích thước của mỗi mẫu tin là sizesize từ file từ file ff
rồi lưu vào vùng nhớ do ptr trỏ tới.rồi lưu vào vùng nhớ do ptr trỏ tới.
Chương 5 - Kiểu dữ liệu cấu trúc32
Các hàm di chuyển con trỏ tập Các hàm di chuyển con trỏ tập tintin• void rewind(FILE *f)void rewind(FILE *f)
– Đưa con trỏ về đầu tập tinĐưa con trỏ về đầu tập tin• int fseek(FILE *f, long so_byte, int vt_bd)int fseek(FILE *f, long so_byte, int vt_bd)
– Dời con trỏ tập tin đi so_byte tính từ vt_bdDời con trỏ tập tin đi so_byte tính từ vt_bd– Nếu:Nếu:
• so_byte>0 : chuyển xuống dướiso_byte>0 : chuyển xuống dưới• so_byte<0 : chuyển ngược lênso_byte<0 : chuyển ngược lên• so_byte=0 : đứng tại vt_bdso_byte=0 : đứng tại vt_bd
– tt_bd có thể mang một trong các giá trị sau:tt_bd có thể mang một trong các giá trị sau: SEEK_SET (0) : vị trí đầu tập tinSEEK_SET (0) : vị trí đầu tập tin SEEK_CUR (1) : vị trí hiện hànhSEEK_CUR (1) : vị trí hiện hành SEEK_END (2) : vị trí cuối tập tinSEEK_END (2) : vị trí cuối tập tin
• long ftell(FILE *f)long ftell(FILE *f)– Cho biết vị trí hiện tại của con trỏ, tính từ đầu tập Cho biết vị trí hiện tại của con trỏ, tính từ đầu tập
tintin
Chương 5 - Kiểu dữ liệu cấu trúc33
Ví dụVí dụ/*Doc noi dung cua mot tap tin:/*Doc noi dung cua mot tap tin:
- Ghi thong tin cua n dinh cua mot da giac. Moi dinh co 2 toa do x,y - Ghi thong tin cua n dinh cua mot da giac. Moi dinh co 2 toa do x,y kieu so nguyenkieu so nguyen- Tap tin co n+1 dong- Tap tin co n+1 dong- Dong dau chua so dinh (n), n dong con lai, moi dong chua toa do - Dong dau chua so dinh (n), n dong con lai, moi dong chua toa do cua mot dinh*/cua mot dinh*/