Bài giảng Cơ sở kỹ thuật lập trình - Chương 5: Hàm và cấu trúc chương trình - Trương Vĩnh Trường Duy

 Lợi ích của việc dùng hàm  Phân biệt giữa hàm do người sử dụng định nghĩa và các hàm chuẩn  Phân biệt giữa truyền tham trị và truyền tham chiếu  Cách viết một hàm  Hàm và con trỏ  Bài tập minh họa Hàm  Giúp phân chia một chương trình thành các module nhỏ hơn  Mỗi module là 1 đoạn chương trình độc lập thực hiện trọn vẹn một công việc nhất định, rồi trả về một giá trị cho chương trình gọi nó  Hàm main() là thành phần bắt buộc, chương trình thực hiện từ câu lệnh đầu tiên của hàm main() đến khi gặp dấu } cuối cùng  Các module được kết hợp lại trong chương trình chính  Không cho phép xây dựng một hàm bên trong hàm khác

pdf43 trang | Chia sẻ: candy98 | Lượt xem: 779 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Bài giảng Cơ sở kỹ thuật lập trình - Chương 5: Hàm và cấu trúc chương trình - Trương Vĩnh Trường Duy, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chương 5: Hàm và cấu trúc chương trình Biên soạn: Trương Vĩnh Trường Duy (duytvt@ptithcm.edu.vn) Từ tài liệu trên Internet và các nguồn khác CƠ SỞ KỸ THUẬT LẬP TRÌNH Nội dung  Lợi ích của việc dùng hàm  Phân biệt giữa hàm do người sử dụng định nghĩa và các hàm chuẩn  Phân biệt giữa truyền tham trị và truyền tham chiếu  Cách viết một hàm  Hàm và con trỏ  Bài tập minh họa Hàm  Giúp phân chia một chương trình thành các module nhỏ hơn  Mỗi module là 1 đoạn chương trình độc lập thực hiện trọn vẹn một công việc nhất định, rồi trả về một giá trị cho chương trình gọi nó  Hàm main() là thành phần bắt buộc, chương trình thực hiện từ câu lệnh đầu tiên của hàm main() đến khi gặp dấu } cuối cùng  Các module được kết hợp lại trong chương trình chính  Không cho phép xây dựng một hàm bên trong hàm khác Bố cục chương trình C  Một chương trình C được tổ chức theo mẫu: Hàm 1 Hàm 2 Hàm n  Ở các vị trí bên ngoài hàm (), ta có thể đặt các toán tử #include, #define, định nghĩa kiểu dữ liệu, khai báo biến ngoài, biến tĩnh ngoài Hàm (ví dụ) Chương trình nhận các chi tiết của 1 nhân viên để tính lương  Gồm các trường: • Employee number • Employee name • Grade • Basic Salary • Standard allowance • Standard deductions  Các chi tiết trong bảng lương: • Employee number • Employee name • Grade • Basic Salary • Allowances • Net salary • Deductions Hàm (ví dụ tiếp theo)  Cần thực hiện các tính toán sau:  Net salary = (Basic + Allowances) - Deductions  Allowances = House Rental Allowance(HRA) + Standard allowance  Deduction = Standard deductions + Provident Fund  Provident fund is deducted at the rate of 6% of the Basic salary  HRA and the allowance are based on the grade Grade HRA • 1 18% of Basic salary • 2 15% of Basic salary • 3 Nil Hàm (ví dụ tiếp theo)  Trong bài toán trên, nếu viết mọi thứ trong một module thì chương trình sẽ quá phức tạp  Chương trình này sẽ được phân thành 2 chương trình nhỏ hơn có tên là:  Provident Fund Calculation  HRA Calculation Hàm (ví dụ tiếp theo)  Đối với việc tính lương của 1 nhân viên: Start emp_no=0 Array emp_name[15] is a character grade=0 basic=0 std_allow=0 std_ded=0 net_sal=0 allow=0 deduct=0 HRA=0 PF=0 reply = ‘y’ (to be continued...) Hàm (ví dụ tiếp theo) while reply=’y’ do Accept emp_no, emp_name, grade, basic, std_all, std_ded PF = PF_CAL() HRA = HRA_CAL() allow = HRA + std_allow deduct = std_ded + PF net_sal = (basic + allow) - deduct display emp_no, emp_name, grade, basic, allow, deduct, net_sal display “Do you wish to continue(y/n)?” Accept reply enddo End Hàm (ví dụ tiếp theo)  Các hàm PF_CAL() và HRA_CAL() PF_CAL () Start if ( grade 3 ) PF = .06 * basic else PF = 0 endif Return PF HRA_CAL () Start if ( grade = 1 ) HRA = .18 * basic else if ( grade = 2 ) HRA = .15 * basic else HRA = 0 endif endif Return HRA Ưu điểm của việc dùng hàm  Dễ bảo trì code  Giúp code dễ đọc, dễ hiểu  Loại trừ những đoạn mã dư thừa  Cho phép tái sử dụng code Chương trình tính x^3 Tham số của hàm  Hàm cộng hai giá trị và hiển thị tổng: Start Add(2, 5) End Add(x is an integer, y is an integer) Start Declare sum as an integer sum = x + y Display sum return  Hàm Add(x is an integer, y is an integer) nhận 2 tham số nguyên x và y  Hàm Add(2, 5) được gọi với các trị truyền vào là 2 và 5 Tham số của hàm(tiếp theo) Cần bảo đảm truyền đúng trật tự và số lượng các tham số: Ví dụ: Start Declare num as an integer num = 10 Add(2, 5) Add(‘9’, 4, 6) Add(2, 5, num) End Add(x is integer, y is integer, z is integer) Start sum is an integer sum = x + y + z Display sum return Errors Tham số của hàm(tiếp theo)  Kết quả hàm Add(2, 5) sẽ bị báo lỗi vì hàm Add() được khai báo với 3 tham số nhưng hàm gọi chỉ được truyền có 2 giá trị  Kết quả hàm Add(‘9’, 4, 6) cũng sẽ bị lỗi vì ‘9’ là 1 ký tự  Hàm Add(2, 5, num) Giá trị trả về  Là giá trị của hàm được trả về cho chương trình gọi (chương trình chính)  Mỗi hàm chỉ có thể trả về một trị cho chương trình gọi nó Giá trị trả về (ví dụ)  Tìm tổng của 2 số và trả về số tổng đó cho chương trình chính Start sum is an integer sum = Add(2,5) Display sum End Add(x is an integer, y is an integer) returns integer Start var1 is an integer var1 = x + y return var1 Hàm  Hàm do người sử dụng định nghĩa  Được viết bởi người lập trình, tùy vào yêu cầu của chương trình  Các Hàm chuẩn  Được đóng gói kèm theo công cụ lập trình  Thực hiện các thao tác thông dụng  Ví dụ: • MsgBox(“thông báo”) trong MS Access • MsgBox(“thông báo”) trong Visual Basic Thư viện hàm  Tập hợp các hàm  Chứa các hàm liên quan đến một lĩnh vực trong lập trình. Ví dụ, thư viện Math chứa các hàm tính toán như: khai căn, lũy thừa, tính trung bình .  Mỗi khi kết hợp vào ứng dụng, chỉ cần gọi tên hàm mà không cần viết lại các câu lệnh của nó.  Hàm được gọi trực tiếp với đúng kiểu và số lượng tham số  Các hàm thường sử dụng thì được đặt trong thư viện hàm Cách viết một hàm  Xác định mục đích hàm: trước hết phải xác định mục đích của hàm dùng để làm gì, trên cơ sở đó ta xác định các thành phần của hàm  Xác định các thành phần của hàm:  Nguyên mẫu của hàm ; Ta có thể không ghi nguyên mẫu của hàm, tuy nhiên nên nhóm các nguyên mẫu hàm đặt trước hàm main() để dễ kiểm soát Cách viết một hàm  Xác định các thành phần của hàm:  Kiểu giá trị của hàm: giá trị trả về của hàm phải được xác định dựa vào mục đích của hàm và trong thân hàm ta phải trả về đúng kiểu giá trị đã định ban đầu  Tên hàm: đặt theo quy định đối với danh định, nên ngắn gọn và phản ánh mục đích. Tên hàm trong nguyên mẫu và khai báo phải giống nhau  Tham số của hàm: • Phân loại theo cách sử dụng • Phân loại theo công dụng Phân loại theo cách sử dụng  Tham số hình thức: các tham số ghi trong nguyên mẫu hay ghi lúc khai báo hàm  Tham số thực: các giá trị, biến ghi sau tên hàm khi gọi hàm đó để thực hiện  Tham chiếu: được truyền cho hàm dưới dạng con trỏ (địa chỉ). Tham chiếu mới ghi nhận lại được những kết quả tính toán khi hàm kết thúc  Tham trị: được truyền cho hàm dưới dạng biến, không bảo lưu lại những kết quả thay đổi Truyền tham trị (ví dụ)  Nhập 2 số và tính trunh bình cộng: Start Declare num1, num2, avg as integers avg = 0 Display “Enter first integer” Accept num1 Display “Enter second integer” Accept num2 Avg_func(pass num1 by value, pass num2 by value, pass avg by value) Display avg End Avg_func(x is an integer, y is an integer, z is an integer) Start z = (x + y) / 2 Display z return Truyền tham trị (ví dụ)  Avg_func(pass num1 by value, pass num2 by value, pass avg by value)  Biến num1, num2 và avg được truyền bằng trị vào hàm Avg_func()  Avg_func(x is an integer, y is an integer, z is an integer)  Cho biết rằng các giá trị num1, num2 và avg được sao chép vào các biến x, y và z  Lệnh ‘Display z’ hiển thị giá trị trung bình  Lệnh ‘Display avg’ hiển thị giá trị avg gốc Truyền tham trị (ví dụ 2)  Nhập vào 1 số và thay đổi giá trị của nó trong hàm: Start num is an integer Display “Enter a number” Accept num Display the value in num before change change(pass num by value) Display the value in num after change End change(var is an integer) Start var = 10 Display the value in var return Truyền tham trị (ví dụ 2)  change(pass num by value)  Biến num được truyền vào hàm dưới dạng tham trị  change(var is an integer)  Giá trị của num được sao chép vào biến var  Lệnh ‘Display the value in var’ hiển thị giá trị var là 10  Lệnh ‘Display the value in num after change’ hiển thị giá trị gốc của num được nhập từ ngưới sử dụng Truyền tham chiếu (ví dụ)  Nhập vào 1 số và thay đổi giá trị của nó trong hàm: Start num is an integer Display “Enter a number” Accept num Display the value of num before change change(pass num by reference) Display the value of num after change End change(var is an integer) Start var = 10 Display the value in var return Truyền tham chiếu (ví dụ)  change(pass num by reference)  Hàm change nhận 1 tham chiếu đến num  change(var is an integer)  Biến var là 1 tham chiếu tới biến num  Lệnh ‘Display the value in var’ hiển thị giá trị của var là 10  Lệnh ‘Display the value in num after change’ cũng sẽ hiển thị giá trị 10 vì biến var là 1 tham chiếu tới biến num Phân loại theo công dụng  Tham số có hai công dụng chính:  Cung cấp các giá trị cho hàm  Lưu các kết quả tính toán  Các loại tham số:  Tham số vào: cung cấp giá trị cho hàm  Tham số ra: lưu kết quả tính toán được  Tham số vừa vào, vừa ra  Phải xác định hàm có bao nhiêu tham số vào, ra  Các tham số ra phải là tham chiếu (con trỏ)  Các tham số vào không muốn thay đổi giá trị phải là tham trị Cách viết một hàm  Xác định các thành phần của hàm:  Nội dung của hàm: • Phân chia nhiều hàm dựa theo chức năng: giúp cho nội dung được rõ ràng, giảm độ phức tạp và độ lớn của hàm • Vị trí khai báo nội dung hàm: các hàm không có nguyên mẫu phải được khai báo trước main(). Nội dung của hàm có nguyên mẫu có thể được khai báo ở bất cứ vị trí nào. Hàm và con trỏ  Nếu đối của hàm là con trỏ kiểu int (float, double, ) thì tham số thực tương ứng phải là địa chỉ của biến kiểu int (float, double, )  Địa chỉ của biến được truyền cho đối con trỏ tương ứng  Có thể được gán giá trị mới Hàm và con trỏ # include #include int a,b; void swap(int a, int b); main () /* Ham chinh */ { clrscr(); a=3; b=7; printf(“\n Truoc khi goi ham: ”) printf("A= %d ",a); printf("B= %d ",b); swap(a,b); printf("\nSau khi goi ham: A = %d B= %d \n",a,b); getch(); } void swap(int a, int b) { int temp ; temp=a; a=b; b=temp; printf("\nTrong ham swap: A= %d B= %d ",a,b); } Hàm và con trỏ # include #include int a,b; void swap(int *a, int *b); main () /* Ham chinh */ { clrscr(); a=3; b=7; printf(“\n Truoc khi goi ham: ”) printf("A= %d ",a); printf("B= %d ",b); swap(&a,&b); printf("Sau khi goi ham: A = %d B= %d \n",a,b); getch(); } void swap(int *a, int *b) { int temp ; temp=*a; *a=*b; *b=temp; printf("\nTrong ham swap A= %d B= %d \n",*a,*b); } Tóm tắt  Hàm là chương trình con, gồm các lệnh liên quan với nhau để thực thi 1 tác vụ cụ thể  Các biến có thể được truyền vào hàm  Những thay đổi giá trị trong hàm sẽ không có ý nghĩa đối với chương trình chính khi truyền bằng phương thức truyền tham trị.  Địa chỉ của biến được truyền theo phương thức truyền tham chiếu  Hàm do người sử dụng định nghĩa là các chương trình con được viết do người lập trình  Các hàm chuẩn được định nghĩa trước bởi các cộng cụ lập trình Bài tập minh họa #include #include void doi(int *a,int b); main() { int x,y; clrscr(); doi(&x,y=2); printf("%d %d",x,y); getch(); } void doi(int *a,int b) { *a=b; *a+=b++; } Bài tập minh họa #include int x=2; int swap(int x,int y); main() { int y=x=1; swap(x,y); printf("%d %d",x,y); } int swap(int x,int y) { int tam; tam=x; x=y; y=tam; } Bài tập minh họa #include #include void doi(int *a); main() { int x=0,y=1; clrscr(); while(x<=y) doi(&x); printf("%d %d",y,x); getch(); } void doi(int *a) { int tam=1; *a+=tam; tam++; } Bài tập minh họa #include int doitri(int *a); main() { int x=1,y=2; x=doitri(&x); printf("%d %d",x,y); } int doitri(int *a) { *a-=1; *a=++y; y-=2; return y; } Bài tập minh họa #include int y=2; int doitri(int *a); main() { int x=1; x=doitri(&x); printf("%d %d",x,y); } int doitri(int *a) { *a-=1; *a=++y; y-=2; return y; } Bài tập minh họa #include #include int doi(int *a,int *b); main() { int x=1,y=2; clrscr(); doi(&y,&y); printf("%d %d",x,y); getch(); } int doi(int *a,int *b) { *a-=1; *a=++(*b); *b-=2; } Bài tập minh họa #include #include void ham1(void); void ham2(int); void main() { clrscr(); ham1(); ham2(3); return; } void ham1(void) { printf("Bai tap lap trinh C\n"); } void ham2(int n) { int I; for(I=0;I<n;I++) printf(" kinh chao cac ban\n"); } Bài tập minh họa #include int a,b,c,d; void confuse(int *,int); void main() { a=1;b=2;c=3;d=4; confuse(&b,c); printf("\na=%d b=%d c=%d d=%d",a,b,c,d); confuse(&b,a); printf("\na=%d b=%d c=%d d=%d",a,b,c,d); } void confuse(int *a,int b) { int c; *a=5;b=10;c=4; printf("\na=%d b=%d c=%d d=%d",*a,b,c,d); } Bài tập minh họa #include float sohoc(float,float,char); void main() { float x,y; printf("\n x="); scanf("%f",&x); printf("\n y="); scanf("%f",&y); printf("\nTong la:%f",sohoc(x,y,'+')); printf("\nHieu la:%f",sohoc(x,y,'-')); printf("\nTich la:%f",sohoc(x,y,'*')); printf("\nThuong la:%f",sohoc(x,y,'/')); } float sohoc(float v1,float v2,char tinh) { float ketqua; switch(tinh) { case '+':ketqua=v1+v2; break; case '-':ketqua=v1-v2; break; case '*':ketqua=v1*v2; break; case '/':ketqua=v1/v2; break; } return ketqua; }