You are on page 1of 136

Giáo trình nhập môn tin học

Biên tập bởi:


Khoa CNTT ĐHSP KT Hưng Yên
Giáo trình nhập môn tin học

Biên tập bởi:


Khoa CNTT ĐHSP KT Hưng Yên

Các tác giả:


Khoa CNTT ĐHSP KT Hưng Yên

Phiên bản trực tuyến:


http://voer.edu.vn/c/69de34bd
MỤC LỤC

1. Giới thiệu giáo trình


2. Bài 1: Thông tin và xử lý thông tin
2.1. Thông tin và xử lý thông tin, hệ thống tính toán và biểu diễn thông tin trong máy
tính
3. Bài 2: Tổng quan hệ thống máy tính
3.1. Tổng quan về hệ thống máy tính
4. Bài 3: Giải bài toán bằng máy tính
4.1. Giải bài toán bằng máy tính
5. Bài 4-5-6: Thực hành, thảo luận và tổng quan về lập trình
5.1. Thực hành, thảo luận và tổng quan về lập trình
6. Bài 7:Thuật toán và chương trình
6.1. Thuật toán và chương trình
7. Bài 8-9: Thảo luận về phát triển ứng dụng C/C++, Các thành phần của một chương
trình
7.1. Thảo luận về phát triển ứng dụng C/C++,Các thành phần của một chương trình
8. Bài 10: Một số hàm chức năng
8.1. Một số hàm chức năng thường dùng trong chương trình
9. Bài 11: Bài thực hành về các thành phần cơ bản và nhập/xuất trong C/C++
9.1. Bài thực hành về các thành phần cơ bản và nhập/xuất trong C/C++
10. Bài 12: Cấu trúc rẽ nhánh
10.1. Cấu trúc rẽ nhánh
11. Bài 13: Bài thực hành về cấu trúc rẽ nhánh
11.1. Bài thực hành về cấu trúc rẽ nhánh
12. Bài 14- 15: Cấu trúc lặp while, do .. while - Cấu trúc lặp for
12.1. Cấu trúc lặp while, do .. while - Cấu trúc lặp for
13. Bài 16- 17: Thảo luận về các cấu trúc điểu khiển - Bài thực hành về cấu trúc lặp
13.1. Thảo luận về các cấu trúc điểu khiển - Bài thực hành về cấu trúc lặp
14. Bài 18: Các kiểu dữ liệu trong C/C++
14.1. Các kiểu dữ liệu trong C/C++
15. Bài 19- 20: Chương trình con - thực hành về xây dựng chương trình con
15.1. Chương trình con - thực hành về xây dựng chương trình con
Tham gia đóng góp

1/134
Giới thiệu giáo trình
Tên Module: Nhập môn Tin học

Mã Module:

Giáo viên: Nguyễn Hữu Đông, Ngô Thanh Huyền

Ngành học: Điện-Điện tửSố giờ học: 144h/45t

Loại hình đào tạo: Chính qui Thời gian thực hiện: 12 tuần

Năm học: 2007/2008 Loại Module: 02LT+01TH

Phiên bản: 20080313 Phương pháp dạy học:

Mục tiêu:

Sau khi hoàn thành module này, người học có khả năng:

• Mô tả tỉ mỉ các khái niệm cơ bản về thông tin, xử lý thông tin, mô hình tính
toán trong máy tính điện tử.
• Thiết kế chương trình máy tính, cài đặt chương trình bằng ngôn ngữ C/C++ để
giải một số bài toán thông thường, đơn giản trong khoa học kỹ thuật, đặc biệt
trong lĩnh vực điện tử, đo lường và điều khiển.
• Hình thành thái độ học tập nghiêm túc, kỹ năng làm việc độc lập và theo nhóm.

Module này sẽ giúp người học phát triển các năng lực: phân tích(M1), thiết kế (M1),
thực hiện(M2)

Điều kiện tiên quyết:

Module có thể thực hiện song song với Module: Toán cao cấp.

Mô tả module:

Phần 1 giới thiệu tổng quan về thông tin và xử lý thông tin, máy tính điện tử, giải bài
toán bằng máy tính.

2/134
Phần 2 cung cấp cho người học những nguyên lý cơ bản về lập trình, các cấu trúc điều
khiển, các kiểu dữ liệu, mô hình hướng chức năng, cách thức xây dựng chương trình con
và một số bài toán trong khoa học kỹ thuật.

Module này sử dụng ngôn ngữ C/C++ để minh họa, cài đặt. Tuy nhiên người học dễ
dàng cài đặt được bằng các ngôn ngữ lập trình khác như: VB.NET, C#, Pascal...

Nội dung module:

Bài 1: Thông tin và xử lý thông tin, hệ thống tính toán và biểu diễn thông tin
trong máy tính

1.1. Thông tin và xử lý thông tin

1.2. Hệ thống tính toán và biểu diễn thông tin trong máy tính

Bài 2: Tổng quan về hệ thống máy tính

2.1. Cấu trúc tổng quan phần cứng máy tính

2.2. Tổng quan về phần mềm

2.3. Khái niệm về mạng Internet

Bài 3: Giải bài toán bằng máy tính

3.1. Thuật toán

3.2. Biểu diễn thuật toán

3.3. Một số thuật toán thông dụng

Bài 4: Bài thực hành làm quen với máy tính, hệ thống tính toán

Bài 5: Thảo luận về các bước giải quyết bài toán trên máy tính

Bài 6: Tổng quan về lập trình

6.1.Giới thiệu phương pháp học

6.2. Ngôn ngữ lập trình

6.3. Các phương pháp lập trình

3/134
6.4. Một số ngôn ngữ lập trình

6.5. Ngôn ngữ lập trình C/C++

Bài 7: Thuật toán và chương trình

7.1. Thuật toán và lưu đồ thuật toán

7.2. Cấu trúc một chương trình C/C++ đơn giản

Bài 8: Thảo luận về môi trường phát triển ứng dụng C/C++

Bài 9: Các thành phần cơ bản của một chương trình

9.1. Các phần tử cơ bản của một ngôn ngữ lập trình

9.1.1. Bảng chữ cái

9.1.2. Từ khoá

9.1.3. Tên (định danh)

9.2. Các kiểu dữ liệu cơ bản

9.3. Biến, hằng và cách khai báo

9.4. Các phép toán

9.5. Biểu thức

Bài 10: Một số hàm chức năng thường dùng trong chương trình

10.1. Một số hàm thường dùng

10.2. Nhập/xuất dữ liệu (bàn phím, màn hình)

Bài 11: Bài thực hành về các thành phần cơ bản và nhập/xuất trong C/C++

Bài 12: Cấu trúc rẽ nhánh

12.1. Câu lệnh đơn, khối lệnh

12.2. Các cấu trúc rẽ nhánh

4/134
12.2.1. Cấu trúc rẽ nhánh if

12.2.2. Cấu trúc rẽ nhánh switch

Bài 13: Bài thực hành về cấu trúc rẽ nhánh

Bài 14: Cấu trúc lặp while, do .. while

14.1. Cấu trúc lặp while

14.2. Cấu trúc lặp do..while

Bài 15: Cấu trúc lặp for và một số lệnh điều khiển khác

15.1. Cấu trúc lặp for

15.2. Break, continue, return

Bài 16: Thảo luận về các cấu trúc điểu khiển khiển

Bài 17: Bài thực hành về cấu trúc lặp

Bài 18: Các kiểu dữ liệu trong C/C++

Bài 19: Chương trình con

19.1. Đặt vấn đề

19.2. Ví dụ về một chương trình có sử dụng chương trình con

19.3. Phạm vi hoạt động của biến

19.4. Cấu trúc một chương trình con

19.5. Truyền tham số cho chương trình con

19.6. Nguyên tắc hoạt động của chương trình con

19.7. Nguyên tắc sử dụng chương trình con

Bài 20: Bài thực hành về xây dựng chương trình con

5/134
Tài liệu tham khảo:

• Sách, giáo trình chính:

1. Giáo trình, hệ thống bài tập, tài liệu do giáo viên biên soạn.

2. “Ngôn ngữ lập trình C thật là đơn giản”. NXB Giáo dục, 2007.

3. Phạm Văn Ất. “Giáo trình C cơ bản và nâng cao”.

• Sách tham khảo:

1. Phạm Văn Ất. “Giáo trình C++”.

2. Nguyễn Thanh Thuỷ và Nguyễn Quang Huy. “Bài tập lập trình ngôn ngữ C”. NXB
Khoa học và kỹ thuật.

• Khác: Internet

Học liệu:

Giáo trình lưu hành nội bộ, sách tham khảo, hệ thống bài tập mẫu, bài tập tự làm, máy
tính, tài nguyên trên Internet, Projector.

Đánh giá:

Hình thức đánh giá:

• Kiểm tra giữa kỳ (lập trình trên máy tính): 20%


• Đánh giá quá trình (kết quả các buổi thực hành): 30%
• Kiểm tra cuối kỳ (lập trình trên máy tính): 50%

Tiêu chí đánh giá:

• - Kỹ năng thiết kế, xây dựng bài toán


• - Kỹ năng cài đặt bài toán.

Người đánh giá: Giáo viên giảng dạy và người học.

Kế hoạch học tập:

Mục Hoạt động giáo Hoạt động sinh Điều hiện thực
Bài TGSV
tiêu viên viên hiện

6/134
7/134
Bài 1: Thông tin và xử lý thông tin
Thông tin và xử lý thông tin, hệ thống tính toán và biểu
diễn thông tin trong máy tính
Thông tin và xử lý thông tin

Khái niệm thông tin

Thông tin ( Informations ) là một khái niệm trừu tượng mô tả những gì đem lại hiểu biết
, nhận thức cho con người cũng như các sinh vật khác. Thông tin tồn tại khách quan.
Thông tin có thể tạo ra, phát sinh, truyền đi, lưu trữ, chọn lọc. Thông tin cũng có thể
méo mó, sai lệch đi do nhiễu tác động hay do người xuyên tạc,…

Xử lý thông tin

• Sơ đồ tổng quát của quá trình xử lý thông tin

Hàng ngày con người luôn phải tiến hành xử lý thông tin. Quá trình xử lý đó có thể
hình dung như sau: Từ những dữ kiện có được và các mục đích được đặt ra, con người
cần suy nghĩ để lựa chọn những tác động và trình tự để thực hiện các tác động đó
nhằm đưa ra được những quyết định đúng để đạt được mục đích. Như vậy, phương án
hành động chính là kết quả của quá trình xử lý thông tin. Quá trình xử lý thông tin nói
chung có thể được mô tả bằng sơ đồ sau: ***SORRY, THIS MEDIA TYPE IS NOT
SUPPORTED.***

• Xử lý thông tin bằng máy tính điện tử

Khi chúng ta sử dụng một máy tính bỏ túi để tính toán, ta thấy máy tính có thể tiếp nhận
số liệu do ta nạp vào thông qua hệ thống các nút bấm. Máy có thể hiện lại các số liệu đã
nhận hoặc hiển thị kết quả tính toán trên màn hình. Máy có thể lưu trữ kết quả tính toán
trung gian để tính tiếp. Toàn bộ các thao tác trên được thực hiện với tốc độ rất cao, gần
như tức thời.

Tuy nhiên máy tính sẽ không làm gì được nếu như không có tác động của con người.
Người sử dụng phải bấm các phím nhập dữ liệu vào máy, bấm các phím thực hiện các
phép toán cũng như yêu cầu lưu trữ hoặc hiển thị các kết quả. Điều đó cũng đúng với
máy tính điện tử (MTĐT). MTĐT chỉ có thể thực hiện chức năng một cách tự động khi
con người đã trao trước cho nó một dãy các chỉ dẫn (quy tắc) gọi là các lệnh hay chương
trình. Chương trình cho MTĐT do con người lập ra và nạp vào trong máy. Khi nhận
được lệnh thực hiện thông qua việc bấm một vài phím quy định, máy sẽ theo chỉ dẫn

8/134
của chương trình, từng bước thực hiện các thao tác đã được vạch sẵn để tiến hành xử lý
các dữ liệu được nạp toàn bộ hoặc từng phần trong máy.

***SORRY, THIS MEDIA TYPE IS NOT SUPPORTED.*** Tóm lại, MTĐT hoạt
động theo nguyên tắc “Tự động điều khiển bằng chương trình”. Ta có thể minh hoạ quá
trình xử lý thông tin trong MTĐT bằng lược đồ sau:

Hệ thống tính toán và biểu diễn thông tin trong máy tính

Biểu diễn thông tin trong máy tính điện tử (MTĐT)

• Hệ đếm và số học nhị phân

Hệ đếm

Hệ đếm được hiểu như tập các ký hiệu và quy tắc sử dụng tập ký hiệu đó để biểu diễn
và xác định giá trị các số.

Ví dụ: Hệ đếm La mã và hệ đếm thập phân

• Các hệ đếm thông dụng

* Hệ đếm cơ số 10:

Dùng các số 0,1,2,...9 ( 10 công cụ )

¯¯¯
tntn − 1...t1t0 , s1s2...sm=tn.10n+ tn-1.10n-1+...+ t1.101+t0+ s1.10-1+ s2.10-2+...+ sm.10-m

Trong đó: ti,si ∈[0,1,2,3,4,5,6,7,8,9]

* Hệ đếm nhị phân, bát phân và thập lục phân:

Dùng a công cụ bắt đầu từ công cụ 0. ta có:

¯¯¯
tntn − 1...t1t0 , s1s2...sm= tn.an + tn-1.an-1 + ... + t1.a1 + t0 + s1.a-1 + s2.a-2 +...+ sm.a-m

a =2 (Hệ nhị phân) ta có hai công cụ: 0,1. Tức là ti,si∈[0,1]

a =8 (Hệ bát phân) ta có tám công cụ: 0,1...7 Tức là ti, si ∈ [0, 1, 2, 3, 4, 5, 6, 7]

a =16 (Hệ thập lục phân) ta có 16 công cụ: 0,1...9,A,B,C,D,E,F

9/134
Tức là ti,si∈[0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F]. Các trị này tương ứng với các số từ 0 đến
15 của hệ thập phân.

* Chuyển dạng biểu diễn nhị phân sang hệ thập phân

Cho một số dưới dạng nhị phân

an,an-1 ...a0

Muốn tìm dạng biểu diễn thập phân ta tính giá trị của đa thức sau:

an .2n +an-1.2n-1+ ...a0.20

Ví dụ: 100(2)=1.22+0.21+0=4(10)

* Chuyển dạng biểu diễn thập phân sang nhị phân

Ta tiến hành theo các bước sau:

Bước 1:

Chia liên tiếp số x cho 2 để được dãy

x0=x, x1, x2....xn=1 (1)

Bước 2: (chẵn lẻ)

Xét dãy (1)

Nếu xi là chẵn thì viết dưới xi với ai=0

Nếu xi là lẻ thì viết dưới xi với ai=1

ta được dãy:

a0, a1, a2.....an (2)

Bước 3:

Viết ngược dãy (2) ta thu được số nhị phân cần tìm là

a0, a1, a2......an

10/134
Ví dụ viết số 11 dưới dạng nhị phân ta tiên hành

• Chia liên tiếp cho 2 được : 11 ,5 , 2, 1


• Chẵn lẻ 1 1 0 1
• Viết ngược lại 1011

Chú ý : bằng cách tương tự ta có thể chuyển hệ 8 hoặc 16 sang hệ thập phân và ngược
lại

* Chuyển dạng biểu diễn từ hệ nhị phân sang dạng thập lục phân và ngược lại

Để chuyển từ hệ nhị phân sang hệ 16 ta chỉ cần nhóm 4 số từ phải sang trái ứng với giá
trị bộ 4 số nhị phân ta có số hệ 16 tương ứng.

Ví dụ

1111 1010 0001=FA1

Ngược lại để chuyên từ hệ 16 sang hệ 2 ta ta viết từng bộ 4 chữ số nhị phân tương ứng
với từng chữ số hệ 16

* Bảng quan hệ giữa các số hệ nhị phân và thập lục phân

Số nhị Số thập Số nhị Số thập Số nhị Số thập Số nhị Số thập


phân lục phân phân lục phân phân lục phân phân lục phân
0000 00 0100 04 1000 08 1100 0C
0001 01 0101 05 1001 09 1101 0D
0010 02 0110 06 1010 0A 1110 0E
0011 03 0111 07 1011 0B 1111 0F

• Các phép toán cơ bản của số nhị phân

* Phép cộng

0+0=0 0+1=1

1+0=1 1+1=10

* Phép nhân

0×0=0 0×1=0

11/134
1×0=0 1×1=1

* Phép trừ

1-1=0 0-0=0

1-0=1 10-1=1

12/134
Bài 2: Tổng quan hệ thống máy tính
Tổng quan về hệ thống máy tính
Cấu trúc tổng quan phần cứng máy tính

Central Processing Unit - Bộ xử lý trung tâm

Là bộ phận quan trọng nhất của máy tính điện tử. Nó có chức năng xử lý, tính toán dữ
liệu. Thực hiện các phép toán số học và logic đồng thời điều khiển quá trình thực hiện
các lệnh. CPU có các thành phần chính như sau:

Đồng hồ (Clock) tạo các xung thời gian chính xác để đồng bộ hoá các thành phân khác
của CPU.

Khối tính toán số học và logic ALU (Arithmetic and Logic Unit) thực hiện hầu hết các
thao tác, các phép tính quan trọng của hệ thống, đó là

• Các phép toán số học ( +, -, *, /…)


• Các phép toán Logic (And, Or, Xor, Not)
• Các phép tính quan hệ ( >, >=, <, <=, =, #, <>,…)

Khối điều khiển CU (Control Unit) điều khiển quyết định dãy các thao tác cần phải làm
đối với hệ thống bằng cách tạo ra các tín hiệu điều khiển mọi công việc.

Khối các thanh ghi (Registers): Ngoài các bộ phận trên CPU còn có một tập các thanh
ghi làm nhiệm vụ nhớ trung gian nhằm đẩy nhanh tốc độ tính toán và xử lý của CPU.

Bộ nhớ ( Memory )

Là thiết bị có chức năng lưu trữ dữ liệu và chương trình.

Bộ nhớ trong (Internal Memory): Là bộ nhớ được dùng để ghi chương trình và dữ liệu
trong thời gian xử lý. Giúp cho quá trình truy xuất dữ liệu được nhanh. Bộ nhớ trong có
đặc điểm

• Tốc độ trao đổi thông tin với CPU rất lớn.


• Dung lượng bộ nhớ không cao, giá thành đắt.

Bộ nhớ trong hiện nay thường được xấy dựng với hai loại vi mạch nhớ cơ bản như sau:

13/134
• RAM (Random Access Memory – Bộ nhớ truy cập ngẫu nhiên): Là bộ nhớ
trong khi máy tính hoạt động có thể ghi và đọc thông tin một cách dễ dàng. Khi
mất điện thì thông tin trên đó cũng mất theo.
• ROM (Read Only Memory – Bộ nhớ chỉ đọc): Là bộ nhớ mà ta chỉ có thể đọc
thông tin ra mà không ghi được thông tin lên đó. Thông tin trên ROM do nhà
sản xuất ghi lên và nó không bị mất khi ngắt điện hoặc tắt máy. Nó được dùng
để chứa dữ liệu và chương trình cố định điều khiển máy tính khi mới bật điện.

Bộ nhớ ngoài (External Memory): Là các thiết bị lưu trữ thông tin với khối lượng lớn.
Tốc độ truy cập chậm hơn bộ nhớ trong. Bộ nhớ ngoài điển hình nhất hiện nay là đĩa từ
và đĩa quang.

Đĩa từ là một tấm đĩa tròn, mỏng làm bằng chất dẻo Mylar (đĩa mềm), thuỷ tinh cứng
hay kim loại cứng (đĩa cứng), bên trên có phủ một lớp bột từ tính oxit sắt từ. Nó được
bảo vệ trong một lớp nhựa hay lớp kim loại cách từ gọi là vỏ đĩa. Đĩa từ hiện nay phổ
biến có hai loại là đĩa cứng và đĩa mềm.

Đĩa mềm có hai loại là 1,2 Mb và 1,44 Mb, ngoài ra hiện nay đang có loại 2,88Mb. Với
đĩa mềm thì ta phải dùng với ổ mềm. Ổ mềm chỉ hoạt động khi có đĩa mềm trong đó.
Mật độ ghi thông tin trên đĩa mềm nhỏ chỉ ở mức Mb.

Đĩa cứng thường được lắp trên Case chứa CPU, có mật độ ghi thông tin rất lớn ở mức
Gb. Với đĩa cứng thì đĩa được lắp trong hộp gọi là ổ đĩa cứng. Khi sử dụng chỉ việc cắm
cable điện và cable dữ liệu cho nó.

Đĩa quang: Là loại đĩa hiện nay được bán phổ biến trên thị trường, giá thành rẻ, khả
năng lưu trữ thông tin lớn, độ an toàn dữ liệu không cao. Có hai loại đĩa quan đang được
sử dụng trên thị trường hiện nay là đĩa CD-ROM (Compact Disc Read Only Memory)
và WORM (Write Once Read Memory).

Thiết bị vào ( Input Device)

Thiết bị vào được dùng phổ biến hiện nay là bàn phím (Keyboard), chuột (Mouse), máy
quét (Scaner),…

Bàn phím (Keyboard ):101 hoặc 102 phím. Có các loại phím như sau:

• Phím chức năng(Functions key): F1...F12


• Phím ký tự: '0'....'9','A'...'Z','a'...'z' và các ký hiệu. Được bố trí dưới 2 dạng:

***SORRY, THIS MEDIA TYPE IS NOT SUPPORTED.*** và ***SORRY, THIS


MEDIA TYPE IS NOT SUPPORTED.***

14/134
Cách gõ: Shift + Phím(1) Chữ in hoa (Giữ Shift trước)

Phím(1) Chữ in thường

Shift + Phím(2) Ký tự phía trên

Phím(2) Ký tự phía dưới

Ghi chú: Nếu bật phím CapsLock thì phím dạng (1) sẽ có kết quả ngược như trên (Hay
nói một cách khác hai phím Shift & CapsLock làm ngược chức năng của nhau cho loại
phím dạng (1))

• Phím dịch chuyển con trỏ: Home,End, PageUp, PageDown, Tab


• Phím xoá: (Backspace) và Delete hoặc Del
• Phím dịch chuyển: Ctrl, Shift, CapsLock, Alt... thường kết hợp với các phím
khác ( tổ hợp phím) để thực hiện một chức năng nào đó.

Có hai phím rất hay dùng là Spacebar và Enter (Ký hiệu lý thuyết: ***SORRY, THIS
MEDIA TYPE IS NOT SUPPORTED.*** ?)

Chuột (Mouse): Có loại hai nút (button), có loại 3 nút. Gọi các nút đó theo vị trí tương
đối của chúng: Nút chuột trái, nút chuột phải, nút chuột giữa. Chuột thường được dùng
cho việc di chuyển đến các thực đơn hoặc các công cụ, các ô điều khiển để nháy (click)
vào đó và yêu cầu thực hiện công việc tương ứng.

Thiết bị ra ( Output Device)

Màn hình (Display)

Có hai chế độ biểu hiện (Text và Graphic)

• Ở chế độ Text 80 cột x 25 hàng.


• Ở chế độ Graphic màn hình ở độ phân giải chuẩn là 640 x 480 dot.

Toạ độ đánh số từ góc trái trên tăng dần qua phải, xuống dưới bắt đầu từ số 0.

Ở chế độ Text có con nháy như "_" luôn nhấp nháy ở tần số 15?20 lần/phút nhắc nhở
địa điểm làm việc trên màn hình.

Ở chế độ đồ hoạ các phần tử biểu diễn dưới dạng điểm tuỳ theo độ phân giải cao hay
thấp của loại màn hình. Thường thì ở chế độ chuẩn là 640x480 dot. Trên màn hình đồ
hoạ không có con trỏ xuất hiện như ở màn hình Text.

15/134
Máy in (Printer)

Khi cần đưa thông tin ra giấy thì người ta sử dụng máy in Tuỳ theo yêu cầu công việc
và điều kiện thực tế người ta sử dụng các loại máy in khác nhau . Hiện nay thường sử
dụng 2 loại máy in chủ yếu : Máy in Kim và máy in LASER

Tổng quan về phần mềm

Hệ điều hành ( OS-Operating System )

Là một hệ thống các chương trình nhằm đảm bảo các chức năng cơ bản sau:

• Điều khiển việc thực thi mọi chương trình.


• Quản lí, phân phối và thu hồi bộ nhớ (cả trong lẫn ngoài)
• Điều khiển các thiết bị, bao gồm cả việc khởi động máy.
• Điều khiển, quản lí việc vào ra dữ liệu.
• Làm nhiệm vụ trung gian ghép nối máy tính với người sử dụng sao cho người
sử dụng thất thuận tiện và hiệu quả.

Hiện nay có rất nhiều hệ điều hành như: Dos, Windows, Unix, Linux,…nhưng phổ biến
ở nước ta từ trước đến nay là hệ điều hành Dos và Windows. Một số nơi ở nước ta hiện
nay đang chuyển sang dùng Linux.

Các chương trình ứng dụng ( Applications)

Là các chương trình phục vụ cho các ứng dụng cụ thể. Hiện nay có rất nhiều các chương
trình ứng dụng cụ thể như:

• Soạn thảo văn bản: Microsoft Word, Notepad,…


• Bảng tính điện tử như: Microsoft Excel, Lotus, Quattro,…
• Thư tín điện tử: Microsoft Mail,…

Khái niệm về mạng Internet

Khái niệm chung về mạng máy tính, lịch sử phát triển

• Khái niệm chung về mạng máy tính.

Là sự kết hợp của hai hay nhiều máy tính với nhau và cho phép dùng chung thiết bị của
nhau, nói cách khác là cho phép chia sẻ tài nguyên giữa các máy tính với nhau như: ổ
đĩa, máy in,…

• Lịch sử phát triển của mạng máy tính.

16/134
Mạng máy tính đầu tiên xuất hiện đó là mạng Sneakernet. Đặc điểm của mạng này là
các máy trao đổi thông tin với nhau thông qua việc dùng các đĩa mềm chép dữ liệu từ
máy này rồi đem sang máy khác dùng. Việc trao đổi dữ liệu đó rất chậm, đôi khi còn
phát sinh nhiều lỗi về dữ liệu. Sau đó người ta phát hiện ra rằng việc trao đổi thông tin
giữa các máy tính dùng Cable hiệu quả hơn, từ đó mạng máy tính được ra đời.

Phân loại mạng máy tính.

Có 4 cách phân loại mạng:

• Phân loại logic mạng: Theo quan điểm này mạng được chia theo khả năng cung
cầu về tài nguyên giữa các máy tính trong mạng và chia làm 3 loại sau:
• Mạng bình đẳng ( peer to peer ): Trong mạng này tất cả các máy có vai trò như
nhau trong mạng, không có máy chủ. Loại mạng này chỉ sử dụng với hệ thống
mạng có quy mô nhỏ.
• Mạng khách chủ (Client/Server): Trong mạng này có một máy chủ và hệ thống
các máy trạm, các tài nguyên chung và quan trọng được tập trung trên máy chủ.
Loại mạng này sử dụng cho hệ thống mạng có quy mô lớn.
• Mạng hỗn hợp: Là sự kết hợp giữa hai loại mạng trên. Loại này được sử dụng
cho hệ thống mạng có quy mô cực lớn.
• Phân loại mạng theo quy mô: Gồm 2 loại:
• Mạng LAN (Local Area Network – Mạng cục bộ): Đây là loại mạng có cấu
trúc thuần nhất, nét đặc trưng nhất để phân biệt mạng LAN với mạng WAN là
khoảng cách từ mỗi máy trạm đến máy chủ không vượt quá khả năng của thiết
bị dành cho mạng cục bộ.
• Mạng WAN (Wide Area Network – Mạng toàn cục): Dùng để chỉ hệ thống
mạng có quy mô lớn, có thể được tạo thành nhờ việc ghép nối của nhiều mạng
LAN và sử dụng các thiết bị viễn thông không có trong mạng LAN (Modem –
Modulation Demodulation - Đều chế và giải điều chế)
• Phân loại theo NIC(Network Interface Card - Card giao diện mạng) Được chia
làm 3 loại tuỳ thuộc vào NIC mà mạng sử dụng gồm:
• Ethernet.
• Arcnet
• Tokenring.
• Phân loại mạng theo sơ đồ nối (Topology): Được chia làm 3 loại:
• Nối theo sơ đồ BUS: Các máy nối tiếp với nhau sử dụng chung một Card.
Điểm đầu và điểm cuối của mạng ở hai đầu khác nhau.
• Nối theo sơ đồ RING: Các máy nối theo vòng tròn, điểm đầu và điểm cuối của
mạng trùng nhau.
• Nối theo sơ đồ STAR: Các máy nối theo kiểu hình sao.

17/134
Internet, Intranet và các dịch vụ trên Internet

• Internet.

Internet là một hệ thống liên kết nhiều mạng máy tính với nhau trên phạm vi toàn cầu
và được gọi là mạng toàn cầu.

Mạng Internet hoạt động trên phạm vi toàn cầu sử dụng công cụ truyền thông chính là
vệ tinh. Tài nguyên trên mạng phong phú, đa dạng về chủng loại và số lượng.

Internet không phải là một chương trình, không phải là phần cứng, không phải là phần
mềm mà nó chỉ là nơi truy xuất thông tin và tạo nên các thông tin lấy miễn phí hay phải
trả tiền.

• Intranet.

Mạng Intranet là mạng cục bộ có phạm vi trên một quốc gia, sử dụng công cụ của
Internet. Tài nguyên trên mạng phong phú, đa dạng về chủng loại và số lượng.

• Các dịch vụ trên Internet.

1. Thư điện tử ( Electric Mail)

Khái niệm: Là dịch vụ phổ biến trên mạng Internet thông qua E_Mail. Mỗi người muốn
tham gia E_Mail cần có một địa chỉ E_Mail riêng của mình và địa chỉ E_Mail nơi gửi
tới.

Lợi ích: Tốc độ truyền cao, đảm bảo độ tin cậy. Khi một E_Mail được gửi đi mà không
có người nhận ngay thì nó sẽ được lưu trên Server.

Ứng dụng: Được ứng dụng trong nhiều lĩnh vực khác nhau như: Truyền các thông tin
ngắn, trao đổi dữ liệu, thông điệp, gửi kèm các tài liệu, tệp tin, chương trình,…

2. Dịch vụ truyền File (File Transfer)

Trên mạng Internet ta có thể truyền các file hình ảnh, âm thanh,… đến một máy trạm
nào đó hay nạp nó lên Internet như một tài nguyên chung của Internet cũng như tải file
từ trên Internet xuống (Nếu như có quyền).

3. Dịch vụ WEB

Trên Internet phổ biến một loại dữ liệu đó là siêu văn bản (bao gồm cả hình ảnh, âm
thanh, chữ viết) nó được sử dụng rộng rãi trong các dịch vụ về thông tin, văn hoá nghệ
thuật trên Internet.

18/134
Để truy cập vào các vùng thông tin mong muốn ta thường sử dụng dịch vụ này. Tất cả
các kho tàng về văn hoá, nghệ thuật, các thông tin kinh tế, thời sự,…đều có thể được
biết đến thông qua các Website (siêu văn bản).

4. Một số dịch vụ khác.

Trên Internet có rất nhiều các dịch vụ, chúng phong phú, đa dạng và có trong tất cả các
lĩnh vực của đời sống xã hội như truy cập thông tin từ xa, các dịch vụ hội thảo, thương
mại điện tử,…

Để sử dụng, nắm bắt được các thông tin trên Internet không có cách nào tốt hơn là hãy
tham gia kết nối Internet. Trên đó ta có thể khai thác đầy đủ các dịch vụ và thông tin cần
thiết.

19/134
Bài 3: Giải bài toán bằng máy tính
Giải bài toán bằng máy tính
THUẬT TOÁN

Thuật toán, còn gọi là giải thuật, là một tập hợp hữu hạn của các chỉ thị hay phương
cách được định nghĩa rõ ràng cho việc hoàn tất một số sự việc từ một trạng thái ban đầu
cho trước; khi các chỉ thị này được áp dụng triệt để thì sẽ dẫn đến kết quả sau cùng như
đã dự đoán.

Nói cách khác, thuật toán là một bộ các qui tắc hay qui trình cụ thể nhằm giải quyết một
vấn đề trong một số bước hữu hạn, hoặc nhằm cung cấp một kết quả từ một tập hợp của
các dữ kiện đưa vào.

Ví dụ: thuật toán để giải phương trình bậc nhất P(x): ax + b = c, (a, b, c là các số thực),
trong tập hợp các số thực có thể là một bộ các bước sau đây:

Nếu a = 0

b = c thì P(x) có nghiệm bất kì

b ≠ c thì P(c) vô nghiệm

Nếu a ≠ 0

P(x) có duy nhất một nghiệm x = (c - b)/a

Lưu ý:

Khi một thuật toán đã hình thành thì ta không xét đến việc chứng minh thuật toán đó mà
chỉ chú trọng đến việc áp dụng các bước theo sự hướng dẫn sẽ có kết quả đúng. Việc
chứng minh tính đầy đủ và tính đúng của các thuật toán phải được tiến hành xong trước
khi có thuật toán. Nói rõ hơn, thuật toán có thể chỉ là việc áp dụng các công thức hay
qui tắc, qui trình đã được công nhận là đúng hay đã được chứng minh về mặt toán học.

"Thuật toán" hiện nay thường được dùng để chỉ thuật toán giải quyết các vấn đề tin học.
Hầu hết các thuật toán tin học đều có thể viết thành các chương trình máy tính mặc dù
chúng thường có một vài hạn chế (vì khả năng của máy tính và khả năng của người lập
trình). Trong nhiều trường hợp, một chương trình khi thiết kế bị thất bại là do lỗi ở các
thuật toán mà người lập trình đưa vào là không chính xác, không đầy đủ, hay không ước

20/134
định được trọn vẹn lời giải của vấn đề. Tuy nhiên cũng có một số bài toán mà hiện nay
người ta chưa tìm được lời giải triệt để, những bài toán ấy gọi là những bài toán NP-
không đầy đủ.

Thuật toán: Thuật toán của một bài toán là một hệ thống chặt chẽ và rõ ràng các quy tắc
nhằm xác định một dãy các thao tác trên những dữ liệu vào (Input), sao cho sau một số
hữu hạn bước thực hiện các thao tác ta thu được kết quả (Output) của bài toán đó.

Chương trình:

Khái niệm thuật giải: Là một tập hợp các thao tác được sắp sếp theo một trình tự nào
đó nhằm giải quyết một vấn đề có hiệu quả.

Biểu diễn thuật toán

Để mô tả thuật giải người ta có thể dùng ngôn ngữ tự nhiên nhưng cũng có thể dùng
hình ảnh trực quan hơn để thể hiện quá trình diễn tiến của việc giải quyết bài toán. Một
thuật giải được biểu diễn bằng các kí hiệu đồ hoạ (Đồ thuật) ta gọi là lưu đồ thuật giải.

Một số thuật toán thông dụng

Sắp xếp nổi bọt

Sắp xếp nổi bọt (bubble sort) là phương pháp sắp xếp đơn giản, dễ hiểu thường được
dạy trong khoa học máy tính. Giải thuật bắt đầu từ đầu của tập dữ liệu. Nó so sánh hai
phần tử đầu, nếu phần tử đứng trước lớn hơn phần tử đứng sau thì đổi chỗ chúng cho
nhau. Tiếp tục làm như vậy với cặp phần tử tiếp theo cho đến cuối tập hợp dữ liệu. Sau
đó nó quay lại với hai phần tử đầu cho đến khi không còn cần phải đổi chỗ nữa.

Sắp xếp chèn

Sắp xếp chèn (insertion sort) là một thuật toán sắp xếp rất hiệu quả với các danh sách
nhỏ. Nó lần lượt lấy các phần tử của danh sách chèn vào vị trí thích hợp trong một danh
sách mới đã được sắp.

Sắp xếp chọn

Sắp xếp chọn (select sort) là phương pháp sắp xếp bằng cách chọn phần tử bé nhất xếp
vào vị trí thứ nhất, tương tự với các phần tử nhỏ thứ hai, thứ ba,...

21/134
Sắp xếp trộn

Sắp xếp trộn (merge sort) cùng với sắp xếp nhanh là hai thuật toán sắp xếp dựa vào tư
tưởng "chia để trị" (divide and conquer). Thủ tục cơ bản là việc trộn hai danh sách đã
được sắp xếp vào một danh sách mới theo thứ tự. Nó có thể bắt đầu trộn bằng cách so
sánh hai phần tử một (chẳng hạn phần tử thứ nhất với phần tử thứ hai, sau đó thứ ba với
thứ tư...) và sau khi kết thúc bước 1 nó chuyển sang bước 2. Ở bước 2 nó trộn các danh
sách hai phần tử thành các danh sách bốn phần tử. Cứ như vậy cho đến khi hai danh sách
cuối cùng được trộn thành một.

Sắp xếp vun đống

Sắp xếp vun đống (heapsort) là một trong các phương pháp sắp xếp chọn. Ở mỗi bước
của sắp xếp chọn ta chọn phần tử lớn nhất (hoặc nhỏ nhất) đặt vào cuối (hoặc đầu) danh
sách, sau đó tiếp tục với phần còn lại của danh sách. Thông thường sắp xếp chọn chạy
trong thời gian O(n2). Nhưng heapsort đã giảm độ phức tạp này bằng cách sử dụng một
cấu trúc dữ liệu đặc biệt được gọi là đống (heap). Đống là cây nhị phân mà trọng số ở
mỗi đỉnh cha lớn hơn hoặc bằng trọng số các đỉnh con của nó. Một khi danh sách dữ
liệu đã được vun thành đống, gốc của nó là phần tử lớn nhất, thuật toán sẽ giải phóng nó
khỏi đống để đặt vào cuối danh sách. Sắp xếp vun đống chạy trong thời gian O(n log n).

Sắp xếp nhanh

Sắp xếp nhanh (quicksort) là một thuật toán theo tư tưởng chia để trị, nó dựa trên thủ
tục phân chia như sau: để chia một dãy ta chọn một phần tử được gọi là "chốt" (pivot),
chuyển tất cả các phần tử nhỏ hơn chốt về trước chốt, chuyển tất cả các phần tử lớn hơn
chốt về sau nó. Thủ tục này có thể thực hiện trong thời gian tuyến tính. Tiếp tục phân
chia các dãy con đó như trên cho đến khi các dãy con chỉ còn một phần tử.

Điểm khác biệt giữa sắp xếp nhanh và sắp xếp trộn là trong sắp xếp trộn việc xác định
thứ tự được xác định khi "trộn", tức là trong khâu tổng hợp lời giải sau khi các bài toán
con đã được giải, còn sắp xếp nhanh đã quan tâm đến thứ tự các phần tử khi phân chia
một danh sách thành hai danh sách con.

Ngoài ra còn nhiều giải thuật sắp xếp khác, trong đó nhiều giải thuật sắp xếp được cải
tiến từ các giải thuật trên. Trong sau giải thuật liệt kê trên, ta thường coi các giải thuật
chèn, chọn, nổi bọt là các giải thuật cơ bản, độ phức tạp trong trường hợp trung bình của
chúng là O(n2). Ba giải thuật còn lại thường được coi là giải thuật cao cấp, độ phức tạp
tính toán trung bình của chúng là n.lnn.

22/134
Sắp xếp theo cơ số

Sắp xếp theo cơ số (radix sort) dựa trên tính chất "số" của các khóa. Trong giải thuật
sắp xếp theo cơ số, ta không chỉ so sánh giá trị của các khóa, mà so sánh các thành phần
của khóa. Giả sử các khóa là các số biểu diễn theo hệ ghi số cơ số M. Khi đó sắp xếp
theo cơ số sẽ so sánh từng ký số của nó.

Chúng ta mô tả cách sắp này khi cơ số M=10. Giả sử phải sắp các hồ sơ đánh số bởi
3 chữ số thập phân. Đầu tiên ta chia các hồ sơ vào các đống có cùng chữ số hàng trăm
(đồng thới xếp các đống theo thứ tự của chữ số hàng trăm), trong mỗi đống con lại phân
chia theo chữ số hàng chục, cuối cùng trong mỗi đống có cùng chữ số hàng trăm và hàng
chục, sắp xếp theo thứ tự của chữ số hàng đơn vị.

Trong máy tính, đương nhiên việc sắp xếp theo cơ số nhị phân (cơ số 2) hoặc cơ số là
lũy thừa của 2 là thuận lợi nhất. Trong trường hợp cơ số 2, việc phân hoạch tương tự
như phân hoạch trong Quick Sort, chỉ khác ở chỗ cách chọn phần tử chốt.

Sắp xếp đếm phân phối

Sắp xếp đếm phân phối là phương pháp sắp xếp có độ phức tạp tuyến tính trong trường
hợp các khóa nhận hữu hạn giá trị trong khoảng cho trước. Để đơn giản ta giả sử các
phần tử của danh sách a[1..n] nhận các giá trị tự nhiên trong khoảng [1..M].

Sắp xếp đếm phân phối đầu tiên đếm các phần tử thuộc danh sách nhận giá trị k với

. Các giá trị đếm được đươc ghi vào mảng Counter[1..M]. Sau đó khi duyệt theo k từ 1
đến M, ta lần lượt xếp Counter[k] phần tử của vào danh sách a[1..n].

23/134
Bài 4-5-6: Thực hành, thảo luận và tổng
quan về lập trình
Thực hành, thảo luận và tổng quan về lập trình
Bài thực hành làm quen với máy tính, hệ thống tính toán Thảo luận về các bước giải
quyết bài toán trên máy tính

Thảo luận về các bước giải quyết bài toán trên máy tính

Tổng quan về lập trình

Giới thiệu phương pháp học

Các ngôn ngữ lập trình ra đời và lỗi thời nhanh một cách đáng kinh ngạc trong ngành
Khoa học Máy tính. Các ngôn ngữ lập trình mới thường chứa đựng những quy tắc khác
nhau làm cho mọi người phải thường xuyên thay đổi cách dùng các công cụ cũng như
thói quen lập trình. Nhưng việc học một ngôn ngữ lập trình mới để cung cấp thêm kiến
thức cho nghề nghiệp của mình cũng là một nhu cầu chính đáng.

Trước khi học một ngôn ngữ mới, bạn thường đặt ra câu hỏi: Làm sao để học ngôn ngữ
lập trình này được hiệu quả? Có một vài gợi ý nhỏ sau có thể giúp bạn học các ngôn ngữ
lập trình dễ dàng hơn:

• Nắm vững các kiểu dữ liệu cơ bản mà ngôn ngữ lập trình cung cấp. Hầu hết các
ngôn ngữ đều cung cấp kiểu số nguyên integer. Bạn phải tìm hiểu thêm thế nào
là long integer hoặc short integer? Thế nào là kiểu liệt kê (Enumerated)? Thế
nào là kiểu kí tự (Character)? Thế nào là kiểu chuỗi (String)? Ngôn ngữ có hỗ
trợ kiểu số thực dấu chấm động hay không, và tầm giá trị của mỗi kiểu dữ liệu
là bao nhiêu? Và khi một ngôn ngữ nào đó không hỗ trợ kiểu dữ liệu mà bạn
cần dùng thì tốt hơn bạn nên chuyển sang dùng một ngôn ngữ khác.
• Nắm vững cấu trúc dữ liệu cơ bản được ngôn ngữ cung cấp. Chẳng hạn Pascal
có cấu trúc mảng (array), Lisp có thể thao tác rất dễ dàng với cấu trúc danh
sách (list), còn Java thì có thể làm việc với các lớp và các giao tiếp.…Và những
vấn đề bạn nghĩ trong đầu cuối cùng phải được biểu diễn bằng các kiểu dữ liệu
mà ngôn ngữ cung cấp, việc hiểu rõ mối quan hệ giữa chúng là nền tảng để giải
quyết các vấn đề.
• Ngôn ngữ cung cấp những toán tử dựng sẵn nào? Ví dụ: Prolog xem tìm kiếm
là một thao tác cơ bản, Snobol xem thao tác đối sánh mẫu trên các chuỗi (string
pattern matching) là một toán tử cơ sở, các ngôn ngữ hàm (ML, Haskell) cho

24/134
phép bạn tạo ra một giá trị mới nhưng không làm thay đổi cấu trúc hiện tại,
APL cung cấp toán tử ma trận, … Danh sách các toán tử dựng sẵn của một
ngôn ngữ sẽ cho ta biết những vấn đề mà những chuyên gia thiết kế ngôn ngữ
đó cho là quan trọng nhất.
• Nắm vững loại vấn đề mà ngôn ngữ có thể trợ giúp giải quyết. Các ngôn ngữ
thường được phát triển vì một lý do nào đó, thường là để giải quyết một loại
vấn đề mang tính đặc trưng. Do đó, bạn nên cố gắng nắm rõ những chức năng
đặc trưng của ngôn ngữ để giải quyết vấn đề đồng thời cũng nên tìm hiểu tại
sao cùng một vấn đề nhưng dùng ngôn ngữ này để giải quyết lại dễ dàng hơn
dùng ngôn ngữ khác.
• Tìm hiểu những thư viện có sẵn trong ngôn ngữ. Các ngôn ngữ thường có các
thư viện do nhiều người đã phát triển để giải quyết những vấn đề khác nhau,
bạn có thể sử dụng lại để giải quyết một vấn đề mới. Smalltalk có một thư viện
đồ sộ với lượng mã luôn sẵn sàng để người lập trình sử dụng. C++ với thư viện
chuẩn STL chứa nhiều cấu trúc dữ liệu thường dùng. Java có các thư viện cung
cấp các tác vụ về mạng. Bạn hãy cố gắng tìm và sẽ thấy những gì cần thiết sẵn
có.
• Hãy học hỏi, mô phỏng lại! Bắt đầu với việc mô phỏng lại các chương trình
hiện có. Phải làm cho chúng có thể hoạt động trên hệ thống của bạn, bởi vì hệ
thống mà nó được phát triển có thể không giống với hệ thống của bạn, và khi
bạn có thể làm cho nó hoạt động tốt trên hệ thống của mình thì tức là bạn đã
hiểu rõ về nó. Học các chương trình để hình dung được các tính năng khác
nhau của ngôn ngữ.
• Hãy thử nghiệm và rút ra kết luận! Khi bạn đã có một vài chương trình có thể
chạy tốt, bạn thử nghiệm bằng cách tạo ra một vài thay đổi. Bạn có thể lấy ra
một chương trình và sửa lại nó để giải quyết một vấn đề sai khác chút ít so với
chương trình ban đầu hay không? Bạn có thể lấy ra một phần nhỏ của chương
trình và diễn đạt lại bằng cách khác hay không?
• Hiện thực lại các vấn đề đã hiểu rõ bằng một ngôn ngữ mới. Lấy một vài
chương trình đã được viết trong một ngôn ngữ rồi cố gắng viết lại chúng trong
ngôn ngữ mới. Không nên dịch từng câu lệnh sang ngôn ngữ mới mà hãy xem
xét những tính năng đặc trưng nào của ngôn ngữ mới có thể dùng để giải quyết
vấn đề. Cẩn thận xem xét những vấn đề nào dễ dàng hiện thực trong ngôn ngữ
mới và những vấn đề nào khó khăn hơn. (Chương trình truyền thống đầu tiên
nên viết là chương trình in ra chuỗi "hello world").
• Khi gặp một vấn đề mới thì nên nghĩ về những vấn đề đã biết trước đó có cùng
đặc điểm với

25/134
Ngôn ngữ lập trình

Khái niệm ngôn ngữ lập trình

Ngôn ngữ lập trình là một ngôn ngữ dùng để viết chương trình cho máy tính. Ta có thể
chia ngôn ngữ lập trình thành các loại sau: ngôn ngữ máy, hợp ngữ và ngôn ngữ cấp cao.

Ngôn ngữ máy (machine language): Là các chỉ thị dưới dạng nhị phân, can thiệp trực
tiếp vào trong các mạch điện tử. Chương trình được viết bằng ngôn ngữ máy thì có thể
được thực hiện ngay không cần qua bước trung gian nào. Tuy nhiên chương trình viết
bằng ngôn ngữ máy dễ sai sót, cồng kềnh và khó đọc, khó hiểu vì toàn những con số 0
và 1.

Hợp ngữ (assembly language): Bao gồm tên các câu lệnh và quy tắc viết các câu lệnh
đó. Tên các câu lệnh bao gồm hai phần: phần mã lệnh (viết tựa tiếng Anh) chỉ phép toán
cần thực hiện và địa chỉ chứa toán hạng của phép toán đó. Ví dụ:

INPUT a ; Nhập giá trị cho a từ bàn phím

LOAD a ; Đọc giá trị a vào thanh ghi tổng A

PRINT a; Hiển thị giá trị của a ra màn hình.

INPUT b

ADD b; Cộng giá trị của thanh ghi tổng A với giá trị b

Trong các lệnh trên thì INPUT, LOAD, PRINT, ADD là các mã lệnh còn a, b là địa chỉ.
Để máy thực hiện được một chương trình viết bằng hợp ngữ thì chương trình đó phải
được dịch sang ngôn ngữ máy. Công cụ thực hiện việc dịch đó được gọi là Assembler.

Ngôn ngữ cấp cao (High level language): Ra đời và phát triển nhằm phản ánh cách thức
người lập trình nghĩ và làm. Rất gần với ngôn ngữ con người (Anh ngữ) nhưng chính
xác như ngôn ngữ toán học. Cùng với sự phát triển của các thế hệ máy tính, ngôn ngữ
lập trình cấp cao cũng được phát triển rất đa dạng và phong phú, việc lập trình cho
máy tính vì thế mà cũng có nhiều khuynh hướng khác nhau: lập trình cấu trúc, lập trình
hướng đối tượng, lập trình logic, lập trình hàm... Một chương trình viết bằng ngôn ngữ
cấp cao được gọi là chương trình nguồn (source programs). Để máy tính "hiểu" và thực
hiện được các lệnh trong chương trình nguồn thì phải có một chương trình dịch để dịch
chuơng trình nguồn (viết bằng ngôn ngữ cấp cao) thành dạng chương trình có khả năng
thực thi.

26/134
Chương trình dịch

Như trên đã trình bày, muốn chuyển từ chương trình nguồn sang chương trình đích phải
có chương trình dịch. Thông thường mỗi một ngôn ngữ cấp cao đều có một chương trình
dịch riêng nhưng chung quy lại thì có hai cách dịch: thông dịch và biên dịch.

Thông dịch (interpreter): Là cách dịch từng lệnh một, dịch tới đâu thực hiện tới đó.
Chẳng hạn ngôn ngữ LISP sử dụng trình thông dịch.

Biên dịch (compiler): Dịch toàn bộ chương trình nguồn thành chương trình đích rồi sau
đó mới thực hiện. Các ngôn ngữ sử dụng trình biên dịch như Pascal, C...

Giữa thông dịch và biên dịch có khác nhau ở chỗ: Do thông dịch là vừa dịch vừa thực
thi chương trình còn biên dịch là dịch xong toàn bộ chương trình rồi mới thực thi nên
chương trình viết bằng ngôn ngữ biên dịch thực hiện nhanh hơn chương trình viết bằng
ngôn ngữ thông dịch.

Một số ngôn ngữ sử dụng kết hợp giữa thông dịch và biên dịch chẳng hạn như Java.
Chương trình nguồn của Java được biên dịch tạo thành một chương trình đối tượng (một
dạng mã trung gian) và khi thực hiện thì từng lệnh trong chương trình đối tượng được
thông dịch thành mã máy.

Các phương pháp lập trình

Lập trình tuyến tính

Máy tính đầu tiên được lập trình bằng mã nhị phân, sử dụng các công tắt cơ khí để nạp
chương trình. Cùng với sự xuất hiện của các thiết bị lưu trữ lớn và bộ nhớ máy tính có
dung lượng lớn nên các ngôn ngữ lập trình cấp cao đầu tiên được đưa vào sử dụng .
Thay vì phải suy nghĩ trên một dãy các bit và byte, lập trình viên có thể viết một loạt
lệnh gần với tiếng Anh và sau đó chương trình dịch thành ngôn ngữ máy.

Các ngôn ngữ lập trình cấp cao đầu tiên được thiết kế để lập các chương trình làm các
công việc tương đối đơn giản như tính toán. Các chương trình ban đầu chủ yếu liên quan
đến tính toán và không đòi hỏi gì nhiều ở ngôn ngữ lập trình. Hơn nữa phần lớn các
chương trình này tương đối ngắn, thường ít hơn 100 dòng.

Khi khả năng của máy tính tăng lên thì khả năng để triển khai các chương trình phức
tạp hơn cũng tăng lên. Các ngôn ngữ lập trình ngày trước không còn thích hợp đối với
việc lập trình đòi hỏi cao hơn. Các phương tiện cần thiết để sử dụng lại các phần mã
chương trình đã viết hầu như không có trong ngôn ngữ lập trình tuyến tính. Thật ra, một
đoạn lệnh thường phải được chép lặp lại mỗi khi chúng ta dùng trong nhiều chương trình
do đó chương trình dài dòng, logic của chương trình khó hiểu. Chương trình được điều

27/134
khiển để nhảy đến nhiều chỗ mà thường không có sự giải thích rõ ràng, làm thế nào để
chương trình đến chỗ cần thiết hoặc tại sao như vậy.

Ngôn ngữ lập trình tuyến tính không có khả năng kiểm soát phạm vi nhìn thấy của các
dữ liệu. Mọi dữ liệu trong chương trình đều là dữ liệu toàn cục nghĩa là chúng có thể bị
sửa đổi ở bất kỳ phần nào của chương trình. Việc dò tìm các thay đổi không mong muốn
đó của các phần tử dữ liệu trong một dãy mã lệnh dài và vòng vèo đã từng làm cho các
lập trình viên rất mất thời gian.

Lập trình cấu trúc

Rõ ràng là các ngôn ngữ mới với các tính năng mới cần phải được phát triển để có thể
tạo ra các ứng dụng tinh vi hơn. Vào cuối các năm trong 1960 và 1970, ngôn ngữ lập
trình có cấu trúc ra đời. Các chương trình có cấu trúc được tổ chức theo các công việc
mà chúng thực hiện.

Về bản chất, chương trình chia nhỏ thành các chương trình con riêng rẽ (còn gọi là hàm
hay thủ tục) thực hiện các công việc rời rạc trong quá trình lớn hơn, phức tạp hơn. Các
hàm này được giữ càng độc lập với nhau càng nhiều càng tốt, mỗi hàm có dữ liệu và
logic riêng.Thông tin được chuyển giao giữa các hàm thông qua các tham số, các hàm
có thể có các biến cục bộ mà không một ai nằm bên ngoài phạm vi của hàm lại có thể
truy xuất được chúng. Như vậy, các hàm có thể được xem là các chương trình con được
đặt chung với nhau để xây dựng nên một ứng dụng.

Mục tiêu là làm sao cho việc triển khai các phần mềm dễ dàng hơn đối với các lập trình
viên mà vẫn cải thiện được tính tin cậy và dễ bảo quản chương trình. Một chương trình
có cấu trúc được hình thành bằng cách bẻ gãy các chức năng cơ bản của chương trình
thành các mảnh nhỏ mà sau đó trở thành các hàm. Bằng cách cô lập các công việc vào
trong các hàm, chương trình có cấu trúc có thể làm giảm khả năng của một hàm này ảnh
hưởng đến một hàm khác. Việc này cũng làm cho việc tách các vấn đề trở nên dễ dàng
hơn. Sự gói gọn này cho phép chúng ta có thể viết các chương trình sáng sủa hơn và giữ
được điều khiển trên từng hàm. Các biến toàn cục không còn nữa và được thay thế bằng
các tham số và biến cục bộ có phạm vi nhỏ hơn và dễ kiểm soát hơn. Cách tổ chức tốt
hơn này nói lên rằng chúng ta có khả năng quản lý logic của cấu trúc chương trình, làm
cho việc triển khai và bảo dưỡng chương trình nhanh hơn và hữu hiện hơn và hiệu quả
hơn.

Một khái niệm lớn đã được đưa ra trong lập trình có cấu trúc là sự trừu tượng hóa
(Abstraction). Sự trừu tượng hóa có thể xem như khả năng quan sát một sự việc mà
không cần xem xét đến các chi tiết bên trong của nó. Trong một chương trình có cấu
trúc, chúng ta chỉ cần biết một hàm đã cho có thể làm được một công việc cụ thể gì là
đủ. Còn làm thế nào mà công việc đó lại thực hiện được là không quan trọng, chừng nào
hàm còn tin cậy được thì còn có thể dùng nó mà không cần phải biết nó thực hiện đúng

28/134
đắn chức năng của mình như thế nào. Điều này gọi là sự trừu tượng hóa theo chức năng
(Functional abstraction) và là nền tảng của lập trình có cấu trúc.

Ngày nay, các kỹ thuật thiết kế và lập trình có cấu trúc được sử rộng rãi. Gần như mọi
ngôn ngữ lập trình đều có các phương tiện cần thiết để cho phép lập trình có cấu trúc.
Chương trình có cấu trúc dễ viết, dễ bảo dưỡng hơn các chương trình không cấu trúc.

Sự nâng cấp như vậy cho các kiểu dữ liệu trong các ứng dụng mà các lập trình viên đang
viết cũng đang tiếp tục diễn ra. Khi độ phức tạp của một chương trình tăng lên, sự phụ
thuộc của nó vào các kiểu dữ liệu cơ bản mà nó xử lý cũng tăng theo. Vấn đề trở rõ ràng
là cấu trúc dữ liệu trong chương trình quan trọng chẳng kém gì các phép toán thực hiện
trên chúng. Điều này càng trở rõ ràng hơn khi kích thước của chương trình càng tăng.
Các kiểu dữ liệu được xử lý trong nhiều hàm khác nhau bên trong một chương trình có
cấu trúc. Khi có sự thay đổi trong các dữ liệu này thì cũng cần phải thực hiện cả các thay
đổi ở mọi nơi có các thao tác tác động trên chúng. Đây có thể là một công việc tốn thời
gian và kém hiệu quả đối với các chương trình có hàng ngàn dòng lệnh và hàng trăm
hàm trở lên.

Một yếu điểm nữa của việc lập trình có cấu trúc là khi có nhiều lập trình viên làm việc
theo nhóm cùng một ứng dụng nào đó. Trong một chương trình có cấu trúc, các lập trình
viên được phân công viết một tập hợp các hàm và các kiểu dữ liệu. Vì có nhiều lập trình
viên khác nhau quản lý các hàm riêng, có liên quan đến các kiểu dữ liệu dùng chung
nên các thay đổi mà lập trình viên tạo ra trên một phần tử dữ liệu sẽ làm ảnh hưởng đến
công việc của tất cả các người còn lại trong nhóm. Mặc dù trong bối cảnh làm việc theo
nhóm, việc viết các chương trình có cấu trúc thì dễ dàng hơn nhưng sai sót trong việc
trao đổi thông tin giữa các thành viên trong nhóm có thể dẫn tới hậu quả là mất rất nhiều
thời gian để sửa chữa chương trình.

Sự trừu tượng hóa dữ liệu

Sự trừu tượng hóa dữ liệu (Data abstraction) tác động trên các dữ liệu cũng tương tự
như sự trừu tượng hóa theo chức năng. Khi có trừu tượng hóa dữ liệu, các cấu trúc dữ
liệu và các phần tử có thể được sử dụng mà không cần bận tâm đến các chi tiết cụ thể.
Chẳng hạn như các số dấu chấm động đã được trừu tượng hóa trong tất cả các ngôn ngữ
lập trình, Chúng ta không cần quan tâm cách biểu diễn nhị phân chính xác nào cho số
dấu chấm động khi gán một giá trị, cũng không cần biết tính bất thường của phép nhân
nhị phân khi nhân các giá trị dấu chấm động. Điều quan trọng là các số dấu chấm động
hoạt động đúng đắn và hiểu được.

Sự trừu tượng hóa dữ liệu giúp chúng ta không phải bận tâm về các chi tiết không cần
thiết. Nếu lập trình viên phải hiểu biết về tất cả các khía cạnh của vấn đề, ở mọi lúc và
về tất cả các hàm của chương trình thì chỉ ít hàm mới được viết ra, may mắn thay trừu
tượng hóa theo dữ liệu đã tồn tại sẵn trong mọi ngôn ngữ lập trình đối với các dữ liệu

29/134
phức tạp như số dấu chấm động. Tuy nhiên chỉ mới gần đây, người ta mới phát triển các
ngôn ngữ cho phép chúng ta định nghĩa các kiểu dữ liệu trừu tượng riêng.

Lập trình hướng đối tượng

Khái niệm hướng đối tượng được xây dựng trên nền tảng của khái niệm lập trình có cấu
trúc và sự trừu tượng hóa dữ liệu. Sự thay đổi căn bản ở chỗ, một chương trình hướng
đối tượng được thiết kế xoay quanh dữ liệu mà chúng ta có thể làm việc trên đó, hơn là
theo bản thân chức năng của chương trình. Điều này hoàn toàn tự nhiên một khi chúng
ta hiểu rằng mục tiêu của chương trình là xử lý dữ liệu. Suy cho cùng, công việc mà
máy tính thực hiện vẫn thường được gọi là xử lý dữ liệu. Dữ liệu và thao tác liên kết với
nhau ở một mức cơ bản (còn có thể gọi là mức thấp), mỗi thứ đều đòi hỏi ở thứ kia có
mục tiêu cụ thể, các chương trình hướng đối tượng làm tường minh mối quan hệ này.

Lập trình hướng đối tượng (Object Oriented Programming - gọi tắt là OOP) hay chi tiết
hơn là Lập trình định hướng đối tượng, chính là phương pháp lập trình lấy đối tượng
làm nền tảng để xây dựng thuật giải, xây dựng chương trình. Thực chất đây không phải
là một phương pháp mới mà là một cách nhìn mới trong việc lập trình. Để phân biệt,
với phương pháp lập trình theo kiểu cấu trúc mà chúng ta quen thuộc trước đây, hay còn
gọi là phương pháp lập trình hướng thủ tục (Procedure-Oriented Programming), người
lập trình phân tích một nhiệm vụ lớn thành nhiều công việc nhỏ hơn, sau đó dần dần chi
tiết, cụ thể hoá để được các vấn đề đơn giản, để tìm ra cách giải quyết vấn đề dưới dạng
những thuật giải cụ thể rõ ràng qua đó dễ dàng minh hoạ bằng ngôn ngữ giải thuật (hay
còn gọi các thuật giải này là các chương trình con). Cách thức phân tích và thiết kế như
vậy chúng ta gọi là nguyên lý lập trình từ trên xuống (top-down), để thể hiện quá trình
suy diễn từ cái chung cho đến cái cụ thể.

Các chương trình con là những chức năng độc lập, sự ghép nối chúng lại với nhau cho
chúng ta một hệ thống chương trình để giải quyết vấn đề đặt ra. Chính vì vậy, cách thức
phân tích một hệ thống lấy chương trình con làm nền tảng, chương trình con đóng vai
trò trung tâm của việc lập trình, được hiểu như phương pháp lập trình hướg về thủ tục.
Tuy nhiên, khi phân tích để thiết kế một hệ thống không nhất thiết phải luôn luôn suy
nghĩ theo hướng “làm thế nào để giải quyết công việc”, chúng ta có thể định hướng tư
duy theo phong cách “với một số đối tượng đã có, phải làm gì để giải quyết được công
việc đặt ra” hoặc phong phú hơn, “làm cái gì với một số đối tượng đã có đó”, từ đó cũng
có thể giải quyết được những công việc cụ thể. Với phương pháp phân tích trong đó đối
tượng đóng vai trò trùng tâm của việc lập trình như vậy, người ta gọi là nguyên lý lập
trình từ dưới lên (Bôttm-up).

Lập trình hướng đối tượng liên kết cấu trúc dữ liệu với các thao tác, theo cách mà tất cả
thường nghĩ về thế giới quanh mình. Chúng ta thường gắn một số các hoạt động cụ thể
với một loại hoạt động nào đó và đặt các giả thiết của mình trên các quan hệ đó.

30/134
Ví dụ1.1: Để dễ hình dùng hơn, chúng ta thủ nhìn qua các công trình xây dựng hiện đại,
như sân vận động có mái che hình vòng cung, những kiến trúc thẩm mĩ với đường nét
hình cong. Tất cả những sản phẩm đó xuất hiện cùng với những vật liệu xây dựng. Ngày
nay, không chỉ chồng lên nhau những viên gạch, những tảng đá để tạo nên những quần
thể kiến trúc (như Tháp Chàm Nha Trang, Kim Tự Tháp,...), mà có thể với bêtông, sắt
thép và không nhiều lắm những viên gạch, người xây dựng cũng có thể thiết kế những
công trình kiến trúc tuyệt mỹ, những toà nhà hiện đại. Chính các chất liệu xây dựng đã
làm ảnh hưởng phương pháp xây dựng, chất liệu xây dựng và nguyên lý kết dính caá
chất liệu đó lại với nhau cho chúng ta một đối tượng để khảo sát, Chất liệu xây dựng
và nguyên lý kết dính các chất liệu lại với nhau được hiểu theo nghĩa dữ liệu và chương
trình con tác động trên dữ liệu đó.

Ví dụ1.2: Chúng ta biết rằng một chiếc xe có các bánh xe, di chuyển được và có thể đổi
hướng của nó bằng cách quẹo tay lái. Tương tự như thế, một cái cây là một loại thực vật
có thân gỗ và lá. Một chiếc xe không phải là một cái cây, mà cái cây không phải là một
chiếc xe, chúng ta có thể giả thiết rằng cái mà chúng ta có thể làm được với một chiếc
xe thì không thể làm được với một cái cây. Chẳng hạn, thật là vô nghĩa khi muốn lái một
cái cây, còn chiếc xe thì lại chẳng lớn thêm được khi chúng ta tưới nước cho nó.

Lập trình hướng đối tượng cho phép chúng ta sử dụng các quá trình suy nghĩ như vậy
với các khái niệm trừu tượng được sử dụng trong các chương trình máy tính. Một mẫu
tin (record) nhân sự có thể được đọc ra, thay đổi và lưu trữ lại; còn số phức thì có thể
được dùng trong các tính toán. Tuy vậy không thể nào lại viết một số phức vào tập tin
làm mẫu tin nhân sự và ngược lại hai mẫu tin nhân sự lại không thể cộng với nhau được.
Một chương trình hướng đối tượng sẽ xác định đặc điểm và hành vi cụ thể của các kiểu
dữ liệu, điều đó cho phép chúng ta biết một cách chính xác rằng chúng ta có thể có được
những gì ở các kiểu dữ liệu khác nhau.

Chúng ta còn có thể tạo ra các quan hệ giữa các kiểu dữ liệu tương tự nhưng khác nhau
trong một chương trình hướng đối tượng. Người ta thường tự nhiên phân loại ra mọi
thứ, thường đặt mối liên hệ giữa các khái niệm mới với các khái niệm đã có, và thường
có thể thực hiện suy diễn giữa chúng trên các quan hệ đó. Hãy quan niệm thế giới theo
kiểu cấu trúc cây, với các mức xây dựng chi tiết hơn kế tiếp nhau cho các thế hệ sau so
với các thế hệ trước. Đây là phương pháp hiệu quả để tổ chức thế giới quanh chúng ta.
Các chương trình hướng đối tượng cũng làm việc theo một phương thức tương tự, trong
đó chúng cho phép xây dựng các các cơ cấu dữ liệu và thao tác mới dựa trên các cơ cấu
có sẵn, mang theo các tính năng của các cơ cấu nền mà chúng dựa trên đó, trong khi vẫn
thêm vào các tính năng mới.

Lập trình hướng đối tượng cho phép chúng ta tổ chức dữ liệu trong chương trình theo
một cách tương tự như các nhà sinh học tổ chức các loại thực vật khác nhau. Theo cách
nói lập trình đối tượng, xe hơi, cây cối, các số phức, các quyển sách đều được gọi là các
lớp (Class).

31/134
Một lớp là một bản mẫu mô tả các thông tin cấu trúc dữ liệu, lẫn các thao tác hợp lệ của
các phần tử dữ liệu. Khi một phần tử dữ liệu được khai báo là phần tử của một lớp thì
nó được gọi là một đối tượng (Object). Các hàm được định nghĩa hợp lệ trong một lớp
được gọi là các phương thức (Method) và chúng là các hàm duy nhất có thể xử lý dữ
liệu của các đối tượng của lớp đó. Một thực thể (Instance) là một vật thể có thực bên
trong bộ nhớ, thực chất đó là một đối tượng (nghĩa là một đối tượng được cấp phát vùng
nhớ).

Mỗi một đối tượng có riêng cho mình một bản sao các phần tử dữ liệu của lớp còn gọi
là các biến thực thể (Instance variable). Các phương thức định nghĩa trong một lớp có
thể được gọi bởi các đối tượng của lớp đó. Điều này được gọi là gửi một thông điệp
(Message) cho đối tượng. Các thông điệp này phụ thuộc vào đối tượng, chỉ đối tượng
nào nhận thông điệp mới phải làm việc theo thông điệp đó. Các đối tượng đều độc lập
với nhau vì vậy các thay đổi trên các biến thể hiện của đối tượng này không ảnh hưởng
gì trên các biến thể hiện của các đối tượng khác và việc gửi thông điệp cho một đối
tượng này không ảnh hưởng gì đến các đối tượng khác.

Như vậy, đối tợng được hiểu theo nghĩa là một thực thể mà trong đó caá dữ liệu và thủ
tục tác động lên dữ liệu đã được đóng gói lại với nhau. Hay “đối tượng được đặc trưng
bởi một số thao tác (operation) và các thông tin (information) ghi nhơ sự tác động của
caá thao tác này.”

Ví dụ 1.3: Khi nghiên cứ về ngăn xếp (stack), ngoài các dữ liệu vùng chứa ngăn xếp,
đỉnh của ngăn xếp, chúng ta phải cài đặt kèm theo các thao tác như khởi tạo (creat) ngăn
xếp, kiểm tra ngăn xếp rỗng (empty), đẩy (push) một phần tử vào ngăn xếp, lấy (pop)
một phần tử ra khỏi ngăn xếp. Trên quan điểm lấy đối tượng làm nền tảng, rõ ràng dữ
liệu và các thao tác trên dữ liệu luôn gắn bó với nhau, sự kết dính chúng chính là đối
tượng chúng ta cần khảo sát.

Các thao tác trong đối tượng được gọi là các phương thức hay hành vi của đối tượng đó.
Phương thức và dữ liệu của đối tượng luôn tác động lẫn nhau và có vai trò ngang nhau
trong đối tượng, Phương thức của đối tượng được qui định bởi dữ liệu và ngược lại, dữ
liệu của đối tượng được đặt trưng bởi các phương thức của đối tượng. Chính nhờ sự gắn
bó đó, chúng ta có thể gởi cùng một thông điệp đến những đối tượng khác nhau. Điều
này giúp người lập trình không phải xử lý trong chương trình của mình một dãy các cấu
trúc điều khiển tuỳ theo thông điệp nhận vào, mà chương trình được xử lý vào thời điểm
thực hiện.

Tóm lại, so sánh lập trình cấu trúc với chương trình con làm nền tảng:

Chương trình = Cấu trúc dữ liệu + Thuật giải

Trong lập trình hướng đối tượng chúng ta có:

32/134
Đối tượng = Phương thức + Dữ liệu

Đây chính là 2 quan điểm lập trình đang tồn tại và phát triển trong thế giới ngày nay.

Một số ngôn ngữ lập trình

• Ngôn ngữ lập trình Pascal

Đây là ngôn ngữ do giáo sư Niklaus Wirth thiết kế vào năm 1970 với mục đích giảng
dạy ý niệm lập trình có cấu trúc. Nhưng sau một thời gian do tính ưu việt của nó nên
PASCAL đã được sử dụng rộng dãi.

PASCAL là ngôn ngữ lập trình bậc cao. Trước khi PASCAL được phát triển thì việc lập
trình được thực hiện trên các ngôn ngữ cấp thấp, các lập trình viên rất khó khăn trong
việc xây dựng các chương trình lớn. PASCAL dùng ngôn ngữ sát với ngôn ngữ tự nhiên
hơn do đó nó thân thiện với người lập trình hơn. Do vậy nó giảm bớt các công việc nặng
nhọc cho người lập trình.

PASCAL kết hợp giữa đặc tính gọn, dễ nhớ, khả năng truy cập cấp thấp, và các
cấu trúc giữ liệu đa dạng. PASCAL còn hỗ trợ khả năng đưa các chương trình viết
bằng ASSEMBLER vào chương trình của bạn, khả năng đồ hoạ và hướng đối
tượng.PASCAL là ngôn ngữ lập trình có cấu trúc. Tính cấu trúc của PASCAL được thể
hiện qua 3 yếu tố: cấu trúc trong dữ liệu, cấu trúc trong các toán tử và cấu trúc trong
công cụ thủ tục.

• Tính cấu trúc của dữ liệu được thể hiện qua phần mô tả. Cũng như các ngôn ngữ lập
trình khác, PASCAL có một số kiểu dữ liệu được định nghĩa sẵn và các phép toán trên
các kiểu dữ liệu này. Từ các kiểu dữ liệu đó, người lập trình có thể xây dựng các kiểu
dữ liệu phức tạp hơn. Sau đó để khai báo đối tượng thuộc kiểu dữ liệu phức tạp đó ta
không cần trình bày lại cấu trúc thiết lập, mà chỉ cần tham chiếu đến kiểu đó.

• Tính cấu trúc của các toán tử được thể hiện ở chỗ bên trong các toán tử thực hiện
một động tác, còn có các toán tử thực hiện nhiều động tác, song sự quan trọng nhất của
PASCAL là toán tử hợp thành. Toán tử hợp thành được xây dựng bắt đầu bằng từ khoá
BEGIN, sau đó đến dãy các toán tử thành phần và kết thúc bằng từ khoá END.

• Tính cấu trúc trong công cụ thủ tục thể hiện thông qua khả năng phân tích chương trình
thành các modul độc lập và lời gọi đệ quy thủ tục. PASCAL không phải là ngôn ngữ khó
học hơn ngôn ngữ dành cho những người mới bắt đầu làm quen với lập trình (BASIC)
nhưng nó lại tỏ ra có những đặc tính cấu trúc hoá tốt hơn và không có những cú pháp
mang lỗi.

PASCAL không phân biệt chữ hoa và chữ thường, do vậy người lập trình có thể thoải
mái hơn trong việc viết các câu lệnh và đặt tên cho các đối tượng của mình.Việc dịch

33/134
một chương trình viết bằng PASCAL được thực hiện bằng một trình biên dịch. Khi
chương trình chứa một lỗi cú pháp nào đó thì mã máy sẽ không được sinh ra. Còn
nếu không có lỗi thì sau khi dịch xong sẽ nhận được một bản mã đối tượng.Với những
chương trình lớn thì dùng ngôn ngữ lập trình có cấu trúc để quản lý sẽ là rất khó khăn, vì
vậy để đáp ứng nhu cầu của người lập trình những phiên bản của PASCAL về sau này
đã có hỗ trợ lập trình hướng đối tượng.

Do mục đích ban đầu của PASCAL và các đặc điểm của nó, PASCAL rất thích hợp
dùng để giảng dạy trong các nhà trường và cho những người mới bắt đầu học lập trình.
Còn đối với những bài toán ứng dụng trong thực tế thì PASCAL ít được sử dụng.

• Ngôn ngữ lập trình Java

JAVA được tạo ra trước năm 1990 bởi nhóm các nhà phát triển của Sun Microsystem có
nhiệm vụ phải viết phầm mềm hệ thống để nhúng vào các sản phẩm điện tử của khách
hàng. Họ đã khắc phục một số hạn chế của C++ để tạo ra ngôn ngữ lập trình JAVA.

Do được phát triển từ C++ nên JAVA rất giống C++. Nhưng JAVA là ngôn ngữ hướng
đối tượng hoàn toàn, còn C++ là ngôn ngữ đa hướng.JAVA là ngôn ngữ lập trình mạnh
vì nó hội tụ được các yếu tố sau:

• JAVA là ngôn ngữ hướng đối tượng (object oriented programming): Các ngôn ngữ lập
trình hướng đối tượng có các modul có thể thay đổi và được xác định trước mà người
lập trình có thể gọi ra để thực hiện những nhiệm vụ cụ thể. Trong JAVA các modul này
gọi là các lớp (class) và chúng được lưu trữ trong thư viện lớp tạo nên cơ sở của bộ công
cụ phát triển JAVA (Java Development Kit). Trong JAVA tất cả các hàm và biến đều
phải là thành phần của một lớp.

• Đơn giản (simple): Mặc dù dựa trên cơ sở của C++ nhưng JAVA đã được lược bỏ các
tính năng khó nhất của C++ làm cho ngôn ngữ này dễ dùng hơn. Do vậy việc đào tạo
một lập trình viên JAVA ngắn hơn và JAVA trở nên thân thiện với người sử dụng hơn.
Trong JAVA không có các con trỏ, không hỗ trợ toán tử Overloading, không có tiền xử
lý. Tất cả mọi đối tượng trong một chương trình JAVA đều được tạo trên heap bằng
toán tử new - chúng không bao giờ được tạo trên stack. JAVA cũng là ngôn ngữ gom
rác (garbage - collected language), vì vậy nó không cần đếm từng new với delete - một
nguồn bộ nhớ chung để thất thoát trong các chương trình của C++. Trong thực tế không
có toán tử delete trong JAVA.

• Đa luồng (multithread): Có nghĩa là JAVA cho phép xây dựng các trình ứng dụng,
trong đó, nhiều quá trình có thể xảy ra đồng thời. Tính đa luồng cho phép các nhà lập
trình có thể biên soạn các phần mềm đáp ứng tốt hơn, tương tác hơn và thực hiện theo
thời gian thực.

34/134
• JAVA độc lập với cấu trúc máy: Đây là thuộc tính đặc sắc nhất của JAVA. Có nghĩa
là JAVA không phụ thuộc vào hệ máy, các ứng dụng bằng JAVA có thể dùng được trên
hầu như mọi máy tính.

Có thể nói JAVA là ngôn ngữ lập trình cho Web:

• Hiểu mạng: JAVA được viết ra để hoạt động trên mạng và có các thủ tục để có thể
quản lý các giao thức TCP/IP, FTP, HTTP. Nói cách khác JAVA được xây dựng để
hoàn toàn tương thích trên Internet.

• JAVA cho phép tạo ra các trang Web động, các ứng dụng nhúng.

• An toàn: Đặc tính an toàn của ngôn ngữ lập trình này bắt nguồn từ việc nó có những
phần hạn chế được cài đặt sẵn nhằm đề phòng các chương trình JAVA thực hiện các
chức năng như ghi vào ổ cứng hoặc cho phép vi rút xâm nhập vào từ mạng.

• Visual Basic

VISUAL BASIC là một môi trường lập trình được phát triển bởi Microsoft nhằm cung
cấp cho những người lập trình một phương pháp phát triển các ứng dụng trên Windows
nhanh và dễ nhất.

VISUAL BASIC cung cấp cho người lập trình một môi trường tích hợp, nơi mà người
lập trình có thể sử dụng các công cụ để tạo ra giao diện người sử dụng một cách nhanh
chóng và dễ dàng tạo ra mã để trả lời lại các tác động từ phái người sử dụng. VISUAL
BASIC cung cấp cho người lập trình cả kỹ thuật lập trình hướng sự kiện và kỹ thuật lập
trình hướng đối tượng.

Môi trường phát triển của VISUAL BASIC có những công cụ soạn thảo và gỡ rối tinh
vi, nó cho phép người lập trình gắn mã với giao diện một cách nhanh chóng cho mỗi sự
kiện.

VISUAL BASIC cung cấp cho bạn một giao diện nhanh nhất nhưng bù lại bạn phải cũng
phải trả giá về tốc độ. Do vậy nếu yêu cầu bài toán cần đến tốc độ thì bạn nên dùng C+.

• Ngôn ngữ lập trình C/C++

Ngôn ngữ C được phát triển từ ngôn ngữ B trên máy UNIX. Đến nay ANSI ban hành
chuẩn về C. Cũng giống như PASCAL, C là ngôn ngữ lập trình có cấu trúc. Nhưng nói
chặt chẽ về mặt kỹ thuật thì C không phải là ngôn ngữ lập trình có câud trúc chính cống
vì trong C không cho phép các khối **********g nhau (chẳng hạn bạn không thể khai
báo hàm này trong hàm khác).

35/134
C là ngôn ngữ cấp trung vì nó cho phép thao tác trên các bit, byte, và địa chỉ. C kết
hợp các yếu tố mềm dẻo của ngôn ngữ bậc cao và khả năng điều khiển mạnh của
ASSEMBLER. Do vậy, C tỏ ra thích hợp với lập trình hệ thống.

Chương trình viết bằng C là tập hợp các hàm riêng biệt, giúp cho việc che giấu mã và
giữ liệu trở nên dễ dàng. Hàm được viết bởi những người lập trình khác nhau không
ảnh hưởng đến nhau và có thể được biên dịch riêng biệt trước khi ráp nối thành chương
trình.

So với PASCAL thì C thoáng hơn, chẳng hạn C không kiểm tra kiểu khi chay, điều này
do người lập trình đảm nhiệm.

C tỏ ra ít gắn bó hơn so với các ngôn ngữ bậc cao, nhưng C lại thực tế hơn so với các
ngôn ngữ khác.

Một đặc điểm nổi bật của C là C có tính tương thích cao. Chương trình viết bằng C cho
một loại máy hoặc hệ điều hành này có thể chuyển dễ dàng sang loại máy hoặc hệ điều
hành khác. Hiện nay hầu hết các loại máy tính đều có trình biên dịch C.Một chương
trình được viết bằng C sẽ cõ tối ưu, chạy với tốc độ cao và tiết kiệm bộ nhớ.Tuy vậy,
C chỉ thích hợp với những chương trình hệ thống hoặc những chương trình đòi hỏi tốc
độ. Còn nếu bài toán lớ và phức tạp thì cũng như PASCAL, C cũng rất khó kiểm soát
chương trình.

Ngôn ngữ lập trình C là một ngôn ngữ mệnh lệnh được phát triển từ đầu thập niên 1970
bởi Ken Thompson và Dennis Ritchie để dùng trong hệ điều hành UNIX. Từ dó, ngôn
ngữ này đã lan rộng ra nhiều hệ điều hành khác và trở thành một những ngôn ngữ phổ
dụng nhất. C là ngôn ngữ rất có hiệu quả và được ưa chuộng nhất để viết các phần mềm
hệ thống, mặc dù nó cũng được dùng cho việc viết các ứng dụng. Ngoài ra, C cũng
thường được dùng làm phương tiện giảng dạy trong khoa học máy tính mặc dù ngôn
ngữ này không dược thiết kế dành cho người nhập môn.

C là một ngôn ngữ lập trình tương đối nhỏ gọn vận hành gần với phần cứng và nó giống
với ngôn ngữ Assembler hơn hầu hết các ngôn ngữ bậc cao. Hơn thế, C đôi khi được
đánh giá như là "có khả năng di động", cho thấy sự khác nhau quan trọng giữa nó với
ngôn ngữ bậc thấp như là Assembler, đó là việc mã C có thể được dịch và thi hành trong
hầu hết các máy tính, hơn hẳn các ngôn ngữ hiện tại trong khi đó thì Assembler chỉ có
thể chạy trong một số máy tính đặc biệt. Vì lý do này C được xem là ngôn ngữ bậc trung.

Những trình dịch về C ngày nay thương được cung cấp kèm chung với C++ và ngay cả
trình dịch cho ngôn ngữ Assmebly. Những sản phẩm trình dịch được bán phổ biến trên
thị trường cũng thường cung cấp thêm nhiều công cụ trợ giúp cho người lập trình như là
IDE, debuger, ...

36/134
Bài 7:Thuật toán và chương trình
Thuật toán và chương trình
Thuật toán

Trong quá trình nghiên cứu giải quyết các vấn đề – bài toán, người ta đã đưa ra những
nhận xét như sau:

• Có nhiều bài toán cho đến nay vẫn chưa tìm ra một cách giải theo kiểu thuật
toán và cũng không biết là có tồn tại thuật toán hay không.
• Có nhiều bài toán đã có thuật toán để giải nhưng không chấp nhận được vì thời
gian giải theo thuật toán đó quá lớn hoặc các điều kiện cho thuật toán khó đáp
ứng.
• Có những bài toán được giải theo những cách giải vi phạm thuật toán nhưng
vẫn chấp nhận được.

Từ những nhận định trên, người ta thấy rằng cần phải có những đổi mới cho khái niệm
thuật toán. Người ta đã mở rộng hai tiêu chuẩn của thuật toán: tính xác định và tính đúng
đắn. Việc mở rộng tính xác định đối với thuật toán đã được thể hiện qua các giải thuật
đệ quy và ngẫu nhiên. Tính đúng của thuật toán bây giờ không còn bắt buộc đối với một
số cách giải bài toán, nhất là các cách giải gần đúng. Trong thực tiễn có nhiều trường
hợp người ta chấp nhận các cách giải thường cho kết quả tốt (nhưng không phải lúc nào
cũng tốt) nhưng ít phức tạp và hiệu quả. Chẳng hạn nếu giải một bài toán bằng thuật
toán tối ưu đòi hỏi máy tính thực hiên nhiều năm thì chúng ta có thể sẵn lòng chấp nhận
một giải pháp gần tối ưu mà chỉ cần máy tính chạy trong vài ngày hoặc vài giờ.

Các cách giải chấp nhận được nhưng không hoàn toàn đáp ứng đầy đủ các tiêu chuẩn
của thuật toán thường được gọi là các thuật giải. Khái niệm mở rộng này của thuật toán
đã mở cửa cho chúng ta trong việc tìm kiếm phương pháp để giải quyết các bài toán
được đặt ra.

Một trong những thuật giải thường được đề cập đến và sử dụng trong khoa học trí tuệ
nhân tạo là các cách giải theo kiểu Heuristic

Thuật toán, còn gọi là giải thuật, là một tập hợp hữu hạn của các chỉ thị hay phương
cách được định nghĩa rõ ràng cho việc hoàn tất một số sự việc từ một trạng thái ban đầu
cho trước; khi các chỉ thị này được áp dụng triệt để thì sẽ dẫn đến kết quả sau cùng như
đã dự đoán.

37/134
Nói cách khác, thuật toán là một bộ các qui tắc hay qui trình cụ thể nhằm giải quyết một
vấn đề trong một số bước hữu hạn, hoặc nhằm cung cấp một kết quả từ một tập hợp của
các dữ kiện đưa vào.

Các lưu đồ thuật toán

• Bắt đầu và kết thúc

K ZZôết thúc

• Đường hướng diễn tiến: Đường mũi tên

• Khối công việc tuần tự: Đặt trong hình chữ nhật

{Các công việc}

• Khối nhập hoặc đưa ra dữ liệu:

{Input (OutPut) Data}

• Lời gọi chương trình con

{CTC}

• Khối rẽ nhánh:

***SORRY, THIS MEDIA TYPE IS NOT SUPPORTED.***

Lưu đồ thuật toán

Khái niệm giải thuật

Giải thuật là một hệ thống chặt chẽ và rõ ràng các quy tắc nhằm xác định một dãy các
thao tác trên những dữ liệu vào sao cho sau một số hữu hạn bước thực hiện các thao tác
đó ta thu được kết quả của bài toán.

Ví dụ 1: Giả sử có hai bình A và B đựng hai loại chất lỏng khác nhau, chẳng hạn bình A
đựng rượu, bình B đựng nước mắm. Giải thuật để hoán đổi (swap) chất lỏng đựng trong
hai bình đó là:

* Yêu cầu phải có thêm một bình thứ ba gọi là bình C.

* Bước 1: Đổ rượu từ bình A sang bình C.

38/134
* Bước 2: Đổ nước mắm từ bình B sang bình A.

* Bước 3: Đổ rượu từ bình C sang bình B.

Ví dụ 2:Một trong những giải thuật tìm ước chung lớn nhất của hai số a và b là:

* Bước 1: Nhập vào hai số a và b.

* Bước 2: So sánh 2 số a,b chọn số nhỏ nhất gán cho UCLN.

* Bước 3: Nếu một trong hai số a hoặc b không chia hết cho UCLN thì thực hiện bước
4, ngược lại (cả a và b đều chia hết cho UCLN) thì thực hiện bước 5.

* Bước 4: Giảm UCLN một đơn vị và quay lại bước 3

* Bước 5: In UCLN - Kết thúc.

Các đặc trưng của giải thuật

* Tính kết thúc: Giải thuật phải dừng sau một số hữu hạn bước.

* Tính xác định: Các thao tác máy tính phải thực hiện được và các máy tính khác nhau
thực hiện cùng một bước của cùng một giải thuật phải cho cùng một kết quả.

* Tính phổ dụng: Giải thuật phải "vét' hết các trường hợp và áp dụng cho một loạt bài
toán cùng loại.

* Tính hiệu quả: Một giải thuật được đánh giá là tốt nếu nó đạt hai tiêu chuẩn sau:

- Thực hiện nhanh, tốn ít thời gian.

- Tiêu phí ít tài nguyên của máy, chẳng hạn tốn ít bộ nhớ.

Giải thuật tìm UCLN nêu trên đạt tính kết thúc bởi vì qua mỗi lần thực hiện bước 4 thì
UCLN sẽ giảm đi một đơn vị cho nên trong trường hợp xấu nhất thì UCLN=1, giải thuật
phải dừng. Các thao tác trình bày trong các bước, máy tính đều có thể thực hiện được
nên nó có tính xác định. Giải thuật này cũng đạt tính phổ dụng vì nó được dùng để tìm
UCLN cho hai số nguyeên dương a và b bất kỳ. Tuy nhiên tính hiệu quả của giải thuật
có thể chưa cao; cụ thể là thời gian chạy máy có thể còn tốn nhiều hơn một số giải thuật
khác mà chúng ta sẽ có dịp trở lại trong phần lập trình C.

39/134
Ngôn ngữ biểu diễn giải thuật

Để biểu diễn giải thuật, cần phải có một tập hợp các ký hiệu dùng để biểu diễn, mỗi ký
hiệu biểu diễn cho một hành động nào đó. Tập hợp các ký hiệu đó lại tạo thành ngôn
ngữ biểu diễn giải thuật.

Ngôn ngữ tự nhiên

Ngôn ngữ tự nhiên là ngôn ngữ của chúng ta đang sử dụng, chúng ta có thể sử dụng
ngôn ngữ tự nhiên để mô tả giải thuật giống như các ví dụ ở trên.

Ví dụ: Ta có giải thuật giải phương trình bậc nhất dạng

ax+b=0ax+b=0 size 12{ ital "ax"+b=0} {} như sau:

* Bước 1: Nhận giá trị của các tham số a, b

* Bước 2: Xét giá trị của a xem có bằng 0 hay không? Nếu a=0 thì làm bước 3, nếu a
khác không thì làm bước 4.

* Bước 3: (a bằng 0) Nếu b bằng 0 thì ta kết luận phương trình vô số nghiệm, nếu b khác
0 thì ta kết luận phương trình vô nghiệm.

* Bước 4: ( a khác 0) Ta kết luận phương trình có nghiệm x=-b/a

Ngôn ngữ sơ đồ (Lưu đồ)

Ngôn ngữ sơ đồ (lưu đồ) là một ngôn ngữ đặc biệt dùng để mô tả giải thuật bằng các sơ
đồ hình khối. Mỗi khối qui định một hành động.

Chẳng hạn ta dùng lưu đồ để biểu diễn giải thuật tìm UCLN nêu trên như sau:

ABegina<bUCLN=aUCLN=bAUCLN=UCLN-1EndVàNhập a,b a

⋮⋮ size 12{ dotsvert } {}UCLNb

⋮⋮ size 12{ dotsvert } {}UCLNSai ĐúngĐúng SaiIn UCLN

Ví dụ 1: Cần viết chương trình cho máy tính sao cho khi thực hiện chương trình đó, máy
tính yêu cầu người sử dụng chương trình nhập vào các số hạng của tổng (n); nhập vào
dãy các số hạng ai của tổng. Sau đó, máy tính sẽ thực hiện việc tính tổng các số ai này
và in kết quả của tổng tính được.

Yêu cầu: Tính tổng n số S=a1+ a2+a3+......+an .

40/134
Để tính tổng trên, chúng ta sử dụng phương pháp “cộng tích lũy” nghĩa là khởi đầu cho
S=0. Sau mỗi lần nhận được một số hạng ai từ bàn phím, ta cộng tích lũy ai vào S (lấy
giá trị được lưu trữ trong S, cộng thêm ai và lưu trở lại vào S). Tiếp tục quá trình này
đến khi ta tích lũy được an vào S thì ta có S là tổng các ai. Chi tiết giải thuật được mô tả
bằng ngôn ngữ tự nhiên như sau:

- Bước 1: Nhập số các số hạng n.

- Bước 2: Cho S=0 (lưu trữ số 0 trong S)

- Bước 3: Cho i=1 (lưu trữ số 1 trong i)

- Bước 4: Kiểm tra nếu i<=n thì thực hiện bước 5, ngược lại thực hiện bước 8.

- Bước 5: Nhập ai

- Bước 6: Cho S=S+ai (lưu trữ giá trị S + ai trong S)

- Bước 7: Tăng i lên 1 đơn vị và quay lại bước 4.

- Bước 8: In S và kết thúc chương trình.

Chí tiết giải thuật bằng lưu đồ:

BeginS=0i=1EndS=S+aii=i+1Nhập số các số hạng ni<=n SaiĐúngNhập số ai In S

Ví dụ 2: Viết chương trình cho phép nhập vào 2 giá trị a, b mang ý nghĩa là các hệ số
a, b của phương trình bậc nhất. Dựa vào các giá trị a, b đó cho biết nghiệm của phương
trình bậc nhất ax + b = 0.

Mô tả giải thuật bằng ngôn ngữ tự nhiên:

- Bước 1: Nhập 2 số a và b

- Bước 2: Nếu a = 0 thì thực hiện bước 3, ngược lại thực hiện bước 4

- Bước 3: Nếu b=0 thì thông báo phương trình vô số nghiệm và kết thúc chương trình,
ngược lại thông báo phương trình vô nghiệm và kết thúc chương trình.

- Bước 4: Thông báo nghiệm của phương trình là –b/a và kết thúc.

BeginEnd

Nhập hai số a,ba=0 Đúng b=0 ĐúngSai SaiNghiệm x=-b/a PT vô nghiệm PT vô định

41/134
Ví dụ 3:Viết chương trình cho phép nhập vào 1 số n, sau đó lần lượt nhập vào n giá trị
a1, a2,…,an. Hãy tìm và in ra giá trị lớn nhất trong n số a1, a2, …, an.

Để giải quyết bài toán trên, chúng ta áp dụng phương pháp “thử và sửa”. Ban đầu giả sử
a1 là số lớn nhất (được lưu trong giá trị max); sau đó lần lượt xét các ai còn lại, nếu ai
nào lớn hơn giá trị max thi lúc đó max sẽ nhận giá trị là ai. Sau khi đã xét hết các ai thì
max chính là giá trị lớn nhất cần tìm.

Mô tả giải thuật bằng ngôn ngữ tự nhiên:

- Bước 1: Nhập số n

- Bước 2: Nhập số thứ nhất a1

- Bước 3: Gán max=a1

- Bước 4: Gán i=2

- Bước 5: Nếu i<=n thì thực hiện bước 6, ngược lại thực hiện bước 9

- Bước 6: Nhập ai

- Bước 7: Nếu max < ai thì gán max=ai.

- Bước 8: Tăng i lên một đơn vị và quay lại bước 5

- Bước 9: In max - kết thúc

Phần mô tả giải thuật bằng lưu đồ, sinh viên tự làm xem như bài tập.

Ví dụ 4: Viết chương trình cho phép nhập vào 1 số n, sau đó lần lượt nhập vào n giá trị
a1, a2,…,an. Sắp theo thứ tự tăng dần một dãy n số a1, a2,...an nói trên. Có rất nhiều
giải thuật để giải quyết bài toán này. Phần trình bày dưới đây là một phương pháp.

Giả sử ta đã nhập vào máy dãy n số a1, a2,..., an. Việc sắp xếp dãy số này trải qua (n-1)
lần:

- Lần 1: So sánh phần tử đầu tiên với tất cả các phần tử đứng sau phần tử đầu tiên. Nếu
có phần tử nào nhỏ hơn phần tử đầu tiên thì đổi chỗ phần tử đầu tiên với phần tử nhỏ
hơn đó. Sau lần 1, ta được phần tử đầu tiên là phần tử nhỏ nhất.

- Lần 2: So sánh phần tử thứ 2 với tất cả các phần tử đứng sau phần tử thứ 2. Nếu có
phần tử nào nhỏ hơn phần tử thứ 2 thì đổi chỗ phần tử thứ 2 với phần tử nhỏ hơn đó. Sau
lần 2, ta được phần tử đầu tiên và phần tử thứ 2 là đúng vị trí của nó khi sắp xếp.

42/134
- Lần (n-1): So sánh phần tử thứ (n-1) với phần tử đứng sau phần tử (n-1) là phần tử thứ
n. Nếu phần tử thứ n nhỏ hơn phần tử thứ (n-1) thì đổi chỗ 2 phần tử này. Sau lần thứ
(n-1), ta được danh sách gồm n phần tử được sắp thứ tự.

Mô tả giải thuật bằng ngôn ngữ tự nhiên:

- Bước 1: Gán i=1

- Bước 2: Gán j=i+1

- Bước 3: Nếu i <=n-1 thì thực hiện bước 4, ngược lại thực hiện bước 8

- Bước 4: Nếu j <=n thì thực hiện bước 5, ngược lại thì thực hiện bước 7

- Bước 5: Nếu ai > aj thì hoán đổi ai và aj cho nhau (nếu không thì thôi).

- Bước 6: Tăng j lên một đơn vị và quay lại bước 4

- Bước 7: Tăng i lên một đơn vị và quay lại bước 3

- Bước 6: In dãy số a1, a2,..., an - Kết thúc.

Các cấu trúc suy luận cơ bản của giải thuật

Giải thuật được thiết kế theo ba cấu trúc suy luận cơ bản sau đây:

Tuần tự (Sequential):

Các công việc được thực hiện một cách tuần tự, công việc này nối tiếp công việc kia.

Cấu trúc lựa chọn (Selection)

Lựa chọn một công việc để thực hiện căn cứ vào một điều kiện nào đó. Có một số dạng
như sau:

- Cấu trúc 1: Nếu < điều kiện> (đúng) thì thực hiện <công việc>

- Cấu trúc 2: Nếu < điều kiện> (đúng) thì thực hiện <công việc 1>, ngược lại (điều kiện
sai) thì thực hiện <công việc 2>

- Cấu trúc 3: Trường hợp < i> thực hiện <công việc i>

Cấu trúc lặp (Repeating)

43/134
Thực hiện lặp lại một công việc không hoặc nhiều lần căn cứ vào một điều kiện nào đó.
Có hai dạng như sau:

- Lặp xác định: là loại lặp mà khi viết chương trình, người lập trình đã xác định được
công việc sẽ lặp bao nhiêu lần.

- Lặp không xác định: là loại lặp mà khi viết chương trình người lập trình chưa xác định
được công việc sẽ lặp bao nhiêu lần. Số lần lặp sẽ được xác định khi chương trình thực
thi.

Trong một số trường hợp người ta cũng có thể dùng các cấu trúc này để diễn tả một giải
thuật.

Cấu trúc một chương trình C/C++ đơn giản

Có lẽ một trong những cách tốt nhất để bắt đầu học một ngôn ngữ lập trình là bằng một
chương trình. Vậy đây là chương trình đầu tiên của chúng ta:

// my first program in C++

#include <iostream.h>

int main ()

cout << "Hello World!";

return 0;

Hello World!

Trên đây là chương trình đầu tiên mà hầu hết những người học nghề lập trình cần làm
quen và kết quả của nó là viết câu "Hello, World" lên màn hình. Chương trình thuộc
mức đơn giản nhất của C++, nhưng nó đã bao gồm những phần cơ bản mà mọi chương
trình C++ có. Hãy cùng xem xét từng dòng một:

// my first program in C++

Đây là dòng chú thích. Tất cả các dòng bắt đầu bằng hai dấu sổ (//) được coi là chú thích
và chúng không có bất kỳ một ảnh hưởng nào đến hoạt động của chương trình. Chúng
được dùng để giải thích hay bình phẩm bên trong mã nguồn của chương trình. Trong

44/134
trường hợp này, dòng chú thích là một giải thích ngắn gọn những gì mà chương trình
chúng ta làm.

#include <iostream.h>

Các câu bắt đầu bằng dấu (#) được dùng cho chương trình xử lý mã trước khi dịch
(preprocessor). Chúng không phải là những dòng mã thực hiện nhưng được dùng để báo
hiệu cho trình dịch. Ở đây câu lệnh, #include báo cho trình dịch biết cần phải "include
(nạp)" thư viện iostream. Đây là một thư viện vào ra cơ bản trong C++ và nó phải được
"include" vì nó sẽ được dùng trong chương trình. Đây là cách cổ điển để sử dụng thư
viện iostream.

int main ()

Dòng này tương ứng với phần bắt đầu khai báo hàm main. Hàm main là điểm mà tất cả
các chương trình C++ bắt đầu thực hiện. Nó không phụ thuộc vào vị trí của hàm này (ở
đầu, cuối hay ở giữa của mã nguồn) mà nội dung của nó luôn được thực hiện đầu tiên
khi chương trình bắt đầu. Thêm vào đó, do nguyên nhân nói trên, mọi chương trình C++
đều phải tồn tại một hàm main.

Theo sau main là một cặp ngoặc đơn bởi vì nó là một hàm. Trong C++, tất cả các hàm
mà sau đó là một cặp ngoặc đơn () thì có nghĩa là nó có thể có hoặc không có tham số
(không bắt buộc). Nội dung của hàm main tiếp ngay sau phần khai báo chính thức được
bao trong các ngoặc nhọn ( { } ) như trong ví dụ của chúng ta.

cout << "Hello World";

Dòng lệnh này có vai trò quan trọng nhất của chương trình. Cout là một dòng (stream)
output chuẩn trong C++, được định nghĩa trong thư viện iostream và những gì mà dòng
lệnh này làm là gửi chuỗi ký tự "Hello World" ra màn hình.

Chú ý rằng dòng này kết thúc bằng dấu chấm phẩy (;). Ký tự này được dùng để kết thúc
một lệnh và bắt buộc phải có sau mỗi lệnh trong chương trình C++ của bạn (một trong
những lỗi phổ biến nhất của những lập trình viên C++ là quên mất dấu chấm phẩy).

return 0;

Lệnh return kết thúc hàm main và trả về mã đi sau nó, trong trường hợp này là 0. Đây
là một kết thúc bình thường của một chương trình không có một lỗi nào trong quá trình
thực hiện. Như bạn sẽ thấy trong các ví dụ tiếp theo, đây là một cách phổ biến nhất để
kết thúc một chương trình C++.

Chương trình được cấu trúc thành những dòng khác nhau để nó trở nên dễ đọc hơn
nhưng hoàn toàn không phải bắt buộc phải làm vậy. Ví dụ, thay vì viết

45/134
int main ()

cout << " Hello World "; return 0;

Ta có thể viết

int main () { cout << " Hello World "; return 0; }

Cũng cho một kết quả chính xác như nhau.

Trong C++, các dòng lệnh được phân cách bằng dấu chấm phẩy (;). Việc chia chương
trình thành các dòng chỉ nhằm để cho nó dễ đọc hơn mà thôi.

Cách chú thích

Các chú thích được lập trình viên sử dụng để ghi chú hay mô tả trong các phần của
chương trình. Trong C++ có hai cách để chú thích:

// Chú thích theo dòng

/* Chú thích theo khối */

Chú thích theo dòng bắt đầu từ cặp dấu sổ (//) cho đến cuối dòng. Chú thích theo khối
bắt đầu bằng /* và kết thúc bằng */ và có thể bao gồm nhiều dòng. Chúng ta sẽ thêm các
chú thích cho chương trình:

/* my second program in C++ with more comments */

#include <iostream.h>

int main ()

cout << "Hello World! "; //says Hello World!

cout << "I"m a C++ program"; //says I"m a C++ program

return 0;

46/134
}

Nếu bạn viết các chú thích trong chương trình mà không sử dụng các dấu //, /* hay */,
trình dịch sẽ coi chúng như là các lệnh C++ và sẽ hiển thị các lỗi.

47/134
Bài 8-9: Thảo luận về phát triển ứng dụng
C/C++, Các thành phần của một chương
trình
Thảo luận về phát triển ứng dụng C/C++,Các thành phần
của một chương trình
Thảo Luận Về Môi Trường Phát Triển và Ưng Dụng C/C++

Các thành phần cơ bản của một chương trình

Các phần tử cơ bản của một ngôn ngữ lập trình

Bảng chữ cái

Mọi ngôn ngữ lập trình đều được xây dựng từ một bộ ký tự nào đó. Các ký tự được
nhóm lại theo nhiều cách khác nhau để tạo nên các từ. Các từ lại được liên kết với nhau
theo một qui tắc nào đó để tạo nên các câu lệnh. Một chương trình bao gồm nhiều câu
lệnh và thể hiện một thuật toán để giải một bài toán nào đó. Ngôn ngữ C được xây dựng
trên bộ ký tự sau:

26 chữ cái hoa: A B C .. Z

26 chữ cái thường: a b c .. z

10 chữ số: 0 1 2 .. 9

Các ký hiệu toán học: + - * / = ( )

Ký tự gạch nối: _

Các ký tự khác: . ,: ; [ ] {} ! \ & % # $ ...

Dấu cách (space) dùng để tách các từ. Ví dụ chữ VIET NAM có 8 ký tự, còn VIETNAM
chỉ có 7 ký tự.

Chú ý:

Khi viết chương trình, ta không được sử dụng bất kỳ ký tự nào khác ngoài các ký tự trên.

48/134
Ví dụ như khi lập chương trình giải phương trình bậc hai ax2 +bx+c=0 , ta cần tính biệt
thức Delta Δ= b2 - 4ac, trong ngôn ngữ C không cho phép dùng ký tự Δ, vì vậy ta phải
dùng ký hiệu khác để thay thế.

Từ khoá

Từ khoá là những từ được sử dụng để khai báo các kiểu dữ liệu, để viết các toán tử và
các câu lệnh. Bảng dưới đây liệt kê các từ khoá của TURBO C:

asm break case cdecl


char const continue default
do double else enum
extern far float for
goto huge if int
interrupt long near pascal
register return short signed
sizeof static struct switch
tipedef union unsigned void
volatile while

Ý nghĩa và cách sử dụng của mỗi từ khoá sẽ được đề cập sau này, ở đây ta cần chú ý:

• Không được dùng các từ khoá để đặt tên cho các hằng, biến, mảng, hàm ...
• Từ khoá phải được viết bằng chữ thường, ví dụ: viết từ khoá khai báo kiểu
nguyên là int chứ không phải là INT.

Tên (định danh)

Tên là một khái niệm rất quan trọng, nó dùng để xác định các đại lượng khác nhau trong
một chương trình. Chúng ta có tên hằng, tên biến, tên mảng, tên hàm, tên con trỏ, tên
tệp, tên cấu trúc, tên nhãn,...

Tên được đặt theo qui tắc sau:

Tên là một dãy các ký tự bao gồm chữ cái, số và gạch nối. Ký tự đầu tiên của tên phải
là chữ hoặc gạch nối. Tên không được trùng với khoá. Độ dài cực đại của tên theo mặc
định là 32 và có thể được đặt lại là một trong các giá trị từ 1 tới 32 nhờ chức năng:
Option-Compiler-Source-Identifier length khi dùng TURBO C.

49/134
Ví dụ:

Các tên đúng:

a_1 delta x1 _step GAMA

Các tên sai :

3MN Ký tự đầu tiên là số


m#2 Sử dụng ký tự #
f(x) Sử dụng các dấu ( )
do Trùng với từ khoá
te ta Sử dụng dấu trắng
Y-3 Sử dụng dấu -

Chú ý:

Trong TURBO C, tên bằng chữ thường và chữ hoa là khác nhau ví dụ tên AB khác với
ab. trong C, ta thường dùng chữ hoa để đặt tên cho các hằng và dùng chữ thường để đặt
tên cho hầu hết cho các đại lượng khác như biến, biến mảng, hàm, cấu trúc. Tuy nhiên
đây không phải là điều bắt buộc.

Các kiểu dữ liệu cơ bản

Kiểu dữ liệu

Các số liệu lưu trữ trong máy tính gọi là dữ liệu (data). Mỗi đơn vị dữ liệu thuộc một
kiểu dữ liệu nào đó.

Kiểu dữ liệu là một tập hợp các giá trị có cùng một tính chất và tập hợp các phép toán
thao tác trên các giá trị đó. Người ta chia kiểu dữ liệu ra làm 2 loại: kiểu dữ liệu sơ cấp
và kiểu dữ liệu có cấu trúc.

• Kiểu dữ liệu sơ cấp

Kiểu dữ liệu sơ cấp là kiểu dữ liệu mà giá trị của nó là đơn nhất.

Ví dụ: Kiểu int gọi là kiểu sơ cấp vì kiểu này bao gồm các số nguyên từ -32768 đến
32767 và các phép toán +, -, *, /, %…

• Kiểu dữ liệu có cấu trúc

50/134
Kiểu dữ liệu có cấu trúc là kiểu dữ liệu mà các giá trị của nó là sự kết hợp của các giá
trị khác.

Ví dụ: Kiểu chuỗi ký tự trong ngôn ngữ lập trình C là một kiểu dữ liệu có cấu trúc.

Các ngôn ngữ lập trình đều có những kiểu dữ liệu do ngôn ngữ xây dựng sẵn, mà ta
gọi là các kiểu chuẩn. Chẳng hạn như kiểu int, char… trong C; integer, array… trong
Pascal. Ngoài ra, hầu hết các ngôn ngữ đều cung cấp cơ chế cho phép người lập trình
định nghĩa kiểu của riêng mình để phục vụ cho việc viết chương trình.

Một số kiểu dữ liệu trong ngôn ngữ C

Kiểu Phạm vi biểu diễn Số ký tự Kích thước


Char ( Signed char ) -128 đến 127 256 1 byte
Unsigned char 0 đến 255 256 1 byte
int -32768 đến 32767 2 byte
unsigned int 0 đến 65535 2 byte
long -2147483648 đến 2147483647 4 byte
unsigned long 0 đến 4294967295 4 byte
Float 3.4E-38 đến 3.4E+38 7 đến 8 4 byte
Double 1.7E-308 đến 1.7E+308 15 đến 16 8 byte
long double 3.4E-4932 đến 1.1E4932 17 đến 18 10 byte

Hằng (Const)

Hằng là một giá trị cố định nào đó ví dụ 3 (hằng nguyên), 'A' (hằng kí tự), 5.0 (hằng
thực), "Ha noi" (hằng xâu kí tự). Một giá trị có thể được hiểu dưới nhiều kiểu khác nhau,
do vậy khi viết hằng ta cũng cần có dạng viết thích hợp.

• Hằng nguyên
• kiểu short, int: 3, -7, ...
• kiểu unsigned: 3, 123456, ...
• kiểu long, long int: 3L, -7L, 123456L, ... (viết L vào cuối mỗi giá trị)

Các cách viết trên là thể hiện của số nguyên trong hệ thập phân, ngoài ra chúng còn
được viết dưới các hệ đếm khác như hệ cơ số 8 hoặc hệ cơ số 16. Một số nguyên trong
cơ số 8 luôn luôn được viết với số 0 ở đầu, tương tự với cơ số 16 phải viết với 0x ở đầu.

51/134
Ví dụ ta biết 65 trong cơ số 8 là 101 và trong cơ số 16 là 41, do đó 3 cách viết 65, 0101,
0x41 là như nhau, cùng biểu diễn giá trị 65.

• Hằng thực

Một số thực có thể được khai báo dưới dạng kiểu float hoặc double và các giá trị của nó
có thể được viết dưới một trong hai dạng.

• Dạng dấu phảy tĩnh

Theo cách viết thông thường. Ví dụ: 3.0, -7.0, 3.1416, ...

• Dạng dấu phảy động

Tổng quát, một số thực x có thể được viết dưới dạng: men hoặc mEn, trong đó m được
gọi là phần định trị, n gọi là phần bậc (hay mũ). Số men biểu thị giá trị x = m x 10n. Ví
dụ số π = 3.1416 có thể được viết:

π = … = 0.031416e2 = 0.31416e1 = 3.1416e0 = 31.416e?1 = 314.16e?2 = …

vì π = 0.031416 x 102 = 0.31416 x 101 = 3.1416 x 100 = …

Như vậy một số x có thể được viết dưới dạng mEn với nhiều giá trị m, n khác nhau, phụ
thuộc vào dấu phảy ngăn cách phần nguyên và phần thập phân của số. Do vậy cách viết
này được gọi là dạng dấu phảy động.

• Hằng kí tự
• Cách viết hằng

Có 2 cách để viết một hằng kí tự. Đối với các kí tự có mặt chữ thể hiện ta thường sử
dụng cách viết thông dụng đó là đặt mặt chữ đó giữa 2 dấu nháy đơn như: 'A', '3', ' ' (dấu
cách) ... hoặc sử dụng trực tiếp giá trị số của chúng. Ví dụ các giá trị tương ứng của các
kí tự trên là 65, 51 và 32. Với một số kí tự không có mặt chữ ta buộc phải dùng giá trị
(số) của chúng, như viết 27 thay cho kí tự được nhấn bởi phím Escape, 13 thay cho kí tự
được nhấn bởi phím Enter ...

Để biểu diễn kí tự bằng giá trị số ta có thể viết trực tiếp (không dùng cặp dấu nháy đơn)
giá trị đó dưới dạng hệ số 10 (như trên) hoặc đặt chúng vào cặp dấu nháy đơn, trường
hợp này chỉ dùng cho giá trị viết dưới dạng hệ 8 hoặc hệ 16 theo mẫu sau:

• '\kkk': không quá 3 chữ số trong hệ 8. Ví dụ '\11' biểu diễn kí tự có mã 9.


• '\xkk': không quá 2 chữ số trong hệ 16. Ví dụ '\x1B' biểu diễn kí tự có mã 27.

52/134
Tóm lại, một kí tự có thể có nhiều cách viết, chẳng hạn 'A' có giá trị là 65 (hệ 10) hoặc
101 (hệ 8) hoặc 41 (hệ 16), do đó kí tự 'A' có thể viết bởi một trong các dạng sau:

65, 0101, 0x41 hoặc 'A' , '\101' , '\x41'

Tương tự, dấu kết thúc xâu có giá trị 0 nên có thể viết bởi 0 hoặc '\0' hoặc '\x0', trong
các cách này cách viết '\0' được dùng thông dụng nhất.

• Một số hằng thông dụng

Đối với một số hằng kí tự thường dùng nhưng không có mặt chữ tương ứng, hoặc các kí
tự được dành riêng với nhiệm vụ khác, khi đó thay vì phải nhớ giá trị của chúng ta có
thể viết theo qui ước sau:

'\n' : biểu thị kí tự xuống dòng (cũng tương đương với endl)

'\t' : kí tự tab

'\a' : kí tự chuông (tức thay vì in kí tự, loa sẽ phát ra một tiếng 'bíp')

'\r' : xuống dòng

'\f' : kéo trang

'\\' : dấu \

'\?' : dấu chấm hỏi ?

'\'' : dấu nháy đơn '

'\"' : dấu nháy kép "

'\kkk' : kí tự có mã là kkk trong hệ 8

'\xkk' : kí tự có mã là kk trong hệ 16

Ví dụ:

cout << "Hôm nay trời \t nắng \a \a \a \n" ;

sẽ in ra màn hình dòng chữ "Hôm nay trời" sau đó bỏ một khoảng cách bằng một tab
(khoảng 8 dấu cách) rồi in tiếp chữ "nắng", tiếp theo phát ra 3 tiếng chuông và cuối cùng
con trỏ trên màn hình sẽ nhảy xuống đầu dòng mới.

53/134
Do dấu cách (phím spacebar) không có mặt chữ, nên trong một số trường hợp để tránh
nhầm lẫn chúng tôi qui ước sử dụng kí hiệu <> để biểu diễn dấu cách. Ví dụ trong giáo
trình này dấu cách (có giá trị là 32) được viết ' ' (dấu nháy đơn bao một dấu cách) hoặc
rõ ràng hơn bằng cách viết theo qui ước <>.

• Hằng xâu kí tự

Là dãy kí tự bất kỳ đặt giữa cặp dấu nháy kép. Ví dụ: "Lớp K43*", "12A4", "A", "<>",
"" là các hằng xâu kí tự, trong đó "" là xâu không chứa kí tự nào, các xâu "<>", "A" chứa
1 kí tự ... Số các kí tự giữa 2 dấu nháy kép được gọi là độ dài của xâu. Ví dụ xâu "" có
độ dài 0, xâu "<>" hoặc "A" có độ dài 1 còn xâu "Lớp K43*" có độ dài 8.

Chú ý phân biệt giữa 2 cách viết 'A' và "A", tuy chúng cùng biểu diễn chữ cái A nhưng
chương trình sẽ hiểu 'A' là một kí tự còn "A" là một xâu kí tự (do vậy chúng được bố trí
khác nhau trong bộ nhớ cũng như cách sử dụng chúng là khác nhau). Tương tự ta không
được viết '' (2 dấu nháy đơn liền nhau) vì không có khái niệm kí tự "rỗng". Để chỉ xâu
rỗng (không có kí tự nào) ta phải viết "" (2 dấu nháy kép liền nhau).

Tóm lại một giá trị có thể được viết dưới nhiều kiểu dữ liệu khác nhau và do đó cách sử
dụng chúng cũng khác nhau. Ví dụ liên quan đến khái niệm 3 đơn vị có thể có các cách
viết sau tuy nhiên chúng hoàn toàn khác nhau:

• 3 : Số nguyên 3 đơn vị
• 3L : Số nguyên dài 3 đơn vị
• 3.0 : Số thực 3 đơn vị
• '3' : Chữ số 3
• "3" : xâu chứa kí tự duy nhất là 3
• Khai báo hằng

Một giá trị cố định (hằng) được sử dụng nhiều lần trong chương trình đôi khi sẽ thuận
lợi hơn nếu ta đặt cho nó một tên gọi, thao tác này được gọi là khai báo hằng. Ví dụ một
chương trình quản lý sinh viên với giả thiết số sinh viên tối đa là 50. Nếu số sinh viên tối
đa không thay đổi trong chương trình ta có thể đặt cho nó một tên gọi như sosv chẳng
hạn. Trong suốt chương trình bất kỳ chỗ nào xuất hiện giá trị 50 ta đều có thể thay nó
bằng sosv. Tương tự C++ cũng có những tên hằng được đặt sẵn, được gọi là các hằng
chuẩn và NSD có thể sử dụng khi cần thiết. Ví dụ hằng π được đặt sẵn trong C++ với
tên gọi M_PI. Việc sử dụng tên hằng thay cho hằng có nhiều điểm thuận lợi như sau:

• Chương trình dễ đọc hơn, vì thay cho các con số ít có ý nghĩa, một tên gọi sẽ
làm NSD dễ hình dung vai trò, nội dung của nó. Ví dụ, khi gặp tên gọi sosv
NSD sẽ hình dung được chẳng hạn, "đây là số sinh viên tối đa trong một lớp",
trong khi số 50 có thể là số sinh viên mà cũng có thể là tuổi của một sinh viên
nào đó.

54/134
• Chương trình dễ sửa chữa hơn, ví dụ bây giờ nếu muốn thay đổi chương trình
sao cho bài toán quản lý được thực hiện với số sinh viên tối đa là 60, khi đó ta
cần tìm và thay thế hàng trăm vị trí xuất hiện của 50 thành 60. Việc thay thế
như vậy dễ gây ra lỗi vì có thể không tìm thấy hết các số 50 trong chương trình
hoặc thay nhầm số 50 với ý nghĩa khác như tuổi của một sinh viên nào đó
chẳng hạn. Nếu trong chương trình sử dụng hằng sosv, bây giờ việc thay thế trở
nên chính xác và dễ dàng hơn bằng thao tác khai báo lại giá trị hằng sosv bằng
60. Lúc đó trong chương trình bất kỳ nơi nào gặp tên hằng sosv đều được
chương trình hiểu với giá trị 60.

Để khai báo hằng ta dùng các câu khai báo sau:

#define tên_hằng giá_trị_hằng ;

hoặc:

const tên_hằng = giá_trị_hằng ;

Ví dụ:

#define sosv 50 ;

#define MAX 100 ;

const sosv = 50 ;

Như trên đã chú ý một giá trị hằng chưa nói lên kiểu sử dụng của nó vì vậy ta cần khai
báo rõ ràng hơn bằng cách thêm tên kiểu trước tên hằng trong khai báo const, các hằng
khai báo như vậy được gọi là hằng có kiểu.

Ví dụ:

const int sosv = 50 ;

const float nhiet_do_soi = 100.0 ;

Biến(Variable)

Biến là một đơn vị dữ liệu của chương trình, biến được xác định bởi định danh biến, hay
đơn giản gọi là tên biến. Một tên biến hợp lệ là một chuỗi gồm các chữ cái, chữ số hoặc
kí tự gạch dưới. Chiều dài của một tên là không giới hạn.

Kí tự trống, các kí tự đánh dấu đều không thể có mặt trong một tên. Chỉ có chữ cái, chữ
số và kí tự gạch dưới là được cho phép. Thêm vào đó, một tên biến luôn phải bắt đầu

55/134
bằng một chữ cái. Chúng cũng có thể bắt đầu bằng kí tự gạch dưới ( _ ) nhưng kí tự
này thường được dành cho các liên kết bên ngoài (external link) hoặc giữa các tên hàm.
Không bao giờ chúng bắt đầu bằng một chữ số.

Một luật nữa mà bạn phải quan tâm đến khi tạo ra các tên của riêng mình là chúng không
được trùng với bất kì từ khoá nào của ngôn ngữ hay của trình biên dịch, ví dụ các tên
sau đây luôn luôn được coi là từ khoá theo chuẩn ANSI-C++ và do vậy chúng không thể
được dùng để đặt tên

CODE

asm, car, bool, break, marry, catch, to char, class, const, const_cast, continue,
default, delete, do, double, dynamic_cast, else, enum, explicit, extern, false, float,
for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private,
protected, public, to register, reinterpret_cast, return, short, signed, sizeof, static,
static_cast, struct, switch, template, this, throw, true, try, typedef, typeid,
typename, union, unsigned, using, virtual, void, volatile, wchar_t

Thêm vào đó, một số biểu diễn khác của các toán tử (operator) cũng không được dùng
làm tên vì chúng là những từ được dành riêng trong một số trường hợp.

CODE

and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq

Trình dịch của bạn có thể thêm một từ dành riêng đặc trưng khác. Ví dụ, rất nhiều trình
dịch 16 bit (như các trình dịch cho DOS) còn có thể các từ khoá far, huge và near.

Chú ý: Ngôn ngữ C/C++ là "case sensitive" có nghĩa là phân biệt chữ hoa chữ thường.
Ví dụ một biến có tên RESULT khác với result cũng như Result.

Mỗi biến cần phải được khai báo trước khi đưa vào sử dụng. Việc khai báo biến được
thực hiện theo mẫu sau:

“Kiểu dữ liệu của biến” “tên biến”;

Ví dụ:

int a,b,c; Khai báo ba biến int là a,b,c


long dai,mn; Khai báo hai biến long là dai và mn
char kt1,kt2; Khai báo hai biến ký tự là kt1 và kt2
float x,y Khai báo hai biến float là x và y

56/134
double canh1, canh2; Khai báo hai biến double là canh1 và canh2

Biến kiểu int chỉ nhận được các giá trị kiểu int. Các biến khác cũng có ý nghĩa tương tự.
Các biến kiểu char chỉ chứa được một ký tự. Để lưu trữ được một xâu ký tự cần sử dụng
một mảng kiểu char.

Vị trí của khai báo biến

Để có thể sử dụng một biến trong C/C++, đầu tiên chúng ta phải khai báo nó, ghi rõ nó
là kiểu dữ liệu nào. Chúng ta chỉ cần viết tên kiểu (như int, short, float...) tiếp theo sau
đó là một tên biến hợp lệ.

Ví dụ:

CODE

int a; //khai báo biến kiểu số nguyên integer

float mynumber; //khai báo biến kiểu số thực dấu phẩy động

Dòng đầu tiên khai báo một biến kiểu int với tên là a. Dòng thứ hai khai báo một biến
kiểu float với tên mynumber. Sau khi được khai báo, các biến trên có thể được dùng
trong phạm vi (scope) của chúng trong chương trình. Nếu bạn muốn khai báo một vài
biến có cùng một kiểu và bạn muốn tiết kiệm công sức viết bạn có thể khai báo chúng
trên một dòng, ngăn cách các tên bằng dấu phẩy.

Ví dụ:

CODE

int a, b, c;

khai báo ba biến kiểu int (a, b và c) và hoàn toàn tương đương với:

CODE

int a;

int b;

int c;

57/134
Các kiểu số nguyên (char, short, long và int) có thể là số có dấu hay không dấu tuỳ theo
miền giá trị mà chúng ta cần biểu diễn. Vì vậy khi xác định một kiểu số nguyên chúng
ta đặt từ khoá signed (hoặc không cần) hoặc unsigned trước tên kiểu dữ liệu.

Ví dụ:

CODE

unsigned short nNumberOfSons;

signed int nMyAccountBalance;

Nếu ta không chỉ rõ signed hoặc unsigned nó sẽ được coi là có dấu, vì vậy trong khai
báo thứ hai chúng ta có thể viết:

CODE

int nMyAccountBalance;

cũng hoàn toàn tương đương với dòng khai báo ở trên. Trong thực tế, rất ít khi người ta
dùng đến từ khoá signed. Ngoại lệ duy nhất của luật này kiểu char. Trong chuẩn ANSI-
C++ nó là kiểu dữ liệu khác với signed char và unsigned char.

Để có thể thấy rõ hơn việc khai báo trong chương trình, chúng ta sẽ xem xét một đoạn
mã C++

Ví dụ như sau:

CODE

// thao tác tính toán với các biến

#include <iostream>

int main ()

//khai báo biến kiểu số nguyên integer

int a, b;

int result;

58/134
//khởi gán và tính toán

a = 5;

b = 2;

a = a + 1;

result = a - b;

//in kết quả

cout << result;

//thoát chương trình

return 0;

[code]

Kết quả sau khi thực hiện chương trình là:

[code]

Đừng lo lắng nếu như việc khai báo có vẻ hơi lạ lùng với bạn. Bạn sẽ thấy phần chi tiết
còn lại trong phần tiếp theo

Khởi tạo các biến (Initial)

Khi khai báo một biến, giá trị của nó mặc nhiên là không xác định. Nhưng có thể bạn sẽ
muốn nó mang một giá trị xác định khi được khai báo. Để làm điều đó, bạn chỉ cần viết
dấu bằng và giá trị bạn muốn biến đó sẽ mang:

kiểu tên_biến = giá_trị_khởi_tạo_ban_đầu;

Ví dụ, nếu chúng ta muốn khai báo một biến int là a chứa giá trị 0 ngay từ khi khởi tạo,
chúng ta sẽ viết:

CODE

59/134
int a = 0;

Bổ xung vào cách khởi tạo kiểu C này, C++ còn có thêm một cách mới để khởi tạo biến
bằng cách bọc một cặp ngoặc đơn sau giá trị khởi tạo.

Ví dụ:

CODE

int a (0);

Cả hai cách đều hợp lệ trong C++.

Lưu ý: một biến khi được khởi tạo ta vẫn có thể gán cho nó 1 giá trị khác trong quá
trình chương trình thực thi và giá trị đó sẽ hợp lệ trong phạm vi hoạt động của biến đó
(xem phần sau)

Phạm vi hoạt động của biến (Scope)

Tất cả các biến mà chúng ta sẽ sử dụng đều phải được khai báo trước. Một điểm khác
biết giữa C và C++ là trong C++ chúng ta có thể khai báo biến ở bất kì nơi nào trong
chương trình, thậm chí là ngay ở giữa các lệnh thực hiện chứ không chỉ là ở đầu khối
lệnh như ở trong C.

Mặc dù vậy chúng ta vẫn nên theo cách của ngôn ngữ C khi khai báo các biến bởi vì nó
sẽ rất hữu dụng khi cần sửa chữa một chương trình có tất cả các phần khai báo được gộp
lại với nhau. Bởi vậy, cách thông dụng nhất để khai báo biến là đặt nó trong phần bắt
đầu của mỗi hàm (biến cục bộ - local) hay trực tiếp trong thân chương trình, ngoài tất cả
các hàm (biến toàn cục - global).

Global variables (biến toàn cục) có thể được sử dụng ở bất kì đâu trong chương trình,
ngay sau khi nó được khai báo và bắt buộc phải đặt ở trên cùng ngoài tất cả các hàm
hoặc đặt ở file header .h

Local variables (biến cục bộ) có tầm hoạt động bị giới hạn trong phần mã mà nó được
khai báo - thường là trong dấu { và } gần nhất. Nếu chúng được khai báo ở đầu một hàm
(như hàm main), tầm hoạt động sẽ là toàn bộ hàm main. Điều đó có nghĩa là trong ví
dụ trên, các biến được khai báo trong hàm main() chỉ có thể được dùng trong hàm đó,
không được dùng ở bất kì đâu khác, tức là 1 biến được khai báo trong hàm A thì ko thể
sử dụng nó trong hàm B nằm ngoài hàm A.

Bên cạnh các biến toàn cục và cục bộ, còn có các biến ngoài (external). Các biến này
không những được dùng trong một file mã nguồn mà còn trong tất cả các file được liên
kết trong chương trình.

60/134
Trong C++ tầm hoạt động của một biến chính là khối lệnh mà nó được khai báo (một
khối lệnh là một tập hợp các lệnh được gộp lại trong một bằng các ngoặc nhọn { } ).
Nếu nó được khai báo trong một hàm tầm hoạt động sẽ là hàm đó, còn nếu được khai
báo trong vòng lặp thì tầm hoạt động sẽ chỉ là vòng lặp đó....

Hãy xem ví dụ sau và tìm hiểu cách hoạt động của các biến:

CODE

int nGlobal; //biến toàn cục có thể đựơc sử dụng trong cả hàm A và B

void A()

int a; //biến cục bộ của hàm A

nGlobal = 5; //câu lệnh gán cho biến toàn cục hợp lệ

b = 1; //trình biên dịch sẽ báo lỗi vì biến này chưa được khai báo trong

//hàm A

void B()

int b; //biến cục bộ của hàm B

for(int i=0; i<10; i++)

int c = 5; //khai báo và khởi tạo biến c local trong vòng for

c = 1; //không hợp lệ vì biến c chỉ có phạm vi hoạt động trong vòng lặp

//for }

61/134
Các khai báo cần phải được đặt ngay sau dấu { đầu tiên của thân hàm và cần đứng trước
mọi câu lệnh khác. Sau đây là một ví dụ về khai báo biến sai:

( Khái niệm về hàm và cấu trúc chương trình sẽ nghiên cứu sau này)

main()

int a,b,c;

a=2;

int d; /* Vị trí của khai báo sai */

.....

Khởi đầu cho biến:

Nếu trong khai báongay sau tên biến ta đặt dấu = và một giá trị nào đó thì đây chính là
cách vừa khai báo vừa khởi đầu cho biến.

Ví dụ:

int a,b=20,c,d=40;

float e=-55.2,x=27.23,y,z,t=18.98;

Việc khởi đầu và việc khai báo biến rồi gán giá trị cho nó sau này là hoàn toàn tương
đương.

Lấy địa chỉ của biến:

Mỗi biến được cấp phát một vùng nhớ gồm một số byte liên tiếp. Số hiệu của byte đầu
chính là địa chỉ của biến. Địa chỉ của biến sẽ được sử dụng trong một số hàm ta sẽ nghiên
cứu sau này ( ví dụ như hàm scanf ).

Để lấy địa chỉ của một biến ta sử dụng phép toán: & tên biến

62/134
Các phép toán

Các phép toán số học

Các phép toán hai ngôi số học là

Phép toán Ý nghiã Ví dụ


+ Phép cộng a+b
- Phép trừ a-b
* Phép nhân a*b
/ Phép chia a/b ( Chia số nguyên sẽ chặt phần thập phân )
% Phép lấy phần dư a%b( Cho phần dư của phép chia a cho b )

Có phép toán một ngôi - ví du -(a+b) sẽ đảo giá trị của phép cộng (a+b).

Ví dụ:

11/3=3

11%3=2

-(2+6)=-8

Các phép toán + và - có cùng thứ tự ưu tiên, có thứ tự ưu tiên nhỏ hơn các phép * , / , %
và cả ba phép này lại có thứ tự ưu tiên nhỏ hơn phép trừ một ngôi.

Các phép toán số học được thực hiện từ trái sang phải. Số ưu tiên và khả năng kết hợp
của phép toán được chỉ ra trong một mục sau này

Các phép toán quan hệ và logic

Phép toán quan hệ và logic cho ta giá trị đúng (1) hoặc giá trị sai (0). Nói cách khác, khi
các điều kiện nêu ra là đúng thì ta nhận được giá trị 1, trái lại ta nhận giá trị 0.

Các phép toán quan hệ là:

Phép toán Ý nghiã Ví dụ


> So sánh lớn hơn a>b 4>5 có giá trị 0
>= So sánh lớn hơn hoặc bằng a>=b 6>=2 có giá trị 1

63/134
< So sánh nhỏ hơn a<b 6<=7 có giá trị 1
<= So sánh nhỏ hơn hoặc bằng a<=b8<=5 có giá trị 0
== So sánh bằng nhau a==b6==6 có giá trị 1
!= So sánh khác nhau a!=b9!=9 có giá trị 0

Bốn phép toán đầu có cùng số ưu tiên, hai phép sau có cùng số thứ tự ưu tiên nhưng thấp
hơn số thứ tự của bốn phép đầu.

Các phép toán quan hệ có số thứ tự ưu tiên thấp hơn so với các phép toán số học, cho
nên biểu thức

i<n-1

được hiểu là i<(n-1).

Các phép toán logic:

Trong C sử dụng ba phép toán logic:

Phép phủ định một ngôi !

a !a
khác 0 0
bằng 0 1

Phép và (AND) &&

Phép hoặc ( OR ) ||

a b a&&b a||b
khác 0 khác 0 1 1
khác 0 bằng 0 0 1
bằng 0 khác 0 0 1
bằng 0 bằng 0 0 0

Các phép quan hệ có số ưu tiên nhỏ hơn so với ! nhưng lớn hơn so với && và ||, vì vậy
biểu thức như:

64/134
(a<b)&&(c>d)

có thể viết lại thành:

a<b&&c>d

Chú ý:

Cả a và b có thể là nguyên hoặc thực.

Phép toán tăng giảm

C đưa ra hai phép toán một ngôi để tăng và giảm các biến ( nguyên và thực ). Toán tử
tăng là ++ sẽ cộng 1 vào toán hạng của nó, toán tử giảm -- thì sẽ trừ toán hạng đi 1.

Ví dụ:

n=5

++n Cho ta n=6

--n Cho ta n=4

Ta có thể viết phép toán ++ và -- trước hoặc sau toán hạng như sau: ++n, n++, --n, n--.

Sự khác nhau của ++n và n++ ở chỗ: trong phép n++ thì tăng sau khi giá trị của nó đã
được sử dụng, còn trong phép ++n thì n được tăng trước khi sử dụng. Sự khác nhau giữa
n-- và --n cũng như vậy.

Ví dụ:

n=5

x=++n Cho ta x=6 và n=6

x=n++ Cho ta x=5 và n=6

Thứ tự ưu tiên các phép toán

Các phép toán có độ ưu tiên khác nhau, điều này có ý nghĩa trong cùng một biểu thức sẽ
có một số phép toán này được thực hiện trước một số phép toán khác.

Thứ tự ưu tiên của các phép toán được trình bày trong bảng sau:

65/134
TT Phép toán Trình tự kết hợp
1 () [] -> Trái qua phải
2 ! ~ & * - ++ -- (type ) sizeof Phải qua trái
3 * ( phép nhân ) / % Trái qua phải
4 +- Trái qua phải
5 << >> Trái qua phải
6 < <= > >= Trái qua phải
7 == != Trái qua phải
8 & Trái qua phải
9 ^ Trái qua phải
10 | Trái qua phải
11 && Trái qua phải
12 || Trái qua phải
13 ?: Phải qua trái
14 = += -= *= /= %= <<= >>= &= ^= |= Phải qua trái
15 , Trái qua phải

Chú thích:

Các phép toán tên một dòng có cùng thứ tự ưu tiên, các phép toán ở hàng trên có số ưu
tiên cao hơn các số ở hàng dưới.

Đối với các phép toán cùng mức ưu tiên thì trình tự tính toán có thể từ trái qua phải hay
ngược lại được chỉ ra trong cột trình tự kết hợp.

Ví dụ:

*--px=*(--px) ( Phải qua trái )

8/4*6=(8/4)*6 ( Trái qua phải )

Nên dùng các dấu ngoặc tròn để viết biểu thức một cách chính xác.

Các phép toán lạ:

66/134
Dòng 1

[ ] Dùng để biểu diễn phần tử mảng, ví dụ: a[i][j]

“.” Dùng để biểu diễn thành phần cấu trúc, ví dụ: ht.ten

-> Dùng để biểu diễn thành phần cấu trúc thông qua con trỏ

Dòng 2

* Dùng để khai báo con trỏ, ví dụ: int *a

& Phép toán lấy địa chỉ, ví dụ: &x

( type) là phép chuyển đổi kiểu, ví dụ: (float)(x+y)

Dòng 15

Toán tử , thường dùng để viết một dãy biểu thức trong toán tử for.

Chuyển đổi kiểu giá trị

Việc chuyển đổi kiểu giá trị thường diễn ra một cách tự động trong hai trường hợp sau:

Khi gán biểu thức gồm các toán hạng khác kiểu.

Khi gán một giá trị kiểu này cho một biến ( hoặc phần tử mảng ) kiểu khác. Điều này
xảy ra trong toán tử gán, trong việc truyền giá trị các tham số thực sự cho các đối.

Ngoài ra, ta có thể chuyển từ một kiểu giá trị sang một kiểu bất kỳ mà ta muốn bằng
phép chuyển sau:

(type) biểu thức

Ví dụ:

(float) (a+b)

Chuyển đổi kiểu trong biểu thức

Khi hai toán hạng trong một phép toán có kiểu khác nhau thì kiểu thấp hơn sẽ được nâng
thành kiểu cao hơn trước khi thực hiện phép toán. Kết quả thu được là một giá trị kiểu
cao hơn. Chẳng hạn:

67/134
Giữa int và long thì int chuyển thành long.

Giữa int và float thì int chuyển thành float.

Giữa float và double thì float chuyển thành double.

Ví dụ:

1.5*(11/3)=4.5

1.5*11/3=5.5

(11/3)*1.5=4.5

Chuyển đổi kiểu thông qua phép gán:

Giá trị của vế phải được chuyển sang kiểu vế trái đó là kiểu của kết quả. Kiểu int có thể
được được chuyển thành float. Kiểu float có thể chuyển thành int do chặt đi phần thập
phân. Kiểu double chuyển thành float bằng cách làm tròn. Kiểu long được chuyển thành
int bằng cách cắt bỏ một vài chữ số.

Ví dụ:

int n;

n=15.6 giá trị của n là 15

Đổi kiểu dạng (type)biểu thức:

Theo cách này, kiểu của biểu thức được đổi thành kiểu type theo nguyên tắc trên.

Ví dụ:Phép toán: (int)a

Cho một giá trị kiểu int. Nếu a là float thì ở đây có sự chuyển đổi từ float sang int. Chú
ý rằng bản thân kiểu của a vẫn không bị thay đổi. Nói cách khác, a vẫn có kiểu float
nhưng (int)a có kiểu int.

Đối với hàm toán học của thư viện chuẩn, thì giá trị của đối và giá trị của hàm đều có
kiểu double, vì vậy để tính căn bậc hai của một biến nguyên n ta phải dùng phép ép kiểu
để chuyển kiểu int sang double như sau:

sqrt((double)n)

Phép ép kiểu có cùng số ưu tiên như các toán tử một ngôi.

68/134
Chú ý:Muốn có giá trị chính xác trong phép chia hai số nguyên cần dùng phép ép kiểu:

((float)a)/b

Để đổi giá trị thực r sang nguyên, ta dùng:

(int)(r+0.5)

Chú ý thứ tự ưu tiên:

(int)1.4*10=1*10=10

(int)(1.4*10)=(int)14.0=14

Biểu thức

Biểu thức là một sự kết hợp giữa các phép toán và các toán hạng để diễn đạt một công
thức toán học nào đó. Mỗi biểu thức có sẽ có một giá trị. Như vậy hằng, biến, phần tử
mảng và hàm cũng được xem là biểu thức.

Trong C, ta có hai khái niệm về biểu thức:

Biểu thức gán.

Biểu thức điều kiện .

Biểu thức được phân loại theo kiểu giá trị: nguyên và thực. Trong các mệnh đề logic,
biểu thức được phân thành đúng ( giá trị khác 0 ) và sai ( giá trị bằng 0 ).

Biểu thức thường được dùng trong:

Vế phải của câu lệnh gán.

Làm tham số thực sự của hàm.

Làm chỉ số.

Trong các toán tử của các cấu trúc điều khiển.

Tới đây, ta đã có hai khái niệm chính tạo nên biểu thức đó là toán hạng và phép toán.
Toán hạng gồm: hằng, biến, phần tử mảng và hàm trước đây ta đã xét. Dưới đây ta sẽ
nói đến các phép toán. Hàm sẽ được đề cập trong chương 6.

69/134
Bài 10: Một số hàm chức năng
Một số hàm chức năng thường dùng trong chương trình
Một số hàm thường dùng

TT Tên hàm Công dụng


1 Scanf() Nhập dữ liệu từ bàn phím
2 Printf() Xuất dữ liệu ra màn hình
3 gets() Nhập xâu từ bàn phím
4 getch() Dừng màn hình chờ nhập một kí tự bất kì
5 clrscr() Xóa màn hình
abs(x), labs(x), Trả lại giá trị tuyệt đối của một số nguyên, số nguyên dài
6
fabs(x) và số thực

7 pow(x, y) Hàm mũ, trả lại giá trị x lũy thừa y (xy)

8 exp(x) Hàm mũ, trả lại giá trị e mũ x (ex)


9 log(x), log10(x) Trả lại lôgarit cơ số e và lôgarit thập phân của x (lnx, logx)
10 sqrt(x) Trả lại căn bậc 2 của x
Trả lại số thực ứng với số viết dưới dạng xâu kí tự
11 atof(s_number)
s_number
sin(x), cos(x),
12 Trả lại các giá trị sinx, cosx, tgx
tan(x)

Nhập/xuất dữ liệu (bàn phím, màn hình)

Thâm nhập vào thư viện chuẩn

Mỗi tệp gốc có tham trỏ tới hàm thư viện chuẩn đều phải chứa dòng:

#include <conio.h> cho các hàm getch(), putch(), clrscr(), gotoxy() ...

#include <stdio.h> cho các hàm khác như gets(), fflus(), fwrite(), scanf()...

70/134
Ở gần chỗ bắt đầu chương trình. Tệp stdio.h định nghĩa các macro và biến cùng các hàm
dùng trong thư viện vào/ra. Dùng dấu ngoặc < và > thay cho các dấu nháy thông thường
để chỉ thị cho trình biên dịch tìm kiếm tệp trong danh mục chứa thông tin tiêu đề chuẩn.

Các hàm vào ra chuẩn - getchar() và putchar() - getch() và putch():

• Hàm getchar ():

Cơ chế vào đơn giản nhất là đọc từng ký tự từ thiết bị vào chuẩn, nói chung là bàn phím
và màn hình của người sử dụng, bằng hàm getchar().

Cách dùng:

Dùng câu lệnh sau:

biến = getchar();

Công dụng:

Nhận một ký tự vào từ bàn phím và không đưa ra màn hình. Hàm sẽ trả về ký tự nhận
được và lưu vào biến.

Ví dụ:

int c;

c = getchar()

• Hàm putchar ():

Để đưa một ký tự ra thiết bị ra chuẩn, nói chung là màn hình, ta sử dụng hàm putchar()

Cách dùng:

Dùng câu lệnh sau:

putchar(ch);

Công dụng:

Đưa ký tự ch lên màn hình tại vị trí hiện tại của con trỏ. Ký tự sẽ được hiển thị với màu
trắng.

Ví dụ:

71/134
int c;

c = getchar();

putchar(c);

• Hàm getch():

Hàm nhận một ký tự từ bộ đệm bàn phím, không cho hiện lên màn hình.

Cách dùng:

Dùng câu lệnh sau:

getch();

Công dụng:

Nếu có sẵn ký tự trong bộ đệm bàn phím thì hàm sẽ nhận một ký tự trong đó.

Nếu bộ đệm rỗng, máy sẽ tạm dừng. Khi gõ một ký tự thì hàm nhận ngay ký tự đó (
không cần bấm thêm phím Enter như trong các hàm nhập khác ). Ký tự vừa gõ không
hiện lên màn hình.

Nếu dùng:

biến=getch();

Thì biến sẽ chứa ký tự đọc vào.

Ví dụ:

c = getch();

• Hàm putch():

Cách dùng:

Dùng câu lệnh sau:

putch(ch);

Công dụng:

72/134
Đưa ký tự ch lên màn hình tại vị trí hiện tại của con trỏ. Ký tự sẽ được hiển thị theo màu
xác định trong hàm textcolor.

Hàm cũng trả về ký tự được hiển thị.

Đưa kết quả lên màn hình - hàm printf:

Cách dùng:

prinf(điều khiển, đối số 1, đối số 2, ...);

Hàm printf chuyển, tạo khuôn dạng và in các đối của nó ra thiết bị ra chuẩn dưới sự
điều khiển của xâu điều khiển. Xâu điều khiển chứa hai kiểu đối tượng: các ký tự thông
thường, chúng sẽ được đưa ra trực tiếp thiết bị ra, và các đặc tả chuyển dạng, mỗi đặc tả
sẽ tạo ra việc đổi dạng và in đối tiếp sau của printf.

Chuỗi điều khiển có thể có các ký tự điều khiển:

\n sang dòng mới

\f sang trang mới

\b lùi lại một bước

\t dấu tab

Dạng tổng quát của đặc tả:

%[-][fw][.pp]ký tự chuyển dạng

Mỗi đặc tả chuyển dạng đều được đưa vào bằng ký tự % và kết thúc bởi một ký tự
chuyển dạng. Giữa % và ký tự chuyển dạng có thể có:

Dấu trừ:

Khi không có dấu trừ thì kết quả ra được dồn về bên phải nếu độ dài thực tế của kết quả
ra nhỏ hơn độ rộng tối thiểu fw dành cho nó. Các vị trí dư thừa sẽ được lấp đầy bằng các
khoảng trống. Riêng đối với các trường số, nếu dãy số fw bắt đầu bằng số 0 thì các vị trí
dư thừa bên trái sẽ được lấp đầy bằng các số 0.

Khi có dấu trừ thì kết quả được dồn về bên trái và các vị trí dư thừa về bên phải ( nếu có
) luôn được lấp đầy bằng các khoảng trống.

73/134
fw:Khi fw lớn hơn độ dài thực tế của kết quả ra thì các vị trí dư thừa sẽ được lấp đầy
bởi các khoảng trống hoặc số 0 và nội dung của kết quả ra sẽ được đẩy về bên phải hoặc
bên trái.

Khi không có fw hoặc fw nhỏ hơn hay bằng độ dài thực tế của kết quả ra thì độ rộng
trên thiết bị ra dành cho kết quả sẽ bằng chính độ dài của nó.

Tại vị trí của fw ta có thể đặt dấu *, khi đó fw được xác định bởi giá trị nguyên của đối
tương ứng.

Ví dụ:

Kết quả ra fw Dấu - Kết quả đưa ra


-2503 8 có -2503
-2503 08 có -2503
-2503 8 không -2503
-2503 08 không 000-2503
"abcdef" 8 không abcdef
"abcdef" 08 có abcdef
"abcdef" 08 không abcdef

pp: Tham số pp chỉ được sử dụng khi đối tương ứng là một xâu ký tự hoặc một giá trị
kiểu float hay double.

• Trong trường hợp đối tương ứng có giá trị kiểu float hay double thì pp là độ
chính xác của trường ra. Nói một cách cụ thể hơn giá trị in ra sẽ có pp chữ số
sau số thập phân.
• Khi vắng mặt pp thì độ chính xác sẽ được xem là 6.
• Khi đối là xâu ký tự:Nếu pp nhỏ hơn độ dài của xâu thì chỉ pp ký tự đầu tiên
của xâu được in ra. Nếu không có pp hoặc nếu pp lớn hơn hay bằng độ dài của
xâu thì cả xâu ký tự sẽ được in ra.

Ví dụ:

Kết quả ra fw pp Dấu - Kết quả đưa ra Độ dài trường ra


-435.645 10 2 có -435.65 7
-435.645 10 0 có -436 4

74/134
-435.645 8 vắng có -435.645000 11
"alphabeta" 8 3 vắng alp 3
"alphabeta" vắng vắng vắng alphabeta 9
"alpha" 8 6 có alpha 5

Các ký tự chuyển dạng và ý nghĩa của nó:

Ký tự chuyển dạng là một hoặc một dãy ký hiệu xác định quy tắc chuyển dạng và dạng
in ra của đối tương ứng. Như vậy sẽ có tình trạng cùng một số sẽ được in ra theo các
dạng khác nhau. Cần phải sử dụng các ký tự chuyển dạng theo đúng qui tắc định sẵn.
Bảng sau cho các thông tin về các ký tự chuyển dạng.

Ký tự
chuyển Ý nghĩa
dạng
d Đối được chuyển sang số nguyên hệ thập phân
o Đối được chuyển sang hệ tám không dấu ( không có số 0 đứng trước )
x Đối được chuyển sang hệ mưới sáu không dấu ( không có 0x đứng trước )
u Đối được chuyển sang hệ thập phân không dấu
c Đối được coi là một ký tự riêng biệt
Đối là xâu ký tự, các ký tự trong xâu được in cho tới khi gặp ký tự không
s hoặc cho tới khi đủ số lượng ký tự được xác định bởi các đặc tả về độ chính
xác pp.
Đối được xem là float hoặc double và được chuyển sang dạng thập phân có
e
dạng [-]m.n..nE[+ hoặc -] với độ dài của xâu chứa n là pp.
Đối được xem là float hoặc double và được chuyển sang dạng thập phân có
dạng [-]m..m.n..n với độ dài của xâu chứa n là pp. Độ chính xác mặc định là
f
6. Lưu ý rằng độ chính xác không xác định ra số các chữ số có nghĩa phải in
theo khuôn dạng f.
g Dùng %e hoặc %f, tuỳ theo loại nào ngắn hơn, không in các số 0 vô nghĩa.

Chú ý :

Mọi dãy ký tự không bắt đầu bằng % hoặc không kết thúc bằng ký tự chuyển dạng đều
được xem là ký tự hiển thị.

75/134
Để hiển thị các ký tự đặc biệt:

Cách viết Hiển thị


\' '
\" "
\\ \

Các ví dụ :

"Nang suat tang


printf("\" Nang suat tang: %d % \" \n\\d"",30,-50);
; 30 %"\d=-50
n=8float x=25.5, y=-47.335printf("\n%f\n%*.2f",x,n,y);Lệnh này
tương đương với printf("\n%f\n%8.2f",x,n,y); Vì n=8 tương ứng 25.500000-47.34
với vị trí *

Vào số liệu từ bàn phím - hàm scanf :

Hàm scanf là hàm đọc thông tin từ thiết bị vào chuẩn ( bàn phím ), chuyển dịch chúng
( thành số nguyên, số thực, ký tự vv.. ) rồi lưu trữ nó vào bộ nhớ theo các địa chỉ xác
định.

Cách dùng:

scanf(điều khiển,đối 1, đối 2, ...);

Xâu điều khiển chứa các đặc tả chuyển dạng, mỗi đặc tả sẽ tạo ra việc đổi dạng biến tiếp
sau của scanf.

Đặc tả có thể viết một cách tổng quát như sau:

%[*][d...d]ký tự chuyển dạng

Việc có mặt của dấu * nói lên rằng trường vào vẫn được dò đọc bình thường, nhưng giá
trị của nó bị bỏ qua ( không được lưu vào bộ nhớ ). Như vậy đặc tả chứa dấu * sẽ không
có đối tương ứng.

d...d là một dãy số xác định chiều dài cực đại của trường vào, ý nghĩa của nó được giải
thích như sau:

76/134
Nếu tham số d...d vắng mặt hoặc nếu giá trị của nó lớn hơn hay bằng độ dài của trường
vào tương ứng thì toàn bộ trường vào sẽ được đọc, nội dung của nó được dịch và được
gán cho địa chỉ tương ứng ( nếu không có dấu * ).

Nếu giá trị của d...d nhỏ hơn độ dài của trường vào thì chỉ phần đầu của trường có kích
cỡ bằng d...d được đọc và gán cho địa chỉ của biến tương ứng. Phần còn lại của trường
sẽ được xem xét bởi các đặc tả và đối tương ứng tiếp theo.

Ví dụ:

int a;

float x,y;

char ch[6],ct[6]

scanf("%f%5f%3d%3s%s",&x&y&a&ch&ct0;

Với dòng vào: 54.32e-1 25 12452348a

Kết quả là lệnh scanf sẽ gán

5.432 cho x

25.0 cho y

124 cho a

xâu "523" và dấu kết thúc \0 cho ch

xâu "48a" và dấu kết thúc \0 cho ct

Ký tự chuyển dạng:

Ký tự chuyển dạng xác định cách thức dò đọc các ký tự trên dòng vào cũng như cách
chuyển dịch thông tin đọc đựợc trước khi gán nó cho các địa chỉ tương ứng.

Cách dò đọc thứ nhất là đọc theo trường vào, khi đó các khoảng trắng bị bỏ qua. Cách
này áp dụng cho hầu hết các trường hợp.

Cách dò đọc thứ hai là đọc theo ký tự, khi đó các khoảng trắng cũng được xem xét bình
đẳng như các ký tự khác. Phương pháp này chỉ xảy ra khi ta sử dụng một trong ba ký tự
chuyển dạng sau: C, [ dãy ký tự ], [^ dãy ký tự ]

77/134
Các ký tự chuyển dạng và ý nghĩa của nó:

c Vào một ký tự, đối tương ứng là con trỏ ký tự. Có xét ký tự khoảng trắng
Vào một giá trị kiểu int, đối tương ứng là con trỏ kiểu int. Trường phải vào là số
d
nguyên
Vào một giá trị kiểu long, đối tương ứng là con trỏ kiểu long. Trường phải vào
ld
là số nguyên
Vào một giá trị kiểu int hệ 8, đối tương ứng là con trỏ kiểu int. Trường phải vào
o
là số nguyên hệ 8
Vào một giá trị kiểu long hệ 8, đối tương ứng là con trỏ kiểu long. Trường phải
lo
vào là số nguyên hệ 8
Vào một giá trị kiểu int hệ 16, đối tương ứng là con trỏ kiểu int. Trường phải
x
vào là số nguyên hệ 16
Vào một giá trị kiểu long hệ 16, đối tương ứng là con trỏ kiểu long. Trường phải
lx
vào là số nguyên hệ 16
f
Vào một giá trị kiểu float, đối tương ứng là con trỏ float, trường vào phải là số
hay
dấu phảy động
e
lf
Vào một giá trị kiểu double, đối tương ứng là con trỏ double, trường vào phải là
hay
số dấu phảy động
le
Vào một giá trị kiểu double, đối tương ứng là con trỏ kiểu char, trường vào phải
s
là dãy ký tự bất kỳ không chứa các dấu cách và các dấu xuống dòng

[ Dãy ký tự ], [ ^Dãy ký tự ] Các ký tự trên dòng vào sẽ lần lượt được đọc cho đến khi
nào gặp một ký tự không thuộc tập các ký tự đặt trong[]. Đối tương ứng là con trỏ kiểu
char. Trường vào là dãy ký tự bất kỳ ( khoảng trắng được xem như một ký tự ).

Ví dụ:

int a,b;

char ch[10], ck[10];

scanf("%d%[0123456789]%[^0123456789]%3d",&a,ch,ck,&b);

Với dòng vào:

78/134
35 13145 xyz 584235

Sẽ gán:

35 cho a

xâu "13145" cho ch

xâu "xyz' cho ck

584 cho b

Chú ý:

Xét đoạn chương trình dùng để nhập ( từ bàn phím ) ba giá trị nguyên rồi gán cho ba
biến a,b,c như sau:

int a,b,c;

scanf("%d%d%d”,&a,&b,&c);

Để vào số liệu ta có thể thao tác theo nhiều cách khác nhau:

Cách 1: Đưa ba số vào cùng một dòng, các số phân cách nhau bằng dấu cách hoặc dấu
tab.

Cách 2: Đưa ba số vào ba dòng khác nhau.

Cách 3: Hai số đầu cùng một dòng ( cách nahu bởi dấu cách hoặ tab ), số thứ ba trên
dòng tiếp theo.

Cách 4: Số thứ nhất trên một dòng, hai số sau cùng một dòng tiếp theo ( cách nahu bởi
dấu cách hoặ tab ), số thứ ba trên dòng tiếp theo.

Khi vào sai sẽ báo lỗi và nhảy về chương trình chứa lời gọi nó.

Đưa kết quả ra máy in:

Để đưa kết quả ra máy in ta dùng hàm chuẩn fprintf có dạng sau:

fprintf(stdprn, điều khiển, biến 1, biến 2,...);

Tham số stdprn xác định thiết bị đưa ra là máy in.

79/134
Điều khiển có dạng đặc tả như lệnh printf.

Dùng giống như lệnh printf, chỉ khác là in ra máy in.

Ví dụ

Đoạn chương trình in ma trận A, cỡ 8x6. Mỗi hàng của ma trận được in trên một dòng:

float a[8][6];

int i,j;

fprintf(stdprn,"\n%20c MA TRAN A\n\n\n",' ');

for (i=0;i<8;++i)

{ for (j=0;j<6;++j)

fprintf(stdprn,"%10.2f",a[i][j]);

fprintf(stdprn,"\n");

80/134
Bài 11: Bài thực hành về các thành phần cơ
bản và nhập/xuất trong C/C++
Bài thực hành về các thành phần cơ bản và nhập/xuất
trong C/C++
Bài 1

Những tên gọi nào sau đây là hợp lệ:

? x ? 123variabe ? tin_hoc ? toan tin ? so-dem

? RADIUS ? one.0 ? number# ? Radius ? nam2000

Bài 2:

Bạn hãy thử viết một chương trình ngắn nhất có thể được.

Bài 3:

Tìm các lỗi cú pháp trong chương trình sau:

#include (iostream.h)

void main(); / Giải phương trình bậc 1

cout << 'Day la chương trình: Gptb1.\nXin chao cac ban';

getch();

Bài 4:

Viết chương trình in nội dung một bài thơ nào đó.

81/134
Bài 5:

Viết chương trình in ra 4 dòng, 2 cột gồm các số sau và gióng cột:

? thẳng theo lề trái 0.63 64.1


? thẳng theo lề phải 12.78 -11.678
? thẳng theo dấu chấm thập phân -124. 6 59.002
65.7 -1200.654

Bài 6:

Hãy viết và chạy các chương trình trong các ví dụ 3, 5.

Bài 7:

Chương trình sau khai báo 5 biến kí tự a, b, c, d, e và một biến số nam. Hãy điền thêm
các câu lệnh vào các dòng … để chương trình thực hiện nhiệm vụ sau:

• Nhập giá trị cho biến nam


• Nhập giá trị cho các biến kí tự a, b, c, d, e.
• In ra màn hình dòng chữ được ghép bởi 5 kí tự đã nhập và chữ "năm" sau đó in
số đã nhập (nam). Ví dụ nếu 5 chữ cái đã nhập là 'H', 'A', 'N', 'O', 'I' và nam
được nhap là 2000, thì màn hình in ra dòng chữ: HANOI năm 2000.
• Nhập chương trình đã sửa vào máy và chạy để kiểm tra kết quả.

#include <iostream.h>

#include <conio.h>

main()

int nam;

char a, b, c, d, e;

clrscr();

cin >> nam ;

82/134
…;

cin.get(a); cin.get(b); cin.get(c); … ; … ;

// in kết quả

cout << a << … << … << … << … << " nam " << … ;

getch();

Bài 8:

Viết câu lệnh khai báo biến để lưu các giá trị sau:

• Tuổi của một người ? Số lượng cây trong thành phố


• Độ dài cạnh một tam giác ? Khoảng cách giữa các hành tinh
• Một chữ số ? Nghiệm x của phương trình bậc 1
• Một chữ cái ? Biệt thức Δ của phương trình bậc 2

Bài 9:

Viết câu lệnh nhập vào 4 giá trị lần lượt là số thực, nguyên, nguyên dài và kí tự. In ra
màn hình các giá trị này để kiểm tra.

Bài 10:

Viết câu lệnh in ra màn hình các dòng sau (không kể các số thứ tự và dấu: ở đầu mỗi
dòng)

1:Bộ Giáo dục và Đào tạo 2:Cộng hoà xã hội chủ nghĩa Việt Nam

3:Sở Giáo dục Hà Nội Độc lập - Tự do - Hạnh phúc

Chú ý: khoảng trống giữa chữ Đào tạo và Cộng hoà (dòng 1) là 2 tab. Dòng 2: để trống.

Bài 11:

Viết chương trình nhập vào một kí tự. In ra kí tự đó và mã ascii của nó.

83/134
Bài 12:

Viết chương trình nhập vào hai số thực. In ra hai số thực đó với 2 số lẻ và cách nhau 5
cột.

Bài 13:

Nhập, chạy và giải thích kết quả đạt được của đoạn chương trình sau:

#include <iostream.h>

void main()

char c1 = 200; unsigned char c2 = 200 ;

cout << "c1 = " << c1 << ", c2 = " << c2 << "\n" ;

cout << "c1+100 = " << c1+100 << ", c2+100 = " << c2+100 ;

Bài 14:

Nhập a, b, c. In ra màn hình dòng chữ phương trình có dạng ax^2 + bx + c = 0, trong đó
các giá trị a, b, c chỉ in 2 số lẻ (ví dụ với a = 5.141, b = ?2, c = 0.8 in ra 5.14 x^2 ?2.00
x + 0.80).

Bài 15:

Viết chương trình tính và in ra giá trị các biểu thức sau với 2 số lẻ:
1
1. √3 + √3 + √3 b. 1
2+
1
2+
2

Bài 16:

Nhập a, b, c là các số thực. In ra giá trị của các biểu thức sau với 3 số lẻ:

1. a2 ? 2b + ab/c c. 3a ? b3 ? 2 √c
b2 − 4ac
2. 2a d. √a2 / b − 4a / bc + 1

84/134
Bài 17:

In ra tổng, tích, hiệu và thương của 2 số được nhập vào từ bàn phím.

Bài 18:

In ra trung bình cộng, trung bình nhân của 3 số được nhập vào từ bàn phím.

Bài 19:

Viết chương trình nhập cạnh, bán kính và in ra diện tích, chu vi của các hình: vuông,
chữ nhật, tròn.

Bài 20:

Nhập a, b, c là độ dài 3 cạnh của tam giác (chú ý đảm bảo tổng 2 cạnh phải lớn hơn cạnh
còn lại). Tính chu vi, diện tích, độ dài 3 đường cao, 3 đường trung tuyến, 3 đường phân
giác, bán kính đường tròn nội tiếp, ngoại tiếp lần lượt theo các công thức sau:

C = 2p = a + b + c ; S = √p(p − a)(p − b)(p − c) ;


2S 1
ha = a ; ma = 2 √2b2 + 2c2 − a2 ;
2
ga = b + c √bcp(p − a) ;

S abc
r= p ;R= 4S ;

Bài 21:

Tính diện tích và thể tích của hình cầu bán kính R theo công thức:

S = 4πR2 ; V = RS/3

Bài 22:

Nhập vào 4 chữ số. In ra tổng của 4 chữ số này và chữ số hàng chục, hàng đơn vị của
tổng (ví dụ 4 chữ số 3, 1, 8, 5 có tổng là 17 và chữ số hàng chục là 1 và hàng đơn vị là
7, cần in ra 17, 1, 7).

85/134
Bài 23:

Nhập vào một số nguyên (có 4 chữ số). In ra tổng của 4 chữ số này và chữ số đầu, chữ
số cuối (ví dụ số 3185 có tổng các chữ số là 17, đầu và cuối là 3 và 5, kết quả in ra là:
17, 3, 5).

Bài 24:

Hãy nhập 2 số a và b. Viết chương trình đổi giá trị của a và b theo 2 cách:

• dùng biến phụ t: t = a; a = b; b = t;


• không dùng biến phụ: a = a + b; b = a - b; a = a - b;

In kết quả ra màn hình để kiểm tra.

Bài 25:

Viết chương trình đoán số của người chơi đang nghĩ, bằng cách yêu cầu người chơi nghĩ
một số, sau đó thực hiện một loạt các tính toán trên số đã nghĩ rồi cho biết kết quả. Máy
sẽ in ra số mà người chơi đã nghĩ. (ví dụ yêu cầu người chơi lấy số đã nghĩ nhân đôi, trừ
4, bình phương, chia 2 và trừ 7 rồi cho biết kết quả, máy sẽ in ra số người chơi đã nghĩ).

Bài 26:

Một sinh viên gồm có các thông tin: họ tên, tuổi, điểm toán (hệ số 2), điểm tin (hệ số 1).
Hãy nhập các thông tin trên cho 2 sinh viên. In ra bảng điểm gồm các chi tiết nêu trên
và điểm trung bình của mỗi sinh viên.

Bài 27:

Một nhân viên gồm có các thông tin: họ tên, hệ số lương, phần trăm phụ cấp (theo lưong)
và phần trăm phải đóng BHXH. Hãy nhập các thông tin trên cho 2 nhân viên. In ra bảng
lương gồm các chi tiết nêu trên và tổng số tiền cuối cùng mỗi nhân viên được nhận.

86/134
Bài 12: Cấu trúc rẽ nhánh
Cấu trúc rẽ nhánh
Câu lệnh đơn, khối lệnh

• Lệnh

Là một tác vụ, biểu thức, hàm, cấu trúc điều khiển…

Ví dụ 1:

x = x + 2;

printf("Day la mot lenh\n");

• Khối lệnh

Là một dãy các câu lệnh được bọc bởi cặp dấu { }, các lệnh trong khối lệnh phải viết
thụt vô 1 tab so với cặp dấu { }

Ví dụ 2:

{ //dau khoi

a = 5;

b = 6; // viết thụt vô 1 tab so với cặp { }

printf("Tong %d + %d = %d", a, b, a+b);

} //cuoi khoi

Quên dùng cặp dấu { } bao bọc khi sử dụng khối lệnh, hoặc mở dấu { và quên đóng dấu
}

87/134
Các cấu trúc rẽ nhánh

Cấu trúc rẽ nhánh if

Toán tử if cho phép lựa chọn chạy theo một trong hai nhánh tuỳ thuộc vào sự bằng
không và khác không của biểu thức. Nó có hai cách viết sau:

if ( biểu thức )khối lệnh 1;/* Dạng if ( biểu thức )khối lệnh 1;elsekhối lệnh 2 ;/*
một */ Dạng hai */

Hoạt động của biểu thức dạng 1 :

Máy tính giá trị của biểu thức. Nếu biểu thức đúng ( biểu thức có giá trị khác 0 ) máy sẽ
thực hiện khối lệnh 1 và sau đó sẽ thực hiện các lệnh tiếp sau lệnh if trong chương trình.
Nếu biểu thức sai ( biểu thức có giá trị bằng 0 ) thì máy bỏ qua khối lệnh 1 mà thực hiện
ngay các lệnh tiếp sau lệnh if trong chương trình.

Hoạt động của biểu thức dạng 2 :

Máy tính giá trị của biểu thức. Nếu biểu thức đúng ( biểu thức có giá trị khác 0 ) máy sẽ
thực hiện khối lệnh 1 và sau đó sẽ thực hiện các lệnh tiếp sau khối lệnh 2 trong chương
trình. Nếu biểu thức sai ( biểu thức có giá trị bằng 0 ) thì máy bỏ qua khối lệnh 1 mà
thực hiện khối lệnh 2 sau đó thực hiện tiếp các lệnh tiếp sau khối lệnh 2 trong chương
trình.

Ví dụ :

Chương trình nhập vào hai số a và b, tìm max của hai số rồi in kết quả lên màn hình.
Chương trình có thể viết bằng cả hai cách trên như sau:

#include "stdio.h"

main()

float a,b,max;

printf("\n Cho a=");

scanf("%f",&a);

printf("\n Cho b=");

88/134
scanf("%f",&b);

max=a;

if (b>max) max=b;

printf(" \n Max cua hai so a=%8.2f va b=%8.2f la Max=%8.2f",a,b,max);

#include "stdio.h"

main()

float a,b,max;

printf("\n Cho a=");

scanf("%f",&a);

printf("\n Cho b=");

scanf("%f",&b);

if (a>b) max=a;

else max=b;

printf(" \n Max cua hai so a=%8.2f va b=%8.2f la Max=%8.2f",a,b,max);

89/134
nếu biểu thức luận lý đúng thì

thực hiện khối lệnh và thoát khỏi if,

ngược lại

không làm gì cả và thoát khỏi if.

Nếu khối lệnh bao gồm từ 2 lệnh trở lên thì phải đặt trong dấu { }

Diễn giải:

+ Khối lệnh là một lệnh ta viết lệnh if như sau:

if (biểu thức luận lý)

lệnh;

+ Khối lệnh bao gồm nhiều lệnh: lệnh 1, lệnh 2..., ta viết lệnh if như sau:

if (biểu thức luận lý)

lệnh 1;

90/134
lệnh 2;

...

Không đặt dấu chấm phẩy sau câu lệnh if.

Ví dụ: if(biểu thức luận lý);

→ trình biên dịch không báo lỗi nhưng khối lệnh không được thực hiện cho dù

điều kiện đúng hay sai.

• Sự lồng nhau của các toán tử if

Ngôn ngữ C cho phép sử dụng các toán tử if lồng nhau có nghĩa là trong các khối lệnh
(1 và 2) ở trên có thể chứa các toán tử if - else khác. Trong trường hợp này, nếu không
sử dụng các dấu đóng mở ngoặc cho các khối thì sẽ có thể nhầm lẫn giữa các if-else.

Chú ý là máy sẽ gắn toán tử else với toán tử if không có else gần nhất. Chẳng hạn như
đoạn chương trình ví dụ sau:

if ( n>0 ) /* if thứ nhất*/

if ( a>b ) /* if thứ hai*/

z=a;

else

z=b;

thì else ở đây sẽ đi với if thứ hai.

Đoạn chương trình trên tương đương với :

if ( n>0 ) /* if thứ nhất*/

if ( a>b ) /* if thứ hai*/

z=a;

91/134
else

z=b;

Trường hợp ta muốn else đi với if thứ nhất ta viết như sau:

if ( n>0 ) /* if thứ nhất*/

if ( a>b ) /* if thứ hai*/

z=a;

else

z=b;

• Lệnh else-if:

Khi muốn thực hiện một trong n quyết định ta có thể sử dụng cấu trúc sau:

if ( biểu thức 1 )

khối lệnh 1;

else if ( biểu thức 2 )

khối lệnh 2;

......

else if ( biểu thức n-1 )

khối lệnh n-1;

else

khối lệnh n;

92/134
Trong cấu trúc này, máy sẽ đi kiểm tra từ biểu thức 1 trở đi đến khi gặp biểu thức nào
có giá trị khác 0.

Nếu biểu thức thứ i (1,2, ...n-1) có giá trị khác 0, máy sẽ thực hiện khối lệnh i, rồi sau
đó đi thực hiện lệnh nằm tiếp theo khối lệnh n trong chương trình.

Nếu trong cả n-1 biểu thức không có biểu thức nào khác 0, thì máy sẽ thực hiện khối
lệnh n rồi sau đó đi thực hiện lệnh nằm tiếp theo khối lệnh n trong chương trình.

Ví dụ :

Chương trình giải phương trình bậc hai.

#include "stdio.h"

main()

float a,b,c,d,x1,x2;

printf("\n Nhap a, b, c:");

scanf("%f%f%f,&a&b&c);

d=b*b-4*a*c;

if (d<0.0)

printf("\n Phuong trinh vo nghiem ");

else if (d==0.0)

printf("\n Phuong trinh co nghiem kep x1,2=%8.2f",-b/(2*a));

else

printf("\n Phuong trinh co hai nghiem ");

printf("\n x1=%8.2f",(-b+sqrt(d))/(2*a));

printf("\n x2=%8.2f",(-b-sqrt(d))/(2*a));

93/134
}

• Lệnh nhảy không điều kiện - toán tử goto:

Nhãn có cùng dạng như tên biến và có dấu: đứng ở phía sau. Nhãn có thể được gán cho
bất kỳ câu lệnh nào trong chương trình.

Ví dụ :

ts: s=s++;

thì ở đây ts là nhãn của câu lệnh gán s=s++.

Toán tử goto có dạng:

goto nhãn;

Khi gặp toán tử này máy sẽ nhảy tới câu lệnh có nhãn viết sau từ khoá goto.

Khi dùng toán tử goto cần chú ý :

Câu lệnh goto và nhãn cần nằm trong một hàm, có nghĩa là toán tử goto chỉ cho phép
nhảy từ vị trí này đến vị trí khác trong thân một hàm và không thể dùng để nhảy từ một
hàm này sang một hàm khác.

Không cho phép dùng toán tử goto để nhảy từ ngoài vào trong một khối lệnh. Tuy nhiên
việc nhảy từ trong một khối lệnh ra ngoài là hoàn toàn hợp lệ. Ví dụ như đoạn chương
trình sau là sai.

goto n1;

.......

{ .....

n1: printf("\n Gia tri cua N la: ");

.....

Ví dụ :

Tính tổng s=1+2+3+....+10

94/134
#include "stdio.h"

main()

int s,i;

i=s=0;

tong:

++i;

s=s+i;

if (i<10) goto tong;

printf("\n tong s=%d",s);

Cấu trúc rẽ nhánh switch

Là cấu trúc tạo nhiều nhánh đặc biệt. Nó căn cứ vào giá trị một biểu thức nguyên để để
chọn một trong nhiều cách nhảy.

Cấu trúc tổng quát của nó là:

switch ( biểu thức nguyên )

case n1

khối lệnh 1

case n2

khối lệnh 2

.......

case nk

95/134
khối lệnh k

[ default

khối lệnh k+1 ]

Với ni là các số nguyên, hằng ký tự hoặc biểu thức hằng. Các ni cần có giá trị khác nhau.
Đoạn chương trình nằm giữa các dấu { } gọi là thân của toán tử switch.

default là một thành phần không bắt buộc phải có trong thân của switch.

Sự hoạt động của toán tử switch phụ thuộc vào giá trị của biểu thức viết trong dấu ngoặc
( ) như sau:

Khi giá trị của biểu thức này bằng ni, máy sẽ nhảy tới các câu lệnh có nhãn là case ni.

Khi giá trị biểu thức khác tất cả các ni thì cách làm việc của máy lại phụ thuộc vào sự
có mặt hay không của lệnh default như sau:

Khi có default máy sẽ nhảy tới câu lệnh sau nhãn default.

Khi không có default máy sẽ nhảy ra khỏi cấu trúc switch.

Chú ý :

Máy sẽ nhảy ra khỏi toán tử switch khi nó gặp câu lệnh break hoặc dấu ngoặc nhọn đóng
cuối cùng của thân switch. Ta cũng có thể dùng câu lệnh goto trong thân của toán tử
switch để nhảy tới một câu lệnh bất kỳ bên ngoài switch.

Khi toán tử switch nằm trong thân một hàm nào đó thì ta có thể sử dụng câu lệnh return
trong thân của switch để ra khỏi hàm này ( lệnh return sẽ đề cập sau ).

Khi máy nhảy tới một câu lệnh nào đó thì sự hoạt động tiếp theo của nó sẽ phụ thuộc
vào các câu lệnh đứng sau câu lệnh này. Như vậy nếu máy nhảy tới câu lệnh có nhãn
case ni thì nó có thể thực hiện tất cả các câu lệnh sau đó cho tới khi nào gặp câu lệnh
break, goto hoặc return. Nói cách khác, máy có thể đi từ nhóm lệnh thuộc case ni sang
nhóm lệnh thuộc case thứ ni+1. Nếu mỗi nhóm lệnh được kết thúc bằng break thì toán
tử switch sẽ thực hiện chỉ một trong các nhóm lệnh này.

Ví dụ:

Lập chương trình phân loại học sinh theo điểm sử dụng cấu trúc switch:

96/134
#include "stdio.h"

main()

int diem;

tt: printf("\nVao du lieu:");

printf("\n Diem =");

scanf("%d",&diem);

switch (diem)

case 0:

case 1:

case 2:

case 3:printf("Kem\n");break;

case 4:printf("Yeu\n");break;

case 5:

case 6:printf("Trung binh\n");break;

case 7:

case 8:printf("Kha\n");break;

case 9:

case 10:printf("Gioi\n");break;

default:printf(Vao sai\n);

97/134
printf("Tiep tuc 1, dung 0:")

scanf("%d",&diem);

if (diem==1) goto tt;

getch();

return;

98/134
Bài 13: Bài thực hành về cấu trúc rẽ nhánh
Bài thực hành về cấu trúc rẽ nhánh
Bài 1. Cho hàm số f(x) = 2 nếu x ≤ 1

f(x) = x² + 1 nếu x > 1

Viết chương trình nhập số thực x từ bàn phím để tính giá trị của hàm số f(x)

Bài 2. Hàm số f(x) được xác định như sau:

? x nếu x>1

f(x) = ? 0 nếu -1 ≤ x ≤ 1

? -x nếu x < -1

Viết phương trình nhập số thực x từ bàn phím và in ra màn hình giá trị của f(x).

Bài 3. Hàm dấu sgn(x) được xác định như sau:

? 1 nếu x>0

sgn(x) = ? 1 nếu x=0

? -1 nếu x<0

Viết chương trình nhập vào số thực x và in ra sgn(x)

Bài 4. Viết chương trình nhập số thực x từ bàn phím. Kiểm tra xem x nằm trong hay
ngoài các đoạn [-1;0] và [1;2]

Bài 5. Viết chương trình nhập 2 số thực x, y từ bàn phím và các phép tính (+,-,*,/) rồi
thực hiện các phép tính đó.

Bài 6. Viết chương trình giải bất phương trình: ax² + bx + c > 0

Bài 7. Viết chương trình giải phương trình trùng phương ax4 + bx² + c = 0

Bài 8. Viết chương trình nhập 4 số thực từ bàn phím.

99/134
a. In ra màn hình số lớn nhất và số nhỏ nhất trong bốn số đó.

b. Tính xem có bao nhiêu số âm, số dương, số không trong bốn số đó.

Bài 9. Viết chương trình kiểm tra 3 số a, b, c có là ba cạnh của tam giác không? Nếu có
hãy nhận diện tam giác đó (vuông, cân , đều) và tình chu vi, diện tích, độ dài ba đường
trung tuyến, bán kính đường tròn nội tiếp và ngoại tiếp tam giác đó.

Cho biết Chu vi C = 2p = a + b + c, diện tích S = căn của [p(p-a)(p-b)(p-c)] ; đường cao
h = 2S/a ; đương trung tuyến m = căn của [(b² + c² - a²/2)2] ; bán kính đường tròn nội và
ngoại tiếp R = abc/4S ; r = S/p

Bài 10. Viết chương trình nhập tọa độ 4 điểm A, B, C, D trong mặt phẳng. Gọi M, N,
P, Q lần lượt là trung điểm của các cạnh AB, BC, CD, DA của tứ giác ABCD. Kiểm tra
xem tứ giác MNPQ có là hình bình hành không?

Bài 11. Viết chương trình tính diện tích của tam giác dựa trên độ dài của 3 cạnh. Chương
trình phải có khả năng báo lỗi khi người dùng nhập sai (Như độ dài nhỏ hơn 0 hoặc độ
dài của 3 cạnh không lập thành một tam giác).Bài 12. Cho 3 số thực x, y, z. Viết chương
trình làm nhiệm vụ sau:

• Có tồn tại hay không 1 tam giác có độ dài 3 cạnh là x, y, z.


• Nếu tồn tại thì đây là tam giác vuông, thường hay cân.

Bài 13. Viết chương trình giải hệ phương trình:

Giải bằng phương pháp tính định thức và phương pháp ma trận nghịch đảo.

Bài 14. Giải phương trình bậc 2 với a, b, c được nhập vào từ bàn phím. Chú ý xét tất cả
các trường hợp có thể xảy ra.

Bài 15. Nhập vào một số x dùng để biểu diễn thời gian tính theo giây. Viết chương trình
chuyển các số này ra dạng giờ-phút-giây.

Bài 16. Nhập vào một tháng và năm bất kỳ. Sau đó hiện lên màn hình tháng đó có bao
nhiêu ngày.

100/134
Bài 14- 15: Cấu trúc lặp while, do .. while -
Cấu trúc lặp for
Cấu trúc lặp while, do .. while - Cấu trúc lặp for
Cấu trúc lặp while, do .. while

Cấu trúc lặp while

Toán tử while dùng để xây dựng chu trình lặp dạng:

while ( biểu thức )

Lệnh hoặc khối lệnh;

Như vậy toán tử while gồm một biểu thức và thân chu trình. Thân chu trình có thể là
một lệnh hoặc một khối lệnh.

Hoạt động của chu trình như sau:

Máy xác định giá trị của biểu thức, tuỳ thuộc giá trị của nó máy sẽ chọn cách thực hiện
như sau:

Nếu biểu thức có giá trị 0 ( biểu thức sai ), máy sẽ ra khỏi chu trình và chuyển tới thực
hiện câu lệnh tiếp sau chu trình trong chương trình.

Nếu biểu thức có giá trị khác không ( biểu thức đúng ), máy sẽ thực hiện lệnh hoặc khối
lệnh trong thân của while. Khi máy thực hiện xong khối lệnh này nó lại thực hiện xác
định lại giá trị biểu thức rồi làm tiếp các bước như trên.

Chú ý:

Trong các dấu ngoặc ( ) sau while chẳng những có thể đặt một biểu thức mà còn có thể
đặt một dãy biểu thức phân cách nhau bởi dấu phảy. Tính đúng sai của dãy biểu thức
được hiểu là tính đúng sai của biểu thức cuối cùng trong dãy.

Bên trong thân của một toán tử while lại có thể sử dụng các toán tử while khác. bằng
cách đó ta đi xây dựng được các chu trình lồng nhau.

Khi gặp câu lệnh break trong thân while, máy sẽ ra khỏi toán tử while sâu nhất chứa câu
lệnh này.

101/134
Trong thân while có thể sử dụng toán tử goto để nhảy ra khỏi chu trình đến một vị trí
mong muốn bất kỳ. Ta cũng có thể sử dụng toán tử return trong thân while để ra khỏi
một hàm nào đó.

Ví dụ:

Chương trình tính tích vô hướng của hai véc tơ x và y:

Cách 1:

#include "stdio.h"

float x[]={2,3.4,4.6,21}, y[]={24,12.3,56.8,32.9};

main()

float s=0;

int i=-1;

while (++i<4)

s+=x[i]*y[i];

printf("\n Tich vo huong hai vec to x va y la:%8.2f",s);

Cách 2:

#include "stdio.h"

float x[]={2,3.4,4.6,21}, y[]={24,12.3,56.8,32.9};

main()

float s=0;

int i=0;

102/134
while (1)

s+=x[i]*y[i];

if (++i>=4) goto kt;

kt:printf("\n Tich vo huong hai vec to x va y la:%8.2f",s);

Cách 3:

#include "stdio.h"

float x[]={2,3.4,4.6,21}, y[]={24,12.3,56.8,32.9};

main()

float s=0;

int i=0;

while ( s+=x[i]*y[i], ++i<=3 );

printf("\n Tich vo huong hai vec to x va y la:%8.2f",s);

Cấu trúc lặp do..while

Khác với các toán tử while và for, việc kiểm tra điều kiện kết thúc đặt ở đầu chu trình,
trong chu trình do while việc kiểm tra điều kiện kết thúc đặt cuối chu trình. Như vậy
thân của chu trình bao giờ cũng được thực hiện ít nhất một lần.

Chu trình do while có dạng sau:

do

103/134
Lệnh hoặc khối lệnh;

while ( biểu thức );

Lệnh hoặc khối lệnh là thân của chu trình có thể là một lệnh riêng lẻ hoặc là một khối
lệnh.

Hoạt động của chu trình như sau:

Máy thực hiện các lệnh trong thân chu trình.

Khi thực hiện xong tất cả các lệnh trong thân của chu trình, máy sẽ xác định giá trị của
biểu thức sau từ khoá while rồi quyết định thực hiện như sau:

Nếu biểu thức đúng ( khác 0 ) máy sẽ thực hiện lặp lại khối lệnh của chu trình lần thứ
hai rồi thực hiện kiểm tra lại biểu thức như trên.

Nếu biểu thức sai ( bằng 0 ) máy sẽ kết thúc chu trình và chuyển tới thực hiện lệnh đứng
sau toán tử while.

Chú ý:

Những điều lưu ý với toán tử while ở trên hoàn toàn đúng với do while.

Ví dụ:

Đoạn chương trình xác định phần tử âm đầu tiên trong các phần tử của mảng x.

#include "stdio.h"

float x[5],c;

main()

int i=0;

printf("\n nhap gia tri cho ma tran x ");

for (i=0;i<=4;++i)

104/134
printf("\n x[%d]=",i);

scanf("%f",&c);

y[i]=c;

do

++i;

while (x[i]>=0 && i<=4);

if (i<=4)

printf("\n Phan tu am dau tien = x[%d]=%8.2f",i,x[i]);

else

printf("\n Mang khong có phan tu am ");

Cấu trúc lặp for và một số lệnh điều khiển khác

Cấu trúc lặp for

Toán tử for dùng để xây dựng cấu trúc lặp có dạng sau:

for ( biểu thức 1; biểu thức 2; biểu thức 3)

Lệnh hoặc khối lệnh ;

Toán tử for gồm ba biểu thức và thân for. Thân for là một câu lệnh hoặc một khối lệnh
viết sau từ khoá for. Bất kỳ biểu thức nào trong ba biểu thức trên có thể vắng mặt nhưng
phải giữ dấu ; .

Thông thường biểu thức 1 là toán tử gán để tạo giá trị ban đầu cho biến điều khiển, biểu
thức 2 là một quan hệ logic biểu thị điều kiện để tiếp tục chu trình, biểu thức ba là một
toán tử gán dùng để thay đổi giá trị biến điều khiển.

Hoạt động của toán tử for:

105/134
Toán tử for hoạt động theo các bước sau:

Xác định biểu thức 1

Xác định biểu thức 2

Tuỳ thuộc vào tính đúng sai của biểu thức 2 để máy lựa chọn một trong hai nhánh:

Nếu biểu thức hai có giá trị 0 ( sai ), máy sẽ ra khỏi for và chuyển tới câu lệnh sau thân
for.

Nếu biểu thức hai có giá trị khác 0 ( đúng ), máy sẽ thực hiện các câu lệnh trong thân
for.

Tính biểu thức 3, sau đó quay lại bước 2 để bắt đầu một vòng mới của chu trình.

Chú ý :

Nếu biểu thức 2 vắng mặt thì nó luôn được xem là đúng. Trong trường hợp này việc
ra khỏi chu trình for cần phải được thực hiện nhờ các lệnh break, goto hoặc return viết
trong thân chu trình.

Trong dấu ngoặc tròn sau từ khoá for gồm ba biểu thức phân cách nhau bởi dấu ;. Trong
mỗi biểu thức không những có thể viết một biểu thức mà có quyền viết một dãy biểu
thức phân cách nhau bởi dấu phảy. Khi đó các biểu thức trong mỗi phần được xác định
từ trái sang phải. Tính đúng sai của dãy biểu thức được tính là tính đúng sai của biểu
thức cuối cùng trong dãy này.

Trong thân của for ta có thể dùng thêm các toán tử for khác, vì thế ta có thể xây dựng
các toán tử for lồng nhau.

Khi gặp câu lệnh break trong thân for, máy ra sẽ ra khỏi toán tử for sâu nhất chứa câu
lệnh này. Trong thân for cũng có thể sử dụng toán tử goto để nhảy đến một ví trí mong
muốn bất kỳ.

Ví dụ 1:

Nhập một dãy số rồi đảo ngược thứ tự của nó.

Cách 1 :

#include “stdio.h”

float x[]={1.3,2.5,7.98,56.9,7.23};

106/134
int n=sizeof(x)/sizeof(float);

main()

int i,j;

float c;

for (i=0,j=n-1;i<j;++i,--j)

c=x[i];x[i]=x[j];x[j]=c;

fprintf(stdprn,“\n Day so dao la \n\n”);

for (i=0;i<n;++i)

fprintf(stdprn,“%8.2f”,x[i]);

Cách 2:

#include “stdio.h”

float x[]={1.3,2.5,7.98,56.9,7.23};

int n=sizeof(x)/sizeof(float);

main()

int i,j;

float c;

for (i=0,j=n-1;i<j;c=x[i],x[i]=x[j],x[j]=c,++i,--j)

107/134
fprintf(stdprn,“\n Day so dao la \n\n”);

for (i=0;++i<n;)

fprintf(stdprn,“%8.2f”,x[i]);

Cách 3:

#include “stdio.h”

float x[]={1.3,2.5,7.98,56.9,7.23};

int n=sizeof(x)/sizeof(float);

main()

int i=0,j=n-1;

float c;

for ( ; ; )

c=x[i];x[i]=x[j];x[j]=c;

if (++i>--j) break;

fprintf(stdprn,“\n Day so dao la \n\n”);

for (i=-1;i++<n-1; fprintf(stdprn,“%8.2f”,x[i]));

Ví dụ 2:

Tính tích hai ma trận mxn và nxp.

108/134
#include "stdio.h"

float x[3][2],y[2][4],z[3][4],c;

main()

int i,j;

printf("\n nhap gia tri cho ma tran X ");

for (i=0;i<=2;++i)

for (j=0;j<=1;++j)

printf("\n x[%d][%d]=",i,j);

scanf("%f",&c);

x[i][j]=c;

printf("\n nhap gia tri cho ma tran Y ");

for (i=0;i<=1;++i)

for (j=0;j<=3;++j)

printf("\n y[%d][%d]=",i,j);

scanf("%f",&c);

y[i][j]=c;

for (i=0;i<=3;++i)

109/134
for (j=0;j<=4;++j)

z[i][j]

Break, continue, return

Câu lệnh break

Câu lệnh break cho phép ra khỏi các chu trình với các toán tử for, while và switch. Khi
có nhiều chu trình lồng nhau, câu lệnh break sẽ đưa máy ra khỏi chu trình bên trong nhất
chứa nó không cần điều kiện gì. Mọi câu lệnh break có thể thay bằng câu lệnh goto với
nhãn thích hợp.

Ví dụ:

Biết số nguyên dưưng n sẽ là số nguyên tố nếu nó không chia hết cho các số nguyên
trong khoảng từ 2 đến căn bậc hai của n. Viết đoạn chưưng trình đọc vào số nguyên
dưưng n, xem n có là số nguyên tố.

# include "stdio.h"

# include "math.h"

unsigned int n;

main()

int i,nt=1;

printf("\n cho n=");

scanf("%d",&n);

for (i=2;i<=sqrt(n);++i)

if ((n % i)==0)

nt=0;

110/134
break;

if (nt)

printf("\n %d la so nguyen to",n);

else

printf("\n %d khong la so nguyen to",n);

Câu lệnh continue

Trái với câu lệnh break, lệnh continue dùng để bắt đầu một vòng mới của chu trình chứa
nó. Trong while và do while, lệnh continue chuyển điều khiển về thực hiện ngay phần
kiểm tra, còn trong for điều khiển được chuyển về bước khởi đầu lại ( tức là bước: tính
biểu thức 3, sau đó quay lại bước 2 để bắt đầu một vòng mới của chu trình).

Chú ý:

Lệnh continue chỉ áp dụng cho chu trình chứ không áp dụng cho switch.

Ví dụ:

Viết chưưng trình để từ một nhập một ma trận a sau đó:

Tính tổng các phần tử dưưng của a.

Xác định số phần tử dưưng của a.

Tìm cực đại trong các phần tử dưưng của a.

#include "stdio.h"

float a[3[4];

main()

int i,j,soptd=0;

111/134
float tongduong=0,cucdai=0,phu;

for (i=0;i<3;++i)

for (j=0;i<4;++j)

printf("\n a[%d][%d]=",i,j );

scanf("%f",&phu);

a[i][j]=phu;

if (a[i][j]<=0) continue;

tongduong+=a[i][j];

if (cucdai<a[i][j]) cucdai=a[i][j];

++soptd; }

printf("\n So phan tu duong la: %d",soptd);

printf("\n Tong cac phan tu duong la: %8.2f",tongduong);

printf("\n Cuc dai phan tu duong la: %8.2f",cucdai);

Lệnh return

Lệnh return được dùng để kết thúc các hàm tại bất cứ điểm nào. Trong một hàm lệnh
return còn có thể được trả về giá trị của hàm và kết thúc hàm.

Ví dụ

int cong(int a, int b){

return a+b;

Hàm trên sẽ trả về giá trị của a+b được xác định trong hàm.

112/134
Bài 16- 17: Thảo luận về các cấu trúc điểu
khiển - Bài thực hành về cấu trúc lặp
Thảo luận về các cấu trúc điểu khiển - Bài thực hành về
cấu trúc lặp
Thảo luận về các cấu trúc điểu khiển khiển

Bài thực hành về cấu trúc lặp

Bài 1

Kiểm tra tìm lỗi :

while ( x<.= 10 )

Total t=x;

++x ;

Bài 2

Giải phương trình bậc 2 : ax2 + bx + c = 0 với a, b, c là số thực nhập từ bàn phím.

Bài 3

Nhập số liệu vào bàn phím, kết thúc nhập bằng cách ấn ^Z hoặc F6 ( mũ = 255 ). Biết :

InWord = on khi ở trong 1 từ. InWord = off khi ngược lại. Ðếm số dòng, số từ, số ký tự.

Bài 4

Tìm các số nằm trong khoảng từ 150 đến 140 thoả tính chất số bằng tổng lập phương
các chữ số của chúng :

Ví dụ : 153 = 13 + 53 + 33 hoặc 370 = 33 + 73 + 03

Bài 5

Số tuyệt hảo là số bằng tổng các ước số thực sự của nó.

113/134
Ví dụ : 6 = 1 + 2 + 3.Tìm các số tuyệt hảo trong khoảng từ 1 đến 3000.

Bài 6

Nhập số liệu vào mãng A gồm 10 phần tử và sắp xếp theo thứ tự tăng dần.

Bài 7

Tìm tất cả các số nguyên tố từ 2 đến 100 bằng lệnh For.

Bài 8

Tìm các số nguyên có 3 chữ số sao cho tổng 3 chữ bằng tích 3 chữ. Ví dụ : 123.

Bài 9

a. Dùng lệnh while để viết chương trình tính :

S1 = 1 x 3 x 5 x 7 x 9. . . . . x ( 2n - 1 ).

S2 = 2 x 4 x 6 x 8 x ......x (2n).

b. làm lại bài trên bằng cách dùng do...while.

Bài 10

Giải bài toán cổ điển vừa gà vừa chó bó lại cho tròn 36 con 100

chân chẵn.

114/134
Bài 18: Các kiểu dữ liệu trong C/C++
Các kiểu dữ liệu trong C/C++
Khái niệm về kiểu dữ liệu

Thông thường dữ liệu hay dùng là số và chữ. Tuy nhiên việc phân chia chỉ 2 loai dữ
liệu là không đủ. Để dễ dàng hơn cho lập trình, hầu hết các NNLT đều phân chia dữ
liệu thành nhiều kiểu khác nhau được gọi là các kiểu cơ bản hay chuẩn. Trên cơ sở kết
hợp các kiểu dữ liệu chuẩn, NSD có thể tự đặt ra các kiểu dữ liệu mới để phục vụ cho
chương trình giải quyết bài toán của mình. Có nghĩa lúc đó mỗi đối tượng được quản lý
trong chương trình sẽ là một tập hợp nhiều thông tin hơn và được tạo thành từ nhiều loại
(kiểu) dữ liệu khác nhau. Dưới đây chúng ta sẽ xét đến một số kiểu dữ liệu chuẩn được
qui định sẵn bởi C++.

Một biến như đã biết là một số ô nhớ liên tiếp nào đó trong bộ nhớ dùng để lưu trữ dữ
liệu (vào, ra hay kết quả trung gian) trong quá trình hoạt động của chương trình. Để quản
lý chặt chẽ các biến, NSD cần khai báo cho chương trình biết trước tên biến và kiểu của
dữ liệu được chứa trong biến. Việc khai báo này sẽ làm chương trình quản lý các biến dễ
dàng hơn như trong việc phân bố bộ nhớ cũng như quản lý các tính toán trên biến theo
nguyên tắc: chỉ có các dữ liệu cùng kiểu với nhau mới được phép làm toán với nhau. Do
đó, khi đề cập đến một kiểu chuẩn của một NNLT, thông thường chúng ta sẽ xét đến các
yếu tố sau:

• tên kiểu: là một từ dành riêng để chỉ định kiểu của dữ liệu.
• số byte trong bộ nhớ để lưu trữ một đơn vị dữ liệu thuộc kiểu này: Thông
thường số byte này phụ thuộc vào các trình biên dịch và hệ thống máy khác
nhau, ở đây ta chỉ xét đến hệ thống máy PC thông dụng hiện nay.
• Miền giá trị của kiểu: Cho biết một đơn vị dữ liệu thuộc kiểu này sẽ có thể lấy
giá trị trong miền nào, ví dụ nhỏ nhất và lớn nhất là bao nhiêu. Hiển nhiên các
giá trị này phụ thuộc vào số byte mà hệ thống máy qui định cho từng kiểu.
NSD cần nhớ đến miền giá trị này để khai báo kiểu cho các biến cần sử dụng
một cách thích hợp.

Dưới đây là bảng tóm tắt một số kiểu chuẩn đơn giản và các thông số của nó được sử
dụng trong C++.

Loại dữ liệu Tên kiểu Số ô nhớ Miền giá trị


Kí tự char 1 byte ? 128 .. 127

115/134
unsigned char 1 byte 0 .. 255
Số nguyên int 2 byte ? 32768 .. 32767
unsigned int 2 byte 0 .. 65535
short 2 byte ? 32768 .. 32767

long 4 byte ? 215 .. 215 – 1

Số thực float 4 byte ± 10 -37 . . ± 10 +38

double 8 byte ± 10 -307 . . ± 10 +308

Bảng 1. Các loại kiểu đơn giản

Trong chương này chúng ta chỉ xét các loại kiểu đơn giản trên đây. Các loại kiểu có cấu
trúc do người dùng định nghĩa sẽ được trình bày trong các chương sau.

Kiểu ký tự (char)

Một giá trị kiểu char chiếm 1 byte ( 8 bit ) và biểu diễn được một ký tự thông qua bảng
mã ASCII. Ví dụ:

Ký tự Mã ASCII
0 048
1 049
2 050
A 065
B 066
a 097
b 098

Có hai kiểu dữ liệu char: kiểu signed char và unsigned char.

Kiểu Phạm vi biểu diễn Số ký tự Kích thước


Char ( Signed char ) -128 đến 127 256 1 byte
Unsigned char 0 đến 255 256 1 byte

116/134
Ví dụ sau minh hoạ sự khác nhau giữa hai kiểu dữ liệu trên: Xét đoạn chương trình sau:

char ch1;

unsigned char ch2;

......

ch1=200; ch2=200;

Khi đó thực chất:

ch1=-56;

ch2=200;

Nhưng cả ch1 và ch2 đều biểu diễn cùng một ký tự có mã 200.

Phân loại ký tự:

Có thể chia 256 ký tự làm ba nhóm:

Nhóm 1: Nhóm các ký tự điều khiển có mã từ 0 đến 31. Chẳng hạn ký tự mã 13 dùng để
chuyển con trỏ về đầu dòng, ký tự 10 chuyển con trỏ xuống dòng dưới ( trên cùng một
cột ). Các ký tự nhóm này nói chung không hiển thị ra màn hình.

Nhóm 2: Nhóm các ký tự văn bản có mã từ 32 đến 126. Các ký tự này có thể được đưa
ra màn hình hoặc máy in.

Nhóm 3: Nhóm các ký tự đồ hoạ có mã số từ 127 đến 255. Các ký tự này có thể đưa ra
màn hình nhưng không in ra được ( bằng các lệnh DOS ).

Kiểu nguyên

Trong C cho phép sử dụng số nguyên kiểu int, số nguyên dài kiểu long và số nguyên
không dấu kiểu unsigned. Kích cỡ và phạm vi biểu diễn của chúng được chỉ ra trong
bảng dưới đây:

Kiểu Phạm vi biểu diễn Kích thước


int -32768 đến 32767 2 byte
unsigned int 0 đến 65535 2 byte
long -2147483648 đến 2147483647 4 byte

117/134
unsigned long 0 đến 4294967295 4 byte

Chú ý :

Kiểu ký tự cũng có thể xem là một dạng của kiểu nguyên.

Kiểu dấu phảy động

Trong C cho phép sử dụng ba loại dữ liệu dấu phảy động, đó là float, double và long
double. Kích cỡ và phạm vi biểu diễn của chúng được chỉ ra trong bảng dưới đây:

Kiểu Phạm vi biểu diễn Số chữ sốcó nghĩa Kích thước


Float 3.4E-38 đến 3.4E+38 7 đến 8 4 byte
Double 1.7E-308 đến 1.7E+308 15 đến 16 8 byte
long double 3.4E-4932 đến 1.1E4932 17 đến 18 10 byte

Giải thích :

Máy tính có thể lưu trữ được các số kiểu float có giá trị tuyệt đối từ 3.4E-38 đến
3.4E+38. Các số có giá trị tuyệt đối nhỏ hơn3.4E-38 được xem bằng 0. Phạm vi biểu
diễn của số double được hiểu theo nghĩa tương tự.

Định nghĩa kiểu bằng TYPEDEF

Công dụng:

Từ khoá typedef dùng để đặt tên cho một kiểu dữ liệu. Tên kiểu sẽ được dùng để khai
báo dữ liệu sau này. Nên chọn tên kiểu ngắn và gọn để dễ nhớ. Chỉ cần thêm từ khoá
typedef vào trước một khai báo ta sẽ nhận được một tên kiểu dữ liệu và có thể dùng tên
này để khai báo các biến, mảng, cấu trúc, vv...

Cách viết:

Viết từ khoá typedef, sau đó kiểu dữ liệu ( một trong các kiểu trên ), rồi đến tên của kiểu.

Ví dụ câu lệnh:

typedef int nguyen;

sẽ đặt tên một kiểu int là nguyen. Sau này ta có thể dùng kiểu nguyen để khai báo các
biến, các mảng int như ví dụ sau ;

118/134
nguyen x,y,a[10],b[20][30];

Tương tự cho các câu lệnh:

typedef float mt50[50];

Đặt tên một kiểu mảng thực một chiều có 50 phần tử tên là mt50.

typedef int m_20_30[20][30];

Đặt tên một kiểu mảng thực hai chiều có 20x30 phần tử tên là m_20_30.

Sau này ta sẽ dùng các kiểu trên khai báo:

mt50 a,b;

m_20_30 x,y;

119/134
Bài 19- 20: Chương trình con - thực hành về
xây dựng chương trình con
Chương trình con - thực hành về xây dựng chương trình
con
Chương trình con

Đặt vấn đề

Trong những chương trình lớn, có thể có những đoạn chương trình viết lặp đi lặp lại
nhiều lần, để tránh rườm rà và mất thời gian khi viết chương trình; người ta thường phân
chia chương trình thành nhiều module, mỗi module giải quyết một công việc nào đó.
Các module như vậy gọi là các chương trình con.

Một tiện lợi khác của việc sử dụng chương trình con là ta có thể dễ dàng kiểm tra xác
định tính đúng đắn của nó trước khi ráp nối vào chương trình chính và do đó việc xác
định sai sót để tiến hành hiệu đính trong chương trình chính sẽ thuận lợi hơn.Trong C,
chương trình con được gọi là hàm. Hàm trong C có thể trả về kết quả thông qua tên hàm
hay có thể không trả về kết quả.

Hàm có hai loại: hàm chuẩn và hàm tự định nghĩa. Trong chương này, ta chú trọng đến
cách định nghĩa hàm và cách sử dụng các hàm đó.

Một hàm khi được định nghĩa thì có thể sử dụng bất cứ đâu trong chương trình. Trong
C, một chương trình bắt đầu thực thi bằng hàm main.

• Một chương trình con (còn được gọi là hàm, thủ tục, hay thủ tục con) là một
chuỗi mã để thực thi một thao tác đặc thù nào đó như là một phần của chương
trình lớn hơn. Đây là các câu lệnh được nhóm vào một khối và được đặt tên và
tên này tùy theo ngôn ngữ có thể được gán cho một kiểu dữ liệu. Những khối
mã này có thể được tập trung lại làm thành các thư viện phần mềm. Các
chương trình con có thể được gọi ra để thi hành (thường là qua tên của chương
trình con đó). Điều này cho phép các chương trình dùng tới những chương trình
con nhiều lần mà không cần phải lặp lại các khối mã giống nhau một khi đã
hoàn tất việc viết mã cho các chương trình con đó chỉ một lần.

Trong một số ngôn ngữ, người ta lại phân biệt thành 2 kiểu chương trình con:

120/134
1. Hàm (function) dùng để chỉ các chương trình con nào có giá trị trả về (trong
một kiểu dữ liệu nào đó) thông qua tên của hàm.
2. Thủ tục (subroutine) dùng để mô tả các chương trình con được thi hành và
không có giá trị trả về.

Tuy nhiên, trong nhiều ngôn ngữ khác như C chẳng hạn thì không có sự phân biệt này
và chỉ có một khái niệm hàm. Để mô tả các hàm không trả về giá trị (tương đương với
khái niệm thủ tục) thì người ta có thể gán cho kiểu dữ liệu của hàm đó là void.

Lưu ý: trong các ngôn ngữ hướng đối tượng, mỗi một đối tượng hay một thực thể
(instance), tùy theo quan điểm, có thể được xem là một chương trình con hay một biến
vì bản thân nội tại của thực thể đó có chứa các phương thức và cả các dữ liệu có thể trả
lời cho các lệnh gọi từ bên ngoài.

• Macro được hiểu là tên viết tắt của một tập các câu lệnh. Như vậy, trong những
chương trình có các khối câu lệnh giống nhau thì người ta có thể định nghĩa
một macro cho khối đại diện và có thể dùng tên của macro này trong lúc viết
mã thay vì phải viết cả khối câu lệnh mỗi lần khối này xuất hiện lặp lại. Một
cách trừu tượng, thì macro là sự thay thế một dạng thức văn bản xác định bằng
việc định nghĩa của một (hay một bộ) qui tắc. Trong quá trình dịch, các phần
mềm dịch sẽ tự động thay các macro này trở lại bằng các mã mà nó viết tắt cho,
rồi mới tiếp tục dịch. Như vậy, các mã này được điền trả lại trong thời gian
dịch. Một số ngôn ngữ có thể cho các macro được phép khai báo và sử dụng
tham số. Như vậy về vai trò macro giống hệt như các chương trình con.

Các điểm khác nhau quan trọng giữa một chương trình con và một macro bao gồm:

1. Mã của chương trình con vẫn được dịch và để riêng ra. Cho tới khi một chương
trình con được gọi ở thời điểm thi hành, thì các mã đã dịch sẵn của chương
trình con này mới được lắp vào dòng chạy của chương trình.Trong khi đó, sau
khi dịch, các macro sẽ không còn tồn tại. Trong chương trình đã được dịch, tại
các vị trí có tên của macro thì các tên này được thay thế bằng khối mã (đã dịch)
mà nó đại diện.
2. Cách viết mã dùng chương trình con sau khi dịch xong sẽ tạo thành các tập tin
ngắn hơn so với cách viết dùng macro.
3. Ngược lại khi máy tính tải lên thì một phần mềm có cách dùng macro ít tốn tính
toán của CPU hơn là phần mềm đó phát triển bằng phương pháp gọi các
chương trình con.

Ví dụ về một chương trình có sử dụng chương trình con

Ví dụ 2: Ta có chương trình chính (hàm main) dùng để nhập vào 2 số nguyên a,b và in
ra màn hình số lớn trong 2 số

121/134
#include <stdio.h>

#include <conio.h>

int max(int a, int b)

return (a>b) ? a:b;

int main()

int a, b, c;

printf("\n Nhap vao 3 so a, b,c ");

scanf("%d%d%d",&a,&b,&c);

printf("\n So lon la %d",max(a, max(b,c)));

getch();

return 0;

Phạm vi hoạt động của biến

Như đã biết chương trình là một tập hợp các hàm, các câu lệnh cũng như các khai báo.
Phạm vi tác dụng của một biến là nơi mà biến có tác dụng, tức hàm nào, câu lệnh nào
được phép sử dụng biến đó. Một biến xuất hiện trong chương trình có thể được sử dụng
bởi hàm này nhưng không được bởi hàm khác hoặc bởi cả hai, điều này phụ thuộc chặt
chẽ vào vị trí nơi biến được khai báo. Một nguyên tắc đầu tiên là biến sẽ có tác dụng
kể từ vị trí nó được khai báo cho đến hết khối lệnh chứa nó. Chi tiết cụ thể hơn sẽ được
trình bày trong chương 4 khi nói về hàm trong C++.

Cấu trúc một chương trình con

Cấu trúc của một hàm tự thiết kế:

122/134
<kiểu kết quả> Tên hàm ([<kiểu t số> <tham số>][,<kiểu t số><tham số>][…])

[Khai báo biến cục bộ và các câu lệnh thực hiện hàm]

[return [<Biểu thức>];]

Giải thích:

- Kiểu kết quả: là kiểu dữ liệu của kết quả trả về, có thể là: int, byte, char, float, void…
Một hàm có thể có hoặc không có kết quả trả về. Trong trường hợp hàm không có kết
quả trả về ta nên sử dụng kiểu kết quả là void.

Kiểu t số: là kiểu dữ liệu của tham số.

Tham số: là tham số truyền dữ liệu vào cho hàm, một hàm có thể có hoặc không có tham
số. Tham số này gọi là tham số hình thức, khi gọi hàm chúng ta phải truyền cho nó các
tham số thực tế. Nếu có nhiều tham số, mỗi tham số phân cách nhau dấu phẩy (,).

Bên trong thân hàm (phần giới hạn bởi cặp dấu {}) là các khai báo cùng các câu lệnh xử
lý. Các khai báo bên trong hàm được gọi là các khai báo cục bộ trong hàm và các khai
báo này chỉ tồn tại bên trong hàm mà thôi.

Khi định nghĩa hàm, ta thường sử dụng câu lệnh return để trả về kết quả thông qua tên
hàm.

Lệnh return dùng để thoát khỏi một hàm và có thể trả về một giá trị nào đó.

Cú pháp:

return ; /*không trả về giá trị*/

return <biểu thức>;/*Trả về giá trị của biểu thức*/

return (<biểu thức>); /*Trả về giá trị của biểu thức*/

Nếu hàm có kết quả trả về, ta bắt buộc phải sử dụng câu lệnh return để trả về kết quả
cho hàm.

Ví dụ 1: Viết hàm tìm số lớn giữa 2 số nguyên a và b

123/134
int max(int a, int b)

return (a>b) ? a:b;

Ví dụ 2: Viết hàm tìm ước chung lớn nhất giữa 2 số nguyên a, b. Cách tìm: đầu tiên ta
giả sử UCLN của hai số là số nhỏ nhất trong hai số đó. Nếu điều đó không đúng thì ta
giảm đi một đơn vị và cứ giảm như vậy cho tới khi nào tìm thấy UCLN

int ucln(int a, int b)

int u;

if (a<b)

u=a;

else

u=b;

while ((a%u !=0) || (b%u!=0))

u--;

return u;

Truyền tham số cho chương trình con

Mặc nhiên, việc truyền tham số cho hàm trong C là truyền theo giá trị; nghĩa là các giá
trị thực (tham số thực) không bị thay đổi giá trị khi truyền cho các tham số hình thức

Ví dụ 1: Giả sử ta muốn in ra nhiều dòng, mỗi dòng 50 ký tự nào đó. Để đơn giản ta viết
một hàm, nhiệm vụ của hàm này là in ra trên một dòng 50 ký tự nào đó. Hàm này có tên
là InKT.

#include <stdio.h>

124/134
#include <conio.h>

void InKT(char ch)

int i;

for(i=1;i<=50;i++) printf(“%c”,ch);

printf(“\n”);

int main()

char c = ‘A’;

InKT(‘*’); /* In ra 50 dau * */

InKT(‘+’);

InKT(c);

return 0;

Lưu ý:

Trong hàm InKT ở trên, biến ch gọi là tham số hình thức được truyền bằng giá trị (gọi là
tham trị của hàm). Các tham trị của hàm coi như là một biến cục bộ trong hàm và chúng
được sử dụng như là dữ liệu đầu vào của hàm.

Khi chương trình con được gọi để thi hành, tham trị được cấp ô nhớ và nhận giá trị là
bản sao giá trị của tham số thực. Do đó, mặc dù tham trị cũng là biến, nhưng việc thay
đổi giá trị của chúng không có ý nghĩa gì đối với bên ngoài hàm, không ảnh hưởng đến
chương trình chính, nghĩa là không làm ảnh hưởng đến tham số thực tương ứng.

Ví dụ 2: Ta xét chương trình sau đây:

#include <stdio.h>

125/134
#include <conio.h>

int hoanvi(int a, int b)

int t;

t=a;/*Đoạn này hoán vị giá trị của 2 biến a, b*/

a=b;

b=t;

printf("\Ben trong ham a=%d , b=%d",a,b);

return 0;

int main()

int a, b;

clrscr();

printf("\n Nhap vao 2 so nguyen a, b:");

scanf("%d%d",&a,&b);

printf("\n Truoc khi goi ham hoan vi a=%d ,b=%d",a,b);

hoanvi(a,b);

printf("\n Sau khi goi ham hoan vi a=%d ,b=%d",a,b);

getch();

return 0;

126/134
Kết quả thực hiện chương trình:

***SORRY, THIS MEDIA TYPE IS NOT SUPPORTED.***

Giải thích:

Nhập vào 2 số 6 và 5 (a=6, b=5)

Trước khi gọi hàm hoán vị thì a=6, b=5

Bên trong hàm hoán vị a=5, b=6

Khi ra khỏi hàm hoán vị thì a=6, b=5

* Lưu ý

Trong đoạn chương trình trên, nếu ta muốn sau khi kết thúc chương trình con giá trị của
a, b thay đổi thì ta phải đặt tham số hình thức là các con trỏ, còn tham số thực tế là địa
chỉ của các biến.

Lúc này mọi sự thay đổi trên vùng nhớ được quản lý bởi con trỏ là các tham số hình thức
của hàm thì sẽ ảnh hưởng đến vùng nhớ đang được quản lý bởi tham số thực tế tương
ứng (cần để ý rằng vùng nhớ này chính là các biến ta cần thay đổi giá trị).

Người ta thường áp dụng cách này đối với các dữ liệu đầu ra của hàm.

Ví dụ: Xét chương trình sau đây:

#include <stdio.h>

#include <conio.h>

long hoanvi(long *a, long *b)

/* Khai báo tham số hình thức *a, *b là các con trỏ kiểu long */

long t;

t=*a;/*gán nội dung của x cho t*/

*a=*b;/*Gán nội dung của b cho a*/

127/134
*b=t;/*Gán nội dung của t cho b*/

printf("\n Ben trong ham a=%ld , b=%ld",*a,*b);

/*In ra nội dung của a, b*/

return 0;

int main()

long a, b;

clrscr();

printf("\n Nhap vao 2 so nguyen a, b:");

scanf("%ld%ld",&a,&b);

printf("\n Truoc khi goi ham hoan vi a=%ld ,b=%ld",a,b);

hoanvi(&a,&b); /* Phải là địa chỉ của a và b */

printf("\n Sau khi goi ham hoan vi a=%ld ,b=%ld",a,b);

getch();

return 0;

Kết quả thực hiện chương trình:

***SORRY, THIS MEDIA TYPE IS NOT SUPPORTED.***

Giải thích:

- Nhập vào 2 số 5, 6 (a=5, b=6)

- Trước khi gọi hàm hoanvi thì a=5, b=6

128/134
- Trong hàm hoanvi (khi đã hoán vị) thì a=6, b=5

- Khi ra khỏi hàm hoán vị thì a=6, b=6

Lưu ý: Kiểu con trỏ và các phép toán trên biến kiểu con trỏ sẽ nói trong phần sau.

Nguyên tắc hoạt động của chương trình con

Trong chương trình, khi gặp một lời gọi hàm thì hàm bắt đầu thực hiện bằng cách
chuyển các lệnh thi hành đến hàm được gọi. Quá trình diễn ra như sau:

Nếu hàm có tham số, trước tiên các tham số sẽ được gán giá trị thực tương ứng.

Chương trình sẽ thực hiện tiếp các câu lệnh trong thân hàm bắt đầu từ lệnh đầu tiên đến
câu lệnh cuối cùng.

Khi gặp lệnh return hoặc dấu } cuối cùng trong thân hàm, chương trình sẽ thoát khỏi
hàm để trở về chương trình gọi nó và thực hiện tiếp tục những câu lệnh của chương trình
này.

Nguyên tắc sử dụng chương trình con

Một hàm khi định nghĩa thì chúng vẫn chưa được thực thi trừ khi ta có một lời gọi đến
hàm đó.

Cú pháp gọi hàm: <Tên hàm>([Danh sách các tham số])

Ví dụ: Viết chương trình cho phép tìm ước số chung lớn nhất của hai số tự nhiên.

#include<stdio.h>

unsigned int ucln(unsigned int a, unsigned int b)

unsigned int u;

if (a<b)

u=a;

else

u=b;

129/134
while ((a%u !=0) || (b%u!=0))

u--;

return u;

int main()

unsigned int a, b, UC;

printf(“Nhap a,b: ”);scanf(“%d%d”,&a,&b);

UC = ucln(a,b);

printf(“Uoc chung lon nhat la: ”, UC);

return 0;

Lưu ý: Việc gọi hàm là một phép toán, không phải là một phát biểu.

Bài thực hành về xây dựng chương trình con

Bài 1. Nêu tên các phương pháp tương ứng giữa tham số thực tế và tham số hình thức
khi thực hiện việc truyền tham số cho chương trình con.

Bài 2. Nêu tên các phương pháp truyền tham số cho chương trình con.

Bài 3. Cho biết sự khác nhau và giống nhau giữa các phương pháp truyền tham số .

Bài 4. Viết chương trình kiểm tra một ngày tháng năm (năm >1581) nhập vào từ bàn
phím hợp lệ hay không?

VD: 31/4/2000 là không hợp lệ. Ngày 30/4/1985 là hợp lệ.

130/134
Tham gia đóng góp
Tài liệu: Giáo trình nhập môn tin học
Biên tập bởi: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://voer.edu.vn/c/69de34bd
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Giới thiệu giáo trình


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/b82473fd
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Thông tin và xử lý thông tin, hệ thống tính toán và biểu diễn thông tin trong
máy tính
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/4c2a2d53
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Tổng quan về hệ thống máy tính


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/e78a0701
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Giải bài toán bằng máy tính


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/075bc1c1
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Thực hành, thảo luận và tổng quan về lập trình


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/7f573d88
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Thuật toán và chương trình


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên

131/134
URL: http://www.voer.edu.vn/m/c983dfa9
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Thảo luận về phát triển ứng dụng C/C++,Các thành phần của một chương
trình
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/e9ae2419
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Một số hàm chức năng thường dùng trong chương trình
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/d8fd4b16
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Bài thực hành về các thành phần cơ bản và nhập/xuất trong C/C++
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/440b459d
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Cấu trúc rẽ nhánh


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/6aa2ed62
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Bài thực hành về cấu trúc rẽ nhánh


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/b424b990
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Cấu trúc lặp while, do .. while - Cấu trúc lặp for
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/02c5d9b7
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Thảo luận về các cấu trúc điểu khiển - Bài thực hành về cấu trúc lặp
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/31a713c2

132/134
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Các kiểu dữ liệu trong C/C++


Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/e605e744
Giấy phép: http://creativecommons.org/licenses/by/3.0/

Module: Chương trình con - thực hành về xây dựng chương trình con
Các tác giả: Khoa CNTT ĐHSP KT Hưng Yên
URL: http://www.voer.edu.vn/m/beea5a4a
Giấy phép: http://creativecommons.org/licenses/by/3.0/

133/134
Chương trình Thư viện Học liệu Mở Việt Nam

Chương trình Thư viện Học liệu Mở Việt Nam (Vietnam Open Educational Resources
– VOER) được hỗ trợ bởi Quỹ Việt Nam. Mục tiêu của chương trình là xây dựng kho
Tài nguyên giáo dục Mở miễn phí của người Việt và cho người Việt, có nội dung phong
phú. Các nội dung đểu tuân thủ Giấy phép Creative Commons Attribution (CC-by) 4.0
do đó các nội dung đều có thể được sử dụng, tái sử dụng và truy nhập miễn phí trước
hết trong trong môi trường giảng dạy, học tập và nghiên cứu sau đó cho toàn xã hội.

Với sự hỗ trợ của Quỹ Việt Nam, Thư viện Học liệu Mở Việt Nam (VOER) đã trở thành
một cổng thông tin chính cho các sinh viên và giảng viên trong và ngoài Việt Nam. Mỗi
ngày có hàng chục nghìn lượt truy cập VOER (www.voer.edu.vn) để nghiên cứu, học
tập và tải tài liệu giảng dạy về. Với hàng chục nghìn module kiến thức từ hàng nghìn
tác giả khác nhau đóng góp, Thư Viện Học liệu Mở Việt Nam là một kho tàng tài liệu
khổng lồ, nội dung phong phú phục vụ cho tất cả các nhu cầu học tập, nghiên cứu của
độc giả.

Nguồn tài liệu mở phong phú có trên VOER có được là do sự chia sẻ tự nguyện của các
tác giả trong và ngoài nước. Quá trình chia sẻ tài liệu trên VOER trở lên dễ dàng như
đếm 1, 2, 3 nhờ vào sức mạnh của nền tảng Hanoi Spring.

Hanoi Spring là một nền tảng công nghệ tiên tiến được thiết kế cho phép công chúng dễ
dàng chia sẻ tài liệu giảng dạy, học tập cũng như chủ động phát triển chương trình giảng
dạy dựa trên khái niệm về học liệu mở (OCW) và tài nguyên giáo dục mở (OER) . Khái
niệm chia sẻ tri thức có tính cách mạng đã được khởi xướng và phát triển tiên phong
bởi Đại học MIT và Đại học Rice Hoa Kỳ trong vòng một thập kỷ qua. Kể từ đó, phong
trào Tài nguyên Giáo dục Mở đã phát triển nhanh chóng, được UNESCO hỗ trợ và được
chấp nhận như một chương trình chính thức ở nhiều nước trên thế giới.

134/134

You might also like