Bài giảng Kỹ thuật lập trình: Bài 5 do TS. Ngô Hữu Dũng biên soạn cung cấp cho người học các kiến thức: Khái niệm kiểu cấu trúc, khai báo cấu trúc, khai báo cấu trúc và biến, khai báo – Nhiều biến cấu trúc, không cần thẻ cấu trúc, cấu trúc trong cấu trúc, mảng trong cấu trúc,...
Kỹ thuật lập trình Bài – Kiểu cấu trúc Ts Ngô Hữu Dũng Khái niệm Kiểu cấu trúc: Nhóm phần tử khơng đồng với Ví dụ 1: Một ngày lưu biến riêng biệt Kiểu mảng: Nhóm phần tử đồng với int day = 28, month = 8, year = 2016; Vậy ngày ta phải dùng biến riêng biệt để lưu trữ Kiểu cấu trúc: Nhóm biến với biến date Ví dụ 2: Một sinh viên gồm nhiều thông tin liên quan 122 char fullname[50]; date birthday; int height; int weight; Kiểu cấu trúc: Nhóm phần tử với biến student Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Khai báo cấu trúc struct t_date{ int day; int month; int year; }; // Khai báo kiểu cấu trúc // Gồm phần tử struct t_date birthday, today;// Khai báo biến // Truy suất phần tử birthday.day = 27; // Dùng dấu chấm ‘.’ birthday.month = 8; birthday.year = 1996; 10 today.year = 2016; 123 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Cú pháp struct [structure tag] { member definition; member definition; member definition; } [one or more structure variables]; 124 struct char char char }; t_name{ first[10]; middle[10]; last[10]; struct { int x; int y; } A, B; Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Khai báo cấu trúc biến struct t_date{ int day; int month; int year; }today; // Khai báo kiểu cấu trúc // Gồm phần tử // Khai báo biến struct t_date birthday; // Khai báo biến // Truy suất phần tử birthday.day = 27; // Dùng dấu chấm ‘.’ birthday.month = 8; birthday.year = 1996; 10 today.year = 2016; 125 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Khai báo – Nhiều biến cấu trúc struct t_date{ // Khai báo kiểu cấu trúc int day; // Gồm phần tử int month; int year; }today, birthday; // Khai báo nhiều biến //struct date birthday; // Truy suất phần tử birthday.day = 27; // Dùng dấu chấm ‘.’ birthday.month = 8; birthday.year = 1996; 10 today.year = 2016; 126 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Khai báo – Không cần thẻ cấu trúc struct { // Không cần thẻ cấu trúc!? int day; // Gồm phần tử int month; int year; }today, birthday; // Khai báo biến //struct date birthday; // Truy suất phần tử birthday.day = 27; // Dùng dấu chấm ‘.’ birthday.month = 8; birthday.year = 1996; 10 today.year = 2016; 127 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Khai báo - typedef typedef struct { int day; int month; int year; }date; // typedef kiểu cấu trúc // Gồm phần tử // Khai báo kiểu date birthday, today; // Khai báo biến // Truy suất phần tử birthday.day = 27; // Dùng dấu chấm ‘.’ birthday.month = 8; birthday.year = 1996; 10 today.year = 2016; 128 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Khai báo – Cấu trúc cấu trúc struct t_date{ int day; int month; int year; }; struct t_student{ char name[50]; struct t_date birth; int height; 10 int weight; 11 }; 129 // Sử dụng cấu trúc struct t_student sv; sv.birth.day = sv.birth.month = 5; sv.birth.year = 1996; sv.height = 175; sv.weight = 65; if(sv.height > 170) printf("Tall one"); Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Khai báo – Mảng cấu trúc struct t_date{ int day; int month; int year; }; struct t_student{ char fullname[50]; struct t_date birth; int height; 10 int weight; 11 }; 130 // Sử dụng cấu trúc struct t_student sv; sv.name[0] = 'n'; sv.name[1] = 'g'; sv.name[2] = '\0'; strcat(sv.name,"uyen"); strcat(sv.name," thi"); strcat(sv.name," ha"); Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Ví dụ vận dụng – Tìm ngày (2) struct t_date{ int day; int month; int year; }; // 136 Function prototype struct t_date tomorrow(struct t_date); Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Tìm ngày (2) 10 11 12 13 137 struct t_date tomorrow(struct t_date aDay) { if (aDay.day < daysOfMonth(aDay))// Chưa tròn tháng aDay.day++; // Tăng ngày else if (aDay.month < 12){// Tròn tháng, chưa tròn năm aDay.day = 1; // Reset ngày aDay.month ++; // Tăng tháng }else{ // Tròn tháng tròn năm aDay.day = aDay.month = 1;// Reset ngày, tháng aDay.year ++; // Tăng năm } return aDay; // Trả ngày } Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Tìm ngày (3) Hàm tính số ngày tháng, có tính đến năm nhuận =IF(OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)0)),"Leap Year", "NOT a Leap Year") int daysOfMonth(struct t_date d) { int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; if(d.month!=2) // Nếu tháng return days[d.month-1]; else // Nếu tháng if((d.year%4==0&&d.year%100!=0)||d.year%400==0) return 29; // Năm nhuận else 10 return 28; // Năm không nhuận 11 } 138 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Tìm ngày (4) // Sử dụng hàm tomorrow struct t_date today, nextDay, nextOfTomorrow; today.day = 1; today.month = 9; today.year = 2016; nextDay = tomorrow(today); nextDay.day = tomorrow(today).day; nextDay.month = tomorrow(today).month; nextDay.year = tomorrow(today).year; 10 11 12 139 nextOfTomorrow = tomorrow(nextDay); nextOfTomorrow = tomorrow(tomorrow(today)); Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Ví dụ vận dụng – Tìm Viết hàm tính sau tăng giây Cấu trúc liệu gồm giờ, phút, giây Input: Một Đối số hàm biến kiểu Output: Ngày Thiết kế cấu trúc kiểu gồm phần tử giờ, phút, giây Hàm trả kiểu Gợi ý thuật tốn Tương tự tính ngày Điểm khác biệt: Năm không bị giới hạn, bị giới hạn (24) 140 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Tìm (2) struct t_time{ int hour; int minute; int second; }; struct 141 t_time nextSec(struct t_time); Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Tìm (3) 10 11 12 13 14 142 struct t_time nextSec(struct t_time time) { if (time.second < 59) // Chưa tròn phút time.second++; // Tăng giây else if(time.minute < 59) { // Tròn phút, chưa tròn time.second = 0; // Reset giây time.minute++; // Tăng phút }else if(time.hour < 23){ //Tròn phút, giờ, chưa tròn ngày time.second = time.minute = 0; // Reset giây, phút time.hour++; // Tăng }else // Tròn phút, tròn giờ, tròn ngày time.second = time.minute = time.hour = 0;// Ngày return time; // Trả thời gian } Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Tìm (4) // Dùng hàm nextSec struct t_time time, nextTime; struct t_time nextOfNextTime; time.hour = 4; time.minute = 59; time.hour = 12; nextTime=nextSec(time); 143 nextOfNextTime=nextSec(nextTime); Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Hồn chỉnh ngày Viết hàm tính ngày hồn chỉnh Cấu trúc liệu gồm ngày, tháng, năm, giờ, phút, giây Dùng cấu trúc kiểu ngày gồm phần tử Input: Một ngày Output: Ngày Gợi ý thuật tốn Tìm số giây nextSec Nếu sang ngày tìm ngày tomorrow 144 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngô Hữu Dũng Ví dụ vận dụng – Hồn chỉnh ngày (2) 10 11 12 13 14 145 struct t_date{ int day; int month; int year; }; struct t_time{ int hour; int minute; int second; }; struct t_timeday{ struct t_date date; struct t_time time; }; struct t_timeday{ year; month; day; hour; minute; second; int int int int int int }; // Cách 2 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Hồn chỉnh ngày (3) – Cách struct t_timeday timeday; timeday.date.day = 31; timeday.date.month = 12; timeday.date.year = 2016; timeday.time.hour = 23; timeday.time.minute = 59; timeday.time.second = 59; timeday.time = nextSec(timeday.time); if (timeday.time.hour==0&&timeday.time.minute==0&& 10 timeday.time.second==0) timeday.date = tomorrow(timeday.date); 11 146 Kỹ thuật lập trình | DHTH11C | HK1 | 2016-2017 Ts Ngơ Hữu Dũng Ví dụ vận dụng – Hồn chỉnh ngày (4) – Cách 2 10 11 12 13 14 15 16 17 18 19 20 struct t_timeday{ int year; int month; int day; int hour; int minute; int second; }; int daysOfMonth(struct t_timeday d) { int days[12]={31,28,31,30,31,30,31,31 ,30,31,30,31}; if(d.month!=2) return days[d.month-1]; else if((d.year%4==0&&d.year%100!=0) || d.year%400==0) return 29; else return 28; } 147 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 struct t_timeday nextTime(struct t_timeday1 time) { if (time.second