Bài giảng Kỹ thuật lập trình - Bài 6: Phong cách lập trình - Trịnh Thành Trung
Nội dung
1. Tổng quan
2. Cấu trúc mã nguồn
3. Đặt tên và chú thích
Tại sao cần có
phong cách lập trình tốt
▪ Lỗi thường xảy ra do sự nhầm lẫn của lập trình viên
▫ Biến này được dùng làm gì?
▫ Hàm này được gọi như thế nào?
▪ Mã nguồn tốt ~ mã nguồn dễ đọc
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Bài 6: Phong cách lập trình - Trịnh Thành Trung", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Bài giảng Kỹ thuật lập trình - Bài 6: Phong cách lập trình - Trịnh Thành Trung
Trịnh Thành Trung (ThS) trungtt@soict.hust.edu.vn Bài 6 PHONG CÁCH LẬP TRÌNH Nội dung 1. Tổng quan 2. Cấu trúc mã nguồn 3. Đặt tên và chú thích 1. Tổng quan Programming style What is this #include _(__,___,____){___/__<=1?_(__,___+1,____):!(___%__) ?_(__,___+1,0):___%__==___/ __&&!____?(printf("%d\t",___/__),_(__,___+1,0)) :___%__>1&&___%__<___/__?_(__,1+___,____ +!(___/__%(___%__))):___<__*__?_(__,___+1,____):0;} main(){_(100,0,0); } “▪typedef struct{double x,y,z}vec;vec U,black,amb={.02,.02,.02};struct sphere{ vec cen,color;double rad,kd,ks,kt,kl,ir}*s,*best,sph[]={0.,6.,.5,1.,1.,1.,.9, .05,.2,.85,0.,1.7,-1.,8.,- .5,1.,.5,.2,1.,.7,.3,0.,.05,1.2,1.,8.,-.5,.1,.8,.8, 1.,.3,.7,0.,0.,1.2,3.,-6.,15.,1.,.8,1.,7.,0.,0.,0.,.6,1.5,-3.,- 3.,12.,.8,1., 1.,5.,0.,0.,0.,.5,1.5,};yx;double u,b,tmin,sqrt(),tan();double vdot(A,B)vec A ,B;{return A.x*B.x+A.y*B.y+A.z*B.z;}vec vcomb(a,A,B)double a;vec A,B;{B.x+=a* A.x;B.y+=a*A.y;B.z+=a*A.z;return B;}vec vunit(A)vec A;{return vcomb(1./sqrt( vdot(A,A)),A,black);}struct sphere*intersect(P,D)vec P,D;{best=0;tmin=1e30;s= sph+5;while(s--sph)b=vdot(D,U=vcomb(- 1.,P,s-cen)),u=b*b-vdot(U,U)+s-rad*s - rad,u=u0?sqrt(u):1e31,u=b-u1e-7?b-u:b+u,tmin=u=1e- 7&&u<tmin?best=s,u: tmin;return best;}vec trace(level,P,D)vec P,D;{double d,eta,e;vec N,color; struct sphere*s,*l;if(!level-- )return black;if(s=intersect(P,D));else return amb;color=amb;eta=s-ir;d= -vdot(D,N=vunit(vcomb(- 1.,P=vcomb(tmin,D,P),s-cen )));if(d<0)N=vcomb(- 1.,N,black),eta=1/eta,d= -d;l=sph+5;while(l--sph)if((e=l - kl*vdot(N,U=vunit(vcomb(-1.,P,l- cen))))0&&intersect(P,U)==l)color=vcomb(e ,l-color,color);U=s- color;color.x*=U.x;color.y*=U.y;color.z*=U.z;e=1-eta* eta*(1- d*d);return vcomb(s- kt,e0?trace(level,P,vcomb(eta,D,vcomb(eta*d-sqrt (e),N,black))):black,vcomb(s- ks,trace(level,P,vcomb(2*d,N,D)),vcomb(s-kd, color,vcomb(s- kl,U,black))));}main(){printf("%d %d\n",32,32);while(yx<32*32) U.x=yx%32-32/2,U.z=32/2- yx++/32,U.y=32/2/tan(25/114.5915590261),U=vcomb(255., trace(3,black,vunit(U)),black),printf("%.0f %.0f %.0f\n",U);} Ai là người đọc mã nguồn này? Tại sao cần có phong cách lập trình tốt ▪ Lỗi thường xảy ra do sự nhầm lẫn của lập trình viên ▫ Biến này được dùng làm gì? ▫ Hàm này được gọi như thế nào? ▪ Mã nguồn tốt ~ mã nguồn dễ đọc 6 Mã nguồn dễ đọc Làm thế nào để mã nguồn dễ đọc? ▪ Cấu trúc chương trình rõ ràng, dễ hiểu, khúc triết ▪ Sử dụng thành ngữ phổ biến ▪ Chọn tên phù hợp, gợi nhớ ▪ Viết chú thích rõ ràng ▪ Sử dụng module Một số quy tắc Nhất quán ▪ Tuân thủ quy tắc đặt tên trong toàn bộ chương trình ▪ Nhất quán trong việc dùng các biến cục bộ. Khúc triết ▪ Mỗi chương trình con phải có một nhiệm vụ rõ ràng. ▪ Đủ ngắn để có thể nắm bắt được ▪ Số tham số của chương trình con là tối thiểu (dưới 6) Một số quy tắc Rõ ràng ▪ Chú thích rõ ràng, vd. đầu mỗi chương trình con Bao đóng ▪ Hàm chỉ nên tác động tới duy nhất 1 giá trị - giá trị trả về của hàm ▪ Không nên thay đổi giá trị của biến chạy trong thân của vòng lặp, ví dụ for(i=1;i<=10;i++) i++; 2. Cấu trúc mã nguồn Structure Khoảng trắng Spacing ▪ Sử dụng khoảng trắng dễ đọc và nhất quán ▫ VD: Gán mỗi phần tử mảng a[j] = j. ▫ Bad code ▫ Good code ▫ Thường có thể dựa vào auto-indenting, tính năng trong trình soạn thảo for (j=0;j<100;j++) a[j]=j; for (j=0; j<100; j++) a[j] = j; Cách lề Indentation ▪ Cách lề hợp lý -> tránh nhầm lẫn về cấu trúc ▫ VD: if (month == FEB) { if (year % 4 == 0) if (day > 29) legal = FALSE; else if (day > 28) legal = FALSE; } if (month == FEB) { if (year % 4 == 0) { if (day > 29) legal = FALSE; } else { if (day > 28) legal = FALSE; } } SAI (nếu day>29?) ĐÚNG Cách lề Indentation ▪ Use “else-if” cho cấu trúc đa lựa chọn VD: So sánh trong tìm kiếm nhị phân ▫ Bad code ▫ Good code if (x < v[mid]) high = mid – 1; else if (x > v[mid]) low = mid + 1; else return mid; if (x < v[mid]) high = mid – 1; else if (x > v[mid]) low = mid + 1; else return mid; 2 4 5 7 8 10 17 low=0 high=6 mid=3 10 x v Cách đoạn Paragraph #include #include int main(void) /* Read a circle's radius from stdin, and compute and write its diameter and circumference to stdout. Return 0 if successful. */ { const double PI = 3.14159; int radius; int diam; double circum; printf("Enter the circle's radius:\n"); if (scanf("%d", &radius) != 1) { fprintf(stderr, "Error: Not a number\n"); exit(EXIT_FAILURE); /* or: return EXIT_FAILURE; */ } diam = 2 * radius; circum = PI * (double)diam; printf("A circle with radius %d has diameter %d\n", radius, diam); printf("and circumference %f.\n", circum); return 0; } Biểu thức Expressions ▪ Dùng các biểu thức dạng nguyên bản ▫ VD: Kiểm tra nếu n thỏa mãn j < n < k ▫ Bad code ▫ Good code ▫ Biểu thức điều kiện có thể đọc như cách thức bạn viết thông thường ▸ Đừng viết biểu thức điều kiện theo kiểu mà bạn không bao giờ sử dụng if (!(n >= k) && !(n <= j)) if ((j < n) && (n < k)) Biểu thức Expressions ▪ Dùng ( ) để tránh nhầm lẫn ▫ VD: Kiểm tra nếu n thỏa mãn j < n < k ▫ Moderately bad code ▫ Moderately better code if ((j < n) && (n < k)) if (j < n && n < k) Biểu thức Expressions ▪ Dùng ( ) để tránh nhầm lẫn ▫ VD: đọc và in các ký tự cho đến cuối tệp. ▫ Wrong code ▫ Right code ▫ Nên nhóm các nhóm một cách rõ ràng ▸ Toán tử Logic (“!=“) có độ ưu tiên cao hơn toán tử gán (“=“) while (c = getchar() != EOF) putchar(c); while ((c = getchar()) != EOF) putchar(c); Biểu thức Expressions ▪ Đơn giản hóa các biểu thức phức tạp ▫ VD: Xác định các ký tự tương ứng với các tháng của năm ▫ Bad code ▫ Good code ▫ Nên xắp xếp các cơ cấu song song if ((c == 'J') || (c == 'F') || (c == 'M') || (c == 'A') || (c == 'S') || (c == 'O') || (c == 'N') || (c == 'D')) if ((c == 'J') || (c == 'F') || (c == 'M') || (c == 'A') || (c == 'S') || (c == 'O') || (c == 'N') || (c == 'D')) 3. Đặt tên và chú thích Structure Đăt tên Naming ▪ Dùng tên gợi nhớ, có tính miêu tả cho các biến và hàm ▫ VD : hovaten, CONTROL, CAPACITY ▪ Dùng tên nhất quán cho các biến cục bộ ▫ VD : i (not arrayIndex) cho biến chạy vòng lặp ▪ Dùng chữ hoa, chữ thường nhất quán ▫ VD : Buffer_Insert (Tên hàm) CAPACITY (hằng số) buf (biến cục bộ) ▪ Dùng phong cách nhất quánkhi ghép từ ▫ VD : frontsize, frontSize, front_size ▪ Dùng động từ cho tên hàm ▫ VD : DocSoLieu(), InKq(), Check_Octal(), Chú thích Comments ▪ Làm chủ ngôn ngữ ▫ Hãy để chương trình tự diễn tả bản thân ▫ Rồi ▪ Viết chú thích để thêm thông tin i++; /* add one to i */ ▪ Chú thích các đoạn (“paragraphs”) code, đừng chú thích từng dòng ▫ Vd : “Sort array in ascending order” ▪ Chú thích dữ liệu tổng thể ▫ Global variables, structure type definitions, . ▪ Viết chú thích tương ứng với code ▫ Và thay đổi khi bản thân code thay đổi. Ví dụ #include #include int main(void) /* Read a circle's radius from stdin, and compute and write its diameter and circumference to stdout. Return 0 if successful. */ { const double PI = 3.14159; int radius; int diam; double circum; /* Read the circle’s radius. */ printf("Enter the circle's radius:\n"); if (scanf("%d", &radius) != 1) { fprintf(stderr, "Error: Not a number\n"); exit(EXIT_FAILURE); /* or: return EXIT_FAILURE; */ } Ví dụ /* Compute the diameter and circumference. */ diam = 2 * radius; circum = PI * (double)diam; /* Print the results. */ printf("A circle with radius %d has diameter %d\n", radius, diam); printf("and circumference %f.\n", circum); return 0; } Chú thích hàm ▪ Mô tả những gì cần thiết để gọi hàm 1 cách chính xác ▫ Mô tả Hàm làm gì, chứ không phải làm như thế nào ▫ Bản thân Code phải rõ ràng, dễ hiểu để biết cách nó làm việc ▫ Nếu không, hãy viết chú thích bên trong định nghĩa hàm ▪ Mô tả đầu vào: Tham số truyền vào, đọc file gì, biến tổng thể được dùng ▪ Mô tả đầu ra: giá trị trả về, tham số truyền ra, ghi ra files gì, các biến tổng thể nó tác động tới Chú thích hàm ▪ Bad comment ▫ Giải thích hàm làm như thế nào /* decomment.c */ int main(void) { /* Đọc 1 ký tự. Dựa trên ký tự ấy và trạng thái DFA hiện thời, gọi hàm xử lý trạng thái tương ứng. Lặp cho đến hết tệp end-of-file. */ } Chú thích hàm ▪ Good function comment ▫ Giải thích hàm làm gì /* decomment.c */ int main(void) { /* Đọc 1 chương trình C qua stdin. Ghi ra stdout với mỗi chú thích thay bằng 1 dấu cách. Trả về 0 nếu thành công, EXIT_FAILURE nếu không thành công. */ } 4. Các quy tắc chung Good programming style từ cuốn The Elements of Programming Style Brian Kernighan and P. J. Plauger McGraw-Hill Book Company, New York, 1974 “ 1. Write clearly / don't be too clever – Viết rõràng – đừng quá thông minh (kỳ bí) 2. Say what you mean, simply and directly – Trình bày vấn đề 1 cách đơn giản, trực tiếp 3. Use library functions whenever feasible. – Sử dụng thư viện mọi khi có thể 4. Avoid too many temporary variables – Tránh dùng nhiều biến trung gian 5. Write clearly / don't sacrifice clarity for efficiency – Viết rõ ràng / đừng hy sinh sự rõ ràng cho hiệu quả 6. Let the machine do the dirty work – Hãy để máy tính làm những việc nặng nhọc của nó. (tính toán) “ 7. Replace repetitive expressions by calls to common functions. – Hãy thay những biểu thức lặp đi lặp lại bằng cách gọi các hàm 8. Parenthesize to avoid ambiguity. – Dùng () để tránh rắc rối 9. Choose variable names that won't be confused – Chọn tên biến sao cho tránh được lẫn lộn 10. Avoid unnecessary branches. – Tránh các nhánh không cần thiết 11. If a logical expression is hard to understand, try transforming it – Nếu 1 biểu thức logic khó hiểu, cố gắng chuyển đổi cho đơn giản “ 12. Choose a data representation that makes the program simple – Hãy lựa chọn cấu trúc dữ liệu để chương trình thành đơn giản 13. Write first in easy-to-understand pseudo language; then translate into whatever language you have to use. – Trước tiên hãy viết chương trình bằng giả ngữ dễ hiểu, rồi hãy chuyển sang ngôn ngữ cần thiết. 14. Modularize. Use procedures and functions. – Mô đul hóa. Dùng các hàm và thủ tục 15. Avoid gotos completely if you can keep the program readable. – Tránh hoàn toàn việc dùng goto “ 16. Don't patch bad code, rewrite it. – Khôngchắp vá mã xấu – Viết lại đoạn code đó 17. Write and test a big program in small pieces. – Viết và kiểm tra 1 chương trình lớn thành từng chương trình con 18. Use recursive procedures for recursively- defined data structures. – Hãy dùng các thủ tục đệ quy cho các cấu trúc dữ liệu đệ quy 19. Test input for plausibility and validity. – Kiểm tra đầu vào để đảm bảo tính chính xác và hợp lệ 20. Make sure input doesn't violate the limits of the program. – Hãy đảm bảo đầu vào không quá giới hạn cho phép của chương trình “ 21. Terminate input by end-of-file marker, not by count. – Hãy kết thúc dòng nhập bằng ký hiệu EOF, không dùng phép đếm 22. Identify bad input; recover if possible. – Xác định đầu vào xấu, khôi phục nếu có thể 23. Make input easy to prepare and output self- explanatory. – Hãy làm cho đầu vào đơn giản, dễ chuẩn bị và đầu ra dễ hiểu 24. Use uniform input formats. – Hãy dùng các đầu vào theo các định dạng chuẩn. “ 25. Make sure all variable are initialized before use.- Hãy đảm bảo các biến được khởi tạo trước khi sử dụng 26. Test programs at their boundary values. – Hãy kiểm tra chương trình tại các cận 27. Check some answers by hand. – Kiểm tra 1 số câu trả lời bằng tay 28. 10.0 times 0.1 is hardly ever 1.0. – 10 nhân 0.1 không chắc đã = 1.0 29. 7/8 is zero while 7.0/8.0 is not zero. 7/8 =0 nhưng 7.0/8.0 ≠ 0 30. Make it right before you make it faster. – Hãy làm cho chương trình chạy đúng, trước khi làm nó chạy nhanh “ 30. Make it clear before you make it faster. – Hãyviết code rõ ràng, trước khi làm nó chạy nhanh 31. Let your compiler do the simple optimizations. – Hãy để trình dịch thực hiện các việc tôi ưu hóa đơn giản 32. Don't strain to re-use code; reorganize instead. – Đừng cố tái sử dụng mã, thay vì vậy, hãy tổ chức lại mã 33. Make sure special cases are truly special. – Hãy đảm bảo các trường hợp đặc biệt là thực sự đặc biệt 34. Keep it simple to make it faster. – Hãy giữ nó đơn giản để làm cho nó nhanh hơn “ 35. Make sure comments and code agree. – Chúthích phải rõ ràng, sát code 36. Don't comment bad code | rewrite it. – Đừng chú thích những đoạn mã xấu, hãy viết lại 37. Use variable names that mean something. – Hãy dùng các tên biến có nghĩa 38. Format a program to help the reader understand it.- Hãy định dạng chương trình để giúp người đọc hiểu đc chương trình 39. Don't over-comment. – Đừng chú thích quá nhiều Thanks! Any questions? Email me at trungtt@soict.hust.edu.vn Presentation template by SlidesCarnival
File đính kèm:
- bai_giang_ky_thuat_lap_trinh_bai_6_phong_cach_lap_trinh_trin.pdf