Phần tiếp theo bài giảng Kỹ thuật lập trình - Chương 3: Các kỹ thuật xây dựng chương trình phần mềm cung cấp cho người học các kiến thức về các kỹ thuật thiết kế chương trình. Đây là một tài liệu hữu ích dành cho các bạn sinh viên ngành Công nghệ Thông tin và những ai quan tâm dùng làm tài liệu học tập và nghiên cứu.
• Với toán, làm để: – Thiết kế giải thuật nhằm giải tốn – Cài đặt giải thuật chương trình máy tính - Làm cho chương trình chạy trước tăng tính hiệu chương trình - Tăng tính hiệu chương trình, đồng thời thể tốt phong cách lập trình cá nhân CHƯƠNG III CÁC KỸ THUẬT XÂY DỰNG CHƯƠNG TRÌNH PHẦN MỀM I II III IV V Mở đầu Làm việc với biến Viết mã chương trình hiệu Thiết kế chương trình Xây dựng hàm/thủ tục IV CÁC KỸ THUẬT THIẾT KẾ CHƯƠNG TRÌNH Nguyên tắc chung Thiết kế giải thuật Thiết kế liệu Mở đầu • Phẩm chất chương trình tốt – Cấu trúc tốt – Logic chương trình + biểu thức diễn đạt theo cách thơng thường – Tên dùng chương trình có tính chất miêu tả – Chú thích hợp lý – Tơn trọng chiến lược divide/conquer/association • Làm để tạo chương trình có phẩm chất tốt – Thiết kế top-down – Tinh chỉnh bước Nguyên tắc chung • Đơn giản: – Thể giải thuật vốn có, đừng q kỳ bí – Lựa chọn cấu trúc liệu cho việc viết giải thuật NNLT cụ thể đơn giản – Tìm cách đơn giản hóa biểu thức – Thay biểu thức lặp lặp lại CTC tương ứng • Trực tiếp: – Sử dụng thư viện lúc – Tránh việc kiểm tra điều kiện khơng cần thiết • Rõ ràng: – Dùng cặp dấu đánh dấu khối lệnh để tránh nhập nhằng – Đặt tên biến, hàm, cho tránh nhầm lẫn – Khơng chắp vá đoạn mã khó hiểu mà nên viết lại Ngun tắc chung • Có cấu trúc tốt: – Tơn trọng tính cấu trúc chương trình theo mơ thức lập trình: • Modul: hàm/ thủ tục • Hướng đối tượng: lớp • Hướng thành phần: thành phần • Hướng dịch vụ: dịch vụ – Viết kiểm thử dựa cấu trúc phân cấp chương trình – Tránh hồn tồn việc dùng goto Nếu cần nên viết giải thuật giả ngữ, viết NNLT cụ thể Thiết kế giải thuật • Chia tốn thành nhiều tốn nhỏ • Tìm giải pháp cho tốn nhỏ • Gộp giải pháp cho toán nhỏ thành giải pháp tổng thể cho tốn ban đầu Đơn giản hóa tốn cách trừu tượng hóa: làm thay làm – Ví dụ: hàm mức trừu tượng • Hàm xếp mảng số nguyên • Hàm nhập vào / xuất ký tự: getchar() , putchar() • Hàm tốn học : sin(x), sqrt(x) Bottom-Up Design is Bad • Bottom-up design – Thiết kế chi tiết phần – Thiết kế chi tiết phần khác – Lặp lại hết • Bottom-up design in programming – Viết phần CT cách chi tiết hết – Viết phần CT cách chi tiết hết – Lặp lại hết … … Top-Down Design is Good • Top-down design – Thiết kế tồn sản phẩm cách sơ bộ, tổng thể – Tinh chỉnh hồn thiện • Top-down design in programming – Phác họa hàm main() (bằng lệnh giả ngữ pseudocode) – Tinh chỉnh lệnh giả ngữ • Cơng việc đơn giản => thay real code • Công việc phức tạp => thay lời gọi hàm – Lặp lại sâu hơn, cụ thể, chi tiết – Kết quả: Sản phẩm có cấu trúc phân cấp tự nhiên … Top-Down Design in Reality • Thiết kế CT Top-down thực tiễn : – Định nghĩa hàm main() = pseudocode – Tinh chỉnh lệnh pseudocode • Nếu gặp cố Oops! Xem lại thiết kế, và… • Quay lại để tinh chỉnh pseudocode có, tiếp tục – Lặp lại (mostly) mức sâu hơn, cụ thể hơn, hàm đc định nghĩa xong Oops 1’ 2’ 1’ 2’ 1’’ Oops 2’’ 4’ 3’ … Expanding Array: Free (3) void Table_free(struct Table *t) { free(t->array); free(t); } struct Table *t; … Table_free(t); … t t STACK HEAP Expanding Array: Free (4) void Table_free(struct Table *t) { free(t->array); free(t); } struct Table *t; … Table_free(t); … t t STACK HEAP Expanding Array: Free (5) void Table_free(struct Table *t) { free(t->array); free(t); } struct Table *t; … Table_free(t); … t STACK HEAP Expanding Array: hiệu • Thời gian tính tốn – – – – Create: O(1), nhanh Add: O(1), nhanh Search: O(n), chậm Free: O(1), nhanh • Giải pháp khác: Sắp xếp mảng theo khóa – Create: O(1), nhanh – Add: O(n), chậm; cần phải dịch cặp khóa/ giá trị để có chỗ thêm – Search: O(log n), chấp nhận được, sử dụng tìm kiếm nhị phân – Free: O(1), nhanh Quản lý nhớ động • Một số hạn chế sử dụng mảng C: – Kích thước mảng cần biết trước – Kích thước mảng khơng thể thay đổi chương trình • Cần: – Cấp phát nhớ lượng cần chạy – Giải phóng nhớ khơng cần dùng – Chương trình khơng cần phải viết lại để xử lý lượng liệu lớn Quản lý nhớ động (dynamic memory) C: Dùng malloc(), calloc(), realloc() free() C++: Dùng new delete 5.1 Quản lý bộ nhớ động C Trong thư viện stdlib.h malloc(size_t n), calloc(size_t m, size_t n) Cấp phát một vùng nhớ mới realloc(void * ptr, size_t n) Thay đổi kích thước cho một vùng nhớ đã được cấp phát free(void * ptr) Giải phóng cho vùng nhớ đã được cấp phát size_t là kiểu dữ liệu chứa kích thước đối tượng (số byte) size_t sizeof(doi_tuong): Kích thước của doi_tuong Ví dụ: sizeof(int) 5.1.1 Cấp phát vùng nhớ void *malloc(size_t n); Lấy về một vùng nhớ liên tục có kích thước ít nhất là n byte Chỉ xin cấp phát vùng nhớ chứ nội dung vùng nhớ vẫn chưa được xác định void *calloc(size_t m, size_t n); Lấy về một vùng nhớ có kích thước ít nhất là m x n byte Vùng nhớ này đủ để chứa một mảng gồm m phần tử, mỗi phần tử chiếm n byte Mỗi byte nhớ được khởi tạo với giá trị Hai hàm trả về trỏ null có lỗi quá trình cấp phát vùng nhớ Bộ nhớ động được quản lý bởi hệ điều hành môi trường đa nhiệm được chia sẻ giữa hàng loạt các ứng dụng Có thể thiếu bộ nhớ #include #include void main() { int i, kthuoc; int *a; double *dPtr = malloc(sizeof(double)); printf("Hay nhap vao kich thuoc cua mang: "); scanf("%d", &kthuoc); a = (int *) calloc(kthuoc, sizeof(int)); if (a == NULL || dPtr == NULL ) //Khong du bo nho printf("Khong du bo nho"); else // Da duoc cap phat du { *dPtr = -8.67; for (i=0;i