Bài giảng Tin học - Chương Trình Con (CTC)
Bạn đang đọc bài của Nguyễn Minh Ngọc – Lớp 11 Toán – THPT Sơn Tây về CHƯƠNG TRÌNH CON. Chuyên đề này được chia làm phần:
• Khái niệm và phân loại CTC, cách dùng các loại CTC, các loại biến trong CTC cũng như sự khác nhau giữa chúng
• Cách dùng tham số và cấp phát bộ nhớ cho CTC
• CTC đệ quy, thiết kế giao diệm Menu, Phương pháp Top-Down và một số bài tập
Mọi thắc mắc, đóng góp cin liên hệ theo địa chỉ:
mo_thi_ta_ngoc@yahoo.com
{không tương thích kiểu}27Các cách truyền tham số: Truyền theo trị Truyền theo biến Phân loại các cách truyền tham số:28Truyền theo trị Việc truyền theo trị được thực hiện qua bản sao. Giá trị bên ngoài được chép vào 1 vùng nhớ được cấp phát tương ứng với kích thước tham số.CTC sẽ làm việc với dữ liệu chứa trong bản sao 29Truyền theo trị Việc truyền theo trị được thực hiện qua bản sao. Nếu trong CTC có những lệnh làm thay đổi giá trị của tham số hình thức thì những thay đổi này không có ảnh hưởng gì đến giá trị của biến được truyền ở đầu vào vì những thay đổi này chỉ được thực hiện trên bản sao tương ứng.Tốn 1 ít bộ nhớ và thời gian cho việc sao chépCho phép giá trị ở đầu vào có thể là những giá trị của hằng, biến, hàm hoặc biểu thức. Nếu đầu vào truyền hàm hoặc biểu thức thì những giá trị này được tính trước khi truyền cho tham số. Giá trị bên ngoài được chép vào 1 vùng nhớ được cấp phát tương ứng với kích thước tham sốĐặc điểm:30Truyền theo biến Nếu trong CTC có những lệnh làm thay đổi giá trị của tham số hình thức thì những thay đổi này cũng chính là những thay đổi trên biến được truyểnKhông tốn thêm bộ nhớ và thời gian do không phải sao chépChỉ cho phép đầu vào là giá trị của biếnViệc truyền tham số theo biến được thực hiện vào chính địa chỉ của biến được truyềnĐặc điểm:31Khai báo * Truyền theo trị:Tên tham số: kiểu tham số* Truyền theo biến:VAR Tên tham số: kiểu tham số32 Việc truyền theo trị hay truyền theo biến nhiều khi dẫn đến những kết quả logic khác nhau. Sự khác nhau này được gọi là hiệu ứng lề.Hiệu ứng lề 33Ví dụ:Program vidu;VAR a: integer;Function F(var x: integer): integer;Begin x:= x+1; F:= x;End;BEGIN a:= 5; writeln(F(a)+F(a)); readln;END.34Một sự thật mà khó có thể giải thích được đối với những người mới làm quen với lập trình. Kết quả sẽ là 13 mà không phải là 12. Lí do là ở đây đã xuất hiện hiệu ứng lề. Do hàm F được tổ chức truyền theo biến đối với đối số x của nó. Lệnh x:= x+1 trong hàm F sẽ làm biến a tăng thêm 1 đơn vị mỗi khi gọi F(a). Khi thực hiện biểu thức F(a)+F(a), giá trị F(a) được gọi 2 lần. Tại lần thứ nhất a = 5, do đó F(a) = 6, tại lần thứ hai a = 6 do đó F(a)= 7 và ta nhận được kết quả là 13.Bạn thư nhận đoán xem kết quả của chương trình trên đưa lại là bao nhiêu?Ví dụ:35Để sửa lại chương trình cho đúng ý muốn ban đầu, ta có 2 cách sửa: Sửa biểu thức F(a)+F(a) thành 2*F(a)Sửa lại việc truyền cho đối số x của hàm F là theo trị Ví dụ:36Một số chương trình lỗi hay mắc phải do cách truyền tham số không đúng:Program Vidu;Var x,y: integer;Procedure Chuyen_doi(x, y: integer);Var t: integer;Begin t:=x; x:=y; y:=t;End;BEGIN x:=1; y:=2; Chuyen_doi(x,y): Writeln(‘x=’,x,’y=’,y); ReadlnEND.37Một số chương trình lỗi hay mắc phải do cách truyền tham số không đúng: Lỗi ở chương trình này là thủ tục Chuyen_doi(x,y) tổ chức tuyền theo trị nên các giá trị của biến x, y không bị ảnh hưởng bởi câu lệnh đổi giá trị trong thủ tục này. Cách sửa: Thêm từ khóa VAR trước tên tham số x, y38Một số chương trình lỗi hay mắc phải do cách truyền tham số không đúng:Program Vidu;Var tu, mau, d: integer;Function UCLN(var a,b: integer): integer;Begin While a b do If a>b then a:=a-b else b:=b-a; UCLN:= a;End;BEGIN Writeln(‘nhap tu so va mau thuc cua phan so:); Readln(tu, mau); d:=UCLN(tu,mau); writeln(‘Dang toi gian cua phan so da cho la: ’,tu/d, ‘/’,mau/d); readln;END.39Một số chương trình lỗi hay mắc phải do cách truyền tham số không đúng:Chương trình trên luôn cho kết quả là 1/1.Lỗi: do hàm UCLN được truyền theo biến, nên sau lời gọi d:=UCLN(tu, mau) ta được đồng thời các giá trị tu, mau đều bằng nhauSửa: bỏ từ khóa VAR trước tên a,b40Truyền theo trị hay truyền theo biến? Nếu trong thân CTC có những lệnh làm thay đổi giá trị tham số hình thức thì việc truyền theo biến hay truyền theo trị không gây ra 1 sự khác biệt nào về kết quả mà chương tình con trả lạiTrong các trường hợp việc truyền theo biến hay truyền theo trị không ảnh hưởng đến kết quả logic của chương trình thì người ta thường chọn cách truyền theo trị cho các tham số thuộc kiểu chuẩn như integer, char, boolean, real, còn các tham số thuộc kiểu phức hợp như mảng, bảng ghi, thì truyền theo biến. Riêng tham số kiểu File hoặc tham số không định kiểu thì luôn phải tổ chức truyền theo biến41Truyền theo trị hay truyền theo biến? Trong các trường hợp việc truyền theo biến hay truyền theo trị không ảnh hưởng Khi CTC có những lệnh làm thay đổi giá trị tham số hình thức thì phải truyền vào nhiệm vụ của CTC đối với tham số mà quyết định cách truyền: Nếu CTC có nhiệm vụ phải thay đổi giá trị tham số thực thì phải tổ chức truyền theo biến cho tham số này Nếu tham số thực sự được dùng để gửi giá trị ở đầu vào cho CTC hoạt động mà không được làm hỏng giá trị này sau khi gọi CTC thì phải tổ chức truyền theo trị cho tham số này. Nếu kết quả logic của chương trình thì người ta thường chọn cách truyền theo trị cho các tham số thuộc kiểu chuẩn như integer, char, boolean, real, còn các tham số thuộc kiểu phức hợp như mang, bảng ghi, thì truyền theo biến. Riêng tham số kiểu File hoặc tham số không địh kiểu thì luôn phải tổ chức truyền theo biến42Cấp phát bộ nhớ cho ctc Việc cấp phát bộ nhớ cho các biến trong CTC (biến địa phương) được thực hiện trong vùng stack (ngăn xếp), trong khi việc cấp phát cho các biến trong chương trình chính (biến toàn cục) được thực hiện trong vùng nhớ data (dữ liệu).Trong quá trình chạy chương trình, mỗi khi gọi CTC, các biến của nó sẽ được cấp phát cho đến khi CTC kết thúc, các biến này lại tự động giải phóng.Vùng cấp phát cho CTC được gọi ở mức trong cùng sẽ giải phóng đầu tiên (vào sau ra trước)43Cấp phát bộ nhớ cho ctc Do vậy, các biến của CTC độc lập với các biến của chương trình chính, các biến của CTC này độc lập với các biến của CTC khác cho dù nó cùng tên.Nếu khai báo quá nhiều biến địa phương trong CTC thì khi gọi CTC này có thể bị lỗi tràn stack (stack overflow)Hiện nay, Turbo Pascal 7.0 ngầm định dành sẵn 16Kb cho vùng stackCách tăng gái trị StackSize: Dùng định hướng biên dịch {M StackSize, HeapMin, HeapMax} Vào Options/MemorySize của môi trường Turbo Pascal để đặt lại giá trị cho kích thước stack44Chương trình con đệ quy Khái niệm: CTC đệ quy là CTC trong khi đang xây dựng lại được gọi chính nó. Một CTC con đệ quy cũng tương tự như một bài toán được chứng minh bằng phương pháp quy nạp.45ví dụ Bài toán: Tính n!Thuật toán giải:Cách 1: n! = 1.2.3. .(n-1).nCách 2: (Tính theo phương pháp đệ quy) 1! = 1 n! = (n-1)!.n46Tính n!Cách 1: Function Giaithua(n: integer):LongInt;Var i: integer; p: LongInt;Begin p:=1; for i:=1 to n do p:=p*i; Giaithua:=p;End;47Tính n!Cách 2: Function Giaithua(n: integer):LongInt;Begin if n 0 then begin chuyen_dia(n-1, a, c, b); writeln(a, ‘-->’, b); chuyen_dia(n-1, c, b, a); end;End;52Chú ý: Khi thiết kế đệ quy, phải đảm bảo điều kiện điểm dừng. Nếu quên điều này thì lời gọi chương trình đệ quy không kết thúc và sẽ gây ra lỗi tràn stack. Để khắc phục việc tràn stack khi dùng đệ quy, bạn cần thực hiện một số kỹ thuật sau:Đảm bảo sự có mặt điểm dừng trong thân CTC đệ quyGiảm tối đa các biến riêng cũng như các tham trị của CTC đệ quy, đặc biệt đối với những biến kích thước lớn như bảng ghi, mảngTăng kích thước stack mà hệ thống dành cho chương trình53Thiết kế giao diện menu Chương trình dưới đây, tôi muốn giúp các bạn tạo một cái khung cho một chương trình có dạng Menu, song xin lưu ý đây chỉ là cái khung để các bạn dựa vào và thiết kế chứ không phải là một Menu hoàn chỉnh: Menu gồm có: Menu chính Mục 1 Mục 2 Trợ giúp Thoát54Thiết kế giao diện menuProgram Menu;Ues CRT;Funtion Menu: char;Begin ClrScr; writeln(‘Menu chinh’); writeln(‘=========’); writeln(‘1. Muc 1’); writlen(‘2. Muc 2’); writeln(‘3. Tro giup’); writeln(‘4. Thoat’); writeln; writeln(‘Nhap mot lua chon.’); Repeat menu:= readkey; Until Menu in [‘1’..’4’];End;55Thiết kế giao diện menuProcedure Muc1;Begin ClrScr; writeln(‘Day la Muc 1’); writeln(‘An ENTER de ve Menu chinh’); readln;End;Procedure Muc2;Begin ClrScr; writeln(‘Day la Muc 2’); writeln(‘An ENTER de ve Menu chinh’); readln;End;56Thiết kế giao diện menuProcedure Trogiup;Begin ClrScr; writeln(‘Day la Tro giup’); writeln(‘An ENTER de ve Menu chinh’); readln;End;BEGIN Repeat case Menu of ‘1’: Muc1; ‘2’: Muc2; ‘3’: Trogiup; ‘4’: Halt; End; until false;END.57Phương pháp top – downKhái niệm: Phương pháp lập trình Top-Down là phương pháp lập trình từ tổng thể đến chi tiết, cho phép phân rã một công việc phức tạp thành nhiều công việc đơn giản hơn.Phương pháp Top-Down là phương pháp cơ bản hiện nay trong lập trình cấu trúc. Nhờ phương pháp này, việc lập trình mang tính công nghệ cao, cho phép xây dựng các chương trình lớn, nhiều người tham gia, thuận tiện cho việc bảo trì và mở rộng58Phương pháp top – downVí dụ: Trên mặt phẳng, xét 1 số dãy các đoạn thẳng, mỗi đoạn được xác định bởi 2 điểm dầu mút cảu chúng. Mỗi điểm trên mặt phẳng được xác định các lớp đồng phương của dãy đoạn đã cho. Lập trình giải bài toán nêu trên, dữ liệu nhập từ bàn phím, trong đó lần lượt từng đoạn thẳng được nhập các tọa độ cảu các điểm đầu mút. Kết quả đưa ra màn hình số lớp đồng phương và với mỗi lớp cần chỉ ra số hiệu các đoạn thuộc lớp đó. Các đoạn thẳng được đánh số từ 1, theo thứ tự nhập59Phương pháp top – downProgram Vidu;Type Kieudiem = record x, y:real; end; Kieudoan = record A, B: Kieudiem; end;Var n, m: integer; Doan: array[1..50]of Kieudiem; Sohieu:array[1..50]og integer;60Phương pháp top – downProcedure Nhap;Var i: integer;Begin writeln(‘Nhap so doan thang:’); readln(n); for i:= 1 to n do begin writeln(‘Vao toa do doan ’, i); with Doan[i] do begin writeln(‘Toa do dau mut thu nhat’); readln(A.x,A.y); writeln(‘Toa do dau mut thu nhat’); readln(B.x,B.y); end; end;End;61Phương pháp top – downFunction Dongphuong(i,j: integer):boolean;Begin Dongphuong:= ABS ((Doan[i].B.x-Doan[i].A.x)* (Doan[j].B.y-Doan[j].A.y)-(Doan[i].B.y-Doan[i].A.y)*(Doan[j].B.x-Doan[j].A.x) 0 then vitri:=1 else if f 0 do begin chu:= n mod 10; t:= t + chu; n:= n div 10; end; sumdigit:=t;End; 73
File đính kèm:
- hoc roi thay yeu tin hoc lien.ppt