Ví dụ mã giả (pseudocode)
15 ví dụ có lời giải viết bằng mã giả Cambridge IGCSE và A-Level, từ lệnh OUTPUT đầu tiên đến sắp xếp nổi bọt. Ví dụ nào cũng có đầu ra, và bạn có thể chạy nó trong trình soạn thảo bên dưới.
Cách đọc các ví dụ này
Mã giả (pseudocode) mô tả các bước của một chương trình bằng tiếng Anh có cấu trúc, không có những quy tắc chặt chẽ của một ngôn ngữ lập trình thật. Mọi ví dụ dưới đây đều dùng chuẩn Cambridge của các kỳ thi IGCSE và A-Level: DECLARE để khai báo biến, ← để gán, OUTPUT để in ra, và các khối lệnh đóng bằng ENDIF, NEXT hoặc ENDWHILE.
Mỗi ví dụ nêu một bài toán, đưa ra mã giả, cho thấy đầu ra và giải thích cách hoạt động. Nhấn Chạy trong trình soạn thảo để tải ví dụ bất kỳ vào trình soạn thảo ở đầu trang, nơi bạn chạy từng dòng một và xem các biến thay đổi. Mới làm quen với cú pháp? Trình soạn thảo mã giả có một thư viện mọi cấu trúc, bấm vào là dùng được.
1. Hello, World
In một thông điệp ra màn hình.
OUTPUT "Hello, World!"Hello, World!OUTPUT in ra bất cứ thứ gì đứng sau nó, và văn bản được đặt trong dấu ngoặc kép. Chỉ một dòng này đã là một chương trình hoàn chỉnh: mã giả không cần hàm main và không cần import.
2. Cộng hai số
Lưu hai số nguyên, cộng chúng lại và in ra tổng.
DECLARE a : INTEGER
DECLARE b : INTEGER
DECLARE total : INTEGER
a ← 12
b ← 30
total ← a + b
OUTPUT "The total is ", totalThe total is 42Mỗi biến được khai báo với tên và kiểu dữ liệu trước khi dùng. Mũi tên ← lưu một giá trị, nên hãy đọc total ← a + b là "total bằng a cộng b". Dấu phẩy trong OUTPUT nối văn bản và giá trị trên cùng một dòng.
3. Chẵn hay lẻ
Xác định một số là chẵn hay lẻ.
DECLARE n : INTEGER
n ← 17
IF n MOD 2 = 0 THEN
OUTPUT n, " is even"
ELSE
OUTPUT n, " is odd"
ENDIF17 is oddMOD cho ra số dư sau phép chia. Số chẵn chia cho 2 không có số dư, nên phép kiểm tra là n MOD 2 = 0. IF chọn một trong hai nhánh và ENDIF đóng khối lệnh. Trong mã giả, một dấu = đơn dùng để so sánh hai giá trị; nó không bao giờ dùng để gán.
4. Xếp loại điểm bài kiểm tra
Đổi điểm trên thang 100 thành xếp loại: A từ 80 trở lên, B từ 60 đến 79, C dưới 60.
DECLARE score : INTEGER
DECLARE grade : CHAR
score ← 74
IF score >= 80 THEN
grade ← 'A'
ELSE
IF score >= 60 THEN
grade ← 'B'
ELSE
grade ← 'C'
ENDIF
ENDIF
OUTPUT "Score ", score, " gets grade ", gradeScore 74 gets grade BCác phép kiểm tra chạy từ mốc cao nhất xuống, nên điểm 74 trượt phép kiểm tra đầu tiên và đạt phép thứ hai. Đặt một IF bên trong ELSE của một IF khác là cách mã giả Cambridge viết chuỗi else-if. Kiểu CHAR chứa đúng một ký tự trong dấu nháy đơn.
5. Tính tổng các số từ 1 đến 10
Cộng tất cả các số nguyên từ 1 đến 10.
DECLARE total : INTEGER
DECLARE i : INTEGER
total ← 0
FOR i ← 1 TO 10
total ← total + i
NEXT i
OUTPUT "Sum of 1 to 10 is ", totalSum of 1 to 10 is 55Vòng lặp FOR chạy một số lần cố định: i lần lượt nhận các giá trị 1, 2, 3 và cứ thế đến 10, còn NEXT i đánh dấu chỗ kết thúc thân vòng lặp. Tổng tích lũy bắt đầu từ 0 và tăng lên sau mỗi lần lặp. Đáp án 55 khớp với công thức n(n + 1) / 2.
6. In bảng cửu chương
In năm dòng đầu của bảng cửu chương 7.
DECLARE i : INTEGER
FOR i ← 1 TO 5
OUTPUT "7 x ", i, " = ", 7 * i
NEXT i7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35Biến đếm i được dùng ngay trong phép tính, nên mỗi lần lặp in ra một dòng khác nhau. OUTPUT có thể nối nhiều đoạn văn bản và nhiều giá trị bằng dấu phẩy.
7. Đếm ngược bằng vòng lặp WHILE
Đếm ngược từ 5 về 1, rồi in một thông điệp cuối.
DECLARE count : INTEGER
count ← 5
WHILE count > 0 DO
OUTPUT count
count ← count - 1
ENDWHILE
OUTPUT "Liftoff!"5
4
3
2
1
Liftoff!Vòng lặp WHILE kiểm tra điều kiện trước mỗi lần lặp và dừng ngay khi điều kiện sai. Ở đây điều kiện là count > 0, và thân vòng lặp giảm count đi một mỗi lần. Bỏ dòng giảm giá trị đi thì vòng lặp sẽ chạy mãi. Dùng WHILE khi bạn không biết trước cần lặp bao nhiêu lần.
8. Tìm số lớn nhất trong mảng
Tìm giá trị lớn nhất trong một danh sách sáu số.
DECLARE nums : ARRAY[1:6] OF INTEGER
DECLARE i : INTEGER
DECLARE largest : INTEGER
nums[1] ← 14
nums[2] ← 3
nums[3] ← 27
nums[4] ← 9
nums[5] ← 21
nums[6] ← 6
largest ← nums[1]
FOR i ← 2 TO 6
IF nums[i] > largest THEN
largest ← nums[i]
ENDIF
NEXT i
OUTPUT "The largest number is ", largestThe largest number is 27ARRAY[1:6] khai báo sáu ô đánh số từ 1 đến 6, vì mảng trong chuẩn Cambridge thường bắt đầu từ 1. Chương trình giả sử phần tử đầu tiên là lớn nhất, rồi so sánh từng phần tử còn lại với nó và giữ lại số nào lớn hơn. Sau một lượt duyệt qua mảng, largest chứa đáp án.
9. Tính trung bình cộng
Tìm điểm trung bình của bốn bài kiểm tra.
DECLARE marks : ARRAY[1:4] OF INTEGER
DECLARE i : INTEGER
DECLARE total : INTEGER
marks[1] ← 70
marks[2] ← 85
marks[3] ← 64
marks[4] ← 91
total ← 0
FOR i ← 1 TO 4
total ← total + marks[i]
NEXT i
OUTPUT "Average mark: ", total / 4Average mark: 77.5Vòng lặp cộng từng phần tử của mảng vào total, rồi chương trình chia cho số bài. Toán tử / cho kết quả là số thập phân, vì vậy đầu ra là 77.5. Dùng DIV khi bạn muốn phép chia lấy phần nguyên.
10. Tìm kiếm tuần tự
Tìm vị trí của tên Dara trong một danh sách tên.
DECLARE names : ARRAY[1:5] OF STRING
DECLARE i : INTEGER
DECLARE found : BOOLEAN
names[1] ← "Ana"
names[2] ← "Ben"
names[3] ← "Chen"
names[4] ← "Dara"
names[5] ← "Eli"
found ← FALSE
i ← 1
WHILE i <= 5 AND found = FALSE DO
IF names[i] = "Dara" THEN
found ← TRUE
ELSE
i ← i + 1
ENDIF
ENDWHILE
IF found = TRUE THEN
OUTPUT "Dara is at position ", i
ELSE
OUTPUT "Not found"
ENDIFDara is at position 4Tìm kiếm tuần tự kiểm tra từng phần tử một, từ đầu danh sách. Điều kiện WHILE dừng vòng lặp khi đã tìm thấy tên hoặc khi đã kiểm tra hết mọi phần tử, và cờ found ghi lại trường hợp nào đã xảy ra. Cách này dùng được cho dữ liệu chưa sắp xếp, nhưng với danh sách dài nó có thể tốn một lần so sánh cho mỗi phần tử.
11. Sắp xếp nổi bọt
Sắp xếp năm số theo thứ tự tăng dần.
DECLARE nums : ARRAY[1:5] OF INTEGER
DECLARE i : INTEGER
DECLARE j : INTEGER
DECLARE temp : INTEGER
nums[1] ← 5
nums[2] ← 1
nums[3] ← 4
nums[4] ← 2
nums[5] ← 8
FOR i ← 1 TO 4
FOR j ← 1 TO 5 - i
IF nums[j] > nums[j + 1] THEN
temp ← nums[j]
nums[j] ← nums[j + 1]
nums[j + 1] ← temp
ENDIF
NEXT j
NEXT i
FOR i ← 1 TO 5
OUTPUT nums[i]
NEXT i1
2
4
5
8Sắp xếp nổi bọt (bubble sort) so sánh từng cặp phần tử kề nhau và đổi chỗ chúng khi sai thứ tự. Sau mỗi lượt của vòng lặp ngoài, giá trị lớn nhất còn lại đã dời về cuối, nên mỗi lần vòng lặp trong có thể dừng sớm hơn một phần tử. Việc đổi chỗ cần một biến thứ ba, temp, để giữ một giá trị trong lúc giá trị kia được chép sang.
12. Tính giai thừa bằng hàm
Viết một hàm trả về n giai thừa (n!), rồi dùng nó để tính 5!.
FUNCTION Factorial(n : INTEGER) RETURNS INTEGER
DECLARE result : INTEGER
DECLARE i : INTEGER
result ← 1
FOR i ← 2 TO n
result ← result * i
NEXT i
RETURN result
ENDFUNCTION
OUTPUT "5! = ", Factorial(5)5! = 120Một FUNCTION nhận tham số, thực hiện công việc và trả lại một giá trị bằng RETURN; dòng khai báo của hàm ghi rõ kiểu dữ liệu trả về. Các biến khai báo bên trong hàm chỉ tồn tại trong lúc hàm chạy. 5! là 5 × 4 × 3 × 2 × 1, tức 120.
13. Đếm nguyên âm trong một từ
Đếm xem từ PSEUDOCODE có bao nhiêu nguyên âm.
DECLARE word : STRING
DECLARE letter : CHAR
DECLARE vowels : INTEGER
DECLARE i : INTEGER
word ← "PSEUDOCODE"
vowels ← 0
FOR i ← 1 TO LENGTH(word)
letter ← SUBSTRING(word, i, 1)
IF letter = 'A' OR letter = 'E' OR letter = 'I' OR letter = 'O' OR letter = 'U' THEN
vowels ← vowels + 1
ENDIF
NEXT i
OUTPUT word, " has ", vowels, " vowels"PSEUDOCODE has 5 vowelsLENGTH cho ra số ký tự trong một chuỗi, còn SUBSTRING(word, i, 1) lấy một ký tự bắt đầu từ vị trí i. Vòng lặp duyệt qua từng ký tự và cộng thêm một vào biến đếm mỗi khi gặp A, E, I, O hoặc U.
14. FizzBuzz
In các số từ 1 đến 15, nhưng in Fizz cho bội của 3, Buzz cho bội của 5 và FizzBuzz cho bội của cả hai.
DECLARE i : INTEGER
FOR i ← 1 TO 15
IF i MOD 15 = 0 THEN
OUTPUT "FizzBuzz"
ELSE
IF i MOD 3 = 0 THEN
OUTPUT "Fizz"
ELSE
IF i MOD 5 = 0 THEN
OUTPUT "Buzz"
ELSE
OUTPUT i
ENDIF
ENDIF
ENDIF
NEXT i1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzzThứ tự các phép kiểm tra rất quan trọng. 15 là bội của cả 3 và 5, nên phép kiểm tra cho 15 phải đứng đầu; nếu không, chương trình sẽ in Fizz và không bao giờ tới được FizzBuzz. Đây là bài khởi động kinh điển trong phỏng vấn vì nó kiểm tra đúng kiểu suy luận này.
15. Thử mật khẩu với REPEAT UNTIL
Lần lượt thử tối đa ba mật khẩu và cho phép truy cập nếu có một mật khẩu đúng.
DECLARE attempts : ARRAY[1:3] OF STRING
DECLARE tries : INTEGER
DECLARE guess : STRING
attempts[1] ← "hunter1"
attempts[2] ← "letmein"
attempts[3] ← "open sesame"
tries ← 0
REPEAT
tries ← tries + 1
guess ← attempts[tries]
OUTPUT "Try ", tries, ": ", guess
UNTIL guess = "open sesame" OR tries = 3
IF guess = "open sesame" THEN
OUTPUT "Access granted"
ELSE
OUTPUT "Locked out"
ENDIFTry 1: hunter1
Try 2: letmein
Try 3: open sesame
Access grantedVòng lặp REPEAT ... UNTIL kiểm tra điều kiện ở cuối, nên thân vòng lặp luôn chạy ít nhất một lần. Nó dừng khi mật khẩu khớp hoặc sau lần thử thứ ba. Các mật khẩu đoán được lấy từ một mảng để ví dụ chạy mà không cần gõ; trong bài thi, bạn thường đọc từng mật khẩu bằng INPUT.
Câu hỏi thường gặp về ví dụ mã giả
Ví dụ về mã giả là gì?
IF score >= 50 THEN OUTPUT "Pass" ELSE OUTPUT "Fail" ENDIF. Nó đọc gần giống tiếng Anh nhưng theo các quy tắc cố định, nên có thể chuyển sang Python, Java hay bất kỳ ngôn ngữ nào khác từng dòng một. 15 chương trình trên trang này đi từ một dòng duy nhất đến tìm kiếm và sắp xếp.Viết mã giả như thế nào?
DECLARE để khai báo biến, ← để gán, IF để rẽ nhánh, FOR hoặc WHILE để lặp và OUTPUT để xuất kết quả. Thụt lề thân của mọi khối lệnh, đóng khối bằng từ khóa kết thúc của nó, và mỗi dòng chỉ làm một việc.Mã giả có giống nhau ở mọi kỳ thi không?
DECLARE và mũi tên ←, AQA dùng ← nhưng không khai báo biến, Exam Reference Language của OCR trông giống Python, còn Edexcel viết SET ... TO. Các ví dụ ở đây dùng chuẩn Cambridge; trình soạn thảo mã giả chuyển được giữa cả bốn kiểu.Có chạy được mã giả không?
Được, ngay trên trang này. Mã giả không phải ngôn ngữ lập trình thật nên không có trình biên dịch chính thức, nhưng trình soạn thảo ở đây chạy mã giả Cambridge ngay trên trình duyệt, hiển thị đầu ra và chạy từng dòng một. Nhấn Chạy trong trình soạn thảo bên dưới ví dụ bất kỳ.
Mã giả và lưu đồ khác nhau thế nào?
Cả hai đều mô tả thuật toán trước khi viết code. Lưu đồ vẽ các bước thành hộp và mũi tên, hợp với quy trình ngắn có ít lựa chọn. Mã giả viết các bước thành văn bản có cấu trúc, dùng được cho chương trình dài hơn và chuyển thành code thật trực tiếp hơn.
Có bắt buộc khai báo biến trong mã giả không?
DECLARE name : TYPE trước khi dùng biến. Các kiểu khác, như của AQA, bỏ qua bước khai báo. Khai báo biến còn cho người đọc biết biến đó chứa kiểu giá trị gì.