Giáo trình Lập trình có cấu trúc với ngôn ngữ C: Phần 2
lượt xem 14
download
Nối tiếp nội dung phần 1, phần 2 cuốn giáo trình "Lập trình có cấu trúc với ngôn ngữ C" giới thiệu tới người đọc các kiến thức: Các kiểu dữ liệu có cấu trúc, hàm, tệp và các thao tác vào/ra, đồ họa. Mời các bạn cùng tham khảo nội dung chi tiết.
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Giáo trình Lập trình có cấu trúc với ngôn ngữ C: Phần 2
- C h ư ơ n g 5 C Á C K I Ể U D ữ L I Ệ U C Ó C Â U T R Ú C Nội dung: > Biết cách khai báo c á c kiểu d ữ liệu phức tạp từ c á c kiểu d ữ liệu cơ sở cấu trúc, hợp. > Biết cách khai báo c á c cấu trúc thành phần bits đ ẻ lưu trữ d ữ liệu gọn hơn. > Cách biểu diễn c á c kiểu danh s á c h liên kết nhờ cấu trúc tự trỏ. > Các thao tác trên danh s á c h liên kết. 5.1. K i ể u cấu trúc r 5.1.1. K h á i n i ệ m v à đ ị n h nghĩa c â u t r ú c Trong lập trình, n g ư ờ i l ậ p trình c ó t h ể sẽ cần đ ế n n h ữ n g k i ể u d ữ l i ệ u phức tạp h ơ n đ ư ợ c tạo t h à n h t ừ n h ữ n g k i ể u d ữ l i ệ u đ ơ n g i ả n m à c h ú n g ta đ ã biết. N h ữ n g k i ể u d ữ l i ệ u n à y cho m ộ t k h ả n ă n g k ế t hợp m ộ t n h ó m các b i ế n c ù n g t h ể h i ệ n m ộ t đ ố i t ư ợ n g chung. C h ẳ n g h ạ n , đ ể lưu g i ữ những t h ô n g t i n liên quan đ ế n m ộ t đ ố i t ư ợ n g n h â n v i ê n , c ó t h ể cần m ộ t b i ế n n à o đ ó có k h ả n ă n g l ư u trữ đ ư ợ c cả t ê n , địa chỉ, n g à y sinh lần m ã số n h â n v i ê n , mức l ư ơ n g . . . Đ e c ó t h ế x ử lý b i ể n n à y n h ư m ộ t phần tử thống nhất, t h ế h i ệ n t h ô n g t i n của m ộ t n h â n v i ê n cụ t h ể , n g ô n n g ữ c cho p h é p t ự x â y d ự n g n h ữ n g k i ể u d ữ l i ệ u phức h ọ p v à sử 140
- dụng những k i ể u d ữ l i ệ u n à y đ ể khai b á o cho c á c b i ế n sử dụng sau đ ó . Những k i ể u d ữ liệu n h ư vậy đ ư ợ c g ọ i là c á c cấu t r ú c . Cấu trúc (struct) là k i ể u d ữ l i ệ u g ồ m n h i ề u mục d ữ l i ệ u k h á c nhau n h ư n g có liên quan v ớ i nhau, hay nói c á c h k h á c , đ ể m ô tả c ù n g m ộ t đôi tượng bằng các phần t ử d ữ l i ệ u c ó m ô tả k i ể u k h á c nhau ta d ù n g cấu trúc k i ể u struct. 5.1.2. Khai báo câu trúc Đ e khai báo cấu trúc cần thực h i ệ n 2 giai đ o ạ n : - Khai báo k i ể u cấu t r ú c (định nghĩa k i ể u ) . - Khai báo b i ế n . • Mầu ỉ: struct tên_kiểu{ kiểụ_l thành_phần_l; kiểu_2 thành_phần_2; } danh_sách_biến; • Màu 2: struct{ kiểu_l thành_phần_l; kiểu_l thành_phần_2; } danh_sách_biến; Trong đ ó : - kiêu_l, kiêu_2, ... là tên các kiểu dữ liệu đã được định nghĩa. N ê u kiêu l ạ i là tên m ộ t k i ể u cấu t r ú c đ ã được định nghĩa trước thì ta có các cấu trúc l ồ n g nhau. - thành phần l, thành_phần_2, ... là tên các thành phần của k i ể u cấu trúc đ a n g đ ư ợ c định nghĩa. 141
- ỉ * í Ví dụ: T h ô n g t i n v ê m ộ t sinh v i ê n bao g ô m h ọ t ê n , l ớ p , d i ê m m ô n Ì, đ i ế m m ô n 2, đ i ể m t r u n g b ì n h . N h ư v ậ y , t h ô n g t i n v ề m ỗ i sinh viên bao g ồ m n h i ề u t h à n h p h ầ n k h á c nhau, m ỗ i t h à n h p h ầ n t h u ộ c m ộ t k i ể u d ữ l i ệ u k h á c nhau, ta g o m c á c t h ô n g t i n đ ó l ạ i t h à n h m ộ t c â u t r ú c v ớ i tên s i n h _ v i ê n n h ư sau: struct sinh_vien { char ten[20]; char lóp[10]; int dieml,diem2; float dtb; } sv[100]; N h ư v ậ y , cứ hai sinh v i ê n k h á c nhau thì c ó ít nhất Ì thuộc tính k h á c nhau, đ i ề u đ ó x á c đ ị n h t í n h duy nhất của m ồ i sinh v i ê n . Sự khác nhau giữa 2 mẫu khai báo: V ớ i m ẫ u khai b á o t h ứ nhất c ó t ê n k i ể u c ấ u t r ú c , n h ư v ậ y n g o à i c á c b i ế n c ó tên trong danh s á c h đ ã đ ư a ra, ta c ò n c ó t h ể khai b á o t h ê m c á c b i ế n k h á c cũng c ó c ù n g c ấ u t r ú c n h ư v ậ y , m ẫ u khai b á o c á c b i ế n cấu trúc n h ư sau: struct tên_kiểu danh_sách biến; V ớ i m ẫ u khai b á o t h ứ hai thì chỉ c ó c á c b i ế n c ó t ê n trong danh s á c h b i ế n m ớ i c ó cấu t r ú c n h ư v ậ y m à t h ô i , m u ố n t h ê m c á c b i ế n k h á c phải x â y d ự n g m ộ t cấu t r ú c k h á c . Lưu ý: K h i x â y d ự n g c á c c ấ u t r ú c l ồ n g nhau b á t b u ộ c c ấ u trúc đ ư ợ c l ồ n g v à o phải đ ư ợ c đ ị n h nghĩa t r ư ớ c . Vi dụ: T h ô n g tin v ề n g à y bao g ồ m : n g à y , t h á n g , n ă m . T h ô n g t i n v ề m ộ t sinh v i ê n bao g ồ m h ọ t ê n , n g à y sinh, đ i ể m Ì , đ i ế m 2, đ i ể m trung b ì n h . K h i đ ó ta x â y d ự n g c á c cấu t r ú c n h ư sau: 142
- Cách tí Cách 2: s t r u c t date struct sinh viên { ỉ i n t ngay,thang,nam; char ten[20]; ì; struct struct sinh_vien { í int ngay,thang,nam; char ten[20]ỉ } ngay sinh; s t r u c t d a t e ngay sinh; int dieml,diem2; int dieml,diem2; float dtb; float dtb; } sv[100]; } sv[100]; 5.1.3. T r u y c ậ p c á c p h ầ n t ử c ủ a c ấ u t r ú c Việc xử lý một cấu trúc bao giờ cũng phải thông qua các thành phần cơ bản của n ó . Mau truy cập: t N r t - K h i biên hoặc m ả n g là t h à n h p h â n trực t i ê p của c â u t r ú c : tên_cấu_trúc.tên_thành_phần - Nếu biến hoặc mảng là thành phần trực tiếp của một cấu trúc mà bản thân cấu trúc l ạ i là t h à n h phần của cấu trúc l ớ n hem: tên_cấu_trúc. tên_cấu_trúc. tên_thành_phần Vỉ dụ: Với khai báo struct Dia_chi í int so_nha; char pho[20] ; char thanh_pho[20]; } ong A , b a B; 143
- Ta có thể truy cập v à o các phần tử của struct v ớ i các biên n h ư sau: o n g _ A . s o _ n h a = 2 2 2Ị ong_A.pho="Hoang Van Thu"; ong_a. thanh_j?ho="Thai n g u y ê n " ; Hoặc dùng các hàm: printf("Hay cho biet ten pho: "); gets(ong_a.pho); Trong những trường hợp này c á c t h à n h phần ten_pho v à thanh_pho là c á c m ả n g n ê n ta c ó t h ể truy cập v à o t ừ n g p h ầ n t ử của c h ú n g . Ví d ụ sau in ra từng k ý t ự của ten_pho: int n=strlen(ong_a.ten_pho); for (i=0; i
- 5.1.4. M ả n g c á c c ấ u t r ú c C ó thê khai b á o t h à n h m ộ t m ả n g c á c c â u t r ú c đ ê d ê sử dụng. Mầu khai báo: struct tên_cấu_trúc tên_mảng[số_phần_tử]; Ví dụ sau là một chương trình minh hoa cho một số vẩn đề về mảng, struct... đ ã học, á p d ụ n g cho b à i t o á n quản lý n h â n sự đ ơ n g i ả n . #include #include #include # d e f ± n e MAX 1 0 0 struct Dia_chi{ char ten[20]; int so_nha; char pho[20]; char thanh_pho[15]; } a d d r [MAX] ; void init_list(void); void enter(void); int menu_select(void); void xoa(void)/ void list(void); int find_free(void); void main(){ clrscr 0 ; char choice; init_list() ; for ( ; ; ) { choice=menu_select(); switch (choice){ case 1 : e n t e r 0 ; b r e a k ; case 2 : xoa();break; 145
- case 3: l i s t o ;break; case 4: exit(0); } } } //khói t a o danh s á c h dĩa chi void init_list(void){ register i n t t; for (t=0;t
- printf("\nHet cho"); re t ù m ; } printf("Ten:"); gets(addr[slot].ten); p r i n t f ( " S o nha: " ) ; scanf("%d",&sn); addr[slot].so_nha=sn; while (getchar 0 Ị = • \ n ' ) ; printf("Ten pho:"); gets(addr[slot].pho); printf("Thanh pho:"); gets(addr[slot].thanh_pho); p r i n t f ( " \ n B a n co tiep không? " ) ; tiep=getch(); }while (tiep== ' Ó ; } f i n d _ f ree (void) { register int t; for (t=0;addr[t].ten[0] && t < M A X ; t + + ) if (t==MAX) re t ù m - 1 ; //hey cho re t ù m t; } void xoa(void){ register int slot; char s [80] ; p r i n t f ( " H a y cho b i e t so ban ghi:"); gets(s) ; s l o t = a t o i (s) ; if (slot>=0 && s l o t < M A X ) addr[slot].ten[0]='\0'; } // Hiên thi void list(void){
- register int t; for (t=0;t
- s t r u c t nhan_cong, * p , * p l , *p2, ncl, nc2, danhsach[100] ; Trong đó: p, p l , p2 là c á c con trỏ c ấ u t r ú c ; ne Ì , nc2 là các b i ế n cấu t r ú c ; danhsach là m ả n g cấu t r ú c . Truy nhập đ ế n c á c t h à n h p h ầ n của cấu trúc t h ô n g qua con trỏ: - Cách Ì: tên con trỏ - > t ê n _ t h à n h _ p h ầ n - Cách 2: ( * t ê n _ c o n _ t r ỏ ) . t ê n _ t h à r i h _ p h ầ n Toán tử -ỳ t h ư ờ n g đ ư ợ c g ọ i là t o á n t ử m ũ i tên. K h i khai b á o m ộ t con trỏ c ấ u t r ú c thì lúc đ ó bản t h â n con trỏ c h ư a có giá trị cụ t h ể , m u ố n sử d ụ n g cần phải thực h i ệ n p h é p g á n g i á trị cho nó. Trong khai b á o t r ê n ta c ó t h ể d ù n g : p = danhsach; pl = &danhsach[2]; p2 = &ncl; khi đó có thể d ù n g * p l thay cho danhsach[2], p2 thay cho ne Ì v à p thay cho danhsach[0]. V à đ ư ơ n g n h i ê n c ũ n g c ó t h ể thực h i ệ n thao tác cộng địa chỉ: p = p +10; // con trỏ p trỏ tới danhsach[10] pl = pl-1; // con trỏ pl trỏ tới danhsach[l] Như vậy, nếu p là con trỏ trỏ tới đầu mảng danhsach (danhsach[100] là m ả n g cấu t r ú c ) thì ta c ó : - Đ ể truy nhập đ ế n m ộ t t h à n h p h ầ n của danhsach c ó t h ể d ù n g : danhsach[i].thành_phần p[i].thành_phần (p+i) thành_phần 149
- - K h i sử dụng cả c ấ u t r ú c thì c á c c á c h v i ế t sau là t ư ơ n g đ ư ơ n g : danhsach[i], p [ i ] , *(p+i); 5.2. Kiểu enum Khái niệm: Kiểu enum là kiểu dữ liệu tự định nghĩa bàng cách liệt k ê tất cả các giá trị m à ta m u ố n c ó . Đ ị n h nghĩa k i ể u : enum t ê n _ k i ể u tập_các_giá_trị; Khai b á o b i ế n : enum t ê n _ k i ể u danh_sách_biến; Ví dụ: Đ ị n h nghĩa k i ể u d ữ l i ệ u t h u : ị enum t h u { c h u _ n h a t , h a i , b a , bon, nam, sau, bay}; Khai báo biến: enum t h u so_thu; sau đ ó ta c ó t h ể sử d ụ n g c á c thao tác t r ê n k i ể u d ữ l i ệ u t h u n h ư c á c kiểu dữ liệu khác. Vỉ dụ: sọ_thu=hai; p r i n t f ( " H o m nay la thu %d, %s", so_thu, so_thu); - v ề bản chất k h i đ ị n h nghĩa m ộ t d ữ l i ệ u k i ể u l i ệ t k ê thì c á c g i á trị trong tập giá trị sẽ t ư ơ n g ứ n g v ớ i c á c số t ự n h i ê n bắt đ ầ u t ừ 0, trong ví d ụ trên chu n h á t t ư ơ n g ứ n g v ớ i sổ 0, hai t ư ơ n g ứ n g v ớ i sổ Ì , .... D o đ ó c â u lệnh t r ê n sẽ cho k ế t q u ả là: H o m nay la t h u Ì - K h ô n g t h ể đ ọ c v à ghi trực t i ế p c á c g i á trị cho k i ể u e n u m đ ư ợ c . M u ố n lần lượt đ ư a ra c á c g i á trị của t h á n g ta l à m n h ư sau: switch (so_thu){ case chu nhát: printf("Chu nhát"); break; 150
- case h a i : printf("Thu h a i " ) ; break; case ba: p r i n t f ( " T h u b a " ) ; break/ case bon: p r i n t f ( " T h u t u " ) ; break; case nam: p r i n t f ( " T h u n a m " ) ; b r e a k ; case s a u : p r i n t f ( " T h u sau"); break; case b a y : p r i n t f ( " T h u bay"); break; } C ó t h ể định nghĩa m ộ t d ữ l i ệ u k i ể u l i ệ t k ê v à k h ở i t ạ o k h á c 0 như sau: enum t h u { c h ụ _ n h a t = l , h a i , b a , b o n , nam, s a u , b a y } ; enum t h u s o _ t h u / Như vậy, các giá trị của so thu lần lượt là Ì, 2, 3 ... Định nghĩa k i ể u typedef: D ù n g đ ể đ ặ t t ê n m ớ i cho k i ể u d ữ l i ệ u đ ã được định nghĩa trước ( k i ể u d ữ l i ệ u đ ã t ồ n t ạ i ) . Ví dụ: Đ ặ t tên m ớ i cho k i ể u float typedef floát real; // Đ ặ t t ê n m ó i cho k i ể u float là real real a,bn; / / các biến a, bn thuộc k i ể u float typedef real so_thuc; // Định nghĩa l ạ i m ộ t l ầ n nữa N h ư v ậ y , d ữ l i ệ u k i ể u í l o a t đ ã c ó t h ê m hai t ê n nữa là real v à so thuc, do đ ó c á c c á c h khai b á o sau l à n h ư nhau: float a,b,c; real a,cb,c; so_thuc a,b,c; 5.3. Kiểu hợp (union) Một biến kiểu union cũng bao gồm nhiều thành phần giống như m ộ t b i ế n cẩu t r ú c , n h ư n g k h á c b i ế n c ấ u t r ú c ở c h ỗ c á c t h à n h p h ầ n của biển cấu trúc đ ư ợ c cấp p h á t c á c v ù n g n h ớ k h á c nhau, c ò n c á c t h à n h 151
- phần của b i ế n union đ ư ợ c cấp p h á t chung m ộ t v ù n g n h ớ . Đ ộ d à i của v ù n g n h ớ đ ủ đ ể chứa đ ư ợ c t h à n h phần d à i nhất trong u n i o n . K h a i b á o m ộ t union đ ư ợ c thực h i ệ n n h ờ t ừ k h ỏ a u n ỉ o n . V i ệ c đ ị n h nghĩa m ộ t b i ế n k i ể u union, m ả n g c á c u n i o n , con t r ỏ union, c ũ n g n h ư c á c h thức truy nhập đ ế n c á c t h à n h p h ầ n của b i ế n u n i o n đ ư ợ c thực h i ệ n h o à n t o à n t ư ơ n g t ự n h ư đ ố i v ớ i c á c c ấ u t r ú c . M ộ t c ấ u t r ú c c ó t h ể c ó t h à n h phần union v à n g ư ợ c l ạ i c á c t h à n h p h ầ n của u n i o n l ạ i c ó t h ể là c â u t r ú c . D ư ớ i đ â y là 2 ví d ụ v ề khai b á o u n i o n : Vỉ dụ : typedef union{ unsigned i n t ival; float fval; unsỉgned char ch[2]ỉ } vai ; vai a, b, x[10]; C â u lệnh trong ví d ụ t r ê n đ ị n h nghĩa k i ể u union vai g ồ m ba t h à n h phần là ivai, f v a l v à m ả n g k ý t ự ch. Đ ộ d à i của vai b ằ n g đ ộ d à i của t r ư ờ n g f v a l v à b à n g 4. T i ế p đ ó khai b á o c á c b i ể n u n i o n a, b v à m ả n g c á c union X. Phép gán: a.ival = 0xalb2; m ộ t số h ệ 16 là 0 x a l b 2 cho t h à n h p h à n vai của a. D o i v a l chỉ c h i ế m hai byte đ ầ u của u n i o n , n ê n sau c â u l ệ n h t r ê n ta c ó : a.ch[0]= Oxal v à a . c h [ Ì ] = 0xb2 N h ư v ậ y , ta đ ã d ù n g khai b á o u n i o n đ ể t á c h ra byte cao v à thấp của m ộ t số n g u y ê n . Ví dụ : struct ng{ int ngay; 152
- int thang; int nam; ì; struct diachií int so nha; char *ten pho; }; unỉon u { struct ng date; struct dỉachi address; } diachi_ngaysinh; Truy xuất k i ể u union: C á c h truy x u ấ t c á c t h à n h phần của union cũng thực h i ệ n giống n h ư truy x u ấ t c á c t h à n h phần của m ộ t struct, nghĩa là có t h ể sử d ụ n g t o á n t ử l ấ y t h à n h phần b ằ n g dấu chấm. 5.4. Các cấu trúc tự trỏ 5.4.1. Danh sách móc nôi à) Giới thiệu danh sách Hên két K h i m u ố n tạo lập m ộ t danh s á c h m à b i ế t trước số phần t ừ trong danh sách, ta c ó t h ể d ù n g cấu t r ú c d ữ l i ệ u k i ể u m ả n g cho c ô n g v i ệ c lập trình được đ ơ n giản. T u y n h i ê n , n h i ề u k h i số phần t ử trong danh s á c h lại k h ô n g biết trước đ ư ợ c , n ê n n ế u sử d ụ n g cấu t r ú c d ữ l i ệ u k i ể u m ả n g thì phải cho số c h i ề u cực đ ạ i c ó t h ể d ù n g t ớ i đ ể khai b á o m ả n g , đ i ề u đó có thể dẫn t ớ i l ã n g p h í b ộ nhớ. Đ ể khắc phục đ i ề u n à y , c ó t h ể d ù n g biến động, cần đ ế n đ â u tạo đ ế n đ ấ y v à đ i ề u đ ó chỉ bị hạn chế b ở i k í c h thước của bộ n h ớ trong m á y . M ộ t trong c á c b i ệ n p h á p khắc phục là d ù n g b i ế n con trỏ đ ể x â y d ự n g m ộ t danh s á c h c á c phần t ử đ ư ợ c m ó c nối v ớ i nhau, nghĩa là c á c p h ầ n t ử c ó chứa con trỏ đ ể trỏ t ớ i p h â n t ử k h á c . N ế u chỉ c ó m ộ t c h i ề u m ó c n ố i thì ta g ọ i là danh sách móc nối mội chiểu (danh s á c h liên k ế t ) . N ế u p h ầ n t ử đ ư ợ c trỏ t ớ i l ạ i c ó con trỏ 153
- đ ể trỏ t ớ i phần t ử kia thì ta g ọ i là danh sách móc nổi hai chiều (danh sách n ố i v ò n g ) . K h i cần q u ả n lý m ộ t danh s á c h n à o đ ó , nói chung t h ư ờ n g x u y ê n phải cập nhật, t h ê m , bớt c á c t h à n h v i ê n của danh s á c h . N ế u sử d ụ n g m ả n g , sẽ rất t ố n k é m ( k h i số t h à n h p h ầ n m ả n g v ư ợ t q u á số t h à n h v i ê n của danh s á c h ) hoặc là k h ô n g đ ủ c h ồ đ ể chứa hết c á c t h à n h p h ầ n m ớ i t h ê m v à o . Trái l ạ i b à n g danh s á c h m ó c n ố i , mặc d ù p h ả i t h ê m c á c t r ư ờ n g con trỏ trong t h à n h p h ầ n c ấ u t r ú c , n h ư n g b ù l ạ i danh s á c h c ó t h ể dài tùy ý theo k h ả n ă n g của b ộ n h ớ v à h ơ n t h ế nữa do sử d ụ n g cấp p h á t đ ộ n g nên sẽ k h ô n g bị l ã n g p h í b ộ n h ớ n h ư trong t r ư ờ n g h ợ p sử dụng mảng. C á c phần t ử của danh s á c h liên k ế t ( đ ư ợ c g ọ i là n ú t ) m ó c n ố i v ớ i nhau theo n g u y ê n tắc: M ỗ i n ú t của danh s á c h c ó m ộ t t r ư ờ n g i n f o là n ộ i dung của n ú t v à m ộ t t r ư ờ n g next là con trỏ chỉ đ ế n n ú t k ể t i ế p . Con trỏ đ ầ u của danh s á c h (íĩrstPtr) chỉ đ ế n n ú t đ ầ u t i ê n , c o n trỏ của \ r t n ú t đ â u chỉ đ è n n ú t t h ứ hai, . . . con trỏ của n ú t c u ô i c ù n g t r o n g danh sách chỉ N Ư L L info next info next tlrstPtr NULL C ú p h á p chung cho khai b á o danh s á c h m ó c n ố i sử d ụ n g k i ể u d ữ l i ệ u con trỏ n h ư sau: typedef struct kiểu_dữ_liệu í } t kiểu dữ liệu; 154
- b) Tạo danh sách Hên kết Đ ể quản lý danh s á c h liên k ế t ta d ù n g con trỏ đ ầ u last l u ô n l u ô n trỏ v à o phần tử được nhập c u ố i c ù n g trong danh s á c h , n ế u last = N U L L thỉ danh sách rỗng. N h ư v ậ y , đ ể tạo danh s á c h liên k ế t ta thực h i ệ n c á c thao tác sau: - K h ở i tạo danh s á c h liên k ế t - Lặp theo đ i ề u k i ệ n n à o đ ó Ị c ấ p p h á t m ộ t b i ế n đ ộ n g l à m m ộ t n ú t cho danh sách liên k ế t l N h ậ p n ộ i dung của n ú t m ớ i Ví dụ: X â y d ự n g c h ư ơ n g trình quản lý h ọ tên học sinh v à đ i ể m thi học kỳ của từng học sinh. D a n h s á c h học sinh đ ư ợ c sắp theo t h ứ t ự alphabet. Định nghĩa cấu trúc n h ư sau: typedef struct sinh_vien { char ho_ten[20]; floát diêm; struct sinh_vien *tiep; } t_sinh_vien; t_sinh_vien *head; /*con trỏ đ ế n đ ầ u danh sách*/ M ỗ i phần t ử chứa t h ô n g t i n của m ộ t học sinh v à m ộ t con trỏ chỉ tới địa chỉ của cấu trúc chứa c á c t h ô n g t i n của học sinh t i ế p theo trong danh sách. Danh s á c h k ế t t h ú c b ằ n g m ộ t t h à n h phần N Ư L L . N h ư v ậ y , ban đầu danh sách (head) đ ư ợ c g á n b ằ n g N Ư L L , chỉ ra rằng c h ư a c ó học sinh n à o đ ư ợ c nhập. M ỗ i khi c ó m ộ t học sinh đ ư ợ c nhập v à o , nghĩa là có m ộ t t h à n h phân m ớ i được tạo ra, p h ả i x i n cấp p h á t m ộ t v ù n g b ộ n h ớ c ó k í c h thước đ ủ đ ể chứa p h ầ n t ử đ ó . T o á n t ử s i z e o f ( t ê n _ k i ể u ) cho biết k í c h thước cần thiết đ ể cấp p h á t cho m ộ t b i ế n c ó k i ể u là t ê n _ k i ể u . T ấ t 155
- n h i ê n , khi cấp p h á t k h ô n g q u ê n k i ể m tra x e m l i ệ u c ó c ò n đ ủ b ộ n h ớ hay k h ô n g , đ i ề u n à y là c ầ n t h i ế t đ ể c h ư ơ n g t r ì n h k h ô n g bị treo. #define sizesv sizeof(t_sinh_vien) t_sinh_vien *sV ; main ( ) { sv =NULL; if((sv=(t_sinh_vien *) malloc(sizesv))=NULL){ printf("\khong con du bo nho de cáp phát"); exit(O) ; } g e t c h () ; } Chú ý: Cần g á n sv = N U L L đ ề p h ò n g t r ư ờ n g hợp sv đ a n g trỏ t ớ i m ộ t t h à n h phần cấu t r ú c n à o đ ó trong danh s á c h . • Danh sách trước khi thêm phần tử mới K h i t h ê m phần t ử m ớ i v à o danh s á c h , c h ư ơ n g t r ì n h sẽ t ự đ ộ n g t ì m vị trí thích hợp cho p h ầ n tử. Sử d ụ n g h à m strcmpO ( h à m n à y đ ã đ ư ợ c trình b à y trong c h ư ơ n g 3) đ ể thực h i ệ n c á c p h é p so s á n h h ọ t ê n của h ọ tên học sinh m ớ i nhập v à o v ớ i h ọ t ê n c á c học sinh t r o n g danh s á c h ( c h ú ý r à n g , danh s á c h l u ô n l u ô n đ ư ợ c sắp x ế p theo v ầ n alphabet của h ọ tên c á c học sinh). C á c t r ư ờ n g h ợ p c ó t h ể x ả y ra k h i t h ê m m ộ t phần t ử m ớ i v à o danh s á c h : - N ế u phần t ử m ớ i ở đ ầ u danh s á c h , c ầ n p h ả i sửa l ạ i con t r ỏ head. - Danh sách sau k h i c h è n p h ầ n t ử m ớ i v à o đ ầ u . - N ê u phần t ử đ ó đ ã c ó (hai t ê n t r ù n g nhau) p h ả i c ó sự lựa c h ọ n l i ệ u có phải 2 học sinh k h á c nhau hay chỉ là m ộ t . - Trong c á c t r ư ờ n g h ợ p k h á c c ầ n p h ả i sửa l ạ i con t r ỏ c á c t h à n h phần m ộ t c á c h trực quan n h ư sau: 156
- • Danh sách sau khi thêm sinh viên K h i loại bỏ, c ô n g v i ệ c đ ư ợ c thực h i ệ n theo c h i ề u n g ư ợ c l ạ i . N g ư ờ i sử dụng cần phải p h â n b i ệ t c á c t r ư ờ n g hợp khi danh sách rỗng hoặc phần tử cần loại b ỏ n ằ m ở đ ầ u danh s á c h . C h ư ơ n g trình sau đ â y minh hoa các điều vừa đ ư ợ c p h â n tích ở trên. #include #include #include tinclude typedef struct hoc_sinh { char ho_ten[20]; float diêm; struct hoc_sinh *tiep; } thocsinh; t h o c s i n h *HEAD=NULL; #define sizesv sizeof(thocsinh) main(){ thocsinh *s,*p,*q; char sv; char name[20]; float d; char n=0; clrscr 0 ; do { printf("thong tin cua hoe sinh %d" n+l); / fflush(stdin); printf("Ho ten"); gets(name); if(strcmp(name,"")!=0) i f ( ( s v == (thocsinh*)malloc (sizesv)) == NULL){ p r i n t f ( " k h ô n g du bo nho" ) ; break ; } 157
- else{ n++; s trcpy(sv=>ho_ten,name) ; printf("Diêm"); scanf("%f",&d); sv->diem = d ; s v - > t i e p =NULL; /* */ if ( h e a d = = NULL) head=sV; else { p=head; while(p!=NULL & strcmp(p->ho_ten,sv->ho_ten)tiep; > if ( p ! = N U L L && s t r c m p ( p - > h o _ t e n , s v - > h o _ t e n )) do { fflush(stdin); printf("co h a i hoe s i n h trung ten trong ds"); } while (toupper(ch=getchar 0 ) Ị =d && toupper(ch)!=s); if (toupper(ch) = S) { free(sv); n=- ; continue; } else Víhile ( p ! =NULL&&Strcmp ( p - > h o _ t e n , s v - > h o _ t e n ) =0) { p=p->tiep; if (p==head) head=sv; 158
- else q->tiep = sv; sv->tiep=p; } }while (strcmp(name ,"")!=0); /*Duyet l a i danh s á c h v a i n r a sinh viên t h i lai*/ p=head; w h i l e ( p ! = N U L L && p - > d i e m >=5.0) if (head==p) head=q=p->tiep; else { q>tieltiep; qp->tiep; } free(p) ; p=q; while(p!-NULL && p - > d i e m < 5 . 0 ) { q=p; p=p->tiep; if (head==NULL) p r i n t f ( " k h ô n g co hoe sinh thi lai " ) ; else{ printf("Danh sách sinh viên phai thi lai \n"); n++; p=head; while(p!=NULL){ p r i n t f ( " % 3 d %20s %6.lf",++n,p->ho_ten,p->diem); p=p->tiep; } printf("co t o n g so %d h o e sinh phai thi lai",n); / • G i a i phong bo nho khi két thúc chuông trinh*/ p=head; while (p!=NULL){ q=p->tiep; 159
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 2
24 p | 208 | 72
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 3
21 p | 159 | 52
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 4
24 p | 126 | 43
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 6
24 p | 119 | 37
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 5
24 p | 129 | 36
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 7
24 p | 121 | 36
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 9
24 p | 118 | 36
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 8
24 p | 135 | 34
-
Giáo trình lập trình cơ sở dữ liệu với Visual Basic part 10
24 p | 123 | 33
-
Giáo trình Lập trình có cấu trúc với ngôn ngữ C: Phần 1
140 p | 100 | 19
-
Giáo trình Lập trình cơ bản với C++: Phần 1
77 p | 16 | 7
-
Giáo trình Lập trình cơ bản: Phần 1
51 p | 63 | 6
-
Giáo trình Lập trình cơ bản (Ngành: Kỹ thuật lắp ráp, sửa chữa máy tính) - CĐ Công nghiệp Hải Phòng
90 p | 35 | 6
-
Giáo trình Lập trình cơ bản và nâng cao (Nghề: Tin học văn phòng - Trung cấp) - Trường Cao đẳng Cơ giới (2019)
111 p | 9 | 6
-
Giáo trình Lập trình cơ bản (Nghề: Công nghệ thông tin - Trung cấp): Phần 2 - Trường CĐ Nghề Công nghiệp Thanh Hóa
46 p | 33 | 4
-
Giáo trình Lập trình cơ bản (Nghề: Công nghệ thông tin - Trung cấp): Phần 1 - Trường CĐ Nghề Công nghiệp Thanh Hóa
72 p | 31 | 3
-
Giáo trình Lập trình cơ bản - Nghề: Lập trình máy tính - CĐ Kỹ Thuật Công Nghệ Bà Rịa-Vũng Tàu
111 p | 40 | 2
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn