Nhập môn lập trình (Pascal)
MỤC LỤC
Phần 1: Tin học cơ sở . 3
Chƣơng 1. Những khái niệm nhập môn tin học cơ sở . 3
1.1. Những khái niệm cơ bản. . 3
1.2. Hệ đếm và cách chuyển đổi giữa các hệ đếm. . 9
Chƣơng 2. Hệ điều hành Windows. 13
2.1. Một số khái niệm . 13.
2.2. Một số lệnh hay dùng nhất của Start memu . 16
2.3 Cách tổ chức và trao đổi thông tin trên DESKTOP . 18
2.4 Cách tạo Shortcut trên DESKTOP . 19
2.5. Trình ứng dụng Windows Explorer . 20
Chƣơng 3. Hệ soạn thảo văn bản Microsoft Word . 25
3.1. Khái niệm . 25
3.2. Những yếu tố đầu tiên để soạn thảo văn bản . 25
3.3. Cất, mở, đóng tệp tài liệu. . 28
3.4. Các xử lý văn bản và khối văn bản; định dạng ký tự . 29
3.5. Một số kỹ thuật tăng tốc khi soạn thảo văn bản . 32
3.6. Tạo bảng và các xử lý trong bảng. 37
3.7. Thiết lập trang và một số chức năng khác . 41
Phần 2: Ngôn ngữ lập trình Pascal. 45
Chƣơng 1. Nhập môn . 45
1.1. Những khái niệm mở đầu chung về lập trình . 45
1.1.1. Ngôn ngữ lập trình là gì? . 45
1.1.2. Chương trình là gì? . 45
1.2. Những khái niệm cơ bản về ngôn ngữ Pascal . 47
1.2.1. Bộ ký tự của PASCAL . 48
1.2.2. Từ khoá . 48
1.2.3. Tên . 49
1.2.4. Tên chuẩn . 49
1.2.5. Cấu trúc của chương trình viết trên PASCAL . 49
1.2.6. Một vài vấn đề khác . 51
1.3. Các kiểu dữ liệu đơn giản chuẩn, các hàm chuẩn . 51
1.4. Các hàm chuẩn của PASCAL. . 54
1.5. Khai báo hằng, biến, kiểu, biểu thức, câu lệnh . 55
Chƣơng 2. Các lệnh cơ bản có cấu trúc . 58
2.1. Cấu trúc tuần tự . 58
2.2. Các cấu trúc rẽ nhánh . 59
2.2.1. Lệnh IF.THEN . 59
2
2.2.2. Lệnh IF.THEN.ELSE . 60
2.2.3. Lệnh CASE.OF . 61
2.3. Các cấu trúc lặp (các câu lệnh lặp) . 62
2.3.1. Câu lệnh FOR (dạng tiến và dạng lùi) . 62
2.3.2. Câu lệnh REPEAT.UNTIL . 63
2.3.3. Câu lệnh WHILE.DO . 63
Chƣơng 3. Lập trình cấu trúc trong Pascal (Hàm - Thủ tục) 65
3.1. Thủ tục trong Pascal . 65
3.1.1. Thủ tục không có các tham số hình thức. . 65
3.1.2. Thủ tục có các tham biến hình thức . 66
3.2. Các loại biến nhớ trong lập trình cấu trúc . 67
3.2.1. Biến chung . 67
3.2.2. Biến riêng . 67
3.3. Hàm trong Pascal . 67
3.4. Hàm đệ quy . 69
Chƣơng 4. Mảng và tập hợp . 72
4.1. Mảng . 72
4.1.1. Khai báo mảng . 72
4.1.2. Một số thuật toán cơ bản trên mảng . 73
4.2. Tập hợp . 75
Chƣơng 5. Dữ liệu kiểu xâu ký tự (String) . 79
5.1. Khai báo xâu và các phép toán trên xâu . 79
5.2. Các thủ tục và hàm xử lý xâu . 80
Chƣơng 6. Dữ liệu kiểu bản ghi và tệp . 82
6.1. Bản ghi . 82
6.2. Mảng các bản ghi . 84
6.3. Tệp . 85
Chƣơng 7: Biến con trỏ . 91
7.1. Khai báo . 91
7.2. Các phép toán . 93
ải thử xem tệp có còn phần tử không (tức là đã ở cuối tệp chưa?). Hàm chuẩn EOF sẽ báo cho biết. Do vậy trước khi đọc tệp cần kiểm tra xem tệp đó đã ở cuối tệp chưa bằng câu lệnh: IF not EOF(Biến_Tệp) then READ(Biến_Tệp, X); Nếu muốn đọc tất cả các phần tử của tệp WHILE NOT EOF(Biến_Tệp) DO Begin READ (Biến_Tệp, X); .... End; Việc cuối cùng là đóng tệp lại: CLOSE(Biến_Tệp); * Tệp với các phần tử của tệp là dữ liệu có cấu trúc: Vì phần tử của tệp là cả một bản ghi nên để ghi vào tệp ta phải dùng: Write (FNS, Nguoi); chứ không thể ghi riêng rẽ từng thành phần, từng trường như: Write (FNS, Nguoi.Ten); Tệp truy nhập trực tiếp: Cách viết: SEEK (Biến_Tệp, No) trong đó No là số thứ tự của phần tử trong tệp Cần chú ý là phần tử đầu tiên của tệp được đánh số là 0; Theo thủ tục này, máy sẽ đặt vị trí con trỏ tệp đến phần tử thứ No. Sau đó ta chỉ việc dùng thủ tục Read để đọc phần tử 89 đó ra, hoặc Write để ghi giá trị mới vào. Như vậy ta có thể cập nhật một tệp một cách dễ dàng. Các thủ tục và hàm xử lý tệp của TP: * FileSize(Biến_Tệp) : Hàm cho số phần tử của tệp. Hàm nhận giá trị 0 khi tệp rỗng. * FilePos(Biến_Tệp) : Hàm cho vị trí tức thời của con trỏ tệp. Phần tử đầu tiên là số 0. * Erase(Biến_Tệp) : Thủ tục xoá file trên đĩa. * Rename(Biến_Tệp, Str) : Thủ tục thay đổi tên tệp với tên có kiểu String chứa trong biến Str. Lưu ý là tên mới không được trùng với một tên tệp nào có sẵn trong đĩa. Tệp văn bản (TEXT File) Trong Pascal có một kiểu tệp đ• được định nghĩa trước, đó là tệp văn bản được định nghĩa với từ chuẩn TEXT Ví dụ: VAR F1, F2 : TEXT; Các phần tử của tệp kiểu TEXT là các ký tự, song TEXT file khác với FILE OF Char ở chỗ tệp văn bản được tổ chức thành từng dòng với độ dài mỗi dòng khác nhau nhờ có thêm các dấu hết dòng (EndOfLine) hay dấu chấm xuống dòng. Đó là cặp ký tự điều khiển: CR(Carriage Return: Nhảy về đầu dòng, mã ASCII = 13) và LF (Line Feed : Nhảy thẳng xuống dòng tiếp theo, mã ASCII = 10). Ví dụ: Đoạn văn bản sau: Hom nay la Chu nhat 12345 Ket thuc được hiểu là máy sẽ chứa trong tệp văn bản thành một dãy như sau: Hom nay la Chu nhat CR LF 12345 CR LF Ket thuc EOF Việc đọc và ghi tệp văn bản cũng như các tệp tuần tự ở trên chỉ khác ở chỗ. Tệp văn bản không chấp nhận nhận xử lý trên các biến có cấu trúc (mảng, bản ghi, file). Tệp không định kiểu (UnTyped File) Tệp không định kiểu là một kiểu file đặc biệt, được định nghĩa ra trong TP và nó là một công cụ mạnh để bạn có thể khai thác. Đó là tệp khi định nghĩa hay khai báo ra, ta 90 không nói rõ nó chứa gì, không nói rõ bản chất của các dữ liệu được ghi trong đó. Cách viết: VAR F1 , F2 : FILE; F1 và F2 ở đây là hai tệp không định kiểu. Không như các tệp văn bản hay tệp có định kiểu, thủ tục Reset và Rewrite đối với tệp không định kiểu F1 và F2 còn có thêm một tham số nữa, đó là kích thước của Record. Ví dụ: RESET (F1, 1): có nghĩa là chuẩn bị FILE để đọc và đọ dài của Record = 1byte. Nếu chỉ ghi RESET(F1): thì máy sẽ coi độ dài Record là 128 bytes. Việc ghi và đọc đối với tệp không định kiểu còn dùng đến hai thủ tục là: BlockRead và BlockWrite. Ví dụ: BlockRead(F1 , Str, SizeOf(Str), RecordRead); Hàm SizeOf(Str) để lấy kích thước của biến Str. RecordRead để nhận biết có bao nhiêu Record đã được đọc từ đĩa ra Str. Nếu tham số này có giá trị = 0 báo rằng hết dữ liệu để đọc. Thủ tục BlockWrite(F2, Str, RecordWrite); RecordWrite là số Record thực sự cần ghi vào đĩa. 91 CHƢƠNG 7: BIẾN CON TRỎ 7.1. Khai báo Khi khai báo một biến, dù là biến đơn hay biến thuộc kiểu dữ liệu có cấu trúc mặc nhiên chúng ta đã quy định độ lớn vùng nhớ dành cho biến. Ví dụ: a: Real; biến a cần 6 byte b: aray[1..100] of Integer; biến mảng b cần 200 byte. Việc khai báo như trên thường là phỏng đoán dung lượng cần thiết chứ không thật chính xác. Để tránh lỗi chúng ta thường khai báo dôi ra gây nên lãng phí bộ nhớ. Việc xác định địa chỉ lưu trữ biến và cấp phát bộ nhớ được thực hiện khi biên dịch, nghĩa là các địa chỉ này cũng như dung lượng bộ nhớ cần cấp phát đã được cố định trước khi thực hiện các thao tác khác. Các đại lượng này không thay đổi trong suốt quá trình thực hiện chương trình, nói cách khác đây là các đại lượng tĩnh. Để tiết kiệm bộ nhớ, ngay khi chương trình đang làm việc người lập trình có thể yêu cầu cấp phát bộ nhớ cho các biến, điều này được gọi là cấp phát bộ nhớ động. Cấp phát bộnhớ động được thực hiện thông qua biến con trỏ. Kiểu con trỏ là một kiểu dữ liệu đặc biệt dùng để biểu diễn các địa chỉ. Kiểu con trỏ do người lập trình định nghĩa theo cú pháp sau: Type Tên kiểu con trỏ = ^Kiểu dữ liệu; Tên kiểu con trỏ tuân theo quy định đặt tên của Pascal, Kiểu dữ liệu của kiểu con trỏ là các kiểu dữ liệu đã định nghĩa trước trong pascal. ðể một kiểu con trỏ có thể đại diện cho một biến nào đó thì kiểu dữ liệu viết sau ký tự ^ sẽ phải giống như kiểu dữ liệu của biến đó, nói cách khác hai kiểu dữ liệu phải tương thích. Ví dụ 7.1: Khai báo kiểu con trỏ: Type Chu = string[20]; CT1 = ^Byte; CT2 = ^chu; CT3 = ^Nguoi; Nguoi = record Hoten:string[20]; Namsinh: 1900..2100; End; 92 Ví dụ trên định nghĩa ba kiểu con trỏ, riêng kiểu CT3 cách định nghĩa có vẻ hơi ngược là định nghĩa kiểu con trỏ trước, định nghĩa kiểu dữ liệu sau. Thật ra chúng ta cứ nên theo thói quen là định nghĩa kiểu dữ liệu trước rồi định nghĩa kiểu con trỏ sau, cách định nghĩa CT3 chẳng qua là muốn giới thiệu để chúng ta biết rằng Pascal cho phép làm ngược lại, tuy nhiên cần nhớ rằng nếu định nghĩa kiểu con trỏ trước thì ngay trong phần Type phải định nghĩa kiểu dữ liệu (không nhất thiết phải liền ngay sau định nghĩa kiểu con trỏ). Biến con trỏ Biến con trỏ cũng như biến mảng, biến kiểu bản ghi hay kiểu tập hợp có thể khai báo thông qua kiểu con trỏ hoặc khai báo trực tiếp. Biến con trỏ có định kiểu sẽ trỏ đến một kiểu dữ liệu cụ thể. Để thuận tiện từ nay chúng ta dùng thuật ngữ "Con trỏ" thay cho thuật ngữ " Biến con trỏ" Ví dụ 7.2: Var So: ^Integer; Sinhvien: Ct3; Hoten: Ct2; Thutu, Mahoso: ^Word; Trong ví dụ trên chúng ta đã khai báo ba con trỏ So, Thutu, Mahoso theo kiểu trực tiếp, hai con trỏ Sinhvien và Hoten khai báo thông qua kiểu đã định nghĩa trong ví dụ 7.1. Con trỏ So trỏ tới kiểu dữ liệu số nguyên, con trỏ Sinhvien trỏ tới kiểu dữ liệu bản ghi còn con trỏ Hoten trỏ tới kiểu dữ liệu chuỗi. Địa chỉ của các biến động và biến tĩnh sẽ được Pascal lưu trữ vào biến con trỏ điều này có nghĩa là biến con trỏ không dùng để lưu trữ các giá trị của biến mà là địa chỉ của biến. Dù kích thước vùng dữ liệu mà các biến con trỏ trỏ tới khác nhau thế nào thì kích thước của biến con trỏ cũng vẫn là 4 byte. Các hàm và thủ tục xử lý biến con trỏ được Pascal lưu trữ trong Unit System. Quy ước: Các biến con trỏ gọi là tương thích nếu chúng trỏ tới cùng một kiểu dữ liệu 93 7.2. Các phép toán Gán giá trị ban đầu: Giả sử ct là một biến con trỏ đã được định nghĩa, để đảm bảo rằng ct chưa trỏ đến bất kỳ một đối tượng nào, nghĩa là ct là một con trỏ rỗng chúng ta phải gán cho ct giá trị NIL ct := Nil; Gán địa chỉ của một đối tượng cho con trỏ: Giả sử ct là một con trỏ và x là một đối tượng (biến, hàm, thủ tục), có ba cách gán địa chỉ của đối tượng x cho con trỏ ct: a. ct := @x; Trong phép gán trên toán tử @ tác động trên đối tượng x sẽ gán vào con trỏ ct địa chỉ kiểu Pointer của đối tượng đó. b. ct := Addr(x); Hàm Addr() cho địa chỉ của đối tượng x, địa chỉ này thuộc kiểu Pointer c. ct := Ptr(segment,offset) ; Hàm Ptr trong phép gán trên đòi hỏi các tham số segment và offset phải là giá trị kiểu Word viết trong hệ 16, ví dụ: ct := Ptr($B800, $0000); đưa con trỏ trỏ tới ô nhớ của vùng Video Ram Nhận xét: Hai phép gán @ và Addr() cùng trả về địa chỉ kiểu pointer nên chúng là tương đương. Phép gán giữa hai con trỏ Hai con trỏ tương thích (cùng kiểu) có thể gán giá trị cho nhau, khi đó chúng cùng trỏ tới một địa chỉ. Ví dụ 7.3: Var ct1: ^Float; ct2: ^Byte; ct3: Pointer; x: string; Ví dụ trên khai báo ba con trỏ thuộc ba kiểu khác nhau, ct1 là con trỏ thực, ct2 là con trỏ nguyên và ct3 là con trỏ không định kiểu, x là biến chuỗi. Khi đó các phép gán: ct3:=@x; ct2 := ct3; là hợp lệ vì ct2 và ct3 là tương thích, chúng cùng trỏ đến địa chỉ của biến x. Còn phép gán 94 ct1 := ct2; là không hợp lệ vì hai con trỏ không tương thích. Phép so sánh hai con trỏ Chỉ tồn tại phép so sánh = (bằng nhau) và (khác nhau) giữa hai con trỏ nếu chúng tương thích. Kết quả so sánh là một giá trị Boolean nghĩa là True hoặc False. Hai con trỏ tương thích gọi là bằng nhau nếu chúng cùng trỏ tới một đối tượng, ngược lại gọi là khác nhau. Ví dụ 7.4: Program contro; Uses crt; Var x,y:real; z:string; ct1: ^integer; ct2: ^byte; ct3:pointer; ct4,ct5: ^real; Begin clrscr; z:='Ha noi'; x:=5; y:=-123.45; ct1:=@x; ct2:=@z; ct3:=@z; ct4:=@z; ct5:=@y; Writeln(ct1=ct2); { không tương thích, máy sẽ báo lỗi} Writeln(ct1=ct3); {false} Writeln(ct2=ct3); {true} writeln(ct4=ct5); {false} readln; end. Ví dụ 7.4 khai báo năm con trỏ, ct1 và ct2 trỏ tới các kiểu nguyên khác nhau, ct3 là con trỏ không kiểu tức là tương thích với mọi con trỏ khác, hai con trỏ ct4 và ct5 là cùng kiểu. Các phép so sánh trong thân chương trình cho thấy một số điều cần chú ý : - Phép so sánh ct1=ct2 là không hợp lệ vì hai con trỏ không tương thích - Phép so sánh ct1 = ct3 cho kết quả False vì hai con trỏ tương thích nhưng trỏ tới các địa chỉ khác nhau - Phép so sánh ct2 = ct3 cho kết quả True vì hai con trỏ là tương thích và cùng trỏ tới một địa chỉ. - Phép so sánh ct4 = ct5 cho kết quả False vì hai con trỏ cùng kiểu nhưng trỏ tới các địa chỉ khác nhau.
File đính kèm:
- Nhập môn lập trình (Pascal).pdf