Bài đọc thêm 2: Ngôn ngữ Pascal

Chia sẻ bởi Tú Tini | Ngày 10/05/2019 | 137

Chia sẻ tài liệu: Bài đọc thêm 2: Ngôn ngữ Pascal thuộc Tin học 11

Nội dung tài liệu:

Lê Minh Hoàng
Nội dung bài học
Cách giao tiếp với máy tính bằng “ngôn ngữ”
Quá trình phát triển của ngôn ngữ lập trình
Ngôn ngữ bậc cao
Trình dịch
Một chương trình viết bằng ngôn ngữ bậc cao được xử lý như thế nào?
Thuật toán là gì?, Kỹ thuật giải quyết các bài toán tin học như thế nào?

Kiến trúc máy tính
Bộ tính toán số học và logic
ALU: Arithmetic-Logic Unit
Bộ điều khiển
CU: Control Unit
Những t/p khác: Bộ đồng xử lý toán học, bộ tăng tốc đồ họa và video…
Bộ nhớ trong
(Main Memory)
Secondary Storage
Thiết bị vào
(Input Device)
Thiết bị ra
(Output Device)
Mô hình xử lý thông tin
Storage
Input: Bàn phím (Keyboard), Con chuột (Mouse), Máy quét (Scanner), …
Processing: Máy tính thực hiện chương trình.
Output: Màn hình (Monitor), Máy in (Printer), Máy Fax …
Storage: Đĩa cứng (Hard Disks), Đĩa mềm (Floppy Disks), Băng từ (Magnetic tape)…
Minh họa một hệ thống máy tính
Scanner
Phần cứng và Phần mềm
Phần cứng (Hardware)
Xử lý dữ liệu bằng cách tiến hành các lệnh theo chỉ thị.
Cung cấp đầu vào (Input) và đầu ra (Output) qua các cổng giao tiếp thiết bị ngoại vi.
Phần mềm
Chứa các chỉ thị lệnh giao cho phần cứng thực hiện.
Là chương trình được viết để thực hiện một nhiệm vụ cụ thể nào đó.
Phần mềm hệ thống (System Programs): Là chương trình viết ra để điều khiển máy tính, các thiết bị nối với máy tính, các chương trình khác chạy trên máy tính. Ví dụ: Hệ điều hành Windows, Linux, Mac OS.
Phần mềm ứng dụng (Application Programs): Là chương trình viết ra để thực hiện một tác vụ chuyên biệt nào đó. Ví dụ: Phần mềm soạn thảo văn bản MS Office, Phần mềm gõ tiếng Việt Unikey v.v…
Ngôn ngữ của máy tính
Nhắc lại:
Phần cứng tiến hành các lệnh theo chỉ thị
Phần mềm cung cấp các chỉ thị cho phần cứng thực hiện
Vậy chỉ thị là?
Ngôn ngữ của máy tính
Chỉ thị được biểu diễn bằng một dãy các số 0 và 1. VD 100010011101.
Cách mã hóa chỉ thị dưới dạng số nhị phân gọi là ngôn ngữ máy
Số 0 và 1 được gọi là chữ số nhị phân (Binary Digit hoặc bit)
Một dãy số nhị phân được gọi là mã nhị phân (Binary Code)
Ví dụ về ngôn ngữ máy
Ví dụ
Độ dài quãng đường = Vận tốc x Thời gian
Cho biết vận tốc = 15 (km/h)
Thời gian = 6 (h)
Tính độ dài quãng đường
Giả sử
1001 chỉ thị máy tính đọc giá trị ở 4 bit tiếp theo.
1011 chỉ thị máy tính nhân giá trị đang có với giá trị ở 4 bit tiếp theo và nhớ lại giá trị kết quả
1000 chỉ thị máy tính cho biết kết quả đang nhớ
Lệnh
1001 1111
1011 0110
1000
Hợp ngữ (Assembly language)
Đặc điểm
Dùng lệnh hợp ngữ thay vì viết mã nhị phân của từng chỉ thị.
Có một chương trình (Assembler) dịch lệnh hợp ngữ ra ngôn ngữ máy.
Cho phép dùng biến số, chấp nhận biểu diễn thập phân và thập lục phân của số nguyên.
Ví dụ
Viết LOAD thay cho 1001, MULT thay cho 1011, STOR thay cho 1000.
Chương trình trở thành
LOAD 15
MULT 6
STOR
Chương trình dễ đọc và khó bị lỗi hơn ngôn ngữ máy
Ngôn ngữ bậc cao (High level languages)
Ngôn ngữ bậc cao: Basic, FORTRAN, COBOL, Pascal, C, Object Pascal, C++…
Để tính quãng đường (L) cho biết vận tốc (V) và thời gian (T), có thể viết lệnh trong ngôn ngữ Pascal: L := V * T
Trình dịch: Là chương trình dịch các lệnh viết trong ngôn ngữ bậc cao thành những chỉ thị tương đương trong ngôn ngữ máy.
Quy trình xử lý chương trình
Một chương trình viết bằng ngôn ngữ bậc cao cần qua nhiều bước xử lý:
Dùng một (chương) trình soạn thảo (Editor) để soạn các lệnh trong ngôn ngữ bậc cao. Chương trình viết ra gọi là mã nguồn (Source code)
Dùng một trình dịch (Compiler) để kiểm tra lỗi cú pháp và dịch các lệnh viết trong mã nguồn ra ngôn ngữ máy. Chương trình dịch ra từ mã nguồn gọi là mã đối tượng (Object code)
Trình dịch thường đi kèm với một hoặc nhiều thư viện (Library) chứa các đoạn mã hữu dụng đã được dịch sẵn dùng để phát triển phần mềm. Nếu mã nguồn sử dụng chúng, trình liên kết (Linker) sẽ tích hợp những mã viết sẵn trong thư viện vào mã đối tượng tạo thành mã khả thi (Executable Code)
Mã khả thi có thể được nạp trực tiếp vào bộ nhớ và chạy độc lập, không phụ thuộc vào Editor, Compiler hay Linker nữa.

Quy trình xử lý chương trình (tiếp)
Source Code
Object Code
Libraries
Executable Code
Quy trình phát triển phần mềm
Lỗi
Không lỗi
Lỗi
Không lỗi
Thiết kế từ trên xuống
(Top-down design)
Tinh chỉnh từng bước
(Step-wise refinement)
Tách biệt từng phần
(Modular programming)
Lê Minh Hoàng
Nội dung bài học
Những khái niệm cơ bản về lập trình
Lịch sử ngôn ngữ lập trình Pascal
Xuất phát từ ALGOL
Trở thành chuẩn mực lập trình
Bị thay thế bởi C++
Sống lại bằng Object Pascal và Delphi
Cuộc chiến giữa Delphi và Visual C#
Làm quen với trình dịch Free Pascal
Giao diện
Hệ thống Menu
Các phím soạn thảo
Các phím tắt (Shortcut)
Lập trình
Một chương trình máy tính là một tập hợp các dòng lệnh (statements) để chỉ thị cho máy tính thực hiện một nhiệm vụ nào đó
Lập trình: Là quá trình viết các lệnh một cách có mục đích, có kế hoạch để tạo ra chương trình
Công thức nấu ăn:
Nấu ăn theo công thức thì dễ hơn tạo ra một công thức nấu ăn mới
Có những công thức tốt và có những công thức tồi
Có những công thức dễ dàng làm theo và có những công thức không dễ.
Có những công thức tạo ra món ăn ngon và có những công thức tạo ra những thứ không ăn được
Người đầu bếp phải có kiến thức về sử dụng dụng cụ nấu ăn để làm theo công thức
Lập trình cũng giống như vậy…
Lập trình (tiếp)
Để viết một chương trình, chúng ta phải học các ký hiệu, các từ, và các luật cú pháp của ngôn ngữ lập trình.
Luật cú pháp cho biết cách viết dòng lệnh nào là hợp lệ (được chấp nhận bởi ngôn ngữ lập trình), cách viết nào là sai.
Ngôn ngữ lập trình: Là một tập các luật cú pháp, ký hiệu, và từ khoá.
Luật ngữ nghĩa: Các luật cú pháp, từ khoá trong ngôn ngữ lập trình bậc cao thường gợi nhớ nghĩa của dòng lệnh bằng tiếng Anh.
and: và
or: hoặc
If x > 0 then : Nếu x là số dương thì làm
while a > b do : Thực hiện chừng nào vẫn thấy a > b
Pascal Programming Language
Ngôn ngữ lập trình Pascal được đặt tên theo tên nhà toán học Pháp Blaise Pascal
Đặc điểm
Dễ học
Thích hợp để mô phỏng thuật toán
Viết chương trình dễ
Chương trình chạy nhanh
Định kiểu mạnh mẽ và luật cú pháp chặt chẽ. Hạn chế lập trình viên viết những đoạn mã tồi
Blaise Pascal
1623-1662
Lịch sử: Nguồn gốc
ALGOL
Ngôn ngữ được phát kiến dành cho tính toán khoa học
Kỳ vọng: Ngôn ngữ độc lập với phần cứng và hệ điều hành
Thất vọng: Quá khó để viết ra một trình dịch ALGOL với điều kiện lúc đó.
Hạn chế: Thiếu trình dịch + Thiếu rất nhiều kiểu dữ liệu cơ bản (như kiểu ký tự) và con trỏ
Giới khoa học và lập trình viên chuyển sang sử dụng FORTRAN…
ALGOL không và không bao giờ được chấp nhận rộng rãi và chỉ còn là ngôn ngữ để…mô tả thuật toán.
Lịch sử: Pascal ra đời
Wirth phát minh PASCAL
Vào những năm 1960s, một vài nhà khoa học máy tính vẫn cố gắng mở rộng ALGOL. Trong số đó có Wirth (Swiss Federal Institute of Technology)
1971: Wirth đưa ra đặc tả về một ngôn ngữ có cấu trúc chặt chẽ và đặt tên là PASCAL (Tên nhà toán học thế kỷ 17, người phát minh ra máy tính đầu tiên…
Quan trọng hơn cả: Wirth viết luôn trình dịch PASCAL. Một trình dịch độc lập phần cứng và hệ điều hành để dịch chương trình PASCAL ra mã đối tượng. Khi chạy trên các máy tính và hệ điều hành khác nhau, chỉ cần một chương trình nhỏ chuyển mã đối tượng thành mã khả thi. (Xem lại các khái niệm mã đối tượng và mã khả thi ở đây).
Đặc tính của PASCAL
Hướng tới dữ liệu, định kiểu mạnh mẽ.
Cho phép người dùng tự định nghĩa những kiểu dữ liệu mới.
Đọc chương trình rất giống với ngôn ngữ tự nhiên (Tiếng Anh).
Chương trình PASCAL rất dễ hiểu.
Lịch sử: Pascal trở thành chuẩn
Đầu những năm 1980s, Pascal được sử dụng rộng rãi. Có 2 lý do:
Cơ quan kiểm tra giáo dục Mỹ quyết định đưa Khoa học máy tính (Computer Science) vào nội dung thi, và ngôn ngữ lập trình được sử dụng là Pascal. (Pascal trở thành ngôn ngữ chính thức tới năm 1999, sau đó chuyển sang C++ 2 năm, và hiện tại là Java)
Một công ty là Borland International đưa ra thị trường Turbo Pascal (TP) - một phần mềm dịch tích hợp Pascal. TP là một cuộc cách mạng:
TP có thay đổi một số thành phần trong Pascal chuẩn, làm cho ngôn ngữ tiện dụng hơn.
Tốc độ tuyệt vời: Trên những máy tính chậm hơn khoảng 1000 lần máy tính hiện nay, TP có thể dịch vài ngàn dòng lệnh trong 1 phút.
Pascal+TP trở thành chuẩn
PC Magazine sử dụng Pascal cùng với hợp ngữ để đăng các đoạn mã nguồn.
Từ phiên bản 1.0 tới phiên bản 7.0. Borland liên tục mở rộng ngôn ngữ Pascal. Phiên bản 7.0 là phiên bản mạnh và ổn định nhất.
Nói thêm: Người thiết kế TP là Anders Hejlsberg, chính là người thiết kế hai công cụ phát triển nổi tiếng nhất hiện nay: Visual C# và Delphi.
Lịch sử: Thế giới thay đổi
Những năm 1970s
Dennis Ritchie và Brian Kernighan tại công ty AT&T và phòng thí nghiệm Bell sáng tạo ngôn ngữ C - ngôn ngữ chính để phát triển hệ điều hành UNIX.
AT&T sau đó không thấy có thị trường cho nghiên cứu hệ điều hành, lấy UNIX cho không các trường đại học với đầy đủ mã nguồn. Với giá = 0, UNIX được chấp nhận rộng rãi trong các trường đại học để các sinh viên học kiến trúc hệ điều hành…
Để hiểu kiến trúc UNIX, phải học C để đọc mã nguồn UNIX. C tiến những bước chậm và chắc vào thế giới lập trình. Nhưng so với C, Pascal vẫn là #1…
Pascal chính thức bị thay thế bởi C++
Tư duy lập trình thay đổi: Từ lập trình hướng cấu trúc (Structure-Oriented Programming) sang hướng đối tượng (Object-Oriented Programming)
Vào đầu những năm 1980s, Bjarne Stroustrop tại phòng thí nghiệm Bell tích hợp những đặc tả cho lập trình hướng đối tượng vào ngôn ngữ C, tạo ra ngôn ngữ C++
Tất cả lập trình viên đều nhận ra nhiều ưu điểm của lập trình OOP so với lập trình cấu trúc, trong khi đó Pascal ra đời khi OOP chưa phổ biến…
TP chấm dứt phát triển: Borland tuyên bố “Sẽ không có Borland (Turbo) Pascal 8 mà thay vào đó sẽ là Delphi”.
Lịch sử: Object Pascal vs. C#
Nhược điểm của ngôn ngữ C++
Quá nhiều ký hiệu, chương trình C++ khác biệt rất nhiều ngôn ngữ tự nhiên nên khó đọc
Quá dễ dãi, C++ định kiểu yếu, chú trọng việc đưa ra những cú pháp tắt. Điều này làm chương trình C++ ngắn bằng khoảng 60% so với Pascal, nhưng lại không hạn chế được lập trình viên viết những mã nguy hiểm hoặc dễ gây nhầm lẫn.
Cơ quan kiểm tra giáo dục Mỹ khi đưa C++ vào các trường học đã phải bỏ bớt hoặc sửa đổi một số đặc điểm của C++ được coi là “nguy hiểm” đối với sinh viên - những người mới học lập trình.
Đối lập với nhược điểm này của C++ lại là đặc tính dễ hiểu, chặt chẽ, định kiểu mạnh của Pascal…
Thế hệ ngôn ngữ mới
Những người phát triển Pascal: Pascal chỉ kém C++ ở phần lập trình hướng đối tượng  Mượn tất cả đặc tả hướng đối tượng trong C++ đưa vào Pascal tạo ra ngôn ngữ mới Object Pascal.
Những người phát triển C++: C++ kém Pascal chủ yếu do tính dễ dãi và khó hiểu  Hạn chế bớt một số tính năng nguy hiểm của C++, tăng cường hệ thống báo lỗi, C# ra đời.
Lịch sử: Delphi vs. Visual C#
Hai môi trường phát triển phần mềm dựa trên Object Pascal và C#. Cả hai đều chạy trên MS Windows và .NET FrameWork.
Borland Delphi của Borland (Nay đổi tên CodeGear Delphi) dựa trên Object Pascal.
Visual C# của Microsoft dựa trên C#.
So sánh
Lập trình viên: Cái gì mình đang dùng là #1
Người đã dùng cả hai: Khó có thể chỉ ra sự khác biệt lớn cả về tính năng và tốc độ phần mềm được viết ra, chỉ khác nhau về ngôn ngữ (như English và Français)
Ý kiến cá nhân:
Delphi hay hơn Visual C# ở tính dễ học và chương trình dễ đọc, thiết kế phần mềm nhanh, dịch nhanh, hệ thống gỡ rối mạnh.
Visual C# ưu điểm hơn Delphi ở tính phổ biến và giá cả, được hỗ trợ bởi Microsoft. (CodeGear RAD Studio: $3274; Microsoft Visual Studio: $799)
So, Why learn Pascal?
C and C++ are very symbolic languages…
{…} vs. begin…end
and very dangerous for students…
Type-casting and pointer arithmetic is common, making it easy to crash programs and write in buffer overruns.
Another reason: Speed
Instead of several hours design graphic user interface in C++.
We can do 10 minutes in Delphi
The last reason:
Pascal was well-suited for teaching programming
Less overhead and fewer ways for students to get program into trouble.
Pascal is an official language of IOI
Answer in one sentence
Because it’s not scary like C, not dangerous like C++, and not abstract like Java.
Free Pascal
Delphi is too complex and too expensive for students…
Open-source community created a project named Free Pascal Compiler.
FPC is Delphi compatible
Can be used in many platforms: Windows, Unix, Linux, Mac…
Lack of many Delphi powerful tools, but enough for learning Object Pascal.
Some issues of instability.
Giao diện của FPC
IDE
Integrated Development
Environment
Menu
Window
Shortcut keys
Hệ thống Menu: File
File: Các chức năng thao tác tệp và đĩa
New: Mở một cửa sổ soạn thảo chương trình
New from template: Tạo ra một cửa sổ soạn thảo chương trình mới với một số đoạn mã đã được viết sẵn theo khuôn mẫu.
Open (F3): Mở chương trình nguồn đã soạn trên đĩa
Save (F2): Ghi mã nguồn đang soạn trong cửa sổ hiện hành vào một tệp trên đĩa
Save as: Ghi mã nguồn đang soạn trong cửa sổ hiện hành vào một tệp trên đĩa với một tên khác hoặc vào thư mục khác
Change Dir: Thay đổi thư mục hoạt động
Command Shell: Thoát khỏi FP tạm thời, mở cửa sổ Command-Line. Khi cần quay về FP, gõ vào exit
Exit (Alt+X): Thoát khỏi FP.
Hệ thống Menu: Edit
Edit: Các chức năng soạn thảo
Undo (Alt+Backspace): Phục hồi lại văn bản từ trạng thái trước thao tác soạn thảo gần nhất. (VD: dùng để phục hồi lại dòng lệnh vừa bị xoá)
Redo: Ngược lại với Undo, phục hồi lại văn bản trước thao tác Undo gần nhất
Cut (Shift+Delete): Cắt phần văn bản đã đánh dấu vào một vùng đệm gọi là clipboard, phần văn bản sau khi cắt sẽ mất. Cách đánh dấu đoạn văn bản: Giữ Shift và dùng các phím di chuyển con trỏ để đánh dấu.
Copy (Ctrl+Insert): Chép phần văn bản đã đánh dấu vào clipboard, phần văn bản sau khi chép vẫn giữ nguyên.
Paste (Shift+Insert): Dán phần văn bản đang có trong clipboard ra vị trí hiện thời của con trỏ.
Clear (Ctrl+Delete): Xoá bỏ phần văn bản đã đánh dấu
Select All: Đánh dấu toàn bộ văn bản
Unselect: Bỏ đánh dấu phần văn bản đang bị đánh dấu
Show clipboard: Hiện nội dung của clipboard. Clipboard chỉ lưu trữ nội dung của thao tác Cut hay Copy gần nhất.
Copy to Windows và Paste from Windows: Tương tự như Copy/Paste, nhưng dùng clipboard của Windows. Dùng để chép/dán đoạn văn bản đã đánh dấu ra/từ phần mềm khác (VD: MS Word).
Hệ thống Menu: Run
Run: Các chức năng chạy chương trình
Run (Ctrl+F9): Chạy chương trình
Step over (F8): Chạy chương trình ở chế độ gỡ rối, chạy từng dòng rồi dừng lại, hiện một dải xanh ở dòng kế tiếp (sắp chạy tới).
Trace into (F7): Tương tự như Step over, nhưng nếu dòng lệnh là một lời gọi chương trình con, FP sẽ thực hiện việc nhảy tới mã lệnh chương trình con để tiếp tục gỡ rối.
Goto Cursor (F4): Chạy ở chế độ gỡ rối, chạy tới dòng chứa con trỏ thì dừng lại.
Until return (Alt+F4): Khi đang gỡ rối một chương trình con, chức năng này cho chạy tiếp tới khi chương trình con thoát ra thì dừng lại để tiếp tục gỡ rối
Run Directory…: Chọn thư mục hoạt động
Parameters…: Giả lập các tham số dòng lệnh cho chương trình, để chương trình hoạt động như chạy trực tiếp file . EXE với tham số dòng lệnh
Program reset (Ctrl+F2): Ngưng thao tác gỡ rối, dừng chương trình.
Ngoài ra nếu chương trình đang chạy bị treo, có thể bấm Ctrl+Break+Break (2 lần Break) để ngưng, quay về màn hình soạn thảo để kiểm tra lại mã lệnh.
Hệ thống Menu: Compile
Compile: Các chức năng dịch
Compile (Alt+F9): Dịch mã nguồn trong cửa sổ hiện hành.
Make (F9): Dịch mã nguồn trong cửa sổ hiện hành, dịch luôn cả các thư viện được sử dụng nếu thư viện đó bị thay đổi.
Build: Tất cả các dẫn hướng biên dịch hiện hành được sử dụng để dịch lại toàn bộ mã nguồn, thư viện bất kể có hay không có sự thay đổi.
Target: Cho biết chương trình dịch ra sẽ chạy trên hệ điều hành nào, phần cứng máy tính nào.
Primary file: Nếu cửa sổ hiện hành là mã nguồn một thư viện chứ không phải chương trình, chức năng này cho biết chương trình nào sử dụng thư viện hiện tại. Khi chạy chương trình, Primary file sẽ được chạy chứ không phải thư viện trong cửa sổ hiện hành.
Clear primary file: Bỏ không sử dụng Primary file nữa
Compiler messages (F12): Hiện các thông báo của trình dịch: Báo lỗi cũ pháp, cảnh bảo nguy hiểm…
Hệ thống Menu: Debug
Debug: Các chức năng gỡ rối
Output: Hiện những gì trên màn hình người dùng trên một cửa sổ mới của IDE.
User screen (Alt+F5): Chuyển sang màn hình người dùng, bấm một phím bất kỳ để quay lại.
Add Watch (Ctrl+F7): Thêm một mục cần theo dõi giá trị vào cửa sổ Watchs.
Watches: Hiện cửa sổ Watchs.
Breakpoint (Ctrl+F8): Tạo điểm ngắt tại một dòng mã nguồn. Chương trình chạy tới điểm ngắt sẽ dừng lại.
Breakpoint List: Hiện danh sách các điểm ngắt, có thể đặt điều kiện ngắt.
Evaluate (Ctrl + F4): Xem nhanh giá trị biến hoặc biểu thức. Có thể thay đổi giá trị biến lúc đang chạy gỡ rối.
Call stack (Ctrl + F3): Xem danh sách lời gọi chương trình con tại thời điểm hiện tại.
Disassembler: Xem mã hợp ngữ của chương trình lúc đang chạy gỡ rối.
Registers: Xem giá trị các thanh ghi của bộ vi xử lý
Floating Point Unit: Xem giá trị các thanh ghi của bộ đồng xử lý toán học
Vector Unit: Xem giá trị các thanh ghi của bộ xử lý vector (MMX)
GDB Window: Dùng để tương tác trực tiếp với trình gỡ rối

Hệ thống Menu: Tools
Tools: Các công cụ hỗ trợ
Messages (F11): Hiện những thông điệp của một công cụ hỗ trợ.
Goto next: Hiện thông điệp kế tiếp
Goto previous: Hiện thông điệp liền trước
Grep: Công cụ Grep
Calculator: Công cụ máy tính bỏ túi
Ascii table: Hiện bảng mã ASCII


Hệ thống Menu: Options
Options: Các thiết lập cho IDE
Mode…: Đặt kiểu dịch (Normal - Bình thường, Debug - Gỡ rối, Release - Dịch ra phiên bản cuối cùng cho người sử dụng)
Compiler…: Đặt các thiết lập cho trình dịch
Memory sizes…: Đặt các ràng buộc về bộ nhớ
Linker…: Đặt các thiết lập cho trình liên kết
Debugger…: Đặt các thiết lập cho trình gỡ rối
Directories…: Đặt các đường dẫn và thư mục
Browser…: Đặt chế độ theo dõi phục vụ cho mục đích tìm kiếm
Tools…: Thêm/bớt công cụ vào menu Tools.
Environments: Các thiết lập chung cho IDE
Open: Nạp các thiết lập đã đặt sẵn từ file .INI
Save/Save as: Ghi các thiết lập hiện thời vào file .INI
Hệ thống Menu: Window
Window: Các thao tác xử lý cửa sổ
Title: Hiện toàn bộ các cửa sổ đang mở lên màn hình làm việc, các cửa sổ sẽ bị thu nhỏ lại sao cho không chồng lên nhau
Cascade: Hiện toàn bộ các cửa sổ xếp theo lớp, chồng lên nhau
Close all: Đóng toàn bộ cửa sổ đang mở:
Size/Move (Ctrl+F5): Thay đổi kích thước/di chuyển cửa sổ hiện hành. Chọn chức năng này rồi bấm  để di chuyển, giữ Shift và bấm  để thay đổi kích thước. Khi xong bấm 
Zoom (F5): Phóng to cửa sổ hiện hành lên cực đại
Next (F6): Chuyển sang cửa sổ kế tiếp
Previous (Shift+F6): Chuyển sang cửa sổ liền trước
Hide (Ctrl+F6): Ẩn cửa sổ hiện hành
Close (Alt + F3): Đóng cửa sổ hiện hành
List (Alt + 0): Hiện dang sách các cửa sổ đang mở
Refresh display: Vẽ lại màn hình IDE (trong trường hợp có lỗi hiển thị)
Hệ thống Menu: Help
Help: Hệ thống trợ giúp
Contents: Hiện các nội dung trợ giúp và tài liệu hướng dẫn sử dụng (dưới dạng sách)
Index (Shift+F1): Hiện các đề mục trợ giúp
Topic search (Ctrl+F1): Đánh dấu một từ hay một cụm từ rồi dùng chức năng này để tìm tài liệu liên quan tới từ đó
Previous topic (Alt+F1): Nhảy tới mục trợ giúp mở ra trước đây.
Using help: Hướng dẫn sử dụng hệ thống trợ giúp
Files…: Quản lý các tệp trợ giúp
About: Hiện thông tin về FP, số hiệu phiên bản…
Lê Minh Hoàng
Nội dung bài học
Cấu trúc chung của chương trình Pascal
Các khái niệm cơ bản
Chú thích
Tên/định danh
Khai báo hằng và khai báo biến
Một số kiểu dữ liệu chuẩn
Phần thân chương trình
Biểu thức
Lệnh gán
Các lệnh nhập xuất chuẩn
Một số thủ tục và hàm chuẩn
Cấu trúc của một chương trình Pascal
program Title; //program: Từ khoá; Title: Tên
//Phần khai báo
//Khai báo thư viện, nhãn, hằng, kiểu, biến
//Khai báo chương trình con
begin //Thân chương trình
Statement1; //Chỉ thị 1
Statement2; //Chỉ thị 2

StatementN; //Chỉ thị N
end.
Ví dụ một chương trình Pascal
Soạn chương trình xong ghi vào đĩa với một file có phần mở rộng là .PAS
Bấm CTRL+F9 để chạy chương trình
Sau đó bấm ALT+F5 xem kết quả
Chú ý khi sử dụng Free Pascal
FPC có thể dịch chương trình dưới nhiều kiểu tương thích, mỗi kiểu có một số điểm khác biệt.
Có thể đặt các kiểu dịch bằng menu Options/Compiler/Syntax
Nhưng tốt hơn nên đặt bằng dẫn hướng biên dịch ở đầu chương trình.
Các dẫn hướng biên dịch để đặt kiểu dịch là:
{$MODE DELPHI}: Dịch chương trình viết theo mã Delphi 4
{$MODE TP}: Dịch chương trình viết theo mã Turbo Pascal
{$MODE FPC}: Dịch chương trình viết theo mã Free Pascal (Mặc định)
{$MODE OBJFPC}: Dịch chương trình viết theo Object Pascal (Tương thích với Delphi 7, Delphi 2005/2006/2007)
{$MODE GPC}: Dịch chương trình viết theo GNU Pascal
{$MODE MACPAS}: Dịch chương trình viết theo Pascal for MacOS (Think Pascal, Metrowerks Pascal, MPW Pascal)
Dẫn hướng biên dịch không phải thành phần của ngôn ngữ, chỉ là để đặt thiết lập cho trình dịch.
Bộ chữ viết của Pascal
Các chữ cái lớn A..Z
Các chữ cái nhỏ a..z
Dấu gạch nối dưới (_) cũng được coi là chữ cái
Các chữ số 0..9
Các ký hiệu toán học thông dụng: +, -, *, /, =, <, >, <=, >=, <>, (, )…
Các ký hiệu đặc biệt: Dấu chấm (.), phẩy (,), chấm phẩy (;) …
Dấu cách để găn cách các từ
Từ khoá: Là một tập hợp các từ buộc phải sử dụng đúng với cú pháp, không dùng vào việc đặt tên hoặc dùng vời mục đích khác:
program, begin, end, const, if, while, repeat …
Pascal không phân biệt chữ hoa và chữ thường
Chú thích (Comments)
Chú thích là phần văn bản không có ý nghĩa với trình dịch, chỉ dùng để đọc chương trình dễ dàng hơn
Cách viết chú thích:
{This is a comment}: Phần văn bản nằm giữa {…} được coi là chú thích.
(*This is a comment*): Phần văn bản nằm giữa (*…*) được coi là chú thích.
//This is a comment: Toàn bộ phần nằm bên phải của 2 ký tự // được coi là chú thích.
Ngoại lệ
{$... } và (*$...*) không phải là chú thích
Dấu $ cho biết đó là dẫn hướng biên dịch (Compile directive)
Dòng tiêu đề chương trình: program Title;
program là từ khoá (reserved word)
Pascal quy định một số từ dành riêng, phải sử dụng đúng với cú pháp, dùng cho một số mục đích nhất định, không được dùng vào mục đích khác.
Title là tên đặt cho chương trình
Tên/định danh (Identifier)
Bắt đầu bằng chữ cái (a..z, A..Z, _)
Tiếp theo là chữ cái hoặc chữ số (a..z, A..Z, _, 0..9)
Dài không quá 127 ký tự
Không trùng với từ khoá
Đặt tên thế nào cho đúng?
Tên chuẩn (Standard Identifiers)
Tên chuẩn là một số tên do trình dịch đã định nghĩa và dùng có mục đích, nhưng người dùng có thể định nghĩa lại và sử dụng với mục đích khác
Ví dụ
ReadLn (Read a Line)
WriteLn (Write a Line)
Real
Integer
Phần khai báo
program Title;
uses

label

const

type

var

procedure
...
function
...
begin
Statement1;
Statement2;
Statement3
end.

Phần khai báo
(Declaration part)
Phần thân chương trình
(Program body)
Trong Pascal, tất cả những gì sử dụng trong chương trình đều phải khai báo.
Có rất nhiều kiểu khai báo
Học trước hai loại khai báo: Khai báo hằng và khai báo biến
Khai báo hằng
Hằng là đại lượng không đổi trong chương trình. Cú pháp khai báo:
const
Identifier1 = Value1;
Identifier2 = Value2;

Trong đó
const là từ khóa
Identifier1, Identifier2, … là các tên hằng: Phải tuân theo đúng luật đặt tên, không được trùng nhau hoặc trùng với tên đã có.
Value1, Value2,… là các giá trị hằng.
Dấu “=” để phân tách giữa tên hằng và giá trị hằng, dấu “;” để kết thúc mỗi khai báo hằng
Công dụng
Dùng tên gợi nhớ ý nghĩa thay cho việc viết giá trị (có thể rất dài và dễ nhầm)
Hạn chế sai sót khi phải sửa đổi một giá trị xuất hiện rất nhiều nơi trong chương trình.
Ví dụ về khai báo hằng
ThisYear là một hằng số nguyên có giá trị 2007, hằng số nguyên có thể viết dưới dạng khác: $Hexa, &Octa, hoặc %Binary,
Pi là một hằng số thực có giá trị 3.1416. Ký pháp thường viết hằng số thực là viết phần nguyên và phần thập phân phân tách bởi dấu chấm “.”
Billion cũng là một hằng số thực có giá trị 1 tỉ. Ký pháp này gọi là ký pháp dấu chấm động hay ký pháp khoa học: Với x, y là 2 số thực viết trong ký pháp thường, xEy = x.10y
FirstLetter là một hằng ký tự có giá trị là chữ ‘A’ trong bảng mã ASCII. Quy tắc viết hằng ký tự là viết ký tự đó trong 2 dấu nháy đơn. Nếu bản thân hằng ký tự là dấu nháy đơn, thì viết dấu nháy đơn 2 lần
Country là một hằng xâu ký tự, gồm có 7 ký tự V, i, e, t, n, a, m. Quy tắc viết hằng xâu ký tự là viết các ký tự liên tiếp trong 2 dấu nháy đơn
Yes là một hằng logic, nhận giá trị đúng (True)
const
ThisYear = 2007;
Pi = 3.1416;
Billion = 1E9;
FirstLetter = `A`;
Country = ‘Vietnam’;
Yes = True;
Khai báo biến
Biến là một đại lượng nhận giá trị trong một tập hợp nào đó. Cú pháp khai báo:
var
IdentiferList1: DataType1;
IdentiferList2: DataType2;

Trong đó
var là từ khóa
IdentifierList1, IdentifierList2,… là các danh sách biến. Mỗi danh sách gồm tên các biến cách nhau bởi dấu phẩy “,”. Các tên biến không được trùng nhau hoặc trùng với tên đã có.
DataType1, DataType2, … là các kiểu dữ liệu.
Dấu “:” để phân tách giữa danh sách biến và kiểu dữ liệu tương ứng.
Dấu “;” để kết thúc một khai báo biến
Ví dụ về khai báo biến
i, j, k là các biến số nguyên
x, y, z là các biến số thực
ch là một biến ký tự, nhận giá trị trong bảng mã ASCII
b là một biến logic, nhận một trong hai giá trị True hoặc False.
var
i, j, k: Integer;
x, y, z: Real;
ch: Char;
b: Boolean;
Dữ liệu và kiểu dữ liệu
Dữ liệu
Là tất cả những gì được máy tính lưu trữ và xử lý
Tồn tại dưới nhiều dạng khác nhau
Không nhất thiết phải là số (có thể là ký tự, mệnh đề logic)
Thể hiện qua các đối tượng cụ thể cần xử lý (giá tiền, tên, tuổi, văn bản, tín hiệu...)
Kiểu dữ liệu
Một tập hợp các giá trị mà một biến thuộc kiểu đó có thể nhận
Trên tập hợp đó xác định một số phép toán. Ví dụ
+, -, *, / với kiểu số thực
div, mod với kiểu số nguyên
and, or, not, xor với kiểu logic mệnh đề
>, < với kiểu ký tự
Những kiểu dữ liệu đơn giản chuẩn: Kiểu số nguyên, Kiểu số thực, Kiểu ký tự, Kiểu logic.
Các kiểu số nguyên
Integer và Cardinal là hai kiểu số nguyên phổ biến.
Luôn được ánh xạ vào kiểu số nguyên tính nhanh nhất
Với dẫn hướng biên dịch {$MODE OBJFPC}
Integer tương đương Longint
Cardinal tương đương Longword
Trong một số trường hợp Int64 và Qword không được coi là kiểu đơn giản.
Các kiểu số thực
Real là kiểu số thực phổ biến, trên máy tính với bộ xử lý 80x86 và hệ điều hành Windows, Real được ánh xạ thành Double.
Comp thực chất là kiểu Int64 nhưng được tính toán như số thực. Comp chỉ lưu trữ được số nguyên 64bit (phần thập phân tự động bị hủy bỏ)
Currency cũng được lưu trữ dưới dạng số nguyên 64 bit, nhưng khi truy cập biến kiểu Comp, giá trị lưu trữ sẽ được tự động chia cho 10000.
Trong biểu thức, các biến số thực đều được chuyển thành Extended trước khi thực hiện phép toán hoặc gọi các hàm chuẩn xử lý số thực.
Kiểu ký tự và logic
Kiểu ký tự
Kiểu logic
Biến kiểu logic chỉ nhận giá trị True hoặc False.
Khi gán giá trị True hay False cho biến kiểu logic, tùy vào kiểu sẽ có cách lưu trữ
Biểu thức
Biểu thức số thực
Gồm các toán hạng: Hằng, biến, hàm thuộc kiểu số thực
Các phép toán: +, -, *, /
Dấu ngoặc: “(” và “)”.
Chú ý: Biểu thức số thực chấp nhận cả toán hạng kiểu số nguyên
Biểu thức số nguyên
Gồm các toán hạng: Hằng, biến, hàm thuộc kiểu số nguyên
Các phép toán: +, -, *, div, mod
Dấu ngoặc: “(” và “)”.
Biểu thức logic
Gồm các toán hạng: Hằng, biến, hàm thuộc kiểu logic
Các phép toán: or, xor, and, not
Dấu ngoặc: “(” và “)”.
Các phép so sánh cũng cho giá trị kiểu logic nên cũng được coi là toán hạng logic: <, <=, =, >=, >, <>.
Ví dụ:
a là biến số thực đang có giá trị 2.5
b là biến số thực đang có giá trị 0.5
3 + Sqrt(a + 3 * b)
3 + Sqrt(a + 1.5)
3 + Sqrt(4.0)
3 + 2.0
5.0
Quy tắc tính biểu thức
Khó đưa ra định nghĩa chính xác và chặt chẽ cho người học nhập môn
Trình bày đủ quy tắc tính biểu thức phải dựa trên cây biểu diễn biểu thức và ký pháp nghịch đảo Ba Lan.
Định nghĩa hình thức
Như cách thực hiện biểu thức trong toán học
Ưu tiên dấu ngoặc trước,
Thứ nhì là phép NOT (biểu thức logic), và dấu - (Phép lấy số đối trong biểu thức số chứ không phải phép trừ)
Tiếp đó là *, /, div, mod (biểu thức số), and (biểu thức logic).
Ưu tiên thấp nhất là +, - (biểu thức số), or, xor (biểu thức logic).
Phần thân chương trình
program Title;
uses

label

const

type

var

procedure
...
function
...
begin
Statement1;
Statement2;
Statement3
end.

Phần khai báo
(Declaration part)
Phần thân chương trình
(Program body)
Bắt đầu bằng từ khoá begin
Tiếp theo là các lệnh (hay chỉ thị – statements) ngăn cách nhau bởi dấu chẩm phẩy (“;”)
Kết thúc bằng từ khóa end và dấu chấm (“.”)
Lệnh gán
Cú pháp: v := E;
v là biến
E là biểu thức thuộc kiểu tương thích với v
Công dụng: Gặp lệnh gán, máy sẽ tính giá trị biểu thức vế phải (E), được bao nhiêu gán cho biến ở vế trái (v).
Ví dụ: Với i biến số nguyên
i := 1; //gán giá trị 1 cho biến i;
i := i + 1; //Tăng giá trị biến i lên 1 (i := 2)
Chú ý: Một cách khác viết phép gán (mượn từ ngôn ngữ C)
Cần có dẫn hướng biên dịch {$COPERATORS ON}
i += 10; //i := i + 10;
i *= 5; //i := i * 5;
Lệnh nhập dữ liệu từ thiết bị nhập chuẩn
Thiết bị nhập chuẩn: Mặc định là bàn phím
Hai lệnh nhập dữ liệu:
Read(VariableList);
ReadLn(VariableList);
Trong đó:
Read/ReadLn là tên thủ tục chuẩn
VariableList là một danh sách các biến đã được khai báo trong phần var. Các biến trong danh sách được phân tách bởi dấu phẩy “,”.
Công dụng:
Khi gặp lệnh đọc dữ liệu từ bàn phím, máy sẽ hiện con trỏ chờ người dùng nhập giá trị cho các biến trong danh sách.
Ví dụ:
Read(a, b, c);
ReadLn(x, y);
Cách nhập dữ liệu
Sự khác biệt giữa Read và ReadLn
Tất cả những gì người dùng gõ vào bàn phím được nằm trong một vùng nhớ đệm, tổ chức như một văn bản gồm nhiều dòng, mỗi khi người dùng gõ  tương đương với việc xuống dòng.
Read và ReadLn sẽ đọc dữ liệu trên một dòng của vùng nhớ đệm rồi gán giá trị cho các biến theo đúng thứ tự đã định.
Nếu dòng đó chưa có đủ dữ liệu gán cho các biến thì Read/ReadLn nhảy xuống dòng dưới và đọc tiếp.
Nếu người dùng gõ thừa dữ liệu trên dòng, Read/ReadLn sẽ chỉ đọc đủ để gán giá trị cho các biến là dừng lại.
ReadLn sau khi đọc xong, sẽ tự động nhảy xuống đầu dòng dưới trong vùng nhớ đệm, Read giữ nguyên vị trí trong vùng nhớ đệm. Điều này ảnh hưởng tới lệnh Read/ReadLn tiếp sau.
Nếu dùng ReadLn, lệnh đọc dữ liệu tiếp sau sẽ đọc từ đầu dòng kế tiếp, nếu dùng Read, lệnh đọc dữ liệu tiếp sau sẽ tiếp tục từ chỗ dừng của lệnh Read.
Xét đoạn chương trình…
Cách nhập dữ liệu (tiếp)
program TestRead;
var
a, b, c: Integer;
d, e: Real;
begin
Read(a, b);
ReadLn(c);
ReadLn(d);
ReadLn(e);
end.
Máy chờ nhập giá trị a và b. Nếu người dùng gõ vào:
1 2 3
Máy sẽ đọc giá trị 1 và 2, lần lượt gán cho biến a và b. Vị trí đọc vẫn ở trên dòng đó (trước số 3)
Máy không chờ người dùng nhập giá trị cho biến c, vì trong vùng đệm vẫn còn số 3, máy đọc luôn giá trị 3 gán cho biến c, sau đó nhảy xuống dòng dưới của vùng đệm (Bởi dùng ReadLn).
Máy phải chờ người dùng nhập giá trị biến d, vì dòng hiện thời của vùng đệm chưa có dữ liệu. Giả sử người dùng gõ vào:
4 5
Máy sẽ đọc giá trị 4 gán cho biến d và nhảy xuống dòng dưới, giá trị 5 bị bỏ qua. Máy lại phải chờ người dùng nhập giá trị cho biến e
Giả sử người dùng gõ vào:
6
Máy sẽ nhận giá trị 6 này gán cho biến e.
Lệnh xuất dữ liệu ra thiết bị xuất chuẩn
Thiết bị xuất chuẩn: Mặc định là màn hình
Hai lệnh in ra màn hình:
Write(ItemList);
WriteLn(ItemList);
Trong đó:
Write/WriteLn là tên thủ tục chuẩn
ItemList là danh sách các hằng, biến, hoặc biểu thức phân tách nhau bởi dấu phẩy “,”.
Công dụng:
Khi gặp lệnh Write/WriteLn máy sẽ in giá trị các hằng, biến, biểu thức trong danh sách ra màn hình.
WriteLn sau khi thực hiện sẽ nhảy tới đầu dòng tiếp theo trên màn hình, Write giữ nguyên con trỏ tại sau vị trí vừa in ra.
Xuất dữ liệu khuôn dạng
Danh sách các tham số (hằng, biến, biểu thức) trong lệnh Write/WriteLn có thể đi kèm khuôn dạng
Mỗi tham số kiểu số nguyên, ký tự, logic, xâu ký tự có thể đi kèm thêm phần :m.
m là một số nguyên chỉ ra: cần phải in tham số đó với ít nhất m chỗ trên màn hình.
Nếu in tham số đó chỉ cần ít hơn m chỗ, máy phải thêm dấu cách vào đầu cho đủ m chỗ.
Nếu in tham số đó cần nhiều hơn m chỗ, máy tự động dành đủ chỗ.
Mỗi tham số kiểu số thực có thể đi kèm thêm phần :m:n
m là số nguyên chỉ ra: cần phải in tham số đó với ít nhất m chỗ trên màn hình.
n là số nguyên chỉ ra, cần phải in tham số đó với n chữ số thập phân.
Ví dụ
WriteLn(‘Test’, 5:10, Pi:10:4);
Kết quả: Test53.1416
Vài hàm chuẩn trong Pascal
(*) e  2.71828182845904523536 (**) Đơn vị đo bằng Radian
Lê Minh Hoàng
Nội dung bài học
Kỹ thuật trình bày mã nguồn
Cấu trúc khối.
Sử dụng dấu cách.
Các cấu trúc điều khiển
Cấu trúc tuần tự
Cấu trúc ghép
Cấu trúc rẽ nhánh
Cấu trúc lặp
Kỹ thuật trình bày mã nguồn
Trình dịch không quan tâm mã nguồn được trình bày như thế nào
Chính lập trình viên phải biết cách trình bày sao cho:
Tiện gỡ rối và soạn thảo.
Dễ bảo trì và nâng cấp phần mềm.
program Stupid; const a=5; b=385.3; var alpha,beta:real; begin alpha := a + b; beta:= b / a end.
No problem
Oh!!!
My God
program NotAsStupid;

const
  a = 5;
  b = 385.3;

var
  alpha, beta: Real;

begin
  alpha := a + b;
  beta := b / a
end.
program NotAsStupid;

const
  a=5;
  b=385.3;

var
  alpha,beta:Real;

begin
  alpha:=a+b;
  beta:=b/a
end.
Một đoạn mã nguồn trình bày tốt
Dấu cách
Cấu trúc tuần tự và cấu trúc ghép
Cấu trúc tuần tự
Statement1;
Statement2;

StatementN;
Cấu trúc ghép
begin
Statement1;
Statement2;

StatementN;
end;
Khi viết các lệnh liên tiếp cách nhau bởi dấu “;”, chương trình sẽ thực hiện lần lượt các lệnh theo đúng thứ tự đó.
Có những nơi trong chương trình không cho phép viết nhiều hơn 1 lệnh, khi đó để thực hiện nhiều lệnh, cần phải làm một lệnh ghép
Lệnh ghép bắt đầu bằng begin, kết thúc bằng end và dấu chấm phẩy. Giữa khối là các lệnh thành phần ngăn cách nhau bởi dấu chấm phẩy
Cấu trúc chọn
if Condition then Statement;
Condition là một biểu thức logic (cho giá trị True hay False)
Statement là 1 lệnh. Lệnh này sẽ được thực hiện nếu biểu thức Condition có giá trị True
if Condition then Statement1
else Statement2;
Condition là một biểu thức logic
Statement1 là 1 lệnh, được thực hiện nếu Condition có giá trị True
Statement2 là 1 lệnh, được thực hiện nếu Condition có giá trị False
Chú ý: Không có dấu chấm phẩy sau Statement1 (trước else)
Trong trường hợp có một dãy lệnh if…then…else lồng nhau, else luôn gắn với if chưa có else phía trên gần nó nhất
Cấu trúc chọn (tiếp)
case Expression of
Constant1: Statement1;
Constant2: Statement2;

ConstantN: StatementN;
end;

case Expression of
Constant1: Statement1;
Constant2: Statement2;

ConstantN: StatementN;
else: StatementE;
end;
Expression là một biểu thức nhận giá trị thuộc kiểu đếm được (Số nguyên, Ký tự, Logic, Liệt kê, Đoạn con).
Constant1..N là các hằng, có kiểu tương thích với Expresssion.
Statement1..N là các lệnh, lệnh StatementK sẽ được thực hiện nếu giá trị biểu thức Expression bằng ConstantK.
StatementE cũng là một lệnh, lệnh này sẽ được thực hiện nếu giá trị biểu thức Expression không trùng với bất kỳ hằng nào trong số Constant1..N


Ví dụ 1: Giải phương trình bậc 2
Nhập vào 3 số thực a, b, c và giải phương trình:
ax2+bx+c = 0
Mô tả thuật toán bằng ngôn ngữ tự nhiên
Nhập a, b và c.
Tính  = b2-4ac
Nếu  < 0, thông báo phương trình vô nghiệm
Nếu không…
Nếu  = 0, đưa ra nghiệm kép x = -b / (2a)
Nếu không, thông báo 2 nghiệm x = (-b ) / (2a)
Chuyển từ ngôn ngữ tự nhiên thành chương trình Pascal…
Giải phương trình bậc 2
program GiaiPTBac2;
var
a, b, c: Real;
Delta: Real;
begin
Write(`Nhap a, b, c: `);
ReadLn(a, b, c); //Nhập a, b và c
Delta := b * b - 4 * a * c;
if Delta < 0 then
WriteLn(`Phuong trinh vo nghiem`)
else //Delta  0
if Delta = 0 then
WriteLn(`Phuong trinh co nghiem kep x = `, -b / (2 * a):1:2)
else //Delta > 0
begin
WriteLn(`Phuong trinh co 2 nghiem`);
WriteLn(` x1 = `, (-b + Sqrt(Delta)) / (2 * a):1:2);
WriteLn(` x2 = `, (-b - Sqrt(Delta)) / (2 * a):1:2);
end;
end.
Ví dụ 2: Tính thứ trong tuần
Nhập vào 3 số nguyên dương là ngày (d), tháng (m), và năm (y). Cho biết ngày đó là ngày thứ mấy?
Công thức Zeller
Coi như không có tháng 1 và 2. Tháng 1 và 2 lần lượt được coi là tháng 13 và 14 của năm trước:
if m < 3 then
begin
m := m + 12; y := y - 1;
end;
Gọi c là số hiệu thế kỷ - 1:
c := y d
* Một số tài liệu cũ có thể bị lỗi font khi hiển thị do dùng bộ mã không phải Unikey ...

Người chia sẻ: Tú Tini
Dung lượng: | Lượt tài: 0
Loại file:
Nguồn : Chưa rõ
(Tài liệu chưa được thẩm định)