PDA

View Full Version : Những câu hỏi thường gặp



QuangTuan
10-09-2005, 05:04 PM
1. Tôi phải làm thế nào để ngăn hoặc bắt phím ngắt (break key) trong Turbo Pascal để chương trình của tôi không bị ngắt?

Có một biến CheckBreak trong unit Crt, luôn được đặt mặc định là true. Muốn tắt nó ta dùng lệnh

uses Crt;

:

CheckBreak := false;

:

Ngoài ra việc tắt kiểm tra ngắt cho phép bạn bắt phím mỗi khi phím ngắt được bấm xuống như là tổ hợp phím Ctrl-C

Cách khác bạn có thế dùng chương trình bắt phím sau:

procedure TEST;

var key : char;

begin


repeat

if KeyPressed then

begin

key := ReadKey;

if key=#3 then

begin {ctrl-c or break}

writeln ('Break');

halt(1);

end; { Terminate the program, or whatever }

end; {if}

until false;

end; (* test *)

Một cách khác, bạn có thể ngăn cấm Ctrl-Break và Ctrl-C bằng ngắt. Sau đây là một ví dụ:

uses Dos;

var OldIntr1B : pointer; { Ctrl-Break ađress }

OldIntr23 : pointer; { Ctrl-C interrupt handler }

answer : string; { For readln test }

{$F+}

procedure NewIntr1B (flags,cs,ip,ax,bx,cx,dx,si,di,ds,es,bp : word);

Interrupt;

{$F-} begin end;

{$F+}

procedure NewIntr23 (flags,cs,ip,ax,bx,cx,dx,si,di,ds,es,bp : word);

Interrupt;

{$F-} begin end;

begin

GetIntVec ($1B, OldIntr1B);

SetIntVec ($1B, @NewIntr1B); { Cấm Ctrl-Break }

GetIntVec ($23, OldIntr23);

SetIntVec ($23, @NewIntr23); { Cấm Ctrl-C }

writeln ('Try breaking, disabled');

readln (answer);

SetIntVec ($1B, OldIntr1B); { Cho phép Ctrl-Break }

SetIntVec ($23, OldIntr23); { Cho phép Ctrl-C }

writeln ('Try breaking, enabled');

readln (answer);

writeln ('Doné);

end.

2. Làm thế nào để kiểm tra xem máy in có sẵn sàng hay không?

Bạn có thể dùng ngắt 17H, với hàm dịch vụ 02H

regs.dx := PrinterNumber; (* LPT1 = 0 *)

regs.ah := $02;

Intr ($17,regs);

status := regs.ah


3. Tôi muốn viết một chương trình khi nhập vào ngày tháng năm thì sẽ in ra ngày đó là ngày thứ mấy trong tuần.

Bạn chỉ cần dùng một thuật toán đơn giản: bạn chọn một mốc thời gian, ví dụ ngày 7-9-1999 là ngày thứ Ba, sau đó bạn tính khoảng cách ngày từ mốc đến thời điểm muốn kiểm tra. Kết quả thu được bạn đem lấy số dư trong phép chia cho 7 là có thể xác định được đó là ngày thứ mấy. Tất nhiên khi tính khoảng cách ngày, bạn phải để ý đến tiêu chuẩn năm nhuận vì năm nhuận chỉ có 365 ngày.

Bạn có thể tìm một chương trình như trên tại địa chỉ ftp://garbo.uwasa.fi/pc/ts/tspa3470.zip


4.Tại sao tôi không thể đọc hay viết lên các cổng COM


Việc lập trình đối với cổng COM (thường gọi là viết chương trình truyền thông - telecommunication programs ) khó hơn rất nhiều so với việc cố sử dụng câu lệnh

write (com, whatever);

read (com, whatever);

Nó đòi hỏi các kĩ năng sử dụng ngắt, thu phát dữ liệu, các chuẩn dữ liệu. Hiện có rất nhiều tài liệu nói về vấn đề này, bạn có thể kiếm chúng tại các quầy sách với những tên như là "Lập trình truyền thông", "Lập trình cho cổng COM"...

QuangTuan
10-09-2005, 05:05 PM
1. Các ngắt là gì và sử dụng chúng như thế nào trong Turbo Pascal?

Một ngắt (interrupt) là một tín hiệu đến bộ vi xử lí (processor) từ một chương trình, một thiết bị phần cứng, hay tại bản thân bộ vi xử lí đế tạm thời dừng chương trình đang thi hành và thực hiện một chương trình con ghi sẵn trong hệ điều hành. Có 256 hàm ngắt cùng các dịch vụ khác, được đưa trong bảng ngắt. Turbo Pascal có một từ khoá đặc biệt Intr cùng với các biến registers được định nghĩa sẵn trong Unit DOS để sử dụng các hàm ngắt này.

Sau đây là một ví dụ đơn giản dùng Intr- chương trình in ra ngày tháng năm hiện tại/


uses Dos;

var

date, year, month, day: string;

regs: Registers;


begin

regs.ah := $2a;

with regs do

intr($21,regs);

with regs do

begin

str(cx ,year);

str(dh ,month);

str(dl,day);

end;

date := month+'/'+day+'/'+year;

writeln('Todaý's date is ', date);

end.


2. Làm thế nào để tôi có thể chạy một lệnh MS-DOS từ một chương trình Pascal

Cách tốt nhất để trả lời cho câu hỏi này là viết một ví dụ

{$M 2048, 0, 0} (* Rất quan trọng *)

program outside;

uses dos;

begin

write ('Lệnh dir');

SwapVectors;

Exec (GetEnv('comspec'), '/c dir *.*'); (* Execution *)

SwapVectors;

(*Kiểm tra lỗi*)

if DosError <> 0 then

writeln ('Lỗi số ', DosError)

else

writeln ('Chương trình chạy tốt ', DosExitCode);

end.


Tham số /c chỉ trong thủ tục Exec chỉ rằng đó là câu lệnh, kết thúc chứ không được ngắt


3. Làm thế nào để đặt các kí tự text thành các kí hiệu của riêng tôi?


Các kí tự text-mode không thể biến đổi được nếu bạn không có card màn hình EGA và VGA. Bảng đồ hoạ của các kí tự từ 0 đến 127 bắt đầu tại $F000 và kết thúc tại $FA6E. Phần còn lại của bảng kí tự lại là ở $007C. Bạn có thể sửa đổi tại đó.

Hơn nữa, bạn có thể dùng ngắt 11H để nạp một bộ chữ tạo sẵn vào ROM-BIOS với AL=4, BL=Khối chữ cần nạp,ES:BP địa chỉ bộ font, CX: số kí tự, DX: kí tự bắt đầu.


4. Làm thế nào để có thể tìm file trong một thư mục và các thư mục con


Trong Turbo Pascal có các thủ tục tìm kiếm, đó là FindFirst và FindNext và một cấu trúc để ghi nhận kết quả là SearchRec. Muốn tìm một file trong thư mục con, bạn có thể ghép tên thư mục tìm được (có thuộc tính DIRECTORY) vào đường dẫn tìm kiếm.

Sau đây là hai chương trình ví dụ


(*Đếm các file trong thư mục, không đếm các thư mục con*)

function DFILESFN (dirName : string) : word;

var nberOfFiles : word;

FileInfo : searchRec;

begin

if dirName[Length(dirName)] <> '' then dirName := dirName + '';

dirName := dirName + '*.*';

nberOfFiles := 0;

FindFirst (dirName, AnyFile, FileInfo);

while DosError = 0 do

begin

if ((FileInfo.Attr and VolumeId) = 0) then

if (FileInfo.Attr and Directory) = 0 then

Inc (nberOfFiles);

FindNext (FileInfo);

end; {while}

dfilesfn := nberOfFiles;

end; (* dfilesfn *)


(*Đếm các thư mục con*)

function ĐIRSFN (dirName : string) : word;

var nberOfDirs : word;

FileInfo : searchRec;

begin

if dirName[Length(dirName)] <> '' then dirName := dirName + '';

dirName := dirName + '*.*';

{}

nberOfDirs:= 0;

FindFirst (dirName, AnyFile, FileInfo);

while DosError = 0 do

begin

if ((FileInfo.Attr and VolumeId) = 0) then

if (FileInfo.Attr and Directory) > 0 then

if (FileInfo.Name <> '.') and (FileInfo.Name <> '..') then

Inc (nberOfDirs);

FindNext (FileInfo);

end; {while}

đirsfn := nberOfDirs;

end; (* đirsfn *)


Sưu tầm

QuangTuan
10-09-2005, 05:05 PM
1. Tôi cần một hàm mũ nhưng không có trong Turbo Pascal


Bạn có thể tự định nghĩa một hàm mũ với cơ số dương với số mũ bất kì như sau:


function POWERFN (number, exponent : real) : real;

begin

powerfn := Exp(exponent*Ln(number));

end;


Hoặc tổng quát hơn:


function GENPOWFN (number, exponent : real) : real;

begin

if (exponent = 0.0) then

genpowfn := 1.0

else if number = 0.0 then

genpowfn := 0.0

else if abs(exponent*Ln(abs(number))) > 87.498 then

begin writeln ('Overflow in GENPOWFN expression'); halt; end

else if number > 0.0 then

genpowfn := Exp(exponent*Ln(number))

else if (number < 0.0) and (Frac(exponent) = 0.0) then

if Ođ(Round(exponent)) then

genpowfn := -GENPOWFN (-number, exponent)

else

genpowfn := GENPOWFN (-number, exponent)

else

begin writeln ('Invalid GENPOWFN expression'); halt; end;

end; (* genpowfn *)


2. Làm thế nào để tôi có thể tạo một bảng lớn hơn 64 kilobytes


Trong Turbo Pascal không trực tiếp hỗ trợ mảng quá lớn nhưng bạn có thể giải quyết vấn đề này bằng cách dùng khéo léo con trỏ. Bạn có thể trỏ đến mỗi phần tử bởi một mảng hai chiều sử dụng â[row].col^[column].Ví dụ như sau:


const maxm = 150;

maxn = 250;

type BigVectorType = array [1..maxn] of real;

BigMatrixType = array [1..maxm] of ^BigVectorType;

var BigAPtr : BigMatrixType;


(* Tạo các biến động *)

procedure MAKEBIG;

var i : word;

heapNeeded : longint;

begin

heapNeeded := maxm * maxn * SizeOf(real) + maxm * 4 + 8196;

if (MaxAvail <= heapNeeded) then

begin writeln ('Out of memorý); halt; end;

for i := 1 to maxm do New (BigAPtr);

end; (* makebig *)


procedure TEST;

var i, j : word;

begin

for i := 1 to maxm do

for j := 1 to maxn do

BigAPtr^[j] := i * j;

writeln (BigAPtr[5]^[7] : 0:0);

writeln (BigAPtr[maxm]^[maxn] : 0:0);

end; (* test *)


BEGIN

writeln ('Chương trình kiểm tra bảng lớn');

writeln;

MAKEBIG;

TEST;

END.

Sưu tầm