Mục lục bài họcĐang ở d07-b1
← IGCSE Computer Science
0/18 bài đã học xong
Chương 7 · Programming · Bài 1/2 của chương · bài 13/18 của IGCSE Computer Science

Data types, variables and control structures

Kiểu dữ liệu, biến và cấu trúc điều khiển
← Mục lục bài học
Lý thuyết · English

The five data types

integera whole number, positive or negative — $7$, $-42$
reala number with a decimal part — $3.75$, $-0.5$
chara single character — $\text{'A'}$, $\text{'?'}$
stringa sequence of characters — $\text{"Hello"}$
Booleanonly two possible values: TRUE or FALSE

Choosing the right type matters: storing a price as an integer loses the pence, and storing a phone number as an integer loses a leading zero — which is why phone numbers are stored as strings.

Variables and constants

  • a variable holds a value that can change while the program runs;
  • a constant holds a value that is fixed when the program is written and cannot change while it runs.

Why use constants: a value like a tax rate appears in many places. Declaring it once as a constant means changing it in one place, and it removes the risk of accidentally overwriting it.

Operators

Arithmetic: $+$, $-$, $*$, $/$, and two that need care:

  • DIV — integer division, giving the whole-number part of the quotient: $17 \ \text{DIV} \ 5 = 3$;
  • MOD — giving the remainder: $17 \ \text{MOD} \ 5 = 2$.

A standard use of MOD: testing divisibility. If $n \ \text{MOD} \ 2 = 0$ then $n$ is even.

Comparison: $=$, $<>$ (not equal), $<$, $>$, $<=$, $>=$.

Boolean: AND (both must be true), OR (at least one true), NOT (reverses).

The three control structures

Sequence — statements carried out one after another, in order.

Selection — a choice between paths, using IF … THEN … ELSE … ENDIF, or CASE OF when there are many possible values of one variable.

Iteration — repetition, in three forms:

count-controlledFOR … TO … NEXT — used when the number of repetitions is known in advance
pre-conditionWHILE … DO … ENDWHILE — condition tested before the loop body, so it may run zero times
post-conditionREPEAT … UNTIL — condition tested after the loop body, so it always runs at least once

This distinction decides marks. Consider validating an input: a REPEAT loop is correct, because you must ask at least once before you have anything to check. Consider processing a list that might be empty: a WHILE loop is correct, because it must be able to run zero times.

Choosing the wrong one produces a logic error: with a REPEAT loop on an empty list, the program processes an item that is not there.

Giải thích tiếng Việt

Năm kiểu dữ liệu.

  • số nguyên — số nguyên dương hoặc âm: $7$, $-42$;
  • số thực — số có phần thập phân: $3{,}75$, $-0{,}5$;
  • ký tựmột ký tự đơn: $\text{'A'}$, $\text{'?'}$;
  • chuỗi — một dãy ký tự: $\text{"Hello"}$;
  • lô-gic — chỉ có hai giá trị: ĐÚNG hoặc SAI.

Chọn đúng kiểu là việc quan trọng: lưu giá tiền dưới dạng số nguyên sẽ mất phần lẻ, và lưu số điện thoại dưới dạng số nguyên sẽ mất số 0 đứng đầu — đó là lý do số điện thoại được lưu dưới dạng chuỗi.

Biến và hằng.

  • biến giữ một giá trị có thể thay đổi trong lúc chương trình chạy;
  • hằng giữ một giá trị cố định từ khi viết chương trình và không đổi được khi chạy.

Vì sao dùng hằng: một giá trị như thuế suất xuất hiện ở nhiều chỗ. Khai báo nó một lần dưới dạng hằng nghĩa là khi cần đổi thì chỉ sửa một chỗ, và nó loại bỏ nguy cơ vô tình ghi đè lên giá trị đó.

Các toán tử.

Số học: $+$, $-$, $*$, $/$, và hai toán tử cần cẩn thận:

  • DIV — chia lấy nguyên, cho phần nguyên của thương: $17 \ \text{DIV} \ 5 = 3$;
  • MOD — cho phần dư: $17 \ \text{MOD} \ 5 = 2$.

Công dụng chuẩn của MOD: kiểm tính chia hết. Nếu $n \ \text{MOD} \ 2 = 0$ thì $n$ là số chẵn.

So sánh: $=$, $<>$ (khác), $<$, $>$, $<=$, $>=$.

Lô-gic: AND (cả hai phải đúng), OR (ít nhất một cái đúng), NOT (đảo ngược).

Ba cấu trúc điều khiển.

Tuần tự — các lệnh thực hiện lần lượt cái này sau cái kia, đúng thứ tự.

Rẽ nhánh — chọn giữa các đường đi, dùng IF … THEN … ELSE … ENDIF, hoặc CASE OF khi một biến có nhiều giá trị có thể.

Lặp — sự lặp lại, có ba dạng:

  • lặp theo bộ đếmFOR … TO … NEXT, dùng khi biết trước số lần lặp;
  • kiểm điều kiện trướcWHILE … DO … ENDWHILE, điều kiện được kiểm trước thân vòng lặp, nên nó có thể chạy không lần nào;
  • kiểm điều kiện sauREPEAT … UNTIL, điều kiện được kiểm sau thân vòng lặp, nên nó luôn chạy ít nhất một lần.

Khác biệt này quyết định điểm. Xét việc kiểm tra dữ liệu nhập: vòng lặp REPEAT là đúng, vì phải hỏi ít nhất một lần thì mới có gì để kiểm. Xét việc xử lý một danh sách có thể rỗng: vòng lặp WHILE là đúng, vì nó phải chạy được không lần nào.

Chọn sai loại tạo ra một lỗi logic: dùng vòng lặp REPEAT trên danh sách rỗng thì chương trình xử lý một phần tử không tồn tại.

Điều kiện kiểm TRƯỚC hay SAU thân vòng lặp? WHILE — kiểm TRƯỚC điều kiện? đúng thân lặp sai → thoát CÓ THỂ CHẠY 0 LẦN dùng khi danh sách CÓ THỂ RỖNG REPEAT — kiểm SAU thân lặp điều kiện? chưa thoả thoả LUÔN CHẠY ÍT NHẤT 1 LẦN dùng khi PHẢI HỎI trước mới có gì để kiểm
Chọn sai loại là lỗi logic — chương trình vẫn chạy và không báo gì cả, chỉ là nó xử lý một phần tử không tồn tại.
Ví dụ — chọn loại vòng lặp đúng

Với mỗi tình huống, nêu loại vòng lặp đúng và giải thích: (a) in bảng cửu chương $7$ từ $1$ đến $12$; (b) yêu cầu người dùng nhập mật khẩu cho tới khi đúng; (c) tính tổng các số trong một danh sách có thể rỗng.

Giải.

(a) In bảng cửu chương $7$ → VÒNG LẶP THEO BỘ ĐẾM.

Lý do: ta biết trước chính xác số lần lặp — đúng $12$ lần, không hơn không kém.

Đây chính là điều kiện dùng $\textbf{FOR} \ i \leftarrow 1 \ \textbf{TO} \ 12$: khi số vòng lặp là một con số đã biết ngay từ lúc viết chương trình.

Dùng WHILE hay REPEAT ở đây vẫn chạy được, nhưng phải tự viết thêm lệnh tăng biến đếm và tự viết điều kiện dừng — dài hơn và dễ sai hơn.

(b) Nhập mật khẩu cho tới khi đúng → VÒNG LẶP KIỂM ĐIỀU KIỆN SAU.

Lý do: phải hỏi ít nhất một lần thì mới có mật khẩu để kiểm.

Nếu dùng vòng lặp kiểm điều kiện trước, chương trình sẽ kiểm điều kiện trước khi người dùng nhập gì cả — mà lúc đó biến mật khẩu còn rỗng hoặc chưa xác định.

Cấu trúc đúng:

$\textbf{REPEAT}$

$\quad \textbf{INPUT } \text{mat\_khau}$

$\textbf{UNTIL } \text{mat\_khau} = \text{mat\_khau\_dung}$

Vòng lặp này luôn chạy ít nhất một lần, đúng thứ ta cần.

(c) Tính tổng danh sách có thể rỗng → VÒNG LẶP KIỂM ĐIỀU KIỆN TRƯỚC.

Lý do: danh sách có thể không có phần tử nào, nên vòng lặp phải chạy được không lần nào.

Vòng lặp kiểm điều kiện trước làm được đúng điều đó: nó kiểm “còn phần tử không?” trước khi vào thân, nên với danh sách rỗng nó bỏ qua toàn bộ và trả về tổng bằng $0$ — hoàn toàn chính xác.

Nếu chọn nhầm REPEAT. Chương trình sẽ chạy thân vòng lặp một lần dù danh sách rỗng, tức nó cố đọc một phần tử không tồn tại.

Kết quả: hoặc chương trình báo lỗi truy cập ngoài phạm vi, hoặc tệ hơn là nó cộng một giá trị rác vào tổng và cho ra kết quả sai mà không báo gì cả.

Nguyên tắc gọn: hỏi “có trường hợp nào cần chạy không lần nào không?” Có → kiểm điều kiện trước. Không, phải làm ít nhất một lần → kiểm điều kiện sau.

Ví dụ — chọn kiểu dữ liệu và dùng MOD

(a) Nêu kiểu dữ liệu phù hợp cho: tuổi học sinh; giá tiền một cuốn sách; số điện thoại; câu trả lời “có/không”. (b) Giải thích $17 \ \text{DIV} \ 5$ và $17 \ \text{MOD} \ 5$, và nêu một công dụng thực tế của MOD.

Giải.

(a) Chọn kiểu dữ liệu.

Tuổi học sinh → số nguyên. Tuổi tính theo năm tròn nên không cần phần thập phân.

Giá tiền một cuốn sách → số thực. Giá có phần lẻ. Nếu lưu dưới dạng số nguyên thì phần lẻ bị cắt mất, và mọi phép tính tiền sau đó đều sai.

Số điện thoại → chuỗi. Đây là lựa chọn hay bị sai nhất, vì số điện thoại “trông giống một con số”.

Hai lý do phải dùng chuỗi. Thứ nhất, số điện thoại thường có số 0 đứng đầu, mà kiểu số vứt bỏ số 0 đầu — $\text{0912}$ thành $912$. Thứ hai, ta không bao giờ tính toán trên số điện thoại: cộng hai số điện thoại là việc vô nghĩa.

Câu trả lời có hoặc không → lô-gic. Chỉ có đúng hai giá trị, nên kiểu lô-gic là vừa khít và tiết kiệm nhất.

(b) DIV và MOD.

$17 \ \text{DIV} \ 5 = 3$ — phép chia lấy nguyên cho phần nguyên của thương. Chia $17$ cho $5$ được $3$ lần trọn vẹn.

$17 \ \text{MOD} \ 5 = 2$ — phép chia lấy dư cho phần dư. Sau khi lấy ra $3 \times 5 = 15$, còn lại $2$.

Cách nhớ liên hệ: $17 = (5 \times 3) + 2$, tức $\text{số bị chia} = (\text{số chia} \times \text{DIV}) + \text{MOD}$.

Chú ý phân biệt với phép chia thường: $17 / 5 = 3{,}4$, một số thực. Cả DIV lẫn MOD đều cho số nguyên.

Công dụng thực tế của MOD: kiểm tính chia hết.

Nếu $n \ \text{MOD} \ 2 = 0$ thì $n$ là số chẵn; ngược lại là số lẻ. Đây là cách chuẩn để kiểm chẵn lẻ, vì không có toán tử riêng cho việc đó.

Cùng nguyên lý: $n \ \text{MOD} \ 3 = 0$ nghĩa là $n$ chia hết cho $3$.

Công dụng thứ hai: tách các chữ số của một số. Với $n = 47$, thì $n \ \text{MOD} \ 10 = 7$ cho chữ số hàng đơn vị, và $n \ \text{DIV} \ 10 = 4$ cho phần còn lại.

Bẫy hay mất điểm — Dùng vòng lặp kiểm điều kiện sau ở chỗ cần kiểm điều kiện trước. Hai loại này trông rất giống nhau khi viết ra, và với dữ liệu thông thường chúng cho cùng một kết quả — nên lỗi này thường lọt qua mọi phép thử. Khác biệt chỉ lộ ra ở một trường hợp duy nhất: khi vòng lặp đáng ra không được chạy lần nào. Vòng lặp kiểm điều kiện trước xét điều kiện trước thân, nên với danh sách rỗng nó bỏ qua toàn bộ. Vòng lặp kiểm điều kiện sau xét điều kiện sau thân, nên nó luôn chạy ít nhất một lần — và trên danh sách rỗng, nó cố đọc một phần tử không tồn tại. Hậu quả: hoặc báo lỗi truy cập ngoài phạm vi, hoặc tệ hơn là cộng một giá trị rác vào kết quả mà không báo gì cả. Phép kiểm một câu: hỏi “có trường hợp nào cần chạy không lần nào không?” Có → kiểm điều kiện trước. Phải làm ít nhất một lần → kiểm điều kiện sau.
Phải nhớ — Năm kiểu dữ liệu: số nguyên, số thực, ký tự, chuỗi, lô-gic — và số điện thoại lưu bằng chuỗi vì kiểu số vứt mất số 0 đầu. Biến đổi được khi chạy, hằng thì không. DIV cho phần nguyên, MOD cho phần dư; $n \ \text{MOD} \ 2 = 0$ là cách chuẩn kiểm số chẵn. Ba cấu trúc: tuần tự, rẽ nhánh, lặp. Vòng lặp theo bộ đếm khi biết trước số lần; kiểm điều kiện trước khi có thể phải chạy không lần nào; kiểm điều kiện sau khi phải làm ít nhất một lần.

Đọc xong rồi — làm thử ngay

Bài tập của chương Programming gồm 14 câu trắc nghiệm và 5 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.

Làm bài tập chương →