You are on page 1of 100

PGS.

TS Phạm Văn Ất – chủ biên


Nguyễn Hiếu Cường – Nguyễn ðức Dư – Hoàng Văn Thông

GIÁO TRÌNH

TIN HỌC ðẠI CƯƠNG

TRƯỜNG ðẠI HỌC GIAO THÔNG VẬN TẢI


HÀ NỘI - 2008

1
Giáo trình Tin học ðại cương

MỤC LỤC
LỜI NÓI ðẦU....................................................................................................................... 3
PHẦN 1 ................................................................................................................................. 4
ðẠI CƯƠNG VỀ TIN HỌC .................................................................................................. 4
CHƯƠNG 1 – NHỮNG KHÁI NIỆM CƠ BẢN VỀ TIN HỌC.......................................... 5
1.1 ðối tượng nghiên cứu của Tin học............................................................................ 5
1.2 Thông tin và xử lý thông tin ..................................................................................... 5
1.3 Hệ ñếm và biểu diễn thông tin trong máy tính........................................................... 6
1.4 Nguyên lý của hệ xử lý thông tin tự ñộng ................................................................. 8
1.5 Cấu trúc máy tính ................................................................................................... 10
1.6 Một số ứng dụng của Tin học ................................................................................. 12
CHƯƠNG 2 – HỆ ðIỀU HÀNH...................................................................................... 14
2.1 Hệ ñiều hành MS-DOS........................................................................................... 14
2.2 Hệ ñiều hành Windows........................................................................................... 16
CHƯƠNG 3 – THUẬT TOÁN ........................................................................................ 21
3.1 Khái niệm............................................................................................................... 21
3.2 Một số phương pháp biểu diễn thuật toán ............................................................... 21
3.3 Các cấu trúc cơ bản của thuật toán.......................................................................... 23
3.4 Một số thuật toán giải một số bài toán ñơn giản ...................................................... 27
PHẦN 2 ............................................................................................................................... 32
NGÔN NGỮ LẬP TRÌNH C ............................................................................................... 32
CHƯƠNG 1 - MỘT SỐ KHÁI NIỆM MỞ ðẦU ............................................................. 34
1.1 Tập ký tự ................................................................................................................ 34
1.2 Từ khóa .................................................................................................................. 34
1.3 Tên......................................................................................................................... 35
1.4 Một số khái niệm.................................................................................................... 35
1.5 Một số chương trình ñơn giản................................................................................. 38
1.6 Một số quy tắc cần nhớ khi viết chương trình ......................................................... 39
1.7 Cách thực hiện các chương trình trên máy tính ...................................................... 40
BÀI TẬP CHƯƠNG 1 ................................................................................................. 41
CHƯƠNG 2 - CÁC KIỂU DỮ LIỆU ............................................................................... 42
2.1 Các kiểu dữ liệu cơ bản .......................................................................................... 42
2.2 Hằng ...................................................................................................................... 43
2.3 Biến........................................................................................................................ 45
2.4 Mảng...................................................................................................................... 46
2.5 Các phép toán trên các kiểu .................................................................................... 48
2.6 Nhập xuất dữ liệu ................................................................................................... 52
2.7 Một số hàm thường dùng........................................................................................ 56
BÀI TẬP CHƯƠNG 2 ................................................................................................. 57
CHƯƠNG 3 - CÁC LỆNH ðIỀU KHIỂN ....................................................................... 58
3.1 Nhắc lại khái niệm về câu lệnh và khối lệnh ........................................................... 58
3.2. Lệnh if................................................................................................................... 58
3.3 Lệnh for ................................................................................................................. 61
3.4 Lệnh while ............................................................................................................. 63
3.5 Lệnh do - while ...................................................................................................... 65
3.6 Lệnh break ............................................................................................................. 66
3.7 Lệnh continue......................................................................................................... 66
BÀI TẬP CHƯƠNG 3 ................................................................................................. 68
CHƯƠNG 4 - HÀM VÀ TỔ CHỨC CHƯƠNG TRÌNH .................................................. 70
4.1 Tổ chức chương trình thành các hàm ...................................................................... 70
4.2 Tham số kiểu con trỏ .............................................................................................. 73

2
Giáo trình Tin học ðại cương

4.3 ðệ quy.................................................................................................................... 79
BÀI TẬP CHƯƠNG 4 ................................................................................................. 83
CHƯƠNG 5 - CẤU TRÚC .............................................................................................. 84
5.1 ðịnh nghĩa cấu trúc và khai báo biến cấu trúc......................................................... 84
5.2 Kết hợp ñịnh nghĩa cấu trúc và khai báo biến cấu trúc ............................................ 84
5.3 Sử dụng typedef ñể ñịnh nghĩa kiểu dữ liệu cấu trúc ............................................... 85
5.4 Truy cập các thành phần của cấu trúc ..................................................................... 86
5.5 Ví dụ minh hoạ....................................................................................................... 86
BÀI TẬP CHƯƠNG 5 ................................................................................................. 89
PHỤ LỤC 1 - BẢNG MÃ ASCII ..................................................................................... 91
PHỤ LỤC 2 ..................................................................................................................... 93
DANH SÁCH CÁC HÀM CỦA TURBO C THEO THỨ TỰ ABC .............................. 93

3
Giáo trình Tin học ðại cương

LỜI NÓI ðẦU


Tin học ñại cương là một môn học quan trọng trong chương trình giáo dục ñại
cương ở bậc ñại học. Tại hầu hết các trường ñại học và cao ñẳng nước ta hiện nay,
môn học này là bắt buộc ñối với mọi sinh viên. Về mặt nội dung, tuy mức ñộ ở các
trường có thể khác nhau, song yêu cầu thì ngày càng nâng cao cả về lý thuyết lẫn thực
hành.
Cuốn Giáo trình Tin học ñại cương này ñược biên soạn theo khung chương
trình của Bộ Giáo dục và ðào tạo dành cho sinh viên ngành kỹ thuật. Cấu trúc của
giáo trình gồm 2 phần: phần 1 gồm 3 chương trình bày những kiến thức tổng quan về
Tin học, phần 2 trình bày kỹ thuật lập trình căn bản bằng ngôn ngữ C, phần này có
nhiều ví dụ mẫu và bài tập ñể sinh viên rèn luyện kỹ năng lập trình trên máy.
Khi biên soạn, chúng tôi ñã tham khảo các giáo trình và tài liệu giảng dạy môn
học này của một số trường ñại học ñể cuốn sách vừa ñạt yêu cầu cao về nội dung vừa
thích hợp với ñông ñảo sinh viên các ngành kỹ thuật. Chúng tôi cũng thừa hưởng ñược
những kinh nghiệm quý có ñược trong quá trình giảng dạy môn học này của các ñồng
nghiệp tại Trường ðại học Giao thông vận tải.
Rất mong nhận ñược các ý kiến ñóng góp của các ñộc giả ñể chất lượng giáo
trình này ngày càng tốt hơn.
Mọi ý kiến ñóng góp xin gửi về: Bộ môn Công nghệ phần mềm, Khoa Công
nghệ thông tin, Trường ðại học Giao thông vận tải, Láng Thượng, ðống ða, Hà Nội.
CÁC TÁC GIẢ

3
Giáo trình Tin học ðại cương

PHẦN 1
ðẠI CƯƠNG VỀ TIN HỌC

4
Giáo trình Tin học ðại cương

CHƯƠNG 1 – NHỮNG KHÁI NIỆM CƠ BẢN VỀ TIN HỌC

1.1 ðối tượng nghiên cứu của Tin học


Tin học là ngành khoa học nghiên cứu về cấu trúc, tính chất và các quá trình xử lý thông
tin một cách tự ñộng dựa trên các phương tiện kỹ thuật. Tin học là một ngành khoa học trẻ,
mới hình thành và phát triển trong mấy thập kỷ qua. ðặc biệt từ ñầu những năm 80 của thế kỷ
trước, cùng với sự phát triển của máy vi tính, mạng máy tính và gần ñây là mạng Internet, tin
học ñã phát triển rất mạnh và trở nên không thể thiếu trong hầu như mọi lĩnh vực của ñời sống
xã hội.
Tin học ñược sinh ra trên miền giáp danh của nhiều lĩnh vực khoa học. Hai ngành khoa
học trực tiếp làm nền móng cho tin học là toán học và vật lý. ðặc trưng quan trọng của tin học
là sự truyền và xử lý thông tin một cách tự ñộng. Việc xử lý thông tin trước ñây chưa ñặt ra
vấn ñề tự ñộng hóa và con người luôn gắn liền với mọi thao tác trong quá trình xử lý thông
tin. ðể ñạt ñược phương thức tự ñộng hóa phải có các phương tiện kỹ thuật, mà quan trọng
nhất là máy tính ñiện tử (MTðT). Phương tiện kỹ thuật vừa là công cụ vừa là ñối tượng
nghiên cứu của tin học.
Ngay từ khi ra ñời, tin học ñã phát triển theo hai bộ phận hợp thành chủ yếu là: bảo ñảm
toán học, thuật toán, chương trình (gọi là phần mềm) và các thiết bị tính toán, lưu trữ, truyền
dẫn thông tin (gọi là phần cứng). Trong bản thân cả phần mềm và phần cứng lại có các lĩnh
vực nghiên cứu chuyên sâu hơn về lý thuyết và ứng dụng. Mặc dù rất khó phân ñịnh chính
xác các lĩnh vực nghiên cứu, ứng dụng của tin học, nhưng khi nói ñến tin học, người ta
thường ñề cập ñến:
- Kỹ thuật chế tạo máy tính
- Mạng máy tính
- Kỹ thuật lập trình
- ðảm bảo toán học cho máy tính và các hệ thống tính toán
- Thuật toán và ñộ phức tạp của thuật toán
- Cơ sở dữ liệu
- Trí tuệ nhân tạo
- ...

1.2 Thông tin và xử lý thông tin


Thông tin theo nghĩa thông thường của ñời sống hàng ngày ñược hiểu như là sự thông
báo, cắt nghĩa, ... Thông tin tồn tại dưới nhiều dạng và ñược lưu trữ nhờ vật mang tin như tờ
báo, quyển sách, băng ghi âm, ñĩa từ, ...
Thông tin về một ñối tượng là các dữ kiện về ñối tượng ñó. Thông tin có khả năng làm
thay ñổi sự hiểu biết của con người, là nguồn gốc của nhận thức. Trước thời ñiểm nhận thông
tin, có một cái gì ñó ta chưa biết, chưa xác ñịnh (bất ñịnh). Chẳng hạn ta biết sinh viên A học
ở ðH Giao thông vận tải nhưng không biết ở khoa nào, lớp nào thì việc tìm ñến sinh viên A
có một ñộ bất ñịnh nào ñó. Bây giờ, giả sử biết thêm sinh viên A học ở khoa Công nghệ thông
tin của trường, thì ñiều này ñã làm giảm ñộ bất ñịnh ở trên. Như vậy tính bất ñịnh ñã thay ñổi
khi nhận thêm thông tin.
Ta xét một ví dụ khác: Nếu biết A ñã thi ñạt kỳ thi học kỳ môn Tin học ñại cương, nhưng
chưa biết ñược bao nhiêu ñiểm thì việc xác ñịnh ñiểm của A có một ñộ bất ñịnh nào ñó. Nếu
5
Giáo trình Tin học ðại cương

biết thêm A ñạt ñiểm 7 hoặc 8 thì lượng thông tin bổ sung này sẽ làm giảm ñộ bất ñịnh trên.
Tính bất ñịnh của sự kiện lúc ñầu thể hiện ở 1 trong 6 (ñiểm có thể là 5, 6, 7, 8, 9, 10) và lúc
sau là 1 trong 2 (ñiểm có thể là 7 hoặc 8). Tính bất ñịnh gắn liền với khái niệm xác suất. Xác
suất càng nhỏ thì ñộ bất ñịnh càng lớn, hay nói cách khác, lượng thông tin tỷ lệ nghịch với xác
suất của sự kiện.
Thông tin thường ñược biểu diễn qua các bộ ký hiệu. Ví dụ, ta có tập ñối tượng X cần
biểu diễn (tập các thí sinh chẳng hạn). Chọn một tập hữu hạn Y các chữ và số làm bảng chữ
cái, ta gọi một dãy hữu hạn các chữ cái ñó là một từ trên Y (ở ñây là số báo danh). Với mỗi
phần tử x ∈ X ta gán một từ y ∈Y và gọi là mã của x (Y gọi là bảng mã). Phép tạo mã tương
ứng này cần ñảm bảo tính chất với x1≠x2 (x1 , x2 ∈X) sẽ có y1≠y2 (y1 , y2 ∈ Y) là mã tương
ứng của chúng. Khi biết mã số (số báo danh), bằng phép giải mã ta sẽ tìm ñược ñối tượng
tương ứng (thí sinh).
Thông tin ñưa vào MTðT (ñể lưu trữ, tính toán, ...) thực chất là dãy các tín hiệu nhị phân
hay còn gọi là các bit (binary digit), nó tương ứng với các trạng thái của các mạch ñiện tử bên
trong máy tính. Vì vậy, trong xử lý thông tin tự ñộng, dạng mã quan trọng ñược dùng là mã
nhị phân. Thông tin ñược mã hóa trên bảng chữ cái gồm 2 ký hiệu là chữ số 0 và chữ số 1.
Ví dụ, với bảng mã ASCII, là bộ mã tiêu chuẩn của Mỹ, mỗi ký tự (chữ cái, chữ số, ký tự
ñặc biệt) tương ứng với một mã 7 bit. Như vậy bảng mã với mỗi bit có 2 trạng thái cho phép
mã hóa 27=128 ký tự. Với bảng mã ANSI, hay còn gọi là ASCII mở rộng, mỗi ký tự ñược mã
hóa bằng 8 bit, và như vậy lượng ký tự có thể mã hóa ñược là 28=256 ký tự. Cuối những năm
80 của thế kỷ trước, bảng mã UNICODE ñược giới thiệu. Bảng mã này có thể sử dụng 16 bit
ñể mã hóa một ký tự, nên lượng ký tự có thể mã hóa ñược là 216=65536 ký tự. Hiện nay
UNICODE ñã trở thành một tiêu chuẩn ñược chấp nhận rộng rãi vì nó có thể mã hóa ñược các
ký tự của tất cả các ngôn ngữ trên thế giới.

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


Hệ ñếm ñược hiểu như tập các ký hiệu và tập các qui tắc xác ñịnh dùng ñể biểu diễn và
tính giá trị các số. Trước hết hãy xét những hệ ñếm quen thuộc, ñại diện cho hai cách ñếm là:
hệ ñếm La Mã (ñếm không theo vị trí) và hệ ñếm thập phân (ñếm theo vị trí).
Hệ ñếm La Mã: Mỗi ký hiệu biểu thị một giá trị (I=1, V=5, X=10, D=500, M=1000). Nó
có các qui tắc, chẳng hạn: n ký hiệu ñứng cạnh nhau cho biết ký hiệu ñó ñược lặp lại n lần, ví
dụ: II=2, III=3, XXX=30; hai ký hiệu trong ñó ký hiệu lớn ñứng trước biểu thị tổng của hai ký
hiệu ñó, ví dụ: VI=6, XI=11, ... Như vậy trong hệ ñếm La Mã, mỗi ký hiệu chỉ ñại diện cho
một giá trị, không phụ thuộc vào vị trí của nó trong biểu diễn.
Hệ ñếm thập phân: Sử dụng 10 ký hiệu (là các chữ số: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Qui tắc
tính giá trị: giá trị của mỗi ký hiệu phụ thuộc vào bản thân ký hiệu ñó và vị trí của nó trong
biểu diễn. Ví dụ: trong số 555, chữ số 5 hàng ñơn vị chỉ 5 ñơn vị, chữ số 5 hàng chục chỉ 50
ñơn vị (5*101), chữ số 5 hàng trăm chỉ 500 ñơn vị (5*102). Số lượng các chữ số dùng trong hệ
thập phân (10 chữ số) gọi là cơ số của hệ ñếm. Số mũ của cơ số 10 xác ñịnh giá trị ñịnh lượng
của mỗi ñơn vị.
Hệ ñếm thập phân chỉ là một trường hợp riêng khi chọn cơ số là 10. Tổng quát, bất kỳ
một số nguyên b > 1 nào cũng ñều có thể chọn làm cơ số. Lúc ñó các ký hiệu của hệ ñếm là 0,
1, 2, ..., b-1.
Trong tin học, các hệ ñếm thường ñược sử dụng là: hệ cơ số 2 (hệ nhị phân) chỉ dùng 2
ký hiệu {0, 1} hệ cơ số 8 dùng các ký hiệu {0, 1, 2, 3, 4, 5, 6, 7} hệ cơ số 16 dùng các ký hiệu
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F}. Khi cần phân biệt số ở hệ ñếm nào, ta có thể sử
dụng cơ số làm chỉ số, ví dụ: 1012 , 58 , 516 .

6
Giáo trình Tin học ðại cương

MTðT chỉ có thể tác ñộng trực tiếp với các số nhị phân, trong khi ñó con người lại
thường làm việc trên hệ thập phân. Vì thế cần phải có thuật toán ñể chuyển ñổi số từ hệ ñếm
này sang hệ ñếm khác. ðể chuyển ñổi số từ hệ ñếm cơ số b1 sang hệ ñếm cơ số b2 , người ta
thường dùng hệ thập phân làm trung gian: chuyển số từ hệ ñếm cơ số b1 sang hệ thập phân,
sau ñó chuyển tiếp số từ hệ thập phân sang hệ ñếm cơ số b2.

1.3.1 Biến ñổi số ở hệ ñếm bất kỳ sang hệ thập phân:


Cho số N= (dn-1dn-2...d1d0d-1d-2...d-m) ở hệ ñếm cơ số b. ðể tìm biểu diễn của N trong hệ
thập phân, ta tiến hành theo các bước:
- Viết N dưới dạng ña thức:
N = dn-1 bn-1 + dn-2 bn-2 + ... + d1 b1 + d0 b0 + d-1 b-1 + d-2 b-2 + ... + d-mb-m
- Sử dụng phép toán của hệ thập phân ñể tính giá trị ña thức.
Ví dụ:
1110,12 = 1.23 + 1.22 + 1.21 + 0.20 + 1.2-1 = 14,5
D3F,416 = D.162 + 3.161 + F.160 + 4.16-1
= 13.162 + 3.161 + 15.160 + 4.16-1= 3391,25

1.3.2 Biến ñổi số ở hệ thập phân sang hệ ñếm cơ số bất kỳ:


Trước hết cần tách phần nguyên và phần thập phân (nếu có), rồi tiến hành biến ñổi chúng
riêng biệt sang hệ ñếm cơ số b. Sau ñó bằng cách ghép nối các kết quả ta thu ñược giá trị cần
tìm.
ðể biến ñổi phần nguyên N, ta chia nguyên nó cho b ñược thương số là N1 và số dư d1.
Sau ñó lại lấy N1 chia nguyên cho b, ñược thương số là N2 vào số dư là d2, ... Lặp lại quá trình
ñó ñến khi thương số Nk=0, ta sẽ có kết quả cần tìm là (dk ... d2d1).
Ví dụ: 5210 = ?2 . Ta thực hiện theo thuật toán như sau:
Phép chia nguyên Thương số Số dư
52 : 2 26 0
26 : 2 13 0
13 : 2 6 1
6:2 3 0
3:2 1 1
1:2 0 1
Như vậy 5210 = 1101002
Ví dụ: 5850610 = ?16 . Ta thực hiện theo thuật toán như sau:
Phép chia nguyên Thương số Số dư
58506 : 16 3656 10
3656 : 16 228 8
228 : 16 14 4
14 : 16 0 14
Như vậy 5850610 = E48A16
ðể biến ñổi phần thập phân 0,M ta nhân nó với b, ñược phần nguyên của kết quả là d1,
phần thập phân còn lại sau khi lấy kết quả trừ ñi d1 là 0,M1. Sau ñó lấy 0,M1 nhân với b, ñược
phần nguyên của kết quả là d2, phần thập phân còn lại sau khi lấy kết quả trừ ñi d2 là 0,M2, ...

7
Giáo trình Tin học ðại cương

Tiếp tục lặp lại quá trình này, nó có kết thúc hoặc lặp vô hạn, khi ñó tùy theo yêu cầu mà
quyết ñịnh dừng khi nào. Ta sẽ có kết quả cần tìm là (0,d1d2d3 ...)
Ví dụ: 0,687510 = ?2
Phép nhân Kết quả Phần nguyên
0,6875 * 2 1,375 1
0,375 * 2 0,75 0
0,75 * 2 1,5 1
0,5 * 2 1,0 1
Như vậy: 0,687510 = 0,10112
Từ ñây suy ra: 52,687510 = 110100,010112

Ví dụ: 0,843510 = ?16


Phép nhân Kết quả Phần nguyên
0,8435 * 16 13,496 13
0,496 * 16 7,936 7
0,936 * 16 14,976 14
0,976 * 16 15,616 15
... ... ...
Như vậy: 0,843510 = 0,D7EF...16
Từ ñây suy ra: 58506,843510 = E48A,D7EF...16

1.3.3 Biểu diễn thông tin trong máy tính:


MTðT xử lý cả dữ liệu số và phi số, nhưng cả hai loại dữ liệu này khi ñưa vào máy ñều
là dãy các tín hiệu nhị phân, thường ñược thể hiện bằng các chữ số 0, 1 (gọi là các bit). Theo
nghĩa ñó MTðT xử lý dữ liệu bằng số, và bit là ñơn vị thông tin. Số ñược biểu diễn dưới dạng
nhị phân chính là một dãy các bit liên tiếp. Các số, các ký hiệu, các lệnh máy ñược biểu diễn
trong máy tính thông qua các dãy nhị phân với ñộ dài xác ñịnh, gọi là từ máy. ðộ dài từ máy
là ñặc trưng của từng họ máy. Các ñộ dài từ máy thông dụng là 8, 16, 32, ... bit. ðộ dài từ máy
là xác ñịnh, do vậy dải số có thể biểu diễn ñược bên trong máy tính là hữu hạn.

1.4 Nguyên lý của hệ xử lý thông tin tự ñộng


1.4.1 Nguyên lý làm việc của máy tính
Von Neumann là người ñề xuất ra nguyên lý làm việc của máy tính số, và nguyên lý này
vẫn ñược dùng làm cơ sở cho hầu hết các MTðT hiện nay. Theo ñó thì MTðT làm việc theo
chương trình có trong bộ nhớ của nó. ðể ñảm bảo nguyên tắc này, MTðT cần phải gồm ñủ 5
thành phần cơ bản: bộ nhớ ñể ghi thông tin, bộ số học logic ñể thực hiện các tính toán, bộ ñiều
khiển, các thiết bị nhập và thiết bị xuất dữ liệu.
Máy tính phải thi hành ñược các lệnh của người dùng ñưa vào. Một chương trình thực
chất là một chuỗi các lệnh, nhằm thực hiện những công việc nào ñó. Một tập hợp các qui ước
ñể viết nên các dòng lệnh ñưa vào máy, cho máy nhận diện và thi hành gọi là ngôn ngữ. Ngôn
ngữ ñược thực hiện trực tiếp dựa trên qui ước của các mạch ñiện tử trong máy gọi là ngôn ngữ
máy. Mỗi loại máy có một ngôn ngữ riêng. Ngôn ngữ máy có ưu ñiểm là máy hiểu ñược
ngay, nhưng nó quá khác biệt so với ngôn ngữ của con người, nên việc xây dựng, kiểm thử
chương trình rất khó khăn.

8
Giáo trình Tin học ðại cương

Từ ñầu những năm 60 của thế kỷ trước ñã bắt ñầu xuất hiện những ngôn ngữ lập trình
(NNLT) bậc cao. Gọi là ngôn ngữ bậc cao vì các ngôn ngữ này thường sử dụng những từ
khóa dựa trên tiếng Anh, có cấu trúc gần gũi hơn với ngôn ngữ của con người. Các NNLT
luôn không ngừng phát triển, các NNLT mới luôn xuất hiện, ngày càng hoàn thiện hơn ñể ñáp
ứng những nhu cầu ngày một cao về qui mô, chất lượng, ñộ tin cậy, ... của phần mềm. Trên
thực tế, sự phát triển của các ngôn ngữ lập trình gắn liền với sự phát triển của công nghệ phần
mềm và của tin học. Một chương trình viết bằng một NNLT nào ñó gọi là chương trình
nguồn. Chúng ta cần phải có một chương trình dịch cho NNLT ñó ñể dịch các chương trình
nguồn bằng NNLT này ra ngôn ngữ máy, khi ñó MTðT mới có thể hiểu và thực hiện.
ðể tự ñộng hóa một số công việc của người vận hành máy, cũng như quản lý, khai thác
các thiết bị phần cứng hiệu quả hơn, từ những năm 1960 người ta ñã xây dựng các hệ ñiều
hành cho máy tính. Ngày nay nói ñến một hệ thống máy tính, ta phải hiểu ñó là thiết bị phần
cứng và hệ ñiều hành cài ñặt trên nó. Các hệ ñiều hành ngày càng phát triển ñể ñáp ứng nhu
cầu không có giới hạn của người dùng và sự thay ñổi, tiến bộ liên tục của phần cứng. Một số
hệ ñiều hành tiêu biểu hiện nay là: MS-DOS, Windows, Linux, ...

1.4.2 Lịch sử phát triển của máy tính


Lịch sử kỹ thuật tính toán ñã có từ lâu ñời. Công cụ tính toán của con người bắt ñầu từ
những thứ rất thô sơ như ngón tay, hòn sỏi, rồi ñến bàn tính gảy, máy tính cơ, máy tính cơ
ñiện. ðến năm 1946, việc chế tạo thành công máy tính ENIAC tại Mỹ ñược coi như mốc ñánh
dấu sự ra ñời của MTðT ñầu tiên trên thế giới. Từ khi có MTðT, kỹ thuật tính toán ñã chuyển
sang một giai ñoạn mới.
Năm Sự kiện
Trước CN Bàn tính gảy ở Trung Quốc
1642 Máy tính cơ, làm ñược phép cộng (Blaise Pascal)
1670 Máy tính cơ, làm ñược cộng,trừ,nhân,chia,căn bậc 2 (Leibnitz)
1842 Máy tính có thể lập trình ñể tính tự ñộng (Charles Babbage)
1890 Herman Hollerith thiết kế hệ thống có thể lưu thông tin trên bìa ñục
lỗ, ñọc ra bằng tế bào quang ñiện, thành lập công ty IBM
1946 Máy ENIAC (Eckert, Mauchly), gồm 18000 bóng chân không, giá
500000$
1958 Máy tính ñầu tiên dùng bóng bán dẫn transitor (IBM 7090)
1964 Máy tính ñầu tiên dùng mạch tích hợp IC (IBM 360)
1976 Hãng DEC giới thiệu máy vi tính VAX 11/780
1981 Hãng IBM ñưa ra máy vi tính IBM PC
Bảng 1.1: Một số mốc trong lịch sử phát triển máy tính

Hình 1.1: Máy tính ñiện tử ENIAC


9
Giáo trình Tin học ðại cương

Sự phát triển của MTðT từ năm 1946 ñến nay ñã trải qua nhiều thế hệ. Mỗi thế hệ là một
bước phát triển lớn và ñược xác ñịnh căn cứ vào tiêu chuẩn kỹ thuật và mức ñộ phong phú của
phần mềm.
Thế hệ thứ nhất (khoảng 1946-1955): Dùng bóng ñèn ñiện tử, ñộ tin cậy thấp, tiêu hao
nhiều năng lượng, tốc ñộ tính toán chỉ từ vài nghìn ñến vài chục nghìn phép tính một giây.
Phần mềm chưa phát triển, chủ yếu dùng ngôn ngữ máy ñể lập trình. Thế hệ MTðT này
thường chỉ dùng trong mục ñích nghiên cứu khoa học.
Thế hệ thứ hai (khoảng 1955-1965): Dùng bóng bán dẫn thay ñèn ñiện tử, tiêu thụ năng
lượng ít hơn, bộ nhớ có dung lượng lớn hơn, tốc ñộ khoảng vài chục nghìn phép tính một
giây. ðã bắt ñầu xuất hiện một số NNLT bậc cao như FORTRAN, COBOL, ... Về ứng dụng,
ñã bắt ñầu dùng vào các mục ñích tính toán trong quản lý kinh tế, thống kê, ...
Thế hệ thứ ba (khoảng 1965-1980): Dùng mạch tích hợp thay cho bóng bán dẫn, tốc ñộ
tính toán lên ñến hàng triệu phép tính một giây. Các tiến bộ khác phải kể ñến: xuất hiện nhiều
hệ ñiều hành tốt hơn, có khả năng sử dụng bộ nhớ ảo, ña chương trình, các thiết bị ngoại vi
phát triển rất mạnh mẽ. Phần mềm phát triển ña dạng, ứng dụng trong nhiều lĩnh vực.
Thế hệ thứ tư (khoảng từ sau 1980): Dùng mạch tích hợp cỡ lớn VLSI, sự phát triển của
mạng máy tính, các kiến trúc song song, tốc ñộ tính toán lên ñến nhiều triệu, thậm chí hàng tỷ
phép tính một giây. Về ứng dụng, ñã ñược sử dụng trong tất cả mọi lĩnh vực.
Dựa trên kích thước, kiến trúc vật lý, tính năng, tốc ñộ và quy mô xử lý, người ta phân
chia MTðT thành các loại: Máy tính lớn (mainfraim), máy tính mini (mini computer) và máy
vi tính (micro computer). Các máy tính lớn có giá thành rất ñắt, thường ñược sử dụng vào các
lĩnh vực quan trọng, ñòi hỏi nhiều tính toán phức tạp. Thuộc loại này có thể kể ñến các máy
Cray, IBM 3090/300, Gen/Blue, ... Các máy tính mini có giá thành vừa phải, thích hợp cho
các mục ñích chuyên dùng. Một số máy loại này là PDP, HP-300, IBM 360, Sun 4, ... Các
máy vi tính xuất hiện từ cuối những năm 70 của thế kỷ 20. Các máy vi tính có kích thước nhỏ,
giá thành rẻ hơn các loại máy trên, nên ñã dần ñược sử dụng rộng rãi, kể cả trong những công
ty nhỏ, trường học, hộ gia ñình hay chỉ cho cá nhân. Chính vì thế phiên bản máy vi tính ñầu
tiên của hãng IBM ñược gọi là máy tính cá nhân (Personal Computer, viết tắt là PC). Máy vi
tính của IBM chiếm thị phần lớn nhất vào ñầu những năm 1980, nên dần dần người ta gần
như ñồng nghĩa từ PC với từ máy vi tính.
Cần lưu ý rằng cách phân loại trên chỉ là tương ñối, cần quan tâm ñến cả yếu tố thời gian.
Nhiều máy vi tính ngày nay có tính năng sử dụng vượt xa các máy tính lớn vào những năm
1970.

1.5 Cấu trúc máy tính


Về cấu trúc logic, một MTðT gồm các bộ phận chính là: bộ nhớ, bộ số học-logic, bộ ñiều
khiển, các thiết bị nhập/xuất dữ liệu và các ñường truyền dẫn. Về tổ chức vật lý, các bộ phận
này ñóng gói thành các thiết bị sau:
- Bo mạch chủ (Mainboard hoặc Motherboard)
- Bộ xử lý trung tâm (Center Processing Unit, viết tắt là CPU)
- Bộ nhớ: gồm bộ nhớ trong (ROM, RAM) và bộ nhớ ngoài hay còn gọi là các thiết
bị lưu trữ (ñĩa từ, ñĩa CD, ...)
- ðường truyền (Bus) và các cổng giao tiếp
- Bộ nguồn
- Các thiết bị ngoại vi: gồm các thiết bị nhập dữ liệu (bàn phím, chuột, ...), các thiết
bị xuất dữ liệu (màn hình, máy in, máy vẽ, ...), ...
10
Giáo trình Tin học ðại cương

Hình 1.2 Máy vi tính Hình 1.3: Máy tính xách tay (laptop)
Thùng máy (case):
Hầu hết các thiết bị của MTðT kể ở trên ñều ñược ñặt bên trong thùng máy, trừ một số
thiết bị ngoại vi. Về hình thức, thường có 2 kiểu thùng máy: ñặt ñứng và ñặt nằm ngang. Chú
ý rằng nhiều người quen gọi cả thùng máy là CPU, gọi như vậy là sai vì CPU chỉ là bộ xử lý
trung tâm gắn trên bo mạch chủ, ñặt bên trong thùng máy.
Bo mạch chủ:
Là thành phần rất quan trọng trong MTðT, kết nối các bộ phận của máy tính với nhau.
Tất cả các thành phần của MTðT ñều ñược cắm trực tiếp, hoặc gián tiếp (thông qua cáp) vào
bo mạch chủ. Bo mạch chủ gồm các thành phần chính: ổ cắm bộ xử lý trung tâm (ñể cắm
CPU), rãnh cắm bộ nhớ trong (ñể cắm các thanh RAM), BIOS, các rãnh cắm cho các thiết bị
ngoại vi (ñể cắm cạc màn hình, cạc mạng, ...), các cổng giao tiếp với các thiết bị ngoại vi, ...

Hình 1.4: Bên trong máy vi tính


Bộ xử lý trung tâm (CPU):
Là bộ não của MTðT, và có thể nói sức mạnh của máy tính phụ thuộc chủ yếu vào khả
năng tính toán của CPU. Bộ xử lý trung tâm bao gồm bộ số học – logic, bộ ñiều khiển và các
thanh ghi. Bộ số học – logic có chức năng thực hiện các phép tính số học cơ bản và các phép
tính logic. Bộ ñiều khiển có chức năng tìm nạp lệnh từ bộ nhớ, ñiều khiển các bước thực hiện
của chương trình. Còn các thanh ghi thực chất là bộ nhớ tốc ñộ cao, mỗi thanh ghi có chức
năng riêng.
CPU có một bộ phận tạo ra xung nhịp ñể ñiều khiển hoạt ñộng của nó và ñồng bộ sự hoạt
ñộng của các bộ phận khác trong toàn hệ thống máy tính. Tốc ñộ CPU chính là thể hiện nhịp
ñồng hồ này, ño bằng megaherz (MHz). Tốc ñộ càng cao tức là máy tính hoạt ñộng càng
nhanh.

11
Giáo trình Tin học ðại cương

Hầu hết các CPU sử dụng hiện nay ñược sản xuất bởi các hãng nổi tiếng như: Intel,
AMD, Motorola.

Hình 1.5: Bộ xử lý trung tâm (CPU)


Bộ nhớ
Bộ nhớ dùng ñể lưu trữ thông tin. ðơn vị ñể ño lượng thông tin là byte (viết tắt là B).
Một byte thực chất là một dãy các bit liên tiếp (8 bit). ðể lưu trữ một ký tự trong bộ nhớ, ta
cần 1 byte. Trong thực tế, thường sử dụng một số ñơn vị là bội số của byte là: kylobyte (viết
tắt là KB, 1 KB = 210 B), megabyte (viết tắt là MB, 1 MB = 210 KB), gigabyte (viết tắt là GB,
1 GB = 210 MB), tetrabyte (viết tắt là TB, 1 TB = 210 GB).
Bộ nhớ trong gồm bộ nhớ chỉ ñọc (Read Only Memory, viết tắt là ROM) và bộ nhớ truy
nhập ngẫu nhiên (Random Access Memory, viết tắt là RAM). ROM chứa những số liệu và
chương trình rất cơ bản ñể máy tính có thể khởi ñộng và làm việc. ROM ñược các hãng sản
xuất máy tính ghi sẵn, nó không bị mất ñi khi tắt máy nhưng ta không thể thay ñổi dữ liệu
trong ROM.
Trên thực tế, khi nói ñến bộ nhớ trong của máy tính người ta thường ngầm hiểu là RAM.
RAM dùng ñể lưu trữ chương trình tạm thời trong khi máy ñang làm việc. Chúng ta có thể
ñọc, ghi, sửa xóa dữ liệu trong RAM, nhưng do ñọc ghi bằng ñiện nên khi tắt máy hoặc mất
ñiện thì mọi thông tin lưu trong ñó sẽ bị mất hết. Bộ nhớ RAM thường ñược tổ chức thành
từng băng (còn gọi là thanh RAM), có dung lượng 16 MB, 32 MB, 64 MB, ... Các thanh
RAM ñược cắm trên bo mạch chủ. Trên bo mạch chủ có thể cắm ñược nhiều thanh RAM.
Bộ nhớ RAM có tốc ñộ truy cập cao, nhưng không lưu ñược dữ liệu sau khi tắt máy, vì
thế những dữ liệu muốn lưu trữ lâu dài cần phải ghi vào các thiết bị lưu trữ. Các thiết bị lưu
trữ hiện nay rất ña dạng, gồm: băng từ, các loại ñĩa từ (ñĩa mềm, ñĩa cứng), các loại ñĩa quang
(ñĩa CD, ñĩa DVD), ñĩa USB (USB Flash Disk), ...

Hình 1.6: Bộ nhớ RAM


Bộ nguồn
Bộ nguồn chuyển ñổi ñiện lưới xoay chiều thành dòng ñiện một chiều ñiện áp thấp
(thường khoảng 3v ñến 12v) ñể cung cấp cho mọi bộ phận trong máy tính.

1.6 Một số ứng dụng của Tin học

12
Giáo trình Tin học ðại cương

Tin học ngày nay ñã trở thành ñộng lực sản xuất của xã hội. MTðT khác các máy móc
khác ở chỗ nó gia công thông tin chứ không gia công nguyên vật liệu. Sản phẩm của MTðT
là những thông tin hướng dẫn các hoạt ñộng thực tiễn. Ban ñầu tin học chủ yếu phục vụ các
vấn ñề khoa học kỹ thuật, người sử dụng khi ñó cũng chủ yếu là những nhà chuyên môn trong
các lĩnh vực ñó. Sự phát triển nhanh chóng của MTðT và mạng Internet cho phép tin học xâm
nhập vào mọi lĩnh vực. Do sự phát triển nhanh, mạnh và rộng khắp của tin học nên sẽ rất khó
ñể nói hết ñược những ứng dụng của nó, dưới ñây chỉ tóm lược một số phần mềm ứng dụng
cơ bản, phổ biến hiện nay.
Phầm mềm toán học:
- Mathematica: là phần mềm cho phép tính toán từ ñơn giản như các tính toán số
học ñến phức tạp hơn, như: các bài toán về ña thức, ñại số tuyến tính, tìm giới
hạn, tìm ñạo hàm, tính tích phân, giải phương trình vi phân, khai triển Taylor, ...
Ngoài ra phần mềm này còn cho phép vẽ biểu ñồ và ñồ thị.
- Matlab: phần mềm này có thể thực hiện ñược các tính toán tương tự như
Mathematica. Ngoài ra Matlab còn dùng kỹ thuật ñồ họa 3 chiều ñể thiết kế các
mô hình trong khoa học kỹ thuật hoặc làm các ñoạn phim hoạt hình ñơn giản.

Phần mềm văn phòng:


Bộ phần mềm văn phòng nổi tiếng nhất, có mặt ở hầu hết các máy tính hiện nay là
Microsoft Office. Trong bộ phần mềm này có những chương trình:
- Word: ñể soạn thảo, lưu trữ, sửa chữa, in ấn các văn bản.
- Excel: ñể tạo lập, lưu trữ, sửa chữa, in ấn các bảng tính, ví dụ: bảng lương, bảng
thống kê bán hàng, ...
- PowerPoint: ñể tạo lập các bản báo cáo (slide) và trình bày báo cáo.
- Access: là một hệ quản trị cơ sở dữ liệu.
- FrontPage: ñể xây dựng các trang Web.
- Outlook: ñể trao ñổi, quản lý thư ñiện tử, lập lịch làm việc, ...
Phần mềm thiết kế:
- AutoCAD: ñể tạo lập và quản lý các bản vẽ kỹ thuật.
- Soap: ñể tính toán kế cấu và ổn ñịnh lực học.
- 3D Max: là một công cụ mạnh, có sự hỗ trợ của multimedia ñể phục vụ cho công
tác thiết kế.
CÂU HỎI CHƯƠNG 1
Câu 1: Kể tên các lĩnh vực nghiên cứu của Tin học? Thông tin trong máy tính ñược lưu
trữ, tính toán theo hệ ñếm nào?
Câu 2: Chuyển giá trị A =1001001 từ hệ ñếm 2 sang hệ ñếm 10? Chuyển giá trị B
=32456,4235 từ hệ ñếm 10 sang hệ ñếm 2? Chuyển giá trị C=100100010 từ hệ ñếm 2 sang
hệ ñếm 8?
Câu 3: Nêu các khái niệm: phần cứng máy tính, phần mềm máy tính, ngôn ngữ lập trình?
Nêu cấu tạo cơ bản của máy tính?

13
Giáo trình Tin học ðại cương

CHƯƠNG 2 – HỆ ðIỀU HÀNH

Hệ ñiều hành (HðH) là tập hợp các chương trình ñặc biệt dùng ñể tổ chức, phối hợp hoạt
ñộng của các thiết bị phần cứng, tạo ra môi trường làm việc cho các chương trình ứng dụng và
giao tiếp với người dùng. HðH là một phần mềm không thể thiếu trên bất kỳ máy tính nào.
HðH tự ñộng ñược tải vào bộ nhớ sau khi khởi ñộng máy tính.
Hiện nay có rất nhiều HðH cho các hệ máy khác nhau. Số lượng các HðH cho máy vi
tính cũng không ít, nhưng trên thế giới cũng như ở Việt Nam từ trước tới nay sử dụng phổ
biến các HðH của hãng Microsoft là MS-DOS và Windows.

2.1 Hệ ñiều hành MS-DOS


Một trong những HðH ñầu tiên cho các máy vi tính là MS-DOS (Microsoft Disk
Operating System), thường gọi tắt là DOS. MS-DOS ñã phát triển qua nhiều phiên bản từ 1.0
ñến 6.0 rồi dần ñược thay thế bởi HðH Windows. Tuy nhiên, nhiều tư tưởng và qui ñịnh của
DOS vẫn ñược áp dụng trong Windows. Ngoài ra, có nhiều phần mềm ñược viết từ khi HðH
Windows chưa phổ biến, chúng chỉ chạy ñược trên nền DOS, nên ngay cả trong Windows vẫn
cho phép chúng ta tạo ra môi trường DOS ảo, giống như khi dùng MS-DOS ñể chạy ñược các
phần mềm cũ.

2.1.1 Một số khái niệm


Tệp tin (file): là tập hợp các thông tin ñược tổ chức lưu trữ thành một ñơn vị ñộc lập. Có
hai loại tệp tin là: tệp tin dữ liệu và tệp tin chương trình. Mỗi tệp tin có một tên, gồm 2 phần,
ñược phân cách bằng dấu chấm (.) là: phần tên và phần mở rộng. ðặt tên tệp tin trên DOS
phải tuân theo một số qui tắc: phần tên không quá 8 ký tự, phần mở rộng không quá 3 ký tự
và không chứa dấu cách và các ký tự ñặc biệt.
Thư mục (directory): ðể tạo sự dễ dàng và thuận lợi trong việc quản lý và truy xuất ñến
các tệp tin, DOS cho phép tổ chức các tệp tin thành từng nhóm, gọi là thư mục. Có thể ví thư
mục như những tủ hồ sơ ñể chứa hồ sơ là các tệp tin. Trong thư mục có thể tạo những thư
mục con của nó. Thư mục mà bên trong không có thư mục con cũng không có tệp tin nào thì
gọi là thư mục rỗng. Thư mục hiện hành là thư mục mà ta ñang làm việc, nó ñược thể hiện
trên dấu nhắc của DOS. Tên thư mục cũng không ñược ñặt quá 8 ký tự.
Dựa trên khái niệm thư mục, DOS tổ chức dữ liệu trên ñĩa một cách logic dưới dạng hình
cây, với “gốc” là ổ ñĩa, rồi phân chia tiếp ra các thư mục, từ các thư mục có thể ñến các thư
mục con của nó, ... và cuối cùng “lá” là các tệp tin. Cách tổ chức dữ liệu trên ñĩa của HðH
Windows cũng tương tự như vậy, chỉ có ñiều trên Windows có thể ñặt tên tệp tin và tên thư
mục với ñộ dài lớn hơn, có thể bao gồm cả dấu cách.
ðường dẫn: ðể truy cập ñến một thư mục hay một tệp tin ta phải chỉ ra nó nằm ở ñâu tính
từ thư mục hiện hành. Các thông tin này ñược trình bày bằng cách liệt kê tên các thư mục và
tệp tin, giữa hai thư mục hoặc tệp tin sử dụng dấu sổ chéo (\). Dãy thư mục và tệp tin ñó gọi là
ñường dẫn. Nếu phải xác ñịnh thư mục hoặc tệp tin ở ổ ñĩa khác với ổ ñĩa hiện hành thì cần
chỉ ra tên ổ ñĩa, kèm theo dấu hai chấm (:). Tên ổ ñĩa thường ký hiệu A cho ổ ñĩa mềm, C, D
cho ổ ñĩa cứng, ...
Ví dụ một ñường dẫn: C:\GIAOTRINH\THDC\CHUONG1.DOC
Các ký tự ñại diện: thường ñược sử dụng khi phải làm việc với nhiều tệp tin có chung
một tính chất nào ñó. Có hai loại ký tự ñại diện là: ‘ ? ‘ ñại diện cho 1 ký tự tại vị trí nó ñứng
và ‘ * ‘ ñại diện cho nhiều ký tự kể từ vị trí nó ñứng.

14
Giáo trình Tin học ðại cương

2.1.2 Một số qui ước


Một lệnh của DOS ñược viết bắt ñầu từ dấu nhắc của DOS trên màn hình. Giữa phần lệnh
và phần thông tin phía sau phải có ít nhất một dấu cách. Trong lệnh của DOS không phân biệt
chữ hoa và chữ thường. Sau khi viết xong lệnh, gõ phím Enter ñể thực hiện lệnh ñó.
Trong cách viết lệnh sau ñây, phần ñặt giữa dấu < và dấu > là bắt buộc phải có, nếu
không lệnh sẽ sai cú pháp, còn phần ñặt giữa dấu [ và ] là phần lựa chọn, tùy theo yêu cầu mà
có cần sử dụng hay không.

2.1.3 Một số lệnh làm việc với thư mục:


1) Tạo thư mục mới:
MD [ñường dẫn] <tên thư mục> <ENTER>
Trong ñó: [ñường dẫn] là tên ổ ñĩa, tên các thư mục ñể xác ñịnh thư mục cần làm việc,
tức là thư mục mà ta sẽ tạo thư mục mới trong nó, <tên thư mục> là tên thư mục mới cần tạo,
<ENTER> là gõ phím Enter trên bàn phím.
Ví dụ trên ổ ñĩa C hiện hành có thư mục GIAOTRINH, cần tạo một thư mục mới có tên
VANPHONG:
MD GIAOTRINH\VANPHONG <ENTER>
2) Xóa một thư mục rỗng:
RD [ñường dẫn] <tên thư mục> <ENTER>
3) Chuyển ñến một thư mục:
CD [ñường dẫn] <tên thư mục> <ENTER>
Thư mục sau khi ñược chuyển ñến sẽ trở thành thư mục hiện hành.
Chuyển ñến thư mục cha:
CD .. <ENTER>
Chuyển ñến thư mục gốc:
CD\ <ENTER>
4) Xem nội dung thư mục:
DIR [ñường dẫn] [tên thư mục] [/p] <ENTER>
Nếu chỉ dùng DIR thì ta sẽ xem ñược nội dung của thư mục hiện hành: nó có những thư
mục con nào, tệp tin nào, kích thước từng tệp tin là bao nhiêu byte. Tham số /p ñể xem từng
trang màn hình, dùng khi số lượng tệp tin của thư mục cần xem lớn.

2.1.4 Một số lệnh làm việc với tệp tin


1) Xóa tệp tin:
DEL [ñường dẫn] <tên tệp tin> <ENTER>
ðể xác ñịnh tên tệp tin cần chỉ rõ tên và phần mở rộng. Có thể sử dụng các ký tự ñại diện
ñể xóa cùng lúc nhiều tệp tin có chung những tính chất nào ñó.
Ví dụ: xóa tất cả các tệp tin có phần mở rộng là TMP trong thư mục THDC
DEL GIAOTRINH\THDC\*.TMP <ENTER>
2) ðổi tên tệp tin:

15
Giáo trình Tin học ðại cương

REN [ñường dẫn] <tên tệp tin> <tên mới> <ENTER>


3) Sao chép tệp tin:
COPY <Nguồn> <ðích> <ENTER>
Trong ñó phần <Nguồn> cần chỉ ra các tệp tin cần sao chép và phần <ðích> chỉ ra ổ ñĩa
hoặc thư mục sẽ sao chép các tệp tin trên vào.

2.2 Hệ ñiều hành Windows


2.2.1 Một số ñặc ñiểm
HðH Windows là bước phát triển tiếp theo của MS-DOS. Khác biệt dễ nhận thấy nhất
của Windows so với DOS là nó có giao diện ñồ họa, với các thực ñơn (menu), cửa sổ và biểu
tượng. Các thao tác trên Windows rất trực quan và dễ dàng, người sử dụng không cần phải
nhớ và gõ những dòng lệnh như trên DOS. Windows ñã có một quá trình phát triển khá dài, từ
giữa những năm 80 của thế kỷ 20, dần dần thay thế DOS và trở thành HðH ñược sử dụng
nhiều nhất trên thế giới.
Những phiên bản ñược sử dụng rộng rãi ñầu tiên là Windows 3.0 và Windows 3.1. Các
phiên bản ñược sử dụng phổ biến hiện nay là Windows 98, Windows 2000, Windows XP.
Nếu máy tính ñã cài ñặt HðH Windows, sau khi khởi ñộng máy, Windows sẽ tự ñộng nạp và
chạy.
Sau khi ñăng nhập, sẽ xuất hiện màn hình nền (desktop) của Windows (các ví dụ ở ñây là
trên phiên bản Windows XP). Mỗi biểu tượng trên màn hình thường ñại diện cho một chương
trình. Muốn thực hiện chương trình nào ta nháy ñúp chuột vào biểu tượng ñó. Chúng ta cũng
có thể tạo các biểu tượng (shortcut) trên màn hình cho bất kỳ tệp tin hay thư mục nào cần
thường xuyên dùng tới. Thanh tác vụ (taskbar) phía dưới màn hình cho biết các ứng dụng nào
ñang thực hiện.
Nút Start chứa ñựng nhiều chức năng quan trọng của Windows. Trong Start, chọn All
Programs ta sẽ có danh sách các chương trình ñã cài ñặt trên máy, muốn chạy chương trình
nào chỉ cần bấm chuột vào biểu tượng tương ứng. ðể tắt máy chọn Turn Off Computer -->
Turn Off, ñể khởi ñộng lại máy chọn Turn Off Computer --> Restart.

16
Giáo trình Tin học ðại cương

Hình 2.1: Màn hình desktop của Windows XP

Hình 2.3 Sau khi bấm chọn nút Start Hình 2.3:Sau khi chọn All Programs

17
Giáo trình Tin học ðại cương

Hình 2.4: Sau khi chọn Log Off Hình 2.5: Sau khi chọn Turn Off Computer
Con chuột là thiết bị giao tiếp chủ yếu dùng trong giao diện ñồ họa. Con chuột thường có
hai phím: phím trái và phím phải. Một số thao tác cơ bản với chuột là:
- Bấm chuột (hoặc còn gọi là nháy chuột, kích ñơn, ... ) là thao tác ấn vào nút trái
chuột, dùng ñể chọn một ñối tượng nào ñó.
- Bấm chuột phải là thao tác ấn vào nút phải chuột, thường dùng ñể kích hoạt bảng
chọn tức thời (bảng chọn gồm những chức năng nào còn phụ thuộc vào ngữ
cảnh).
- Bấm ñúp chuột (hoặc còn gọi là nháy kép, kích ñúp, ...) là thao tác bấm nhanh 2
lần liên tiếp phím trái chuột, thường dùng ñể kích hoạt một ñối tượng nào ñó.
- Thao tác kéo-thả: bấm và giữ phím trái chuột, kéo chuột tới vị trí dự ñịnh, nhả
phím bấm ra. Thao tác này dùng ñể di chuyển vị trí hay thay ñổi kích thước một
ñối tượng.

Hình 2.6: Bảng chọn tức thời


ðể thực hiện các công tác quản lý tệp tin, ta cần mở chương trình Windows Explorer,
bằng cách nháy ñúp vào biểu tượng trên màn hình desktop, hoặc bấm tổ hợp phím tắt:
- E.

18
Giáo trình Tin học ðại cương

Hình 2.7: Windows Explorer

2.2.2 Các thao tác trong Windows Explorer


Hiển thị nội dung:
Phía bên trái màn hình Windows Explorer là tổ chức thư mục, cách tổ chức này cũng
giống như ở DOS. Khi chọn một thư mục nào ñó (bằng cách bấm chuột vào nó) thì danh sách
các tệp tin và thư mục con của nó xuất hiện ở bên phải màn hình. Ta có thể sắp xếp và xem
các tệp tin này theo nhiều cách khác nhau (theo tên, theo kiểu, ...) bằng cách bấm chuột phải ở
màn hình bên phải, chọn Arrange Icons By, sau ñó chọn cách sắp xếp tương ứng.

Hình 2.8: Chọn cách sắp xếp các biểu tượng tệp tin
ðóng mở thư mục:
ðể mở một thư mục: bấm chọn biểu tượng dấu cộng , ñể ñóng một thư mục: bấm chọn
biểu tượng dấu trừ .
Chọn ñối tượng (tệp tin và thư mục):
ðể chọn một tệp tin (hoặc thư mục) ta bấm chuột vào nó, ñể chọn nhiều tệp tin liền nhau
ta bấm chuột vào tệp tin ñầu, giữ phím Shift rồi bấm chuột vào tệp tin cuối, ñể chọn nhiều tệp
tin không liền nhau, ta giữ phím Ctrl rồi lần lượt bấm chọn các tệp tin.
19
Giáo trình Tin học ðại cương

Sao chép ñối tượng (các tệp tin và thư mục từ thư mục nguồn sang thư mục ñích):
Tìm ñến thư mục nguồn, nơi chứa ñối tượng. ðánh dấu chọn ñối tượng cần sao chép. Bấm chuột
phải ñể mở bảng chọn tức thời, chọn Copy. Cuối cùng tìm ñến thư mục ñích, bấm chuột phải, chọn
Paste trên bảng chọn tức thời. Nếu muốn thay vì sao chép, ta chuyển ñối tượng từ thư mục nguồn sang
thư mục ñích (ñối tượng ñó không còn trong thư mục nguồn), chỉ việc thay Copy bằng Cut.

Hình 2.9: Bảng chọn khi Copy Hình 2.10: Bảng chọn khi Paste
ðổi tên tệp tin, thư mục:
Chọn một ñối tượng (tệp tin hoặc thư mục), bấm chuột phải vào ñối tượng, chọn chức
năng Rename trong bảng chọn, cuối cùng gõ tên mới.
Xóa tệp tin, thư mục:
Chọn một ñối tượng (tệp tin hoặc thư mục), bấm chuột phải vào ñối tượng, chọn chức năng
Delete trong bảng chọn hoặc gõ phím Delete trên bàn phím. Chú ý: các tệp tin, thư mục sau khi
thực hiện các thao tác trên không bị xóa hẳn, mà chỉ bị ñưa vào thùng rác. Nếu muốn phục hồi ta
chỉ cần vào thùng rác, chọn các tệp tin, thư mục cần phục hồi, bấm chuột phải, chọn Restore. Nếu
muốn xóa hẳn tệp tin, thư mục nào, thì ta cần giữ phím Shift khi chọn chức năng Delete.

Hình 2.11: Biểu tượng thùng rác


Thao tác trong Windows Explorer chủ yếu sử dụng chuột, ngoài các thao tác ñơn giản,
nên tận dụng thêm khả năng kéo-thả. Chẳng hạn ñể sao chép các tệp tin vào một thư mục nào
ñó, ta có thể ñánh dấu chọn các tệp tin ñó rồi kéo và thả vào thư mục ñích. ðể xóa các tệp tin,
ta có thể bấm chọn các tệp tin ñó, rồi kéo và thả vào biểu tượng thùng rác.
Chúng tôi chỉ giới thiệu ở ñây một số kiến thức cơ bản nhất, vì các khả năng của HðH
Windows rất phong phú, không thể ñề cập hết trong giáo trình này. Tuy nhiên với giao diện
ñồ họa, trực quan, việc tự học và làm chủ các thao tác, khai thác các chức năng khác của
Windows sau khi ñã nắm ñược những kiến thức cơ bản là hoàn toàn không khó.
CÂU HỎI CHƯƠNG 2
Câu 1: Nêu khái niệm HðH? Kể tên một số HðH?
Câu 2: Quy tắc ñặt tên File trong hệ ñiều hành DOS? Nêu các lệnh làm việc với thư mục,
các lệnh làm việc với tệp tin?
Câu 3: Các thao tác ñể tắt máy tính trong hệ ñiều hành Windows?

20
Giáo trình Tin học ðại cương

CHƯƠNG 3 – THUẬT TOÁN

3.1 Khái niệm


Thuât toán là một dãy các quy tắc, nhằm xác ñịnh một dãy các thao tác trên các ñối
tượng (dữ liệu ñầ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 ñạt
ñược mục tiêu cần làm (dữ liệu ra là kết quả bài toán).
Ví dụ: Thuật toán tìm ước số chung lớn nhất (USCLN) của hai số nguyên dương a,b.
- Input: a,b hai số nguyên dương
- Output: ƯSCLN của a, b
Có thể mô tả thuật toán này như sau:
Bước 1: Tìm số dư r của phép chia a cho b
Bước 2: Kiểm tra:
- Nếu r = 0 thì thông báo b là USCLN và kết thúc
- Nếu r<>0 thì thực hiện ñặt a=b, b=r rồi quay lại làm lại Bước 1
Thuật toán trên gồm các thao tác tính số dư r, kiểm tra r<>0?, nếu r<>0 ñặt a=b, b=r.
Các ñặc trưng cơ bản của thuật toán
- Thuật toán phải có tính dừng: Thuật toán phải kết thúc sau một số hữu hạn bước.
- Tính xác ñịnh: Ở mỗi bước các thao tác phải rõ ràng, không gây nhập nhằng, tùy
chọn.
- ðại lượng vào: Mỗi thuật toán phải có một hoặc nhiều dữ liệu ñầu vào
- ðại lượng ra: Sau khi kết thúc thuật toán ta có thể thu ñược một số ñại lượng ra là
kết quả của bài toán.
- Tính hiệu quả: Mỗi bài toán có thể có nhiều thuật toán khác nhau ñể giải. Một
thuật toán là tốt thì nó phải ñơn giản, tiết kiệm bộ nhớ và thời gian thực hiện.
- Tính phổ dụng: Thuật toán có thể giải ñược một số bài toán trong một lớp bài
toán.
- Tính hình thức hóa: Thuật toán phải có thể hình thức ñược và cài ñặt ñược trên
máy tính.

3.2 Một số phương pháp biểu diễn thuật toán


Máy tính ñược sử dụng như là một công cụ ñể hỗ trợ con người giải quyết các bài toán
trong thực tế. Bản thân máy tính chỉ là một vật vô chi vô giác, không có tư duy. Do ñó, bản
thân nó không thể tự giải các bài toán trong thực tế ñược, mà nó chỉ có thể thực hiện ñược các
lệnh, do con người bảo nó làm thông qua một ngôn ngữ lập trình. Vì vậy ñể máy có thể giúp
chúng ta giải một bài toán nào ñó thì ta cần phải cài ñặt thuật toán giải bài toán ñó cho máy,
theo ñó máy thực hiện giải bài toán. ðể cài ñặt thuật toán cho máy người cài ñặt phải có thuật
toán giải bài toán ñó.
Có nhiều cách biểu diễn thuật toán như ñặc tả tự nhiên (liệt kê từng bước), sơ ñồ khối, giả
mã, …. Ở ñây ta làm quen với một số cách biểu diễn thuật toán thông dụng

3.2.1 ðặc tả tự nhiên (Liệt kê từng bước)


21
Giáo trình Tin học ðại cương

Sử dụng ngôn ngữ tự nhiên ñể biểu diễn thuật toán bằng cách chỉ ra từng bước cần thực
hiện của thuật toán.
Ví dụ: Thuật toán giải phương trình bậc 2: ax2+bxc=0 với các hệ số a, b, c là các số thực, a≠ 0.
Bước 1: Xác ñịnh các hệ số a=?, b=?, c=? của phương trình
Bước 2: Tính ∆ = b2 - 4ac
Bước 3: Kiểm tra ∆:
- Nếu ∆ < 0 thì kết luận phương trình vô nghiệm
- Nếu ∆ = 0 thì kết luận phương trình có nghiệp kép x1=x2=-b/(2a)
- Nếu ∆>0 thì kết luận phương trình có 2 nghiệm
x1=(-b + ∆ )/(2a); x2=(-b- ∆ )/(2a)

3.2.2 Sử dụng sơ ñồ khối


Sử dụng hệ thống các kí hiệu ñể biểu diễn thuật toán.
Một số ký hiệu sử dụng biểu diễn thuật toán:
STT Ký hiệu Ý nghĩa của ký hiệu

1 begin Ký hiệu bắt ñầu thuật toán

2 end Ký hiệu kết thúc thuật toán

3 Input: Ký hiệu nhập dữ liệu vào

Output: Ký hiệu xuất dữ liệu ra


4

S Ký hiệu rẽ nhánh
Bt Lôgíc
Nếu Bt Lôgíc có giá trị ðúng thì
5 thực hiện theo nhánh ð
Nếu Bt Lôgíc có giá trị Sai thì thực
ð hiện theo nhánh S

Biến=1, 2, ..,n
Ký hiệu vòng lặp với số lần xác
A ñịnh trước.
6 Thực hiện công việc A n lần, ban
ñầu Biến ñược gán bằng 1, sau mỗi
lần lặp biến tăng lên 1 ñơn vị

Kí hiệu khối các thao tác


7 A
thực hiện các công việc A
Kí hiệu gọi chương trình con A
8 A
thực hiện

22
Giáo trình Tin học ðại cương

Kí hiệu chỉ hướng thực hiện thuật


9 toán

Bảng 3.1: Một số ký hiệu dùng trong vẽ sơ ñồ khối


Ví dụ: Biểu diễn thuật toán giải phương trình bậc 2 bằng sơ ñồ khối.

Begin

Input: a, b, c

2
Delta = b – 4ac

Delta < 0 S Delta = 0 S

ð
ð
x = -b/2a x1 = ( −b + Delta ) /(2 a )
x 2 = ( −b − Delta ) /(2 a )

Output: Pt vô nghiệm Output: Pt Có nghiệm kép x Output: Pt có 2


nghiệm x1, x2

End

Sơ ñồ khối biểu diễn thuật giải phương trình bậc hai ax2+bx+c=0, a≠0, a, b, c, x ∈ R.
Nhận xét: Sử dụng sơ ñồ khối ñể biểu diễn thuật toán có ưu ñiểm là trực quan, dễ hiểu,
dễ kiểm tra, nhưng có một số nhược ñiểm là phải vẽ khá nhiều, cồng kềnh, không thuận lợi
cho bài toán phức tạp. Phương pháp này chủ yếu sử dụng cho người mới lập trình và ñể biểu
diễn các thuật toán ñơn giản (ít thao tác).

3.3 Các cấu trúc cơ bản của thuật toán


Khi mô tả thuật toán ta sử dụng các cấu trúc sau ñây ñể mô tả.
- Cấu trúc tuần tự
- Cấu trúc rẽ nhánh
- Cấu trúc lặp

3.3.1 Cấu trúc tuần tự


Khái niệm: Cấu trúc tuần tự là cấu trúc bao gồm nhiều bước. Các bước này ñược sắp
xếp theo một trật tự nhất ñịnh. Khi máy thực hiện nó sẽ thực hiện theo thứ tự các bước ñã
ñược sắp xếp.
Trong biểu diễn thuật toán bằng phương pháp ñặc tả tự nhiên thì các bước ñược sắp xếp
tuần tự. Trong ñặc tả ñó chỉ ra bước nào thực hiện trước bước nào thực hiện sau.
23
Giáo trình Tin học ðại cương

Ví du: ðặc tả thuật toán giải phương trình bậc hai ở ví dụ trong mục 3.2.1 thì thứ tự thực
hiện các bước là: thực hiện bước 1, sau khi thực hiện xong bước 1 thì thực hiện bước 2 và sau
khi thực hiện xong bước 2 thì thực hiện bước 3.
Trong biểu diễn thuật toán bằng sơ ñồ khối thì trình tự thực hiện của thuật toán ñược thực
hiện theo chiều mũi tên.
Ví du: Tính diện tích, chu vi của một hình tròn bán kính r.
Sơ ñồ khối mô tả thuật toán giải bài toán trên:

begin

Input: r

S = πr2
C = 2πr

Output: S, C

End

3.3.2 Cấu trúc rẽ nhánh


Khái niệm: Cấu trúc rẽ nhánh là cấu trúc báo cho máy cần kiểm tra một ñiều kiện nào ñó
của bài toán. Ở ñây kết quả của ñiều kiện kiểm tra chỉ nhận một trong hai giá trị ñúng (ð)
hoặc sai (S). Nếu kết quả kiểm tra có giá trị ñúng sẽ thực hiện theo nhánh ñúng, nếu sai sẽ
thực hiện theo nhánh sai.
Biểu thức ñiều kiện chính là một biểu thức lôgíc
Sơ ñồ khối thể hiện cấu trúc rẽ nhánh

S
Biểu thức Lôgíc

Ví dụ: Giải phương trình bậc nhất ax + b = 0


Sơ ñồ khối thể hiện thuật toán:

24
Giáo trình Tin học ðại cương

begin

Input :a, b

S
a=0

S x = -b/a
b=0

Output: Pt vô số nghiệm Ouput: Pt vô nghiệm Output: x

end

3.3.3 Cấu trúc lặp


Trong lập trình chúng ta có hai dạng cấu trúc lặp: cấu trúc lặp xác ñịnh trước và cấu trúc
lặp không xác ñịnh trước.
Cấu trúc lặp xác ñịnh:
Khái niệm: Cấu trúc lặp xác ñinh trước là cấu trúc báo cho máy lặp ñi lặp lại một miền
tác ñộng nào ñó với số lần lặp xác ñịnh trước.
Trong miền tác ñộng có thể bao gồm một tập cấu trúc cơ bản.
Sơ ñồ khối thể hiện cấu trúc
Biến = 1, 2, .. n

Miền tác ñộng

Cấu trúc lặp không xác ñịnh:


Khái niệm: Cấu trúc lặp không xác ñịnh là cấu trúc báo cho máy lặp ñi lặp lại một miền
tác ñộng nào ñó với số lần lặp không xác ñịnh trước. ðiều kiện kết thúc vòng lặp là một biểu
thức lôgíc.
25
Giáo trình Tin học ðại cương

Trong miền tác ñộng có thể bao gồm một tập cấu trúc cơ bản.
Sơ ñồ khối thể hiện cấu trúc

S Miền tác ñộng


Biểu thức lôgíc

ð Hoặc
S Biểu thức lôgíc
Miền tác ñộng

1 1 1
Ví dụ: Tìm số tự nhiên n nhỏ nhất ñể tổng s = 1 + + + ... + ≥ 2.5
2 3 n
Giải: Theo yêu cầu bài toán là cần tìm n nhỏ nhất ñể s ≥ 2.5. ðể tìm ñược n ta thực hiện
theo thuật toán sau:
Sử dụng phương pháp ñặc tả tự nhiên mô tả thuật toán:
Bước 1. Khởi tạo giá trị ban ñầu n = 0, s = 0.
1
Bước 2. Tăng giá trị n lên 1 ñơn vị (n = n + 1), tính s = s +
n
Bước 3. Kiểm tra: Nếu s >= 2.5 thì dừng lại ta có n là giá trị cần tìm
Nếu s < 2.5 thì quay lại thực hiện lại bước 2.
Sử dụng sơ ñồ khối mô tả thuật toán

begin

s = 0, n = 1

s < 2.5 S

ð
s, n
s = s + 1/n
n = n +1
end

26
Giáo trình Tin học ðại cương

3.4 Một số thuật toán giải một số bài toán ñơn giản
3.4.1 Bài toán ñếm
Bài toán: Cho một dãy n các phần tử a1, a2,…, an. Hãy ñếm xem trong dãy có bao nhiêu
phần tử thoả mãn ñiều kiện nào ñó.
Một cách tự nhiên thì ñể giải bài toán trên, ta thực hiện duyệt qua từng phần tử. Với mỗi
phần tử thoả mãn ñiều kiện thì tăng biến ñếm lên một ñơn vị.
Thuật toán
Bước 1. Xác ñịnh n và các phần tử a1, a2, ... an
Bước 2. Khởi tạo một biến ñếm với giá trị là 0
Bước 3. Thực hiện duyệt qua từng phần tử. Với mỗi phần tử ñược duyệt, thực hiện kiểm
tra xem nó có thoả mãn ñiều kiện bài toán không? Nếu thoả mãn thì tăng biến ñếm lên một
ñơn vị. Nếu không thoả mãn thì duyệt phần tử tiếp theo.
Mô tả thuật toán bằng sơ ñồ khối

Begin

n i = 1, 2, .., n

i = 1, 2, .., n

Bt Lôgíc
S

ai ð

Dem = Dem +1

Dem = 0
Dem

End

Ví dụ 1: Cho một dãy n số nguyên. ðếm xem trong dãy có bao nhiêu số chẵn.
Thuật toán
Sử dụng phương pháp ñặc tả tự nhiên mô tả thuật toán
27
Giáo trình Tin học ðại cương

Bước 1. Xác ñịnh n và các phần tử a1, a2, ... an


Bước 2. Khởi tạo một biến ñếm với giá trị là 0
Bước 3. Thực hiện duyệt qua từng phần tử. Với mỗi phần tử ñược duyệt, thực hiện kiểm
tra: Nếu ai chia hết cho 2 thì tăng biến ñếm lên một ñơn vị. Ngược lại, duyệt phần tử tiếp
theo.
Sử dụng sơ ñồ khối mô tả thuật toán

Begin

i = 1, 2, .., n
Input: n

i = 1, 2, .., n S
ai M2

ð
Input: ai
Dem = Dem +1

Output: Dem
Dem = 0

End

Mô tả thuật toán ñếm các số chẵn trong một dãy số

3.4.2 Bài toán tìm giá trị lớn nhất, giá trị nhỏ nhất
Trong cuộc sống thực tế, hàng ngày chúng ta luôn phải ñi tìm giá trị lớn nhất, nhỏ nhất
trong một tập phần tử. Ví dụ như tìm người có chiều cao cao nhất (thấp nhất) trong lớp; tìm
sinh viên có ñiểm tổng kết cao nhất (thấp nhất) trong lớp, trong khoa, trong trường,…. Như
vậy nếu có một thuật toán giải bài toán này và cài ñặt nó trên máy tính ñể máy giải giúp chúng
ta thì ñó thực sự là một ứng dụng có ích. Bài toán cụ thể ñược phát biểu như sau:
Bài toán: Cho một dãy n số bất kỳ. Hãy tìm giá trị lớn nhất (nhỏ nhất) của dãy số ñó.
ðể tìm giá trị lớn nhất (nhỏ nhất) của các phần tử trong dãy. Ta thực hiện so sánh các
phần tử trong dãy với nhau sẽ tìm ra ñược giá trị mong muốn. Quá trình tìm ñược thể hiện
bằng thuật toán sau ñây.
Thuật toán
Sử dụng phương pháp ñặc tả tự nhiên môt tả thuật toán
Bước 1. Xác ñịnh n và các số a1, a2, …, an
Bươc 2. Sử dụng Max lưu giá trị lớn nhất. Giả sử giá trị lớn nhất là a1 (tức là Max = a1).
Bước 3. Duyệt lần lượt qua các phần tử a2, a3, …, an. So sánh giá trị của phần tử ai với
Max. Nếu ai > Max (i=2..n) thì gán giá trị của ai cho Max (Max = ai). Nếu ai < Max thì chuyển
xét phần tử tiếp theo.
Giá trị cuối cùng lưu trong Max chính là giá trị lớn nhất của dãy số.

28
Giáo trình Tin học ðại cương

Sử dụng sơ ñồ khối mô tả thuật toán

Begin

Input: n i = 2, 3,..., n

i = 1, 2, .., n
Max<ai S

Input: ai ð
Max = ai

Max = a1
Output: Max

End

Thuật toán tìm giá trị lớn nhất của một dãy số.
ðối với bài toán tìm giá trị nhỏ nhất cũng tương tự, nhưng trong phép so sánh ta phải
thay dấu “<” bằng dấu “>” và thay tên Max thành Min ñể phù hợp với ý nghĩa của kết quả lưu
trong nó.
Một số bài toán qui về bài toán tìm max, min
Bài 1. Cho tọa ñộ của một dãy n ñiểm { xi , yi }i =1 trong mặt phẳng. Tìm diện tích ñường
n

tròn tâm O(0,0) có bán kính nhỏ nhất chứa n ñiểm trên.
Gợi ý: Bài toán này qui về bài toán tìm Max

Bài 2. Cho tọa ñộ của một dãy n ñiểm { xi , yi }i =1 trong mặt phẳng. Tìm hình chữ nhật có
n

diện tích nhỏ nhất và các cạnh song song với các trục toạ ñộ chứa n ñiểm trên.
Gợi ý: Bài toán này qui về bài toán tìm cả Min và Max.

3.4.3 Bài toán tính tổng một dãy số


Bài toán: Cho 1 dãy n số. Tính tổng tất cả các phần tử của dãy.
Thuật toán
Sử dụng phương pháp ñặc tả tự nhiên mô tả thuật toán
Bước 1. Xác ñịnh n, a1, a2, …, an
Bước 2 .Khởi tạo S = 0
Bước 3. Duyệt qua từng phần tử của dãy số. Với phần tử ai của dãy thực hiện S = S + ai.
Sau khi duyệt qua hết các phần tử ta ñược tổng của dãy lưu trong S.
Sử dụng sơ ñồ khối mô tả thuật toán
29
Giáo trình Tin học ðại cương

Begin

Input: n

i = 1, 2, .., n i = 1, 2,..., n

Input: ai
S = S + ai

S=0
Output: S

End

Một số bài toán qui về bài toán tính tổng


Bài 1. Tính giá trị của ña thực Pn(x) = a0 + a1x + a2x2 + … +anxn
n
Bài 2. Tính tổng theo công thức (công thức tổng quát dạng S = f(x) + ∑ g ( x, i ) )
i =1

Ví dụ 1: Cho x là số thực, n là số nguyên dương. Tính

1+ x 1 + x2 1 + xn
S = ex + + +…+
2 3 n +1
Ví dụ 2: Cho x là số thực, n là số nguyên dương. Tính
S = | x+ (1+x)3 + (2+x)3 + … +(n+x)3|
Ví dụ 3: Cho x là số thực, n là số nguyên dương. Tính
x +1 x + 2 x+n
s = 2006 − + − ... + (−1) n
1! 2! n!
Ví dụ 4: Cho x là số thực, n là số nguyên dương. Tính
x2 xn
S = 2006 + x + + ... +
2! n!
Ví dụ 5: Cho n ñiểm trên mặt phẳng tọa ñộ ðề các xOy: M1, M2, ... Mn. Tính ñộ dài
ñường gấp khúc lần lượt ñi qua các ñiểm trên theo thứ tự từ M1 ñến Mn ?

30
Giáo trình Tin học ðại cương

3.4.4 Bài toán tính tích một dãy số


Bài toán: Cho 1 dãy n số. Tính tích tất cả các phần tử của dãy.
Thuật toán tính tích của một dãy số cũng tương tự như thuật toán tính tổng. Tuy nhiên
khác với thuật toán tính tổng là khi khởi gán cho ñại lượng lưu trữ tích là 1 thay vì khởi gán 0
và thay phép + bằng phép * (nhân).
Các bài toán qui về thuật toán tính tích
Bài 1. Cho số tự nhiên n. Tính S = n!
Bài 2. Cho số thực x, số tự nhiên n. Tính S = xn

CÂU HỎI CHƯƠNG 3

Vẽ sơ ñồ khối thể hiện thuật toán giải các bài toán sau:
Bài 1: Cho số nguyên dương n. Hãy kiểm tra xem n có là số nguyên tố không?
Bài 2: Cho 2 số nguyên dương m và n. Tìm ước chung lớn nhất của 2 số?
Bài 3: Cho dãy số nguyên a1, a2, ... an. Hãy ñếm xem có bao nhiêu bộ 3 phần tử liên tiếp của
dãy theo thứ tự tạo thành cấp số cộng?
Bài 4: Cho dãy số thực x1, x2, ..... xn. Hãy tính trung bình cộng các phần tử của dãy có giá trị
thuộc ñoạn [-6,9]?

Bài 5: Cho dãy số thực x1, x2, ..... xn. Tìm giá trị lớn nhất trong số các phần tử âm của dãy?

31
Giáo trình Tin học ðại cương

PHẦN 2
NGÔN NGỮ LẬP TRÌNH C

32
Giáo trình Tin học ðại cương

Một số giới thiệu mở ñầu về Ngôn ngữ lập trình C


Vào năm 1970 từ một ngôn ngữ cũ hơn gọi là BCPL, Dennis Ritchie và Brian
Kernighan ñã ñưa ra ngôn ngữ C với mục ñích ban ñầu là viết Hệ ñiều hành Unix trên máy
mini DEC PDP-11. Sau ñó C ñã nhanh chóng ñược sử dụng trên các máy tính PC. Năm 1987
hãng Borland ñã cung cấp phần mềm Turbo C - bộ chương trình dịch rất hiệu quả, tiện lợi,
nhờ ñó việc dùng ngôn ngữ C trở nên dễ dàng hơn. Trong quá trình phát triển ñã xuất hiện
nhiều phiên bản C khác nhau. ðể tiến tới sự thống nhất, năm 1990 ANSI [1] ñã xây dựng
ngôn ngữ C chuẩn (ANSI C). C là một trong các ngôn ngữ lập trình cấu trúc tiêu biểu có tốc
ñộ xử lý nhanh, có các công cụ mạnh ñể quản lý bộ nhớ và các thiết bị ngoại vi. ðã có nhiều
sản phẩm phầm mềm trong mọi lĩnh vực viết bằng C như hệ ñiều hành, các ứng dụng xử lý
ñồ hoạ, ña phương tiện, xử lý văn bản, cơ sở dữ liệu, mạng,... . C hiện ñang không ngừng
phát triển, từ C có thể nghiên cứu các ngôn ngữ tân tiến khác như C++, C trên Windows,
Visual C++, Java. Chính vì vậy C ñã ñược ñưa vào giảng dạy cho tất cả các khoa công nghệ
thông tin và nhiều khoa chuyên ngành kỹ thuật khác. Trong vài năm gần ñây Trường ðại học
Giao thông Vận tải ñã ñưa ngôn ngữ C vào giảng dạy trong chương trình Tin học ðại cương.
Trong phần II này, chúng tôi cung cấp những kiến thức cơ sở của Turbo C. Các vấn
ñề lý thuyết ñược giải thích tỉ mỉ và ñược minh hoạ bằng nhiều ví dụ. Các câu lệnh phức tạp
ñược giới thiệu dần dần từ dễ ñến khó. Thường mỗi lệnh ñiều khiển có thể viết theo nhiều
dạng. Các ví dụ và bài tập sẽ giúp người ñọc luyện tập cách vận dụng các câu lệnh ñể viết
chương trình.
Phần II gồm 5 chương và 02 phụ lục
Chương 1: ngoài việc giới thiệu các khái niệm cơ bản còn ñưa ra một số chương trình C
ñơn giản và cách thực hiện chúng trên máy ñể giúp người ñọc mau chóng tiếp cận với máy tính.
Chương 2: trình bày các kiểu dữ liệu, cách biểu diễn các giá trị dữ liệu và cách tổ
chức (lưu trữ) dữ liệu trong biến và mảng.
Chương 3: nói về một lớp toán tử rất quan trọng dùng ñể thể hiện các thuật toán , ñó
là toán tử rẽ nhánh if, và các toán tử tạo lập chu trình (vòng lặp) for, while, do - while.
Chương 4: trình bày cách tổ chức chương trình thành các hàm, các quy tắc xây dựng
và sử dụng hàm. Các vấn ñề hay và khó ở ñây là con trỏ và kỹ thuật ñệ quy.
Chương 5: nói về một kiểu dữ liệu quan trọng là cấu trúc (tương tự như bản ghi của
Foxpro và Pascal) dùng ñể biểu diễn các ñối tượng thường gặp như thí sinh, học sinh, giáo
viên, hoá ñơn bán hàng, phiếu xuất nhập vật tư, công văn ñi ñến,...
Phụ lục 1: trình bày bảng mã ASCII.
Phụ lục 2 giới thiệu hơn 200 hàm chuẩn của C theo thứ tự ABC ñể tiện tra cứu.

33
Giáo trình Tin học ðại cương

CHƯƠNG 1 - MỘT SỐ KHÁI NIỆM MỞ ðẦU

Chương này sẽ giới thiệu những thành phần cơ bản của ngôn ngữ lập trình C, ñó là: tập
ký tự, từ khóa và tên. ðể có thể lập ñược một chương trình ñầy ñủ, chúng tôi sẽ trình bày ñôi
ñiều về câu lệnh gán, các câu lệnh vào ra, chỉ thị #include và những qui tắc cần lưu ý khi viết
chương trình. Ngoài ra ñể giúp bạn ñọc mau chóng tiếp cận với máy, chúng tôi sẽ giới thiệu
vài chương trình ñơn giản nhưng hoàn chỉnh và cách vận hành chúng trên máy ñể nhận ñược
kết quả cuối cùng. Tất cả những ñiều nói trên là bổ ích và ñáng ghi nhớ vì chúng sẽ ñược
thường xuyên sử dụng sau này. ðọc xong chương 1 bạn có thể lập ñược một số chương trình
ñơn giản, biết cách thực hiện chương trình trên môi trường Turbo C 2.0 và Turbo C++ 3.0

1.1 Tập ký tự
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 ñể lập lên các từ. ðến lượt mình, các từ lại ñược liên kết theo
một qui tắc nào ñó ñể tạo thành các câu lệnh. Một chương trình bao gồm nhiều câu lệnh và
diễn ñạt 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 như: + - * / = ( )
Ký tự gạch nối: _ ( chú ý: phân biệt với dấu - )
Các ký hiệu ñặc biệt khác như: . ,;: [] {} ?! \ & | % # $ , ...
Dấu cách (space) thực sự là một khoảng trống dùng ñể tách các từ. Ví dụ HA NOI gồm 6
ký tự, còn HANOI gồm 5 ký tự.
Chú ý: Khi viết chương trình ta không ñược sử dụng bất kỳ ký hiệu nào khác ngoài tập
các ký tự nói trên.
Chẳng hạn khi giải phương trình bậc hai:
ax2 + bx + c = 0
ta cần tính biểu thức:
∆ = b2 - 4ac
Ký tự ∆ không cho phép dùng trong ngôn ngữ C, vì vậy ta phải dùng một cách ký hiệu
khác như d hay delta.

1.2 Từ khóa
Từ khóa là những từ ñược ñịnh nghĩa trước và có một ý nghĩa hoàn toàn xác ñịnh. Chúng
thường ñượ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. Sau
ñây là các từ khóa của TURBO C:
asm break case cdecl
char const continue default
do double else enum

34
Giáo trình Tin học ðại cương

extern far float for


goto huge if int
interrupt long near pascal
register return short signed
sizeof static struct switch
typedef union unsigned void
volatile while
Ý nghĩa và cách sử dụng của chúng sẽ ñược lần lượt giới thiệu ở các mục sau. Ở ñây chỉ
cần nhớ hai ñiều:
- Không ñược dùng từ khóa ñể ñặt tên cho các hằng, biến, mảng, hàm, ...
- Từ khóa phải ñược viết bằng chữ thường. Chẳng hạn không ñược viết iNT mà
phải viết int.

1.3 Tên
Tên là một khái niệm rất quan trọng, nó dùng ñể xác ñịnh các ñối tượ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 cấu trúc,
tên nhãn,...
Việc ñặt tên phải tuân theo một số quy tắc: tên là một dãy các ký tự có thể gồm chữ, số và
dấu gạch nối. Ký tự ñầu của tên không ñược là số. Tên không ñược trùng với từ khóa (xem
1.2). ðộ dài cực ñại của tên ñối với môi trường Turbo C mặc ñịnh là 32 ký tự.
Các ví dụ ñúng về tên:
a_1 BETA x1 delta_7 _x1
Các ví dụ sai về tên:
3XYZ_7 (Ký tự ñầu tiên là số)
r#3 (sử dụng ký tự # )
f(x) (sử dụng các dấu ngoặc tròn)
case (trùng với từ khóa )
be ta (sử dụng khoảng trống)
X-1 (sử dụng dấu gạch ngang)
Chú ý: Trong các tên, chữ hoa và chữ thường ñược xem là khác nhau, như vậy tên AB
khác tên ab.

1.4 Một số khái niệm


1.4.1 Biến
Biến là ñại lượng dùng ñể chứa (lưu trữ) các giá trị trong quá trình tính toán. Có thể hiểu
khái niệm biến ở ñây giống như khái niệm biến trong toán học.
Vấn ñề khai báo sẽ nói kỹ trong chương 2. Ở ñây chúng ta chỉ cần biết vài ñiều sơ lược.
Mọi biến trước khi sử dụng ñều phải khai báo ñể xác ñịnh kiểu của nó. ðể khai báo các biến
nguyên (kiểu int) ta dùng từ khoá int. ðối với biến thực (kiểu float) ta dùng từ khoá float. Ví
d ụ:

35
Giáo trình Tin học ðại cương

int a,b,c; /* khai báo các biến a, b, c kiểu int */


float x,y,z; /* khai báo các biến x,y,z kiểu float */
Sự khác nhau giữa biến kiểu int và biến kiểu float là ở chỗ: biến kiểu int luôn luôn nhận
giá trị nguyên trong quá trình tính toán còn biến kiểu float có thể nhận cả các giá trị là các số
thực.

1.4.2 Hằng
Hằng là các ñại lựong có giá trị không ñổi trong chương trình. Khái niệm này sẽ ñược ñề
cập chi tiết trong 2.2.

1.4.3 Toán tử gán


Câu lệnh gán sẽ nói kỹ trong chương 2. Ở ñây ta có thể hiểu toán tử gán có dạng:
b = bt;
Trong ñó b là một biến, còn bt là một biểu thức toán học nào ñó. Tác dụng của câu lệnh
này là: trước tiên tính biểu thức bt và sau ñó gán giá trị tính ñược cho biến b.
Ví dụ: Sau khi thực hiện ñoạn chương trình:
float x;
x = 10.5;
x = 2*x - 2.5;
biến x sẽ nhận giá trị là 18.5.
Chú ý: khái niệm gán không giống như khái niệm ñẳng thức trong toán học.

1.4.4 Câu lệnh và khối lệnh


Mỗi câu lệnh thực hiện 1 chức năng (công việc) nào ñó, nó có thể ñược viết trên một
hoặc nhiều dòng nhưng phải kết thúc bằng dấu;
Ví dụ:
clsrcr();
printf("Hello");
Khối lệnh là một dãy các câu lệnh ñược bao bởi cặp dấu { và }.
Ví dụ:
{
int a,b;
a=2;
b=3;
printf ("\n%6d%6d",a,b);
}
Chú ý: Về mặt cú pháp, C xem một khối lệnh cũng như một câu lệnh riêng lẻ. Nói cách
khác chỗ nào viết ñược một câu lệnh thì ở ñó cũng có quyền ñặt một khối lệnh.
Khai báo ở ñầu khối lệnh
Các khai báo biến, mảng(1) có thể ñặt ở ñầu của một hàm, hoặc có thể viết ở ñầu khối
lệnh, ví dụ:
{
int a,b,c[50];

(1)
Các khái niệm này ñược trình bày ở 2.3, 2.4. ðộc giả có thể hiểu ñơn giản như sau: biến là các ñại lượng dùng ñể lưu trữ số liệu; mảng là
tập hợp của nhiều biến.
36
Giáo trình Tin học ðại cương

float x,y,z,t[20][30];
a = 3; b = 5;
x = 5.7; y=a*x;
z=b*x;
printf ("\ny=%8.2f\nz=%8.2f",y,z);
}
Sự lồng nhau của các khối lệnh
Bên trong một khối lệnh lại có thể viết các khối lệnh khác. Số các khối lệnh lồng nhau là
không hạn chế.
Phạm vi hoạt ñộng của các biến và mảng
Khi gặp khai báo của biến và mảng, máy sẽ cấp phát bộ nhớ cho biến và mảng. Các biến
chỉ tồn tại trong khối lệnh mà biến ñược khai báo, và sẽ mất ñi khi kết thúc khối lệnh.
Từ ñó có thể rút ra một số kết luận sau:
- Giá trị của một biến hay một mảng khai báo bên trong một khối lệnh không thể
ñưa ra ñể sử dụng ở bất kỳ chỗ nào bên ngoài khối lệnh ñó.
- Từ bên ngoài một khối lệnh, không thể can thiệp ñến các biến và các mảng ñược
khai báo bên trong khối lệnh.
Về các khối lệnh lồng nhau
Ta có thể khai báo hai biến hoặc hàm cùng tên, một ở ngoài và một ở khối lệnh bên trong,
khi ñó hai biến ñó là hai biến ñộc lập cùng tên.
Ví dụ xét ñoạn chương trình:
{
int a=5;
{
int a=4;
printf ("a = %d\n", a);
}
printf("a = %d\n", a);
}
ðoạn chương trình trên có hai lệnh printf giống nhau, cùng in ra giá trị của a, nhưng là
hai biến a khác nhau, kết quả ñưa ra sẽ là:
a = 4
a = 5
Biến a bên trong trùng tên với biến a bên ngoài, do ñó lệnh printf bên trong sẽ in giá trị
của biến a ở khối lệnh bên trong, hay nói cách khác, ở khối lệnh bên trong, biến a bên trong
ñã “che”2 biến a bên ngoài.

1.4.5 Chú thích


Trong một chương trình, ngoài các câu lệnh, ta có thể ñưa thêm vào các lời chú thích.
Các chú thích này không ảnh hưởng ñến kết quả họat ñộng của chương trình, nó chỉ có tác
dụng ñối với người ñọc chương trình.
Các lời giải thích cần ñược ñặt giữa dấu /* và dấu */ và có thể ñược viết:
- Trên một dòng.
- Trên nhiều dòng.

2
Biến a bên trong ñược ưu tiên hơn so với biến a bên ngoài.
37
Giáo trình Tin học ðại cương

- Trên phần còn lại của một dòng.


Trong TC 3.0 ta có thể dùng dấu // ñể chú thích. Phần chú thích sẽ bắt ñầu từ dấu // ñến
cuối dòng.
Ví dụ:
clrscr(); // xoá màn hình
printf(“Hello”); // in ra màn hình dòng chữ Hello

1.5 Một số chương trình ñơn giản


Dưới ñây là các ví dụ nhằm minh hoạ cấu trúc của một chương trình C. ðộc giả dễ dàng
hiểu ñược mỗi câu lệnh qua các giải thích viết giữa các dấu /* */.
Ví dụ 1. Viết chương trình cho hiện lên màn hình hai dòng chữ:
TURBO C HAN HANH
LAM QUEN VOI BAN
Dưới ñây là hai chương trình cùng thực hiện yêu cầu ñề ra.
/* Chương trình in hai dòng chữ - Bản 1 */
#include <stdio.h> /* sử dụng thư viện vào ra chuẩn */
#include <conio.h>
void main () /* hàm chính */
{
/* Xuống dòng (\n) và in: TURBO C HAN HANH */
printf("\nTURBO C HAN HANH");
/* Xuống dòng và in: LAM QUEN VOI BAN */
printf("\nLAM QUEN VOI BAN");
getch(); /* Tạm dừng máy ñể xem kết quả */
}
Phiên bản sau ghép hai câu lệnh printf thành một câu lệnh duy nhất.
/* Chương trình in 2 dòng chữ - Bản 2 */
#include "stdio.h" /* sử dụng thư viện vào ra chuẩn */
#include "conio.h"
void main () /* hàm chính */
{
/*
Xuống dòng, in: TURBO C HAN HANH,
tiếp tục xuống dòng rồi in: LAM QUEN VOI BAN
*/
printf("\nTURBO C HAN HANH\nLAM QUEN VOI BAN");
getch(); /* Tạm dừng máy ñể xem kết quả */
}
Nhận xét: Mỗi cậu lệnh printf trong bản 1 in ñược một dòng. Câu lệnh printf trong bản 2
in ñược hai dòng.
Ví dụ 2. Chương trình dưới ñây tính chu vi và diện tích hình tròn theo giá trị bán kính r
nhập từ bàn phím.
#include "stdio.h"
#include "conio.h"
#include "math.h" /*Sử dụng thêm thư viện các hàm toán học*/
void main()
{
float r,cv,dt; /* Khai báo 3 biến thực */
/* ðưa ra man hình thông báo về yêu cầu nhập số liệu */
printf("\nBan kinh r= ");
/* Nhập một giá trị thực ñưa vào biến r */
scanf("%f",&r);
/* Tính chu vi và diên tích hình tròn
38
Giáo trình Tin học ðại cương

Dùng hằng M_PI (PI) ñã ñịnh nghĩa trong math.h


*/
cv = 2*M_PI*r; dt = M_PI*r*r;
/* In kết quả */
printf("\nChu vi=%10.2f\nDien tich=%10.2f",cv,dt);
getch(); /* Tạm dừng máy ñể xem kết quả */
}
Ví dụ 3: Tính x luỹ thừa y.
/* chuong trinh tinh x luy thua y */
#include "stdio.h"
#include "math.h"
void main ()
{
float x,y,z; // khai bao ba bien kieu float
printf("\n vao x va y ");
scanf("%f%f",&x,&y); // vao x, y tu ban phim
z=pow(x,y); // tinh z = x ^ y

/* in ket qua tren 3 dong */


printf("\nx = %f\ny = %f\nz = %f", x, y, z);
}
Ví dụ 4: Minh hoạ khả năng ñưa ra
/* chuong trinh minh hoa cac kha nang dua ra */
#include "stdio.h"
void main()
{
int a,c,t; float b,d;
a = 123; c = -4685; t = 12;
b = -45.855; d = 123.425;
printf("\nChuc cac ban may man \n");
printf("Tong san luong hang nam tang %d %",t);
/* giua cac so dua ra khong co khoang cach */
printf("\n%d%f%d%f",a,b,c,d);
/* giua cac so dua ra co nhung khoang trong */
printf("\n%d %f %d %f",a,b,c,d);
/* giua cac so co dat them cac ky tu khac */
printf("\na = %d, b = %f, c=%d, d=%f", a,b,c,d);
}
Kết quả thực hiện chương trình:
Chuc cac ban may man
Tong san luong hang nam tang 12 %
123-45.855000-4685123.425000
123 -45.855000 -4685 123.425000
a = 123, b = -45.85, c = -4685, d = 123.43

1.6 Một số quy tắc cần nhớ khi viết chương trình
Bây giờ chúng ta vừa giải thích ñôi ñiều về ví dụ trên, vừa rút ra một số chú ý khi viết chương
trình.
Quy tắc ñầu tiên cần nhớ là: Mỗi câu lệnh có thể viết trên một hay nhiều dòng nhưng phải
ñược kết thúc bằng dấu;
Nhìn vào ví dụ 2 của 1.5 ta thấy:
+ Câu lệnh printf ñược viết trên 1 dòng.
+ Hai câu lệnh gán ñể tính cv và dt ñược viết trên một dòng.

39
Giáo trình Tin học ðại cương

Một ñiểm cần lưu ý ở ñây là cách viết một hằng xâu ký tự (dãy ký tự ñặt trong hai dấu
nháy kép) trên nhiều dòng. ðể báo cho TURBO C biết một chuỗi ký tự vẫn còn tiếp tục ở
dòng dưới, ta ñặt thêm dấu \ trước khi xuống dòng. Ví dụ:
printf("\nTURBO C HAN HANH\
\nLAM QUEN VOI BAN");
Quy tắc thứ hai là quy tắc viết các lời giải thích. Các lời giải thích cần ñược ñặt giữa dấu /* và
dấu */ và có thể ñược viết:
- Trên một dòng.
- Trên nhiều dòng.
- Trên phần còn lại của một dòng.
Những lời giải thích không có tác dụng ñối với sự làm việc của chương trình trên máy tính.
Chúng chỉ có tác dụng ñối với người ñọc.
Qui tắc thứ ba là qui tắc sử dụng các hàm chuẩn. Trong chương trình trên có dùng hàm chuẩn
printf. Hàm này có trong tệp stdio.h (trong thư mục của C), vì vậy ở ñầu chương trình cần
viết:
#include "stdio.h"
Ta cũng chú ý rằng: cuối dòng này không có dấu ; như cuối một câu lệnh.
Tóm lại trước khi sử dụng một hàm cần biết nó nằm trên tệp nào và phải dùng toán tử
#include ñể gắn tệp ñó vào tệp chương trình của ta.
Qui tắc thứ tư nói về cấu trúc của một chương trình. Một chương trình có thể chỉ có một
hàm chính (main) như các ví dụ trên, hoặc có thể thêm vài hàm khác. ðiều này sẽ ñược trình
bày chi tiết trong chương 4. Tại ñây ta có thể xem cấu trúc của chương trình như sau:

#include ……
khai báo các biến, các mảng toàn cục nếu có
khai báo và xây dựng các hàm nếu có
void main()
{
.. các lệnh…
}
xây dựng các hàm ñã khai báo

1.7 Cách thực hiện các chương trình trên máy tính
Phần việc còn lại sau khi ñã có chương trình là thực hiện chương trình trên máy tính ñể
nhận kết quả cuối cùng. ðây là phần việc có tính chất tác nghiệp ít ñòi hỏi suy nghĩ và sáng
tạo hơn so với công việc lập trình. Quá trình vận hành một chương trình trên máy tính bao
gồm các bước cơ bản sau:
- Tạo tệp chương trình gốc ñuôi C và soạn thảo chương trình.
- Dịch và chạy chương trình.

40
Giáo trình Tin học ðại cương

Dưới ñây sẽ trình bày cách sử dụng các phần mềm TC2.0 (Turbo C 2.0) và TC++3.0
(Turbo C++ 3.0) ñể thực hiện chương trình. Chúng ta sẽ thấy trình tự thao tác là rất ñơn giản
và tượng tự như nhau (ñối với TC2.0 và TC++3.0) .
Thực hiện chương trình trong TC2.0
Giả sử TC2.0 ñã ñược cài ñặt trong thư mục C:\TC
Soạn thảo chương trình: Vào môi trường của TC2.0 bằng cách khởi ñộng tệp TC.EXE
trong thư mục C:\TC. Khi ñó sẽ nhận ñược menu chính của TC2.0 gồm các menu: File, Edit,
Run, Compile, Project, Option, Debug và Break/Watch.
Chọn menu File, mục New ñể nhận cửa sổ soạn thảo. Dùng bàn phím ñể soạn thảo
chương trình trong cửa sổ này, sau ñó dùng phím F2 (hoặc chọn File - Save) ñể ghi chương
trình lên tệp.
Dịch và chạy chương trình: Bấm ñồng thời 2 phím Ctrl và F9, hoặc chọn menu Run,
mục Run.
Thực hiện chương trình trong TC++3.0
Giả sử TC++3.0 ñã ñược cài ñặt trong thư mục C:\TC++
Soạn thảo chương trình: Vào môi trường của TC++3.0 bằng cách khởi ñộng tệp
TC.EXE trong thư mục C:\TC++\BIN. Khi ñó sẽ nhận ñược menu chính của TC++3.0 gồm
các menu: File, Edit, Search, Run, Compile, Debug, Project, Option, Window và Help.
Chọn menu File, mục New ñể nhận cửa sổ soạn thảo. Dùng bàn phím ñể soạn thảo
chương trình trong cửa sổ này, sau ñó dùng phím F2 (hoặc chọn File - Save) ñể ghi chương
trình lên tệp.
Dịch và chạy chương trình: Bấm ñồng thời 2 phím Ctrl và F9, hoặc chọn menu Run,
mục Run.

BÀI TẬP CHƯƠNG 1


Bài 1. Thực hiện các chương trình viết trong mục 1.5 trên máy. ðối chiếu kết quả nêu trong
sách với kết quả nhận ñược.
Bài 2. Lập chương trình tính tích của 4 số thực ñược nạp từ bàn phím, sau ñó thực hiện
chương trình trên máy (dùng dấu * ñể biểu thị phép nhân).
Bài 3. Cho biết lương kỳ hai của cán bộ tính theo công thức:
bl * 540
lk2 = *n − t
26
trong ñó bl là bậc lương, n là số ngày công trong tháng, t là các khoản tiền ñã lĩnh ở kỳ một.
Lập chương trình nhập bl, n, lk1 từ bàn phím, sau ñó tính lk2 theo công thức trên. Thực hiện
chương trình trên máy với các số liệu cụ thể (dùng dấu / ñể biểu thị phép chia, ví dụ a/b =
a:b).

41
Giáo trình Tin học ðại cương

CHƯƠNG 2 - CÁC KIỂU DỮ LIỆU

Kiểu dữ liệu của một biến hay hằng là khái niệm chỉ dạng thông tin của biến hay hằng ñó.
Ví dụ biến có kiểu nguyên dùng ñể lưu các giá trị nguyên, biến kiểu thực dùng ñể lưu các giá
trị thực.

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


Trong chương này, chúng ta sẽ tìm hiểu một số kiểu dữ liệu cơ bản ñược ñịnh nghĩa
trong Turbo C, bao gồm kiểu nguyên và kiểu thực.

2.1.1 Các kiểu số nguyên


Tuỳ từng yêu cầu cụ thể mà chúng ta có thể sử dụng các kiểu số nguyên có phạm vi biểu
diễn khác nhau. Bảng sau chỉ ra các kiểu số nguyên và phạm vi biểu diễn tương ứng.
Kiểu Phạm vi biểu diễn Kích thước
char -128 → 127 1 byte
int -32768 → 32767 2 byte
long hoặc long int -2147483648→2147483647 4 byte
Tương ứng với các kiểu số nguyên có dấu là các kiểu số nguyên không dấu. Các kiểu số
nguyên không dấu ñược thành lập bằng cách thêm từ khoá unsigned vào trước kiểu số nguyên
có dấu tương ứng. Bảng sau chỉ ra các kiểu số nguyên không dấu:
Kiểu Phạm vi biểu diễn Kích thước
unsigned char 0 → 255 1 byte
unsigned int 0 → 65535 2 byte
unsigned long 0 → 4294967295 4 byte

2.1.2 Các kiểu số thực


Kiểu số thực, hay kiểu dấu phẩy ñộng dùng ñể lưu các giá trị thực. Trong C cho phép sử
dụng ba kiể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 (byte)


float 3.4E-38 → 3.4E+38 7-8 4
double 1.7E-308 → 1.7E+308 15-16 8
long double 3.4E-4932 → 1.1E4932 17-18 10
Giải thích: Máy có thể lưu trữ ñược số kiểu float có giá trị tuyệt ñối từ 3.4E-38 ñến
3.4E+38. Số có giá trị tuyệt ñối nhỏ hơn 3.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ự.

2.1.3 Biểu diễn các kiểu khác qua kiểu cơ bản


Kiểu ký tự

42
Giáo trình Tin học ðại cương

ðể biểu diễn các ký tự, người ta dùng một số nguyên lưu mã của ký tự ñó trong bảng mã.
Với bảng mã ASCII3, mỗi ký tự ñược biểu diễn bằng một số nguyên 8 bit.
Ví dụ:
Ký tự Mã ASCII
0 48
1 49
2 50
A 65
B 66
a 97
b 98
Bảng mã ASCII gồm 256 ký tự, có thể phân thành 3 nhóm:
- 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
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 các ký tự văn bản có mã từ 32 ñến 126. Các ký tự này có thể ñưa ra màn
hình và máy in.
- 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 ñược (bằng các lệnh DOS).
Kiểu ñúng sai
Trong TC quy ñịnh rằng, các biểu thức có giá trị khác 0 là ñúng và ngược lại các biểu
thức có giá trị bằng 0 là sai.

2.2 Hằng
Hằng là các ñại lượng mà giá trị của nó không thay ñổi trong quá trình tính toán. Dưới
ñây trình bày cách biểu diễn các hằng trong C.

2.2.1 Hằng số thực (float và double)


Hằng số thực (hằng có giá trị thực) hay gọi là Hằng dấu phẩy ñộng. Hằng dấu phẩy ñộng
ñược viết theo hai cách:
Cách 1 (dạng thập phân): Số gồm phần nguyên, dấu chấm thập phân và phần thập phân,
ví dụ:
214.35 -4563.48 234.0
Chú ý: Phần nguyên hoặc phần thập phân có thể vắng mặt nhưng dấu chấm không thể
thiếu, ví dụ cho phép viết:
.34 15.
Cách 2 (dạng khoa học hay dạng mũ): Số ñược tách thành 2 phần là ñịnh trị và phần bậc.
Phần ñịnh trị là một số nguyên hoặc số thực dạng thập phân, phần bậc là một số nguyên. Hai
phần này cách nhau bởi ký tự e hoặc E. Ví dụ:
123.456E-4 (biểu diễn giá trị 0.0123456)
0.12E3 (biểu diễn giá trị 120.0)

3
ASCII: American Standard Code for Interchange Information, bạn ñọc tham khảo bảng mã này ở phụ lục 1
43
Giáo trình Tin học ðại cương

-49.5e-2 (biểu diễn giá trị -0.495)


1e8 (biểu diễn giá trị 100000000.0)

2.2.2 Hằng số nguyên kiểu int


Là hằng số nguyên (hằng có giá trị nguyên) có giá trị trong khoảng từ -32768 ñến 32767.
Ví dụ:
-45 4007 635 ...
Chú ý: phân biệt 125 và 125.0. Số 125 là hằng nguyên còn 125.0 là hằng thực (dấu phảy
ñộng).

2.2.3 Hằng kiểu long


Hằng kiểu long ñược biểu diễn bằng cách thêm L hoặc l vào cuối giá trị nguyên.
Ví dụ:
-4893L hoặc -4893l
Một số nguyên vượt ra ngoài miền xác ñịnh của int cũng ñược xem là hằng kiểu long.
Ví dụ:
4563946L và 4563946 là hai hằng kiểu long có cùng giá trị.

2.2.4 Biểu diễn hằng nguyên trong hệ 8


Có thể biểu diễn các hằng số nguyên theo hệ cơ số 8 bằng cách ñặt số 0 ở ñầu, khi ñó các
chữ số phía sau phải nằm trong khoảng từ 0 ñến 7. Hằng nguyên hệ 8 luôn luôn nhận giá trị
dương.
Ví dụ:
0345
là một hằng nguyên hệ 8. Giá trị của nó trong hệ 10 là
3*8*8 + 4*8 + 5 = 229

2.2.5 Biểu diễn hằng nguyên trong hệ 16


Hệ cơ số 16 cần 16 ký tự ñể biểu diễn các chữ số, vì vậy ngoài các giá trị từ 0 ñến 9, còn
dùng các ký tự từ a (hoặc A) ñến f (hoặc F) ñể biểu diễn. Hằng biểu diễn trong hệ 16 bắt ñầu
bằng 0x hoặc 0X.
Ví dụ:
0xa9 , 0Xa9 , 0xA9, 0XA9
Các hằng trên cùng biểu diễn một giá trị, trong hệ 10 là:
10*16 + 9 = 169

2.2.6 Biểu diễn hằng nguyên dạng ký tự


Có thể biểu diễn một giá trị nguyên trong khoảng từ 0 ñến 255 bằng một ký tự ñặt trong
cặp dấu nháy ñơn, khi ñó giá trị của hằng bằng mã ASCII của ký tự ñó.
Ví dụ:
'9' tương ñương với 57

44
Giáo trình Tin học ðại cương

'a' tương ñương với 97


ðể biểu diễn một số hằng ñặc biệt, người ta dùng cách biểu diễn với dấu \. Bảng sau chỉ
ra cách biểu diễn một số hằng ñặc biệt:
Cách viết Ký tự
'\'' '
'\"' "
'\\' \
'\n' \n (chuyển dòng)
'\0' \0 (null)
'\t' Tab
'\b' Backspace
'\r' CR (về ñầu dòng)
'\f' LF (sang trang)

2.2.7 Hằng xâu ký tự


Hằng xâu ký tự dùng ñể biểu diễn một dãy các ký tự, trong ñó các ký tự ñược ñặt trong
hai dấu nháy kép, ví dụ:
"Ha noi"
"Hai phong"
"" /* xâu rỗng */
Xâu ký tự ñược lưu trữ trong máy dưới dạng một mảng có các phần tử là các ký tự riêng
biệt. Trình biên dịch tự ñộng thêm ký tự \0 vào cuối mỗi xâu (ký tự \0 ñược xem là dấu hiệu
kết thúc của một xâu ký tự).
Chú ý: Cần phân biệt 'a' và "a", 'a' là hằng nguyên ñược lưu trữ trong một byte, còn "a"
là hằng xâu ký tự ñược lưu trữ trong một mảng hai phần tử: phần tử thứ nhất chứa mã chữ a
còn phần tử thứ hai chứa \0.

2.2.8 ðặt tên cho hằng


Một số hằng có ý nghĩa ñịnh trước, ví dụ số pi. Trong trường hợp này, chúng ta có thể ñặt
cho hằng ñó một cái tên, và thay vì viết trực tiếp hằng thì ta dùng tên của hằng trong các biểu
thức. ðể ñặt tên cho hằng, dùng chỉ thị #define.
Ví dụ:
#define MAX 1000
#define PI 3.141593
Khi ñã ñặt tên cho các hằng, chúng ta có thể sử dụng chúng trong các biểu thức, ví dụ:
float r, s;
r = 5.0f;
s = PI*r*r;

2.3 Biến
2.3.1. Khai báo
Như ñã ñề cập ở 1.4.1, biến là ñại lượng dùng ñể lưu trữ các giá trị trong quá trình tính
toán, giá trị của nó có thể ñược thay ñổi trong quá trình chương trình thực hiện. Tên biến là
tên một vùng nhớ trên RAM ñể lưu trữ dữ liệu. Mọi biến cần phải khai báo trước khi sử dụng.
Việc khai báo biến ñược thực hiện theo mẫu sau:

45
Giáo trình Tin học ðại cương

<kiểu dữ liệu> <danh_sách_tên_biến>;


Tên các biến ñược ñặt theo quy tắc ñặt tên của TC ñược nêu trong 1.3, các biến trong
danh sách ñược phân biệt nhau bởi dấu phẩy “,”. Kiểu dữ liệu là các kiểu ñã nêu trong 2.1,
hoặc các kiểu do người lập trình tạo ra trước khi khai báo biến.

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


Các khai báo cần ñặt ngay sau dấu { ñầu tiên của thân hàm hoặc của khối lệnh và cần
ñứng trước mọi câu lệnh khác. Như vậy, sau một câu lệnh gán chẳng hạn thì không ñược khai
báo nữa . Sau ñây là một ví dụ sai về vị trí của khai báo
#include <stdio.h>
void main ()
{
int a;
a = 35;
int d; /* Vị trí của khai báo sai */
d = a * 2;
printf(“%d”, d);
}

2.3.3 Việc khởi ñầu cho các biến


Nếu trong khai báo, ngay 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 một biến.
Ví dụ:
int a, b = 20, c ,d = 40;
float e = -35.1, x = 23.0, y, z, t = 36.1;
Tất nhiên ñiều này có thể ñạt ñược nhờ toán tử gán, và về thực tế hai cách này là tương
ñương. Vậy ñể ñạt ñược ý ñịnh như ví dụ trên ta có thể dùng các câu lệnh:
int a, b, c, d;
float e, x, y, z ,t;
b = 20; d = 40; e = -35.1; x = 23.0; t = 36.1;

2.3.4 Cấp phát bộ nhớ cho biến


Khi thực hiện chương trình, nếu máy gặp một khai báo biến nó sẽ thực hiện việc cấp phát
bộ nhớ cho biến gồm một số byte liên tiếp nhau tùy thuộc vào kiểu dữ liệu của biến. Ví dụ
như biến kiểu int ñược cấp phát hai byte bộ nhớ, biến kiểu float ñược cấp phát 4 byte bộ
nhớ….

2.3.5 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ỉ biến dùng trong một số hàm, như hàm scanf. ðể nhận ñịa
chỉ biến ta dùng phép toán:
& tên_biến

2.4 Mảng
2.4.1 Khái niệm về mảng, cách khai báo
Mỗi biến chỉ có thể chứa một giá trị. ðể chứa một dẫy số hay một bảng số ta có thể dùng
nhiều biến nhưng cách này không tiện lợi. Việc sử dụng mảng là cách tốt hơn nhiều trong
những trường hợp như vậy .

46
Giáo trình Tin học ðại cương

Mảng có thể hiểu là một tập hợp nhiều phần tử có cùng một kiểu giá trị và có chung một
tên. Mỗi phần tử mảng có vai trò như một biến và chứa ñược một giá trị. Có bao nhiêu kiểu
biến thì cũng có bấy nhiêu kiểu mảng. Mảng cần ñược khai báo ñể ñịnh rõ:
- Kiểu mảng (int, float double,... )
- Tên mảng
- Số chiều và kích thước mỗi chiều.
Khái niệm về kiểu mảng và tên mảng cũng giống như khái niệm kiểu biến và tên biến,
ñiều này ñã nói ở các mục trên. Ta sẽ giải thích khái niệm số chiều và kích thước mỗi chiều
thông qua các ví dụ sau. Các khai báo:
int a[10], b[4][2];
float x[5], y[3][3];
sẽ xác ñịnh 4 mảng: a, b, x và y. Ý nghĩa của chúng như sau:
- ðối với mảng thứ nhất thì kiểu là int, tên là a, số chiều là một, kích thước bằng
10. Mảng có 10 phần tử ñược ñánh số như sau:
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
Mỗi phần tử a[i] chứa ñược một giá trị kiểu int và mảng a có thể biểu diễn ñược một
dãy 10 số nguyên.
- ðối với mảng thứ hai thì kiểu là int, tên là b, số chiều là 2. Kích thước của các
chiều là 4 và 2. Mảng có 8 phần tử, chúng ñược ñánh số và ñược sắp xếp như sau:
b[0][0] b[0][1]
b[1][0] b[1][1]
b[2][0] b[2][1]
b[3][0] b[3][1]
Mỗi phần tử b[i][j] chứa ñược một giá trị kiểu int và mảng b có thể biểu diễn ñược
một bảng số nguyên 4 dòng, 2 cột.
- ðối với mảng thứ ba thì kiểu là float, tên là x, số chiều là một, kích thước bằng 5.
Mảng có 5 phần tử ñược ñánh số như sau:
x[0], x[1], x[2], x[3], x[4]
Mỗi phần tử x[i] chứa ñược một giá trị kiểu float và mảng x có thể biểu diễn ñược
một dãy 5 số thực.
- ðối với mảng thứ 4 thì kiểu là float, tên là y, số chiều là 2, kích thước của mỗi
chiều là 3. Mảng có 9 phần tử, chúng ñược ñánh số và ñược sắp xếp như sau:
y[0][0] y[0][1] y[0][2]
y[1][0] y[1][1] y[1][2]
y[2][0] y[2][1] y[2][2]
Mỗi phần tử y[i][j] chứa ñược một giá trị kiểu float, và mảng y có thể biểu diễn
ñược một bảng số thực 3 dòng, 3 cột.
Chú ý:
- Các phần tử của mảng ñược cấp phát các khoảng nhớ liên tiếp nhau trong bộ nhớ.
Nói cách khác, các phần tử mảng có ñịa chỉ liên tiếp nhau.
- Trong bộ nhớ, các phần tử của mảng hai chiều ñược sắp xếp theo hàng.

2.4.2 Chỉ số mảng

47
Giáo trình Tin học ðại cương

Một phần tử cụ thể của mảng ñược xác ñịnh nhờ các chỉ số của nó. Chỉ số của mảng phải
có giá trị int không vượt quá kích thước của chiều tương ứng. Số chỉ số phải bằng số chiều
của mảng.
Giả sử a, b, x, y ñã ñược khai báo như trên và giả sử i, j là các biến nguyên trong ñó i=2,
j=1. Khi ñó:
a[j+i-1] là a[2]
b[j+i][2-i] là b[3][0]
x[j/i] là x[0]
y[i][j] là y[2][1]
Các cách viết sau là sai:
y[j] vì y là mảng hai chiều, cần hai chỉ số
b[i][j][1] vì b là mảng hai chiều, chỉ cần hai chỉ số

2.4.3 Lấy ñịa chỉ phần tử mảng


Dưới ñây khi nói mảng ta hiểu là mảng một chiều. Mảng có từ hai chiều trở lên ta nói
mảng kèm số chiều (ví dụ mảng hai chiều, ...). Có một vài hạn chế trên các mảng nhiều chiều.
Chẳng hạn có thể lấy ñịa chỉ phần tử mảng một chiều, nhưng nói chung không cho phép lấy
ñịa chỉ phần tử mảng nhiều chiều. Như vậy máy sẽ chấp nhận phép tính:
&a[i]
nhưng không chấp nhận phép tính
&y[i][j]

2.5 Các phép toán trên các kiểu


2.5.1 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 ñó. Khi viết biểu thức có thể và nên dùng các dấu ngoặc tròn ñể thể hiện
ñúng trình tự tính toán trong biểu thức. Mỗi biểu thức sẽ có một giá trị. Hằng, biến, phần tử
mảng và hàm cũng ñược xem là biểu thức. Trong C ñưa ra nhiều quan niệm mới về biểu thức
như 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 không) và sai (giá trị bằng 0).

2.5.2 Phép toán số học


Các phép toán hai ngôi số học là:
Phép toán Ý nghĩa Ví dụ
+ Cộng a+b
- Trừ a-b
* Nhân a*b
/ Chia a/b
% Lấy phần dư a%b
Có phép toán một ngôi - ví dụ -(a+b) nhưng không có phép +.
Phép chia hai số nguyên sẽ chặt cắt phần thập phân (kết quả của phép chia 2 số nguyên là
một số nguyên; số nguyên ñó là phần nguyên của thương số), ví dụ:
11/3 = 3

48
Giáo trình Tin học ðại cương

Phép toán % cho phần dư của phép chia nguyên, nó không áp dụng ñược cho các giá trị
kiểu float và double. Ví dụ:
11%3 = 2
Các phép toán + và - có cùng số ưu tiên, và nhỏ hơn số ưu tiên của * / và %. Ba phép
toán này lại có số 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.
Các phép toán số học dùng ñể viết các công thức toán học, ví dụ:
(a*a-b*b)/(x*x+y*y)

2.5.3 Các phép toán so sánh


Phép toán so sánh cho ta hoặc giá trị 1 (ñúng) hoặc giá trị 0 (sai). 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, trong trường hợp trái lại, ta nhận ñược giá trị 0.
Các phép toán so sánh cho trong bảng sau:
Phép toán ý nghĩa Ví dụ
> Có lớn hơn không ? a>b
3>7 có giá trị 0
>= Có lớn hơn hay a>=b
bằng không ? 8>=8 có giá trị 1
< Có nhỏ hơn không? a<b
9<9 có giá trị 0
<= Có nhỏ hơn hay a<=b
bằng không ? 3<=10 có giá trị 1
== Có bằng nhau không? a==b
3==9 có giá trị 0
!= Có khác nhau không a!=b
3!=9 có giá trị 1
Bốn phép ñầ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ự ưu tiên của bốn phép ñầu.
Các phép so sánh có số ư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).
Nói chung, nên dùng các dấu ngoặc ñể tránh những lỗi do ñộ ưu tiên phép toán gây nên.

2.5.4 Phép toán logic


Cũng giống như các phép toán so sánh, các phép toán logic cho ta giá trị 1 (ñúng) hoặc
giá trị 0 (sai).Trong C sử dụng ba phép toán logic:
- Phép Phủ ñịnh !
- Phép Và (AND) &&
- Phép Hoặc (OR) ||
Ý nghĩa của chúng ñược cho trong các bảng:
A !a a b a&&b a||b
Khác không 0 Khác không Khác không 1 1
Bằng không 1 Khác không Bằng không 0 1
Bằng không Khác không 0 1
Bằng không Bằng không 0 0
49
Giáo trình Tin học ðại cương

Trong ñó a và b có thể nguyên hay thực.


Ví dụ:
3>7 có giá trị 0
7>3 có giá trị 1
3 && 7 có giá trị 1
! 15.6 có giá trị 0
Các phép toán so sánh và logic ñược dùng ñể thiết lập ñiều kiện rẽ nhánh trong toán tử if
và ñiều kiện kết thúc chu trình trong các toán tử for, while và do while. Ở chương 3 sẽ có rất
nhiều ví dụ về việc sử dụng các phép toán này

2.5.5 Chuyển kiểu


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 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 kia. ð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
(chương 4), trong câu lệnh return (chương 4).
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
ép kiểu:
(<Kiểu dữ liệu>) (<biểu thức>)
Ví dụ:
(float)(a+b)

2.5.6 Cá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
++ sẽ cộng 1 vào toán hạng của nó, toán tử giảm -- sẽ trừ ñi 1. Chẳng hạn nếu n ñang có giá
trị bằng 5 thì:
Sau phép tính ++n, n có giá trị 6
Sau phép tính --n, n có giá trị 4
Dấu phép toán ++ và -- có thể ñứng trước hoặc sau toán hạng, như vậy có thể viết:
++n n++ --n n--
Sự khác nhau của ++n và n++ ở chỗ: Trong phép n++ thì n 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 nó ñược sử dụng. Sự khác nhau
giữa --n và n-- cũng như vậy.
Ví dụ: Nếu n bằng 5 thì câu lệnh
x = n++;
sẽ gán 5 cho x, còn câu lệnh
x = ++n;
sẽ gán 6 cho x. Trong cả hai trường hợp n ñều trở thành 6.
Việc chọn phương án này hay phương án khác là tùy thuộc ngữ cảnh. Phép toán tăng
giảm thường ñược sử dụng trong các toán tử for, while,... ñể tăng hay giảm giá trị cho các
biến ñiều khiển. Rất nhiều ví dụ như vậy có thể tìm thấy trong các chương sau.
50
Giáo trình Tin học ðại cương

Cuối cùng, một ñiều cần lưu ý là không nên sử dụng toán tử tăng giảm quá tùy tiện trong
các biểu thức, vì việc ñó có thể dẫn ñến các kết quả sai.

2.5.7 Biểu thức ñiều kiện


Biểu thức ñiều kiện là biểu thức có dạng:
<biểu thức kiểm tra> ? <biểu thức 1> : <biểu thức 2>
Giá trị của biểu thức ñiều kiện bằng giá trị của biểu thức 1 nếu biểu thức kiểm tra ñúng
(khác không) và bằng giá trị của biểu thức 2 nếu biểu thức kiểm tra sai (bằng không).
Ví dụ:
printf("\n %8.2f", a < b ? a : b);
ñưa ra giá trị nhỏ nhất của hai biến thực a và b.

2.5.8 Câu lệnh gán và biểu thức gán


Biểu thức gán là biểu thức có dạng:
<biến> = <biểu thức>
Vế trái của biểu thức là một biến (hay phần tử mảng), vế phải là một biểu thức. Giá trị
của biểu thức gán là giá trị ñược gán. Nếu ñặt dấu ; vào sau biểu thức gán thì ta ñược lệnh
gán:
<biến> = <biểu thức>;
Biểu thức gán có thể sử dụng trong các phép toán và các câu lệnh như các biểu thức khác.
Ví dụ, khi viết
a = b = 5;

thì ñiều ñó có nghĩa là gán giá trị của biểu thức b = 5 cho biến a. Kết qủa là b=5 và a=5.
Một số dạng khác của toán tử gán.
Trong trường hợp các biểu thức gán có dạng như:
i = i+2;
trong ñó vế trái ñược lặp lại có thể viết gọn hơn như sau:
i += 2;
Các biểu thức gán này có dạng:
<biến> <phép toán> = <biểu thức>;
Trong ñó <phép toán> là một phép toán hai ngôi.
Ví dụ câu lệnh:
x = x*(y+3);
có thể viết thành:
x *= y+3;

2.5.9 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 là trong cùng một biểu thứ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.

51
Giáo trình Tin học ðại cương

STT 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 * / % 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 ?: Phải qua trái
10 = += -= *= /= %= <<= >>= &= ^= |= Phải qua trái
11 , Trái qua phải

Giải thích:
- Các phép toán trê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 phép toán ở 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. ðiều này chỉ ra trong cột "Trình tự kết hợp".
- ðể viết biểu thức một cách chính xác nên sử dụng các dấu ngoặc tròn (ngoặc ñơn).

2.6 Nhập xuất dữ liệu


Nhập xuất dữ liệu là cách chúng ta ñưa dữ liệu vào chương trình và ñưa ra kết quả của
chương trình. Thông thường, dữ liệu ñược ñưa vào thông qua bàn phím và kết quả ñược ñưa
ra màn hình.

2.6.1 ðưa kết quả ra màn hình


Có thể ñưa ra màn hình một dòng chữ, hoặc các giá trị số bằng lệnh printf. Lệnh printf có
dạng:
printf (<chuỗi ñiều khiển>, bt1, bt2, ..., btn);
Ở ñây bt1, bt2,..., btn là các biểu thức mà giá trị của chúng cần ñược ñưa ra màn hình.
Trong chuỗi ñiều khiển, có thể chứa:
- Ký tự ñiều khiển.
- Các ký tự hiển thị.
- Các ký tự dùng ñể mô tả kiểu cách ñưa ra của các biến, ta sẽ gọi chúng là các ñặc
tả.
Một số ký tự ñiều khiển ñược ñịnh nghĩa trước, thường có dấu \ phía trước, ví dụ ký tự
ñiều khiển xuống dòng là \n, ký tự tab là \t.
Các ký tự hiển thị sẽ ñược ñưa ra giống như khi chúng xuất hiện ở trong chuỗi ñiều
khiển.
Các ñặc tả sẽ chỉ ra cách mà giá trị của các biểu thức sẽ ñược ñưa ra. Mỗi biểu thức cần
phải có một ñặc tả tương ứng. Khi in ra màn hình, giá trị của các biểu thức sẽ ñược thay thế
tương ứng vào vị trí các ñặc tả.
Sau ñây là một số dạng thường dùng của câu lệnh printf.
ðưa ra một thông báo
52
Giáo trình Tin học ðại cương

ðôi khi chúng ta chỉ muốn ñưa ra một thông báo, một câu hướng dẫn, khi ñó chỉ cần ñưa
vào chuỗi ñiều khiển không chứa các ñặc tả. Nội dung của xâu sẽ ñược ñưa ra màn hình.
Ví dụ, ñể ñưa ra một thông báo nhắc người dùng nhập vào hệ số của ña thức, có thể dùng
lệnh:
printf(“\nNhap he so da thuc: ”);
Khi ñó trên màn hình sẽ xuất hiện:
Nhap he so da thuc:
ðưa ra các giá trị nguyên
Khi muốn ñưa ra các kết quả là các giá trị nguyên, chúng ta dùng ñặc tả %d. Sau ñây
chúng ta sẽ xét một số ví dụ ñể có thể hiểu ñược hoạt ñộng của ñặc tả này.
Ví dụ, ñoạn mã sau ñưa ra tổng của hai số nguyên:
int a, b;
a = 10;
b = 25;
printf(“Tong cua %d va %d la %d”, a, b, a + b);
Câu lệnh printf sẽ thay thế các ñặc tả %d bằng giá trị các biểu thức tương ứng theo thứ tự
ñưa vào. Trong ñoạn mã trên, giá trị của a, b và a + b sẽ lần lượt ñược thay thế vào các vị trí
%d trong chuỗi ñiều khiển, kết quả ñưa ra màn hình như sau:
Tong cua 10 va 25 la 35
Trong ví dụ trên, giá trị của các biểu thức có bao nhiêu chữ số thì bấy nhiêu vị trí trên
màn hình ñược sử dụng ñể in giá trị, ví dụ giá trị 10 cần hai vị trí thì máy sẽ dành ñúng hai vị
trí ñể in ra giá trị 10.
Tuy nhiên, trong một số trường hợp, như in ra các giá trị của một ma trận, hoặc in các giá
trị theo dạng cột, thì chúng ta cần dành một số vị trí nhất ñịnh cho một giá trị, mặc dù số vị trí
cần thiết ñể in ra giá trị ñó có thể nhỏ hơn.
Ví dụ, ñoạn chương trình sau in ra giá trị các luỹ thừa của 2 theo dạng cột:
#include <stdio.h>
void main()
{
int i, a;
a = 1;
for (i = 1; i <= 10; i++)
{
a*= 2;
printf("2 ^ %2d = %4d\n", i, a);
}
}
Kết quả ñưa ra như sau:
2 ^ 1 = 2
2 ^ 2 = 4
2 ^ 3 = 8
2 ^ 4 = 16
2 ^ 5 = 32
2 ^ 6 = 64
2 ^ 7 = 128
2 ^ 8 = 256
2 ^ 9 = 512
2 ^ 10 = 1024

53
Giáo trình Tin học ðại cương

Trong ví dụ trên, ta ñã dành 2 vị trí cho việc in số mũ và dành 4 vị trí ñể in ra các luỹ
thừa, bất kể các giá trị này bằng bao nhiêu. Trường hợp giá trị cần in ra có số chữ số lớn hơn
4 vị trí, máy sẽ chuẩn bị số vị trị vừa ñủ cho giá trị ñó.
ðưa ra các giá trị thực
ðể ñưa ra các giá trị thực, chúng ta dùng ñặc tả %f. Ví dụ sau tính diện tích của một hình
tròn và ñưa kết quả ra màn hình.
#include <stdio.h>
void main()
{
float r;
r = 2.34f;
printf("Dien tich hinh tron ban kinh %f la %f\n", r, 3.14*r*r);
}
Kết quả in ra là:
Dien tich hinh tron ban kinh 2.340000 la 17.193383
Tuy nhiên, ñôi khi ta không cần kết quả gồm nhiều chữ số thập phân như thế, mà chỉ cần
lấy một số lượng chữ số sau dấu phảy nhất ñịnh.
Câu lệnh printf sau sẽ thay thế cho câu lệnh printf trong ñoạn mã trên ñể ñưa ra các kết
quả lấy hai chữ số sau dấu phảy, và dành 6 ký tự cho việc in ra mỗi giá trị.
printf("Dien tich hinh tron ban kinh %6.2f la %6.2f\n",
r, 3.14*r*r);
Kết quả là:
Dien tich hinh tron ban kinh 2.34 la 17.19
Một trường hợp nữa là chúng ta vẫn muốn lấy một số lượng chữ số sau dấu phẩy nhất
ñịnh, nhưng không có ý ñịnh dành sẵn một số vị trí xác ñịnh, khi ñó trong ñặc tả có thể vắng
mặt số phía trước dấu chấm.
Sau ñây là câu lệnh printf thường dùng nhất cho các bài dạng trên:
printf("Dien tich hinh tron ban kinh %.2f la %.2f\n",
r, 3.14*r*r);
Kết quả là:
Dien tich hinh tron ban kinh 2.34 la 17.19
ðưa ra các xâu ký tự
Khi muốn ñưa ra các giá trị là các xâu ký tự, ví dụ như họ và tên hay ñịa chỉ, dùng ñặc tả
%s.
Ví dụ sau yêu cầu nhập vào tên và in ra lời chào.
#include <stdio.h>
void main()
{
char szHoTen[100];
printf("Nhap ten ban: ");
fflush(stdin);
gets(szHoTen);
printf("Xin chao %s", szHoTen);
}
Khi chạy, nhập vào một tên và máy sẽ in ra lời chào tương ứng.
Nhap ten ban: Minh Quang
Xin chao Minh Quang
54
Giáo trình Tin học ðại cương

Với ñặc tả %s, ta cũng có thể dành sẵn ñộ rộng cho giá trị in ra, sử dụng trong các trường
hợp như in họ tên theo cột. Việc chỉ ñịnh ñộ rộng giống như ñối với trường hợp số nguyên.

2.6.2 Nhập dữ liệu từ bàn phím


Nhập dữ liệu từ bàn phím là một cách thông dụng ñể nạp giá trị cho các biến hoặc mảng.
Trong phần này, chúng ta sẽ tìm hiểu cách nhập liệu cho các biến nguyên, biến thực và xâu ký
t ự.
Nhập số nguyên, số thực bằng scanf
Câu lệnh scanf có thể dùng ñể nhập dữ liệu cho các biến nguyên, thực. Một cách tổng
quát câu lệnh scanf có dạng:
scanf("t1t2...tk", &b1,&b2,...,&bk);
Trong ñó b1, b2,..., bk là các biến (kiểu int và kiểu float) còn t1, t2,..., tk là các ñặc tả
tương ứng. Dùng ñặc tả %d ñối với biến nguyên và %f ñối với biến thực.
Một vài chú ý:
- Trong câu lệnh scanf, không dùng tên biến như trong câu lệnh printf mà dùng ñịa
chỉ của biến bằng cách ñặt phép toán & trước tên biến.
- Mỗi biến ứng với một ñặc tả. Như vậy số ñặc tả bằng số biến.
- Trong chuỗi ñiều khiển chỉ nên chứa các ñặc tả và các ñặc tả nên viết liền nhau.
Ví dụ, ñể vào 3 giá trị: 25, -137, 45.3 cho hai biến nguyên m, n và một biến thực f, dùng
lệnh:
scanf(“%d%d%f”, &n, &m, &f);
Khi gặp câu lệnh này, máy sẽ dừng ñể ñợi thao tác viên vào số liệu từ bàn phím. Các giá
trị cần ñược phân cách nhau bởi một hoặc vài khoảng trắng (ở ñây khoảng trắng ñược hiểu là
dấu cách hoặc dấu xuống dòng).
Thao tác viên có thể sử dụng một trong các cách bấm phím sau:
Cách 1: Mỗi giá trị trên một dòng, bằng cách nhấn phím Enter sau mỗi số.
25
-137
45.3
Cách 2: ðặt cả 3 giá trị trên một dòng, cách nhau bằng các dấu cách.
25 -137 45.3
Sau khi nhập xong, n nhận giá trị 25, m nhận giá trị -137 và f nhận giá trị 45.3.
Nhập xâu ký tự bằng gets
ðể nhập xâu ký tự, có thể dùng lệnh gets. Lệnh gets có dạng:
gets(<xâu ký tự>)
Ở ñây, xâu ký tự là một mảng kiểu char.
Chú ý: Nếu trước lệnh gets mà có các lệnh scanf, thì có thể không nhập ñược xâu do ký
tự return còn ở trong bộ ñệm. Vì vậy ñể sử dụng ñúng ñắn câu lệnh gets, nên thêm lệnh
fflush(stdin) trước lệnh gets trong mọi trường hợp, ñể làm sạch bộ ñệm (xóa hết các ký tự còn
trong ñó) trước khi ñưa (nhập) giá trị mới.

55
Giáo trình Tin học ðại cương

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


ðộc giả xem chi tiết danh mục các hàm trong phụ lục 2 của bài giảng. Tại ñây chúng tôi
chỉ trích giới thiệu một số ít các hàm thường dùng.

2.7.1 Hàm toán học


Các hàm thuộc thư viện math.h hoặc trong stdlib.h
1. abs – Tính giá trị tuyệt ñối của số nguyên x
int abs(int x);
2. labs-Tính giá trị tuyệt ñối của số nguyên dài x
long int labs(long int x)
3. cos – Tính cosine của x
double cos(double x)
4. exp – Tính e mũ x
double exp(double x)
5. fabs-Tính giá trị tuyệt ñối của x
double fabs(double x)
6. log – Tính logarit cơ số tự nhiên của x
double log(double x)
7.log10 - Tính logarit cơ số10 của x
double log10(double x)
8. pow – Tính x mũ y
double pow(double x, double y)
9. sin – Tính sine của x
double sin(double x)
10. sqrt – Tính căn bậc hai của x
double sqrt(double x)

2.7.2 Hàm xử lý chuỗi ký tự


Các hàm khai báo trong string.h
1. strcmp: so sánh 2 chuỗi s1, s2 phân biệt chữ thường và chữ hoa
int strcmp(char * s1, char *s2)
hàm này trả về 1 số nguyên là ñộ lệch giữa ký tự ñầu tiên của 2 chuỗi. Nếu hàm trả về
giá trị 0 thì 2 chuỗi s1 và s2 là giống nhau.
2. strcmpi: so sánh 2 chuỗi không phân biệt chữ thường và chữ hoa
int strcmpi(char *s1, char *s2)
hàm này hoạt ñộng giống hàm strcmp nhưng không phân biệt chữ thường và chữ hoa
3. strcpy : sao chép chuỗi
int strcpy(char *dest, char *sour)
4. stricmp: giống hàm strcmpi
5. strlen: tính ñộ dài của chuỗi
int strlen(char *s)
hàm này trả về số nguyên là số ký tự của chuỗi s (ñộ dài của s)
6. strrev: ñảo ngược 1 chuỗi
char * strrev( char *s)
hàm này trả về chuỗi ñảo của chuỗi s
Các hàm strcmpi và strcpy sẽ ñược dùng trong các bài tập ở chương 6 mục 6.6

56
Giáo trình Tin học ðại cương

BÀI TẬP CHƯƠNG 2


Bài 1. Tìm các chỗ sai trong chương trình sau
#include "stdio.h"
void main()
{
printf("\na=%10.0f, b=%10d, c=%10ld, d=%10d",
-3456, 25e3, 4635, 456398461);
}
Sửa lại cho ñúng rồi thực hiện trên máy.
Bài 2. Viết chương trình in một dòng với nội dung sau:
N = 365
Bằng cách sử dụng các loại hằng khác nhau (hằng số dấu phẩy ñộng, hằng int, hằng long,
hằng int hệ 8, hằng int hệ 16, hằng kí tự, hằng xâu kí tự).
Bài 3. Tìm các chỗ sai trong ñoạn chương trình
float a[3], b = 2;
a[0] = 5;
a[10] = 4, a[b] = 7;
Bài 4. Tìm các chỗ sai trong ñoạn chương trình
{
int a = 6;
float b=5.3;
{
float x = a*b, y=a+b;
}
printf("\na=%10.2f, b=%10.2f, x=%10.2f,
y=%10.2f ", a, b, x, y);
}
Sửa chữa bổ sung ñể ñược một chương trình hoàn chỉnh sau ñó thực hiện trên máy.

57
Giáo trình Tin học ðại cương

CHƯƠNG 3 - CÁC LỆNH ðIỀU KHIỂN

Một chương trình bao gồm nhiều câu lệnh. Thông thường các câu lệnh ñược thực hiện
một cách lần lượt theo thứ tự mà chúng ñược viết ra. Các lệnh ñiều khiển cho phép thay ñổi
trật tự nói trên, do ñó máy có thể ñang từ một câu lệnh này nhảy tới thực hiện một câu lệnh
khác ở trước hoặc sau nó. ðường ñi của máy trở nên linh hoạt hơn và nhờ vậy ta có thể viết
chương trình một cách hiệu quả hơn. Xét về mặt công dụng có thể chia các lệnh ñiều khiển
thành ba nhóm chính:
- Nhảy không ñiều kiện (goto)
- Rẽ nhánh (if, switch )
- Tổ chức chu trình (for, while,do while)
Ngoài ra còn có một số lệnh khác có chức năng bổ trợ như break, continue.
Chương này sẽ giới thiệu cách viết và các nguyên tắc hoạt ñộng của một số lệnh nêu trên.
Chúng ta sẽ thấy các lệnh ñiều khiển của C có những khả năng làm việc rất linh hoạt, phong
phú và mạnh mẽ. Tất cả những ñiều này ñược giải thích tỉ mỉ và ñược minh họa rõ ràng trên
nhiều chương trình hoàn chỉnh ñã thử nghiệm trên máy.

3.1 Nhắc lại khái niệm về câu lệnh và khối lệnh


Trong C mỗi câu lệnh có thể viết trên một hoặc nhiều dòng và ñược kết thúc bằng dấu
chấm phảy. Khái niệm về khối lệnh hay câu lệnh hợp thành ñã trình bày ở mục 1.4.4, ở ñây ta
chỉ nhắc lại vài ñiều.
- Khối lệnh là một dãy các câu lệnh ñặt trong các dấu { }.
- Không ñược ñặt dấu chấm phảy sau dấu ngoặc nhọn kết thúc khối.
- Khối lệnh tương ñương với câu lệnh riêng lẻ về mặt cú pháp. Nói cách khác, chỗ
nào ñặt ñược một câu lệnh thì ở chỗ ñó ta cũng có quyền viết một khối lệnh.
- Khi khối lệnh chỉ gồm một câu lệnh thì có thể bỏ các dấu ngoặc nhọn ñầu và cuối.
Nói cách khác có thể xem câu lệnh là trường hợp riêng của khối lệnh.
Dưới ñây khi trình bày các lệnh ñiều khiển như if, for, while, ..., ta dùng thuật ngữ "khối
lệnh", nhưng mọi ñiều vẫn ñúng nếu ta dùng "câu lệnh" (vì câu lệnh xem như trường hợp
riêng của khối lệnh).

3.2. Lệnh if
Lệnh if cho phép lựa chọn ñể thực hiện một trong hai nhánh tùy thuộc vào ñiều kiện ñúng
(khác không) hay sai (bằng không) của một biểu thức, gọi là biểu thức ñiều kiện. Mỗi nhánh
của lệnh if là một khối lệnh khác nhau.

3.2.1 Cú pháp của if


Lệnh if có hai dạng sau:
Dạng 1
if (<biểu thức ñiều kiện>)
<khối lệnh>
Dạng 2
if (<biểu thức ñiều kiện>)

58
Giáo trình Tin học ðại cương

<khối lệnh 1>


else
<khối lệnh 2>
Trong cú pháp trên, biểu thức ñiều kiện có thể là một biểu thức bất kỳ. Các khối lệnh có
thể là một câu lệnh ñơn, khi ñó kết thúc câu lệnh phải có dấu chấm phẩy.
Lệnh if dạng 1 dùng khi cần kiểm tra ñiều kiện xem có hay không thực hiện một khối
lệnh nào ñó.
Lệnh if dạng 2 dùng khi muốn lựa chọn một trong hai khối lệnh ñể thực hiện.

3.2.2 Hoạt ñộng của if


Sự hoạt ñộng của lệnh if dạng 1
Khi gặp câu lệnh này, máy sẽ tính giá trị của biểu thức. Nếu biểu thức ñúng thì máy thực
hiện khối lệnh và sau ñó thực hiện các lệnh tiếp theo. Nếu biểu thức sai thì máy bỏ qua khối
lệnh và chuyển ñến các lệnh viết sau nó.
Sự hoạt ñộng của lệnh if dạng 2
Trước tiên máy sẽ xác ñịnh giá trị của biểu thức. Nếu biểu thức ñúng máy sẽ thực hiện
khối lệnh 1, sau ñó nhảy tới các lệnh viết sau khối lệnh 2. Nếu biểu thức sai thì máy sẽ không
thực hiện khối lệnh 1 mà chỉ thực hiện khối lệnh 2 và sau ñó thực hiện các lệnh viết sau nó.
Ví dụ sau minh hoạ cho hoạt ñộng của câu lệnh if. ðể tính giá trị lớn nhất của hai biến a
và b ta có thể sử dụng hai chương trình ứng với hai dạng khác nhau của lệnh if.
/* Chuong trinh tinh max cua hai so thuc, dung if dang 1 */
#include <stdio.h>
void main()
{
float a,b,max;
printf("\nVao hai so a va b: ");
scanf("%f%f", &a, &b);/*gia tri cua a va b nhan tu ban phim*/
max = a;
if (b > max)
max = b;
printf("\na = %8.2f\nb = %8.2f\nmax = %8.2f", a, b, max );
}

/* Chuong trinh tinh max cua hai so thuc, dung if dang 2 */


#include <stdio.h>
void main()
{
float a,b,max;
printf("\nVao hai so a va b: ");
scanf("%f%f",&a,&b);/*gia tri cua a va b nhan tu ban phim */
if (a > b)
max = a;
else
max = b;
printf("\na = %8.2f\n b = %8.2f\n max = %8.2f", a, b, max);
}

3.2.3 Sự lồng nhau của lệnh if


Các lệnh if có thể lồng nhau. ðiều ñó có nghĩa là: các khối lệnh 1 và khối lệnh 2 (xem
dạng 1 và dạng 2) lại có thể chứa các lệnh if khác.

59
Giáo trình Tin học ðại cương

Trong trường hợp có nhiều if và else, thì một vấn ñề quan trọng là chúng ta phải xác ñịnh
ñược mệnh ñề else nào thuộc if nào. Có một nguyên tắc ñể xác ñịnh, ñó là: mệnh ñề else sẽ
ñược gắn với if gần nhất trước nó.
Tuy nhiên, ñể tránh nhầm lẫn, nên dùng cặp ngoặc {}.
Sau ñây là ví dụ giải phương trình bậc nhất ax + b = 0 sử dụng if lồng nhau.
#include <stdio.h>
void main()
{
float a, b;
printf("Nhap a, b: ");
scanf("%f%f", &a, &b);

if (a == 0)
if (b == 0)
printf("Vo so nghiem.");
else
printf("Vo nghiem.");
else
printf("x = %f", -b/a);
}
ðể lựa chọn một trong nhiều trường hợp, ta có thể dùng lệnh if lồng nhau. Ví dụ, với
chương trình giải phương trình bậc 2, giá trị của delta có thể rơi vào các trường hợp: lớn hơn
0, bằng 0 và nhỏ hơn 0.
Với các trường hợp này, câu lệnh if – else viết có phần hơi khác bình thường, bằng cách
ñặt câu lệnh if con nằm cùng hàng với else trước ñó.
Sau ñây là ví dụ giải phương trình bậc 2 sử dụng if lồng nhau.
#include <stdio.h>
#include <math.h>
void main()
{
float a, b, c, delta;
printf("Nhap a, b, c: ");
scanf("%f%f%f", &a, &b, &c);
delta = b*b - 4*a*c;

if (delta < 0)
printf("Vo nghiem.");
else if (delta == 0)
printf("x = %f", -b/(2*a));
else //if (delta > 0)
printf("x1 = %f\nx2 = %f",
(-b - sqrt(delta))/(2*a),
(-b + sqrt(delta))/(2*a));
}
Chú ý: ñối với trường hợp cuối cùng có thể không cần if, như ở ví dụ trên.

3.2.4 Viết chương trình theo cấu trúc


ðể chương trình rõ ràng, dễ kiểm tra và tránh nhầm lẫn, ta nên viết chương trình theo các
quy tắc sau:
- Các câu lệnh và khối lệnh nằm trong một lệnh ñiều khiển thì viết lui vào bên phải.
- Các câu lệnh và khối lệnh cùng cấp thì viết trên cùng một cột (thẳng cột).
- ðiểm ñầu và ñiểm cuối của một khối lệnh cũng thẳng cột.
60
Giáo trình Tin học ðại cương

3.3 Lệnh for


Lệnh for cho phép thực hiện một khối lệnh một số lần xác ñịnh. Lệnh for thường dùng ñể
giải các bài toán có tính chu trình, ví dụ như các bài toán về dãy số, về ma trận.

3.3.1 Cú pháp của for


Lệnh for có dạng sau:
for (<biểu thức khởi tạo>; <biểu thức kiểm tra>; <biểu thức tăng>)
<khối lệnh>
Trong cú pháp trên:
- for: từ khoá của lệnh for.
- biểu thức khởi tạo, biểu thức kiểm tra và biểu thức tăng bắt buộc phải ñược trong
cặp ngoặc tròn và cách nhau bởi dấu chấm phẩy. Các biểu thức4 này có thể vắng
mặt, nhưng vẫn phải ñủ các dấu chấm phẩy.
- Khối lệnh, còn ñược gọi là phần thân của lệnh for là khối lệnh cần thực hiện nhiều
lần.
Thông thường, biểu thức khởi tạo thường ñược dùng ñể khởi tạo giá trị cho các biến ñiều
khiển, biểu thức tăng dùng ñể thay ñổi giá trị của biến ñiều khiển.

3.3.2 Hoạt ñộng của for


Lệnh for làm việc theo các bước sau:
- Bước 1. Tính giá trị biểu thức khởi tạo.
- Bước 2. Tính giá trị của biểu thức kiểm tra. Nếu ñúng, tới bước 3, ngược lại thoát
khỏi lệnh for.
- Bước 3. Thực hiện khối lệnh.
- Bước 4. Tính giá trị biểu thức tăng, sau ñó quay trở lại bước 2.
Chú ý:
- Nếu biểu thức kiểm tra vắng mặt thì nó ñược xem là ñúng. ðể tránh lặp vô tận,
trong phần thân của for phải có lệnh nhảy ra khỏi for bằng các lệnh break, return
hoặc goto.
- Các biểu thức trong lệnh for có thể là một biểu thức ghép, tức là gồm nhiều biểu
thức cách nhau bởi dấu phẩy. Trong trường hợp ñó, tính ñúng sai ñược xác ñịnh
theo biểu thức cuối cùng trong biểu thức ghép.

3.3.3 Ví dụ minh hoạ


Ví dụ 1: ðảo ngược một dãy số cho trước.
/* Chuong trinh dao nguoc mot day so */
#include <stdio.h>
float x[] = { 63.2, -45.6, 70.1, 3.6, 14.5};
int n = 5;
void main()
{
int i, j;
float c;

4
Chú ý rằng, biểu thức ở ñây có thể bao gồm nhiều biểu thức con.
61
Giáo trình Tin học ðại cương

for(i = 0, j = n - 1; i < j; i++, j--)


{
c = x[i]; x[i] = x[j]; x[j] = c;
}
printf("\nDay ket qua: \n");
for(i = 0; i < n; i++)
printf(“%8.2f", x[i]);
}
Ví dụ 2: Chương trình dưới ñây giải quyết bài toán tìm giá trị lớn nhất và nhỏ nhất trên
mỗi hàng của ma trận. Trong chương trình sử dụng các chu trình lồng nhau.
#include <stdio.h>
float a[3][4] = {
{15.0, 46.0, 3.5, 6.3},
{34.0, 0.0, -25.0, 35.0} ,
{ 1.0, -13.0, 46.0, -38.0}};

void main()
{
int i, j;
float max, min;

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


{
max = a[i][0];
min = a[i][0];
for (j = 0; j < 4; j++)
{
if (max < a[i][j])
max = a[i][j];
if (min > a[i][j])
min = a[i][j];
}
printf("Gia tri lon nhat va nho nhat cot %d la %.2f va %.2f\n",
i + 1, max, min);
}
}
Ví dụ 3: Chương trình nhập một dãy số và in ra màn hình dãy vừa nhập.
#include <stdio.h>
void main()
{
float a[100];
int n, i ;

printf("\nSo phan tu cua day: ");


scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Phan tu thu %d: ", i + 1);
scanf("%f", &a[i]);
}

printf("Day so vua nhap:\n");


for (i = 0; i < n; i++)
printf("%8.2f", a[i]);
}

Ví dụ 4: Chương trình dưới ñây sẽ nhập một ma trận thực cấp MxN sau ñó tính các tổng
cột của ma trận.

62
Giáo trình Tin học ðại cương

#include <stdio.h>
#include <conio.h>
void main()
{
float a[20][20], tc, tg;
int m, n, i, j;

printf("\nNhap so hang va so cot cua ma tran: ");


scanf("%d%d", &m, &n);

for (i = 1; i<= m; i++)


for (j = 1; j <= n; j++)
{
printf("a[%d][%d] = ", i, j);
scanf("%f", &tg);
a[i][j] = tg ;
}

/* Tinh tong cot */


for (j = 1; j <= n; j++)
{
tc = 0;
for (i = 1; i <= m; ++i)
tc += a[i][j] ;
printf ("\nTong cot %d = %.1f", j, tc);

}
}

3.4 Lệnh while


Lệnh while cho phép thực hiện một khối lệnh nhiều lần. Thông thường while sử dụng
trong các trường hợp mà số lần lặp không xác ñịnh trước.

3.4.1 Cú pháp của while


Cú pháp của while có dạng:
while (<biểu thức kiểm tra5>)
<khối lệnh>
Trong cú pháp trên:
- while: từ khoá của lệnh while.
- Biểu thức kiểm tra: bắt buộc phải ñặt trong cặp ngoặc tròn.
- Khối lệnh, còn gọi là phần thân của while, là khối lệnh cần thực hiện nhiều lần.

3.4.2 Hoạt ñộng của while.


Lệnh while làm việc theo các bước sau:
- Bước 1: Tính giá trị của biểu thức kiểm tra. Nếu biểu thức ñúng, sang bước 2,
ngược lại thoát khỏi lệnh while.
- Bước 2: Thực hiện khối lệnh, sau ñó quay trở lại bước 1.
Nhận xét: Thân của while có thể ñược thực hiện một lần hoặc nhiều lần và cũng có thể
không ñược thực hiện lần nào nếu ngay từ ñầu biểu thức kiểm tra ñã sai.

5
Cũng giống như trong câu lệnh for, biểu thức kiểm tra ở ñây có thể là một dãy nhiều biểu thức.
63
Giáo trình Tin học ðại cương

Chú ý:
- ðể tránh lặp vô tận, trong phần thân của while cần có lệnh làm thay ñổi giá trị
biểu thức kiểm tra và cần ñảm bảo tới một lúc nào ñó thì biểu thức kiểm tra sẽ sai.
- Biểu thức kiểm tra có thể là một biểu thức ghép, tức là gồm một dãy các biểu thức
cách nhau bởi dấu phẩy. Tính ñúng sai ñược xác ñịnh dựa vào biểu thức cuối cùng
trong dãy.

3.4.3 Ví dụ minh hoạ


Ví dụ 1: Tính tích vô hướng của hai véc tơ x và y.
/* Chương trinh tinh tich vo huong */
#include <stdio.h>
float x[] = {4.0, 6.0, 8.0, 3.5};
float y[] = {2.6, 3.2, 4.0, 7.0};
void main()
{
float s;
int i;
s = 0;
i = 0;
while (i < 4)
{
s += x[i]*y[i];
i += 1;
}
printf("\nTich vo huong = %.2f", s);
}
Ví dụ 2: Chương trình dưới ñây sẽ tìm số nguyên dương n nhỏ nhất sao cho:
1 + 2 + ... + n > 1000.
#include <stdio.h>
void main()
{
float s;
int n;
s = 0;
n = 0;
while (s <= 1000)
s += ++n;
printf("\nN = %d", n);
}
Ví dụ 3: Tìm phần tử âm ñầu tiên trong một dãy số nguyên.
#include <stdio.h>
int a[] = {2, 34, 16, -5, 43, 27};

void main()
{
int i, n;
i = 0;
n = 6;
while ((i < n) && (a[i] >= 0))
i++;
if (i < n)
printf("Phan tu am a[%d] = %d", i, a[i]);
64
Giáo trình Tin học ðại cương

else
printf("Khong co phan tu am.");
}

3.5 Lệnh do - while


Trong các lệnh while và for, việc kiểm tra ñiều kiện kết thúc ñặt ở ñầu chu trình. Khác
với hai lệnh trên, 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.

3.5.1 Cú pháp của do – while


Lệnh do - while có dạng sau:
do
<khối lệnh>
while (<biểu thức kiểm tra>);
Trong cú pháp trên:
- do, while là các từ khoá của lệnh do – while.
- Khối lệnh, còn gọi là phần thân của do – while là khối lệnh cần thực hiện nhiều
lần.
- Biểu thức kiểm tra phải ñặt trong cặp ngoặc tròn (ngoặc ñơn).

3.5.2 Hoạt ñộng của do while


Lệnh do – while thực hiện như sau:
- Bước 1: Thực hiện khối lệnh.
- Bước 2: Tính giá trị biểu thức kiểm tra. Nếu ñúng, quay trở lại bước 1, ngược lại,
thoát khỏi lệnh do – while.

3.5.3 Ví dụ minh hoạ


Ví dụ : Tính căn bậc hai của một số nguyên a, thuật toán như sau:
x(0) = a
x(n+1) = ( x(n)*x(n) + a ) / ( 2*x(n) ) , với n>=0
Quá trình lặp kết thúc khi
| (x(n+1) - x(n)) / x(n)| < 0.00001
Khi ñó x(n+1) ñược xem là giá trị gần ñúng của căn a.
Thuật toán trên ñược chương trình hoá như sau.
/* Chuong trinh tinh can bac hai */
#include <stdio.h>
#include <math.h>
void main()
{
double a, x, c;
printf("\na = ");
scanf("%f", &a);

x = a;
do
{
c = x;
x = (x*x + a)/(2*x);
65
Giáo trình Tin học ðại cương

}
while (fabs((x-c)/c) >= 1e-5);
printf("Can bac hai cua %.4f la %.4f", a, x);
}

3.6 Lệnh break


Khi sử dụng các lệnh lặp như for, while hay do – while ở các ví dụ trên, ñiều kiện thoát ra
khỏi các vòng lặp này là biểu thức kiểm tra sai. Tuy nhiên, trong một vài trường hợp, ta muốn
thoát ra khỏi các vòng lặp này ngay tức thời, khi ñó có thể sử dụng lệnh break.

3.6.1 Cú pháp của break


Lệnh break có dạng sau:
break;
Ghi chú:
- Lệnh break có thể ñược ñặt ở bất cứ ñâu trong thân của các lệnh lặp.
- Khi có nhiều lệnh lặp lồng nhau, lệnh break chỉ thoát ra khỏi lệnh lặp trong cùng
chứa nó.

3.6.2 Hoạt ñộng của break


Khi gặp break, máy sẽ bỏ qua các lệnh còn lại trong phần thân của lệnh lặp, dừng lặp và
thoát ra khỏi lệnh lặp.

3.6.3 Ví dụ minh hoạ


Chương trình tìm phần tử âm ñầu tiên của một ma trận dưới ñây sẽ minh họa cách sử
dụng các chu trình lồng nhau và cách dùng break ñể ra khỏi chu trình.
/* Chuong trinh tim phan tu am dau tien cua ma tran dùng break */
#include <stdio.h>
float a[3][4] = {
{15.0, 46.0, 3.5, 6.3},
{34.0, 0.0, -25.0, 35.0} ,
{ 1.0, -13.0, 46.0, -38.0}};

void main()
{
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
if (a[i][j] < 0)
break; /* ra khoi for j */
if ( j < 4)
break; /* ra khoi for i */
}
if ((i < 3)&&(j < 4))
printf("\nPhan tu am dau tien la a(%d,%d) = %.2f",
i + 1, j + 1, a[i][j]);
else
printf("\nMa tran khong co phan tu am.");
}

3.7 Lệnh continue


Lệnh continue dùng ñể bắt ñầu lại một chu trình.

66
Giáo trình Tin học ðại cương

3.7.1 Cú pháp của continue


Lệnh continue có dạng:
continue;
Ghi chú:
- Lệnh continue chỉ sử dụng trong các lệnh lặp.
- Lệnh continue có thể ñặt bất cứ ñâu trong phần thân của lệnh lặp.
- Khi có nhiều lệnh lặp lồng nhau, lệnh continue chỉ có tác dụng ñối với lệnh lặp
trong cùng.

3.7.2 Hoạt ñộng của continue


Khi gặp continue, máy sẽ bỏ qua các lệnh còn lại trong phần thân của lệnh lặp và quay lại
bắt ñầu vòng lặp mới.
ðối với while và do – while, vòng lặp mới bắt ñầu từ bước tính biểu thức kiểm tra.
ðối với for, vòng lặp mới bắt ñầu từ bước tính biểu thức tăng.

3.7.3 Ví dụ minh hoạ


Cho ma trận a, viết chương trình ñể từ một ma trận a cho trước:
- 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 giá trị lớn nhất của các phần tử dương của A.
#include <stdio.h>
float a[][4] = {
{ 25.0, 0.0, -3.0, 5.0},
{ -6.0, 4.0, 0.0, -2.0},
{ 30.0, -4.0, 7.0, -3.0}};

void main()
{
int i, j, demD;
float tongD, maxD;
demD = 0;
tongD = 0;
maxD = 0;

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


for(j = 0; j < 4; j++)
{
if(a[i][j] <= 0)
continue;
++demD;
tongD += a[i][j];
if (maxD < a[i][j])
maxD = a[i][j];
}
printf("\nSo phan tu duong la: %d", demD);
printf("\nTong cac phan tu duong la: %.2f", tongD);
printf("\nMax cac phan tu duong la: %.2f", maxD);
}

67
Giáo trình Tin học ðại cương

BÀI TẬP CHƯƠNG 3


Bài 1. Lập chương trình giải hệ phương trình:
ax + by = c
dx + ey = f
các hệ số a, b, c, d, e, f nhận từ bàn phím . Yêu cầu xét tất cả các trường hợp có thể.
Bài 2. Lập chương trình:
- Nhập một dãy số từ bàn phím.
- Tính trung bình cộng của các số dương và trung bình cộng của các số âm trong
dãy số trên.
Bài 3. Lập chương trình tính ex theo công thức xấp xỉ
x x2 xn
e x = 1+ + + ... +
1 2! n!
với ñộ chính xác 0.00001. Tức là n cần chọn sao cho
xn
< 0.00001
n!
Bài 4. Lập chương trình tính sin(x) với ñộ chính xác 0.0001 theo công thức:
x3 x5 x2n −1
sin( x) = x − + + ... + ( −1) n
3! 5! ( 2 n − 1)!
Bài 5. Lập chương trình vào bốn dãy số a1, ..., an, b1, ..., bn, c1, ..., cn, d1, ..., dn. In kết quả trên
n dòng , mỗi dòng 6 giá trị theo mẫu sau:
ai bi ci di min(ai,bi,ci,di) max(ai,bi,ci,di)
Bài 6. Lập chương trình tính tổ hợp chập m của n
n.( n − 1)...( n − m + 1)
C( m, n) =
m!
Bài 7. Lập chương trình in một dãy n số thực x1,..., xn trên nhiều dòng, mỗi dòng gồm m số
(dòng cuối cùng có thể ít hơn). Các giá trị m, n và x1,..., xn nhận từ bàn phím.
Bài 8. Nhập các hệ số a1 ,..., an từ bàn phím sau ñó in hàm f(x) trên một dòng theo mẫu sau:
f(x) = a1x1 + ... + anxn
Bài 9. Lập chương trình tính
S = ( a 12 + a 22 +... + a n2 ) 0 .5
trong ñó n và a1,...,an nhận từ bàn phím.
Bài 10. Cần có tổng số 200000ñ từ 3 loại giấy bạc 1000ñ, 2000ñ và 5000ñ. Lập chương trình
tìm tất cả các phương án có thể.
Bài 11. Lập chương trình tìm phần tử âm cuối cùng của dãy a1,...,an.
Bài 12. Cho hai dãy số: a1,...,an và b1,...,bm, cả hai ñều xếp theo thứ tự tăng. Lập chương trình
trộn hai dãy trên thành một dãy mới cũng theo thứ tự tăng.
Bài 13. Cho dãy số a1,...,an. Lọc các số dương ñưa vào mảng b, các số âm ñưa vào mảng c.

68
Giáo trình Tin học ðại cương

Bài 14. Sắp xếp một dãy số theo thứ tự tăng dần.
Bài 15. Cho dãy số a1,...,an. Lập chương trình in các số âm trên một dòng, các số dương trên
dòng tiếp theo.
Bài 16. Cho hiện lên màn hình các kí tự có mã ASCII từ 33 ñến 255.
Bài 17. Viết chương trình tính giá trị của ña thức và ñạo hàm của nó.
Bài 18. Viết chương trình tính ñịnh thức của ma trận vuông cấp n.
Bài 19. Viết chương trình nhập toạ ñộ x, y của một dãy n ñiểm, sau ñó tìm một cặp ñiểm cách
xa nhau nhất.

69
Giáo trình Tin học ðại cương

CHƯƠNG 4 - HÀM VÀ TỔ CHỨC CHƯƠNG TRÌNH

Một chương trình viết theo ngôn ngữ C là một dãy các hàm trong ñó có một hàm chính
(hàm main). Thứ tự của các hàm trong chương trình là bất kỳ nhưng chương trình bao giờ
cũng ñược thực hiện từ hàm main. Mỗi hàm sẽ thực hiện một phần việc nào ñó và chương
trình sẽ giải quyết cả bài toán trọn vẹn. Một trong các ưu ñiểm của C là nó cho phép tổ chức
và sử dụng các hàm một cách ñơn giản và hiệu quả. Chương này sẽ giới thiệu các qui tắc xây
dựng và sử dụng hàm.

4.1 Tổ chức chương trình thành các hàm


4.1.1. Khái niệm chung về hàm
Xét bài toán ñơn giản sau: Tìm giá trị lớn nhất của ba số mà giá trị của chúng ñược ñưa
vào từ bàn phím. Ta tổ chức chương trình thành hai hàm: hàm main và một hàm mà ta ñặt tên
là max3s. Nhiệm vụ của hàm max3s là tính giá trị lớn nhất của ba số giả ñịnh mà ta gọi là a, b,
c. Nhiệm vụ của hàm main là ñọc ba giá trị từ bàn phím, dùng hàm max3s ñể tính max của ba
giá trị vừa ñọc ñược, ñưa kết qủa ra màn hình. Chương trình ñược viết như sau.
#include <stdio.h>
/* Nguyen mau ham max3s */
float max3s(float a,float b,float c);

void main()
{
float x, y, z;
printf("\nNhap ba so thuc: ");
scanf("%f%f%f", &x, &y, &z);
printf("\nx = %0.2f\ny = %0.2f\nz= %0.2f\nmax = %0.2f",
x, y, z, max3s(x, y, z));
}

/* Dinh nghia ham max3s */


float max3s(float a, float b, float c)
{
float max;
max = a>b?a:b;
return (max>c?max:c); /* Gia tri tra ve */
}
Ghi chú:
- Nên khai báo nguyên mẫu của hàm trước khi sử dụng hàm.
- Nguyên mẫu của hàm thực chất là dòng ñầu của hàm và thêm vào dấu chấm phẩy.
Tuy nhiên trong nguyên mẫu có thể bỏ tên các ñối.
Qua chương trình này có thể rút ra nhiều khái niệm và qui tắc quan trọng liên quan ñến
việc xây dựng và sử dụng hàm:
- Mỗi hàm phải có một tên. Ta có thể ñặt cho mỗi hàm một tên bất kỳ theo các qui
tắc nêu trong chương 1.
- Trong cùng một chương trình, các hàm phải có tên khác nhau và mặc dù tên là tùy
ý nhưng ta cũng nên ñặt cho hàm những tên phù hợp với chức năng của hàm.
- Hàm thường có một vài ñối. Ví dụ hàm max3s có ba ñối là a, b, c. Cả ba ñối này
ñều có kiểu giá trị float. Cũng có hàm không ñối như hàm main trong các ví dụ
trên, khi ñó vẫn phải có cặp dấu ngoặc tròn.
70
Giáo trình Tin học ðại cương

- Hàm thường cho ta một giá trị nào ñó. Ví dụ, hàm max3s cho giá trị lớn nhất của
ba ñối của nó. Giá trị của hàm có thể có kiểu int, float, double, ... . Hàm max3s có
giá trị kiểu float. Ngoài ra còn có những hàm không có giá trị trả về, khi ñó khai
báo kiểu trả về của hàm là void.

4.1.2 Quy tắc xây dựng một hàm


Hàm có thể xem là một ñơn vị ñộc lập của chương trình. Trong C không cho phép xây
dựng một hàm bên trong các hàm khác. Hàm ñược viết theo thứ tự sau:
Nguyên mẫu hàm
Nguyên mẫu hàm cho biết tên hàm, các ñối của hàm và kiểu giá trị trả về. Việc khai báo
nguyên mẫu hàm cho phép sử dụng hàm trước khi ñịnh nghĩa hàm.
Nguyên mẫu hàm khai báo theo mẫu sau:
<kiểu> <tên_hàm>(
<kiểu 1> [<ñối1>,
<kiểu 2> [<ñối 2>],
…,
<kiểu n> [<ñối n>]
);
Như vậy, nguyên mẫu của hàm khai báo những thông tin tối thiểu nhất của hàm ñể có thể
sử dụng ñược hàm ñó.
Trong trường hợp hàm ñược ñịnh nghĩa trước khi sử dụng, thì không cần thiết phải khai
báo nguyên mẫu.
ðịnh nghĩa hàm
ðịnh nghĩa hàm gồm hai phần: tiêu ñề và thân hàm. Xét ví dụ về hàm max3s:
/* Dinh nghia ham max3s */
float max3s(float a, float b, float c)
{
float max;
max = a>b?a:b;
return (max>c?max:c); /* Gia tri tra ve */
}
Trong ví dụ trên, tiêu ñề của hàm là:
float max3s(float a, float b, float c)
Thân hàm bắt ñầu bằng dấu { và kết thúc bởi dấu }. Trong thân hàm chứa các câu lệnh
cần thiết ñể thực hiện một yêu cầu nào ñó ñã ñề ra cho hàm. Thân của hàm max3s là ñoạn
chương trình tính giá trị lớn nhất của ba ñối a, b, c.
Trong thân hàm ta dùng thêm biến max. Cần phân biệt sự khác nhau giữa biến max và
ñối a, b, c. Biến max là biến cục bộ nó chỉ có tác dụng trong thân hàm và không có bất cứ một
liên hệ gì ñến các biến của các hàm khác trong chương trình. Trái lại các ñối a, b, c lại ñược
dùng ñể trao ñổi dữ liệu giữa các hàm.
Trong thân hàm có thể sử dụng một câu lệnh return, có thể dùng nhiều câu lệnh return ở
những chỗ khác nhau và cũng có thể không sử dụng câu lệnh này nếu hàm không có giá trị trả
về. Dạng tổng quát của nó là:
return [<biểu thức>];
Giá trị của biểu thức trong câu lệnh return sẽ ñược gán cho hàm. Trong ví dụ ñang xét,
giá trị của biểu thức này là giá trị lớn nhất của ba ñối a, b, c.

71
Giáo trình Tin học ðại cương

4.1.3 Sử dụng hàm


Hàm ñược sử dụng bằng cách gọi hàm. Lời gọi hàm có dạng sau:
<tên hàm> ([<danh sách tham số thực>])
Khi gọi hàm, cần phải truyền cho mỗi tham số một giá trị. Các giá trị này gọi là các tham
số thực ñể phân biệt với các tham số ñược khai báo khi ñịnh nghĩa hàm (tham số hình thức).
Như vậy ta có các khái niệm sau:
+ Biến toàn bộ hay biến toàn cục: là các biến ñược khai báo ở ñầu chương trình, nó có
thể sử dụng ở vị trí bất kỳ trong chương trình.
+ Biến cục bộ, biến ñịa phương: là các biến ñược khai báo trong các hàm, tại ñầu mỗi
khối lệnh. Phạm vi họat ñộng của các biến này là trong thân hàm hay khối lệnh chứa nó.
+ ðối số hay tham số hình thức: là các biến ñược khai báo sau tên hàm trong 2 dấu
ngoặc tròn.
+ ðối số thực sự hay tham số thực sự: Khi sử dụng hàm, ta viết tên hàm, cặp dấu
ngoặc tròn và các giá trị trong 2 dấu ngoặc tròn nếu có. Các giá trị ñó ñược gọi là các tham số
thực sự.
Nguyên tắc hoạt ñộng của chương trình khi gặp lời gọi hàm:
Khi gặp một lời gọi hàm thì hàm bắt ñầu ñược thực hiện. Nói cách khác, khi máy gặp một
lời gọi hàm ở một chỗ nào ñó của chương trình, thì máy sẽ tạm rời chỗ ñó và chuyển ñến hàm
tương ứng. Quá trình ñó sẽ diễn ra theo trình tự 4 bước như sau:
a/ Cấp phát bộ nhớ cho các ñối và các biến cục bộ.
b/ Gán giá trị của các tham số thực cho các ñối tương ứng.
c/ Thực hiện các câu lệnh trong thân hàm.
d/ Khi gặp câu lệnh return hoặc dấu } cuối cùng của thân hàm thì máy sẽ xoá các ñối, các
biến cục bộ (giải phóng bộ nhớ của các ñối, biến cục bộ) và thoát khỏi hàm.
Nếu trở về từ một câu lệnh return có chứa biểu thức thì giá trị của biểu thức ñược gán cho
hàm. Giá trị của hàm sẽ ñược sử dụng trong các biểu thức chứa nó.
Trong ví dụ trên, giá trị của hàm max3s(x,y,z) sẽ ñược sử dụng trong câu lệnh printf. Nói
cách khác, giá trị lớn nhất của ba số x, y, z sẽ ñược ñưa ra màn hình.

4.1.4 Cấu trúc tổng quát của chương trình


Chương trình gồm nhiều hàm ñược viết theo trình tự sau:
- Các #include
- Các #define
- Khai báo các ñối tượng dữ liệu ngoài (biến, mảng, cấu trúc,...).
- Khai báo nguyên mẫu của các hàm
- Hàm main
- Xây dựng (ñịnh nghĩa) các hàm
Chú ý: Hàm main có thể ñặt sau hoặc xen vào giữa các hàm khác.

72
Giáo trình Tin học ðại cương

4.2 Tham số kiểu con trỏ


Trong phần này, chúng tôi giới thiệu sơ lược về con trỏ trong C và ứng dụng trong truyền
tham số cho hàm.

4.2.1 ðịa chỉ


Liên quan ñến một biến ta ñã có khái niệm:
- Tên biến
- Kiểu biến
- Giá trị của biến
Ví dụ câu lệnh
float alpha = 30.5;
xác ñịnh một biến có tên là alpha có kiểu float và có giá trị 30.5. Ta cũng ñã biết, theo
khai báo trên, máy sẽ cấp phát cho biến alpha một khoảng nhớ gồm 4 byte liên tiếp.
ðịa chỉ của biến là số thứ tự của byte ñầu tiên của vùng nhớ của biến trong bộ nhớ.
Một ñiều cần lưu ý là mặc dù ñịa chỉ của biến là một số nguyên nhưng không ñược ñánh
ñồng nó với các số nguyên thông thường dùng trong các phép tính.
ðể lấy ñịa chỉ của một biến, dùng phép toán &. Ví dụ ñể lấy ñịa chỉ của biến alpha.
&alpha

4.2.2 Con trỏ


Con trỏ là biến dùng ñể chứa ñịa chỉ, có nghĩa là giá trị của con trỏ là ñịa chỉ của một
biến nào ñó.
Vì có nhiều loại ñịa chỉ nên cũng có nhiều kiểu con trỏ tương ứng. Con trỏ kiểu int dùng
ñể chứa ñịa chỉ các biến kiểu int. Tương tự, ta có con trỏ kiểu float, kiểu double,... . Cũng như
ñối với bất kỳ một biến nào khác, một con trỏ cần khai báo trước khi sử dụng.
Việc khai báo biến con trỏ ñược thực hiện theo mẫu sau:
<kiểu> *<tên con trỏ>;
Ví dụ câu lệnh sau khai báo hai biến kiểu int là x, y và hai con trỏ kiểu int là px và py.
int x, y, *px, *py;
Tương tự câu lệnh sau khai báo các con trỏ kiểu float.
float f, *pf;
Khi ñã có các khai báo trên thì các câu lệnh sau hoàn toàn xác ñịnh.
px = &x;
py = &y;
Câu lệnh thứ nhất sẽ gán ñịa chỉ của x cho con trỏ px và câu lệnh thứ hai sẽ gán ñịa chỉ
của biến y cho con trỏ py.
Khi con trỏ px chứa ñịa chỉ của biến x thì ta nói px trỏ tới x.
Chúng ta không ñược gán ñịa chỉ của một biến nguyên cho một con trỏ kiểu thực. Ví dụ
câu lệnh sau là không hợp lệ.
pf = &y;

73
Giáo trình Tin học ðại cương

4.2.3 Qui tắc sử dụng con trỏ trong các biểu thức
Với một biến, có hai ñại lượng liên quan, ñó là giá trị của biến và ñịa chỉ của biến. Khi
một con trỏ trỏ tới một biến, khi ñó cũng có hai ñại lượng liên quan, ñó là giá trị con trỏ
(chính là ñịa chỉ của biến) và giá trị của biến mà con trỏ ñang trỏ tới.
Trong biểu thức, tên con trỏ ñại diện cho giá trị của con trỏ và dạng khai báo ñại diện cho
giá trị biến mà con trỏ ñang trỏ tới.
Sử dụng tên con trỏ
Con trỏ cũng là một biến nên khi tên của nó xuất hiện trọng một biểu thức thì giá trị của
nó sẽ ñược sử dụng trong biểu thức này. Khi tên con trỏ ñứng ở bên trái của một toán tử gán
thì giá trị của biểu thức bên phải (giá trị này phải là ñịa chỉ) ñược gán cho con trỏ.
Ta hãy xem các câu lệnh sau làm gì ?
float a, *p, *q;
p = &a;
q = p;
Câu lệnh thứ nhất khai báo một biến kiểu float (biến a) và hai con trỏ p và q kiểu float.
Câu lệnh thứ hai sẽ gán ñịa chỉ của biến a cho con trỏ p và câu lệnh thứ ba sẽ gán giá trị của p
cho q. Kết quả là con trỏ q chứa ñịa chỉ của biến a.
Sử dụng dạng khai báo của con trỏ
Xét ñoạn lệnh sau:
float x, y, *px, *py;
x = 100.0;
y = 215.3;
px = &x;
py = &y;
Sau các lệnh gán thì px trỏ tới x, py trỏ tới y. Khi ñó biến mà px trỏ tới (biến x) ñược biểu
diễn dưới dạng *px.
Nói một cách khác, nếu con trỏ px trỏ tới biến x thì các cách viết
x và *px
là tương ñương trong mọi ngữ cảnh.
Theo nguyên lý này thì ba câu lệnh sau ñều có hiệu lực như nhau
y = 3*x + 1;
*py = 3*x + 1;
*py = 3*(*px) + 1;
Từ ñây có thể rút ra một kết luận quan trong là: Khi biết ñược ñịa chỉ của một biến thì
chẳng những chúng ta có thể sử dụng giá trị của nó mà còn có thể gán cho nó một giá trị mới
(làm thay ñổi nội dung của nó). ðiều này sẽ ñược áp dụng như một phương pháp chủ yếu ñể
nhận kết quả của hàm thông qua ñối.

4.2.4 Mảng và con trỏ


Khi khai báo một mảng, máy cấp phát một vùng nhớ dùng ñể lưu giá trị các phần tử của
mảng.
Ví dụ khai báo một mảng số nguyên:
int a[100];

74
Giáo trình Tin học ðại cương

Khi ñó máy sẽ cấp phát 100 ô nhớ, mỗi ô nhớ có kích thước của một số nguyên tương
ứng với một phần tử, và các phần tử sẽ sắp xếp liên tiếp nhau trong bộ nhớ, từ phần tử ñầu
tiên.
Trong C, tên mảng chính là ñịa chỉ của phần tử ñầu tiên của mảng, ñiều có nghĩa là:
a bằng &a[0]
Vì tên mảng là một ñịa chỉ, nên ta có thể gán cho một con trỏ. Ví dụ:
int *p;
p = a;
Như vậy giữa mảng con trỏ có sự tương ñồng. Do ñó, trong C cho phép sử dụng thay thế
giữa mảng và con trỏ trong một số trường hợp.
Ví dụ, sau khi ñã gán p bằng a thì:
a[4] và p[4] ñều biểu diễn phần tử thứ 5 của mảng.
a[0], *a và *p cùng biểu diễn phần tử ñầu tiên của mảng.
Tuy nhiên giữa mảng và con trỏ có sự khác nhau. Con trỏ là một biến, vì thế giá trị của
nó có thể thay ñổi ñược và ta có thể gán giá trị cho một con trỏ. Trong khi ñó tên mảng là một
hằng ñịa chỉ, vì khi mảng ñược cấp phát thì ñịa chỉ của phần tử ñầu tiên là xác ñịnh. Vì vậy
không thể thay ñổi ñược giá trị của tên mảng.

4.2.5 Hàm có ñối con trỏ


ðối con trỏ thường ñược sử dụng trong các trường hợp sau ñây:
- Sử dụng hàm ñể thay ñổi giá trị của một biến.
- Truyền một mảng vào cho hàm.
- Trả về nhiều kết quả.
Sử dụng hàm ñể thay ñổi giá trị của một biến
Như chúng ta ñã biết, khi truyền tham số thực cho hàm, thì chỉ có giá trị của các biểu
thức là ñược sử dụng. Nếu chúng ta thay ñổi giá trị của ñối số bên trong hàm, thì sự thay ñổi
ñó không ảnh hưởng ñến giá trị các biến truyền vào cho hàm.
Vì vậy, nếu muốn dùng hàm ñể thay ñổi giá trị của một biến, thì phải truyền ñịa chỉ của
biến thay vì giá trị của biến.
ðể khai báo một tham số là ñịa chỉ của một biến, ta khai báo tham số ñó là một con trỏ có
kiểu tương ứng. Ví dụ sau ñịnh nghĩa một hàm cho phép ñảo giá trị của hai biến.
#include <stdio.h>
void hoan_vi(float *px, float *py)
{
float z;
z = *px;
*px = *py;
*py = z;
}
void main()
{
float a = 7.6, b = 13.5;
hoan_vi(&a, &b);
printf("\na = %0.2f b = %0.2f", a, b);
}

75
Giáo trình Tin học ðại cương

Kết quả thực hiện chương trình


a = 13.50 b = 7.60
Ta hãy xem hàm hoán_vị làm việc thế nào. Như ñã biết, chương trình bắt ñầu từ câu lệnh
ñầu tiên trong hàm main(). Kết qủa là biến a nhận giá trị 7.6 và biến b nhận giá trị 13.5. Tiếp
ñó là lời gọi hàm hoan_vi. Máy sẽ gán giá trị của các tham số thực cho ñối tương ứng. Như
vậy ñịa chỉ của a ñược gán cho con trỏ px , ñịa chỉ của b ñược gán cho con trỏ py. Sau ñó máy
lần lượt xét ñến các câu lệnh trong thân hàm. Câu lệnh thứ nhất sẽ cấp phát cho biến cục bộ z
một khoảng nhớ 4 byte. Theo qui tắc về sử dụng con trỏ nêu trong mục 4.2.3 thì ba câu lệnh
tiếp theo tương ñương với các câu lệnh:
z = a;
a = b;
b = z;
Như vậy a sẽ nhận giá trị của b và ngược lại. Tiếp ñó, máy trở về hàm main() và in ra
những dòng kết qủa như ñã chỉ ra ở trên.

Truyền một mảng một chiều vào cho hàm


Khi muốn truyền một mảng vào cho một hàm, ví dụ như hàm in các số hạng của một dãy
số, khi ñó ta dùng ñối con trỏ.
Do mảng là ñịa chỉ của phần tử ñầu nên kiểu của ñối là kiểu con trỏ của kiểu phần tử
mảng. Ví dụ, với mảng các phần tử int thì kiểu ñối là con trỏ kiểu int.
Khi truyền mảng vào cho hàm, bên trong hàm không rõ số lượng phần tử của mảng, do
ñó cần thêm ñối chỉ ra số lượng phần tử của mảng.
Ví dụ sau ñịnh nghĩa hai hàm, một hàm nhập dữ liệu cho một dãy số và một hàm in dãy
số ñó ra màn hình.
#include <stdio.h>

// Nguyen mau ham


void NhapDaySo(int *a, int n);
void InDaySo(int *a, int n);

void main() {
int a[100];
int n;
printf("Nhap so phan tu: ");
scanf("%d", &n);

// Nhap day so
NhapDaySo(a, n);

printf("Day so vua nhap:\n");


// In day so
InDaySo(a, n);
}

void NhapDaySo(int *a, int n)


{
int i;
for (i = 0; i < n; i++)
{
printf("a[%d] = ", i + 1);
scanf("%d", &a[i]);
}
}
76
Giáo trình Tin học ðại cương

void InDaySo(int *a, int n)


{
int i;
for (i = 0; i < n; i++)
printf("%8d", a[i]);
}
Trong ví dụ trên, các tham số của hai hàm NhapDaySo và InDaySo ñược khai báo giống
nhau, bao gồm một tham số kiểu con trỏ nguyên và một tham số nguyên.
Tuy nhiên, trong hai trường hợp ý nghĩa tham số là khác nhau.
- Tham số a trong hàm NhapDaySo là kết quả ñưa ra.
- Tham số a trong hàm InDaySo là dữ liệu ñầu vào.
Về mặt cú pháp, chúng ta không phân biệt ñược sự khác nhau ở trên, mà chỉ phân biệt
ñược theo mục ñích sử dụng.
Vì vậy, khi truyền một mảng vào cho hàm mà trong hàm không có nhu cầu thay ñổi giá
trị của các phần tử của mảng, thì có thể thêm từ khoá const khi khai báo tham số. Ví dụ, hàm
InDaySo có thể ñược ñịnh nghĩa như sau:
void InDaySo(const int *a, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%8d", a[i]);
}
Khi ñó thì có thể xác ñịnh ngay tham số a là dữ liệu vào cho hàm.
Truyền một mảng nhiều chiều vào cho hàm
Trong một số trường hợp, chúng ta phải truyền một mảng nhiều chiều vào cho hàm, ví dụ
như truyền một ma trận vào hàm in ma trận.
Khi khai báo một tham số là một mảng nhiều chiều, cần phải chỉ ra số phần tử tương ứng
của các chiều, trừ chiều ñầu tiên là không cần thiết phải chỉ ra.
Ví dụ sau nhập in một ma trận thực theo dạng bảng, sử dụng cả hai cú pháp khai báo là
mảng và con trỏ.
#include <stdio.h>

// Nguyen mau ham


void NhapMaTran(float a[20][20], int, int);
// Su dung dang khai bao mang
void InMaTran(float a[20][20], int, int);

void main()
{
float a[20][20];
int m, n;
printf("Nhap so hang, so cot: ");
scanf("%d%d", &m, &n);

// Nhap ma tran
NhapMaTran(a, m, n);

// In ma tran
InMaTran(a, 3, 3);
}
77
Giáo trình Tin học ðại cương

void NhapMaTran(float a[20][20], int m, int n)


{
int i, j;
float f;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
{
printf("a[%d][%d] = ", i + 1, j + 1);
scanf("%f", &f);
a[i][j] = f;
}
}

void InMaTran(float a[20][20], int m, int n)


{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf("%8.2f", a[i][j]);
printf("\n");
}
}
Chú ý: một số trình dịch không cho phép lấy ñịa chỉ của một phần tử mảng nhiều chiều,
do ñó chúng ta phải dùng một biến trung gian khi nhập giá trị các phần tử mảng, như trong
hàm NhapMaTran ở trên.
Trả về nhiều kết quả
Một trường hợp mà ñối là con trỏ thường ñược sử dụng ñó là khi chúng ta muốn hàm trả
về nhiều giá trị. Như chúng ta ñã biết, hàm chỉ có thể trả về một giá trị dưới dạng tên hàm, do
ñó ñể trả về nhiều giá trị chúng ta phải sử dụng tham số là con trỏ.
Ví dụ: khi viết một hàm giải phương trình bậc hai, thì chúng ta cần phải trả về các ñại
lượng:
- Hàm ñó có bao nhiêu nghiệm (0, 1, 2).
- Nếu có nghiệm, thì giá trị của nghiệm là bao nhiêu.
Như vậy ở ñây chúng ta phải trả về ba ñại lượng: số nghiệm, một hoặc hai nghiệm (trong
trường hợp có nghiệm).
Ví dụ sau thể hiện cách chúng ta trả về nhiều kết quả.
/* Chuong trinh giai phuong trinh bac hai */

#include <stdio.h>
#include <math.h>

// Nguyen mau ham


int GiaiPTBac2(float, float, float, float*, float*);

void main()
{
float a, b, c, x1, x2;
int songhiem;

printf("Nhap a, b, c: ");
scanf("%f%f%f", &a, &b, &c);

// Giai phuong trinh


78
Giáo trình Tin học ðại cương

songhiem = GiaiPTBac2(a, b, c, &x1, &x2);


if (songhiem == 0)
printf("Phuong trinh vo nghiem.");
else if (songhiem == 1)
printf("Nghiem kep: %.3f", x1);
else
printf("x1: %.3f\nx2: %.3f", x1, x2);
}

int GiaiPTBac2(float a, float b, float c, float *px1, float *px2)


{
float delta;
delta = b*b - 4*a*c;
if (delta < 0)
return 0;
else if (delta == 0)
{
*px1 = -b/(2*a);
return 1;
}
else
{
*px1 = (-b - sqrt(delta))/(2*a);
*px2 = (-b + sqrt(delta))/(2*a);
return 2;
}
}

4.3 ðệ quy
4.3.1 Khái niêm chung về ñệ quy
C không những cho phép từ hàm này gọi tới hàm khác, mà nó còn cho phép từ một vị trí
trong thân của một hàm gọi tới chính hàm ñó. Hàm như vậy gọi là hàm ñệ quy. Trong một số
trường hợp, sử dụng ñệ quy sẽ làm chương trình ngắn gọn, dễ hiểu hơn.
Khi hàm gọi ñệ quy ñến chính nó thì mỗi lần gọi, máy sẽ tạo ra một tập các biến cục bộ
mới hoàn toàn ñộc lập với các tập biến (cục bộ) ñã ñược tạo ra trong các lần gọi trước.
Ta cũng chú ý rằng: Có bao nhiêu lần gọi tới hàm thì cũng có bấy nhiêu lần thoát ra khỏi
hàm và cứ mỗi lần ra khỏi hàm thì một tập các biến cục bộ bị xóa. Sự tương ứng giữa các lần
gọi tới hàm và các lần ra khỏi hàm ñược thực hiện theo thứ tự ngược, nghĩa là: Lần ra ñầu tiên
ứng với lần vào cuối cùng và lần ra khỏi hàm cuối cùng ứng với lần ñầu tiên gọi tới hàm.
ðể minh họa những ñiều nói trên, ta ñưa ra một ví dụ ñơn giản. Giả sử ta cần viết một
hàm tính n giai thừa. Thông thường ta sẽ viết như sau:
long giai_thua(int n)
{
long s;
int i;
for (s = 1, i = 1; i <= n; i++)
s*= i;
return s;
}
Một cách khác, ta thấy rằng n! có thể tính theo công thức truy hồi như sau:
n!= 1 nếu n = 0
n!= n*(n-1)! nếu n > 0
Dựa vào công thức trên ta có thể xây dựng hàm ñể tính n! một cách ñệ quy như sau:
79
Giáo trình Tin học ðại cương

#include <stdio.h>

long giai_thua(int n)
{
return (n > 0)?n*giai_thua(n - 1) : 1;
}

void main()
{
printf("%d", giai_thua(5));
}
Cơ chế hoạt ñộng của hàm giai_thua trong chương trình trên có thể giải thích như sau:
- Trong hàm main, có một lời gọi hàm giai_thua(5) ñể tính giai thừa của 5. Khi ñó
hàm giai_thua sẽ ñược gọi ra ñể thực hiện với tham số n bằng 5.
- Trong hàm giai_thua, do n lớn hơn 0 nên giá trị trả về là n*giai_thua(n -1), tức là
5*giai_thua(4). Tuy nhiên lúc này giá trị giai_thua(4) chưa xác ñịnh, nên máy lại
tiếp tục gọi hàm giai_thua ñể tính giai thừa của 4.
- Trong lần gọi thứ hai này, do n vẫn lớn hơn 0, nên tiếp tục cần tính giai_thua(3).
- Cứ như vậy, cho tới khi n bằng 0, khi ñó giá trị trả về của lần gọi giai_thua(0) là 1
và ñược sử dụng ñể tính biểu thức trả về cho lần gọi giai_thua(1) bằng
1*giai_thua(0), bằng 1*1.
- Giá trị giai_thua(1) bằng 1, lại ñược sử dụng ñể tính biểu thức trả về cho lần gọi
giai_thua(2), bằng 2*1.
- Cứ như vậy, cuối cùng giá trị trả về của lời gọi giai_thua(5) trong main có giá trị
bằng 5*4*3*2*1*1.

4.3.2 Cách dùng ñệ quy


Bài toán nào có thể dùng ñệ quy
Phương pháp ñệ quy thường áp dụng cho các bài toán phụ thuộc tham số có hai ñặc ñiểm
sau:
- Bài toán dễ dàng giải quyết trong một số trường hợp riêng ứng với các giá trị ñặc
biệt của tham số. Ta gọi ñây là trường hợp suy biến.
- Trong trường hợp tổng quát, bài toán có thể quy về một bài toán cùng dạng nhưng
giá trị tham số thay ñổi. Và sau một số hữu hạn bước biến ñổi ñệ quy, sẽ dẫn tới
trường hợp suy biến.
Ta nhận thấy bài toán tính n! nêu trên thể hiên rất rõ các ñặc ñiểm này.
Cách xây dựng hàm ñệ quy
Hàm ñệ quy thường ñược viết theo thuật toán sau:
if (trường hợp suy biến)
{
trình bày cách giải bài toán
(giả ñịnh ñã có cách giải)
}
else /* trường hợp tổng quát */
{
gọi ñệ quy tới hàm (ñang lập) với
giá trị khác của tham số
}

80
Giáo trình Tin học ðại cương

4.3.3 Các ví dụ
Mục này sẽ trình bày một số ví dụ nhằm minh hoạ cách xây dựng hàm ñệ quy.
Ví dụ 1: Xét bài toán tìm ước số chung lớn nhất của hai số nguyên dương x và y.
- Trường hợp suy biến là trường hợp x = y. Khi ñó:
uscln(x,y) = x.
- Trường hợp x khác y có thể tính ƯSCLN một cách ñệ quy như sau:
uscln(x,y) = uscln(x-y,y) nếu x > y
uscln(x,y) = uscln(x,y-x) nếu x < y
Chương trình sau ñịnh nghĩa hàm tính ước số chung lớn nhất và sử dụng hàm ñó ñể tính
ước số chung lớn nhất của hai số nhập vào:
#include <stdio.h>

// Nguyen mau ham


int uscln(int, int);

void main()
{
int a, b;
printf("Nhap hai so nguyen: ");
scanf("%d%d", &a, &b);

printf("USCLN cua %d va %d la %d.", a, b, uscln(a, b));


}

int uscln(int a, int b)


{
if (a > b)
return uscln(a - b, b);
else if (a < b)
return uscln(a, b - a);
else
return a;
}
Ví dụ 2: Bài toán tháp Hà Nội.
Bài toán tháp Hà Nội ñược ñặt ra như sau: Có một tháp gồm n tầng, tầng trên nhỏ hơn
tầng dưới. Nhiệm vụ là phải chuyển tháp từ một vị trí A ñến một vị trí mới B. ðiều kiện khi
chuyển là:
- Mỗi lần chỉ ñược phép chuyển một tầng.
- Cho phép sử dụng thêm một vị trí trung gian C ñể ñặt các tầng.
- Luôn ñảm bảo tầng trên nhỏ hơn tầng dưới ở mọi vị trí và mọi thời ñiểm.
Thuật toán chuyển tháp có thể diễn ñạt như sau:
 Trường hợp suy biến: n = 1, khi ñó chỉ cần chuyển tầng 1 từ A ñến B.
 Trường hợp tổng quát n > 1 có thể giải quyết ñệ quy như sau:
- Chuyển tháp n -1 tầng từ A ñến C, dùng B làm vị trí trung gian.
- Chuyển tầng n từ A ñến B.
- Chuyển tháp n - 1 tầng từ C ñến B, dùng A làm vị trí trung gian.

81
Giáo trình Tin học ðại cương

Chương trình sau cài ñặt thuật toán trên.


/* Thap Ha noi */
#include <stdio.h>

// Nguyen mau ham


void Chuyen(int, int, int, int);

void main()
{
int n;
printf("Nhap so tang: ");
scanf("%d", &n);
Chuyen(n, 'A', 'B', 'C');
}

void Chuyen(int n, int A, int B, int C)


{
if (n == 1)
printf("Chuyen tang 1 tu %c sang %c\n", A, B);
else
{
Chuyen(n - 1, A, C, B);
printf("Chuyen tang %d tu %c sang %c\n", n, A, B);
Chuyen(n - 1, C, B, A);
}
}

82
Giáo trình Tin học ðại cương

BÀI TẬP CHƯƠNG 4


Viết hàm thực hiện các bài toán dưới ñây.
Bài 1. Giải hệ phương trình bậc nhất
ax + by = c
dx + ey = f
Hàm có sáu ñối vào là a, b, c, d, e, f và hai ñối ra là x, y.
Bài 2. Tính ña thức cấp n
f(x) = a0 + a1x + ... + an-1 xn-1 + anxn
Hàm có hai ñối là biến nguyên n và mảng thực a.
Bài 3. Tính cực ñại và cực tiểu của một dãy số.
Bài 4. Tính giá trị trung bình và ñộ lệch tiêu chuẩn của một ñại lượng ngẫu nhiên theo công
thức
x 1 + ... + x n
s=
n
( x1 − s) 2 +...+ ( x n −s ) 2
d =
2

n
Trong ñó x1, ..., xn là dãy quan sát nhận ñược.
Bài 5. Nhân ma trận A cấp mxn với véc tơ X cấp n.
Bài 6. Chuyển vị một ma trận chữ nhật A cho trước.
Bài 7. Tìm tọa ñộ giao ñiểm của hai ñường thẳng AB và CD khi biết tọa ñộ của các ñiểm A,
B, C, D.
Bài 8. Xây dựng 3 hàm số sau ñây bằng phương pháp ñệ qui
f(x,n) = xn
s(n) = (2n)!!
p(n) = 13 + 23 + . . . + n3

83
Giáo trình Tin học ðại cương

CHƯƠNG 5 - CẤU TRÚC

ðể lưu trữ và xử lý thông tin trong máy tính ta có các biến và các mảng. Mỗi biến chứa
ñược một giá trị. Mảng có thể xem là tập hợp nhiều biến có cùng một kiểu giá trị và ñược biểu
thị bằng một tên. Cấu trúc có thể xem như một sự mở rộng của các khái niệm biến và mảng,
nó cho phép lưu trữ và xử lý các dạng thông tin phức tạp hơn. Cấu trúc là một tập hợp các
biến, các mảng và ñược biểu thị bởi một tên duy nhất.
Một ví dụ truyền thống về cấu trúc là phiếu ghi lương: Mỗi công nhân ñược miêu tả bởi
một tập hợp các thuộc tính như tên, ñịa chỉ, ngày sinh, bậc lương,... Một vài trong các thuộc
tính này lại có thể là cấu trúc: Tên có thể có nhiều thành phần, ñịa chỉ và thậm chí ngày sinh
cũng vậy.

5.1 ðịnh nghĩa cấu trúc và khai báo biến cấu trúc
Cấu trúc là kiểu dữ liệu do người dùng tự ñịnh nghĩa. Khi ñịnh nghĩa một cấu trúc, cần
chỉ ra tên của kiểu cấu trúc và các thành phần của cấu trúc.
ðể ñịnh nghĩa một cấu trúc, chúng ta dùng mẫu sau:
struct <Tên cấu trúc>
{
<Kiểu 1> <Tên thành phần 1>;
<Kiểu 2> <Tên thành phần 2>;
...
};
ðể khai báo một biến cấu trúc sau khi ñã ñịnh nghĩa kiểu cấu trúc, ta viết:
struct <Tên cấu trúc> danh_sách_tên_biến_cấu_trúc;
Ví dụ, ñịnh nghĩa cấu trúc mô tả ngày tháng, như sau:
struct Ngay
{
int ngay;
int thang;
int nam;
};
Sau khi ñịnh nghĩa trên, chúng ta ñã có kiểu dữ liệu mô tả ngày tháng là struct Ngay.
Kiểu dữ liệu này có thể dùng ñể khai báo các biến cấu trúc. Ví dụ, biến ngay_sinh kiểu ngày
tháng ñược khai báo như sau:
struct Ngay ngay_sinh;
Ta thấy việc khai báo các biến cấu trúc cũng giống như khai báo các biến kiểu dữ liệu
chuẩn. Trong dòng khai báo trên, kiểu dữ liệu là struct Ngay và tên biến là ngay_sinh.

5.2 Kết hợp ñịnh nghĩa cấu trúc và khai báo biến cấu trúc
Trong phần 5.1, chúng ta ñã biết ñịnh nghĩa một cấu trúc và sử dụng kiểu dữ liệu ñó ñể
khai báo các biến. Có thể kết hợp cả ñịnh nghĩa cấu trúc và khai báo biến vào một lệnh duy
nhất theo mẫu sau:
struct [Tên cấu trúc]
{
<Kiểu 1> <Tên thành phần 1>;
<Kiểu 2> <Tên thành phần 2>;
...
} <danh sách biến>;

84
Giáo trình Tin học ðại cương

Với cách này, các biến sẽ có kiểu là cấu trúc có các thành phần như ñược khai báo trong
cặp ngoặc nhọn {}. Tên cấu trúc trong trường hợp này có thể có, có thể không.
Ví dụ, ñịnh nghĩa cấu trúc mô tả ngày tháng ñồng thời khai báo biến tu_ngay, den_ngay,
ta có thể dùng một trong hai cách sau:
Cách 1: có tên cấu trúc:
struct Ngay
{
int ngay;
int thang;
int nam;
} tu_ngay, den_ngay;
Cách 2: không có tên cấu trúc:
struct
{
int ngay;
int thang;
int nam;
} tu_ngay, den_ngay;
Sự khác nhau của hai cách này ñó là, cách 1 vừa ñịnh nghĩa cấu trúc tên là Ngay và các
biến cấu trúc tu_ngay, den_ngay. Sau ñịnh nghĩa này, ta có thể dùng kiểu struct Ngay ñể khai
báo các biến khác.
Cách 2 ñịnh nghĩa các biến tu_ngay, den_ngay có kiểu là một cấu trúc gồm ba trường:
ngay, thang và nam. Vì không ñặt tên cho cấu trúc, nên sau ñịnh nghĩa ngày chúng ta không
thể sử dụng kiểu dữ liệu này ñược nữa, do ñó không thể ñịnh nghĩa các biến cùng kiểu với các
biến tu_ngay, den_ngay.

5.3 Sử dụng typedef ñể ñịnh nghĩa kiểu dữ liệu cấu trúc


5.3.1 ðịnh nghĩa kiểu bằng typedef
Sử dụng từ khoá typedef, chúng ta có thể ñịnh nghĩa các kiểu dữ liệu mới dựa trên các
kiểu dữ liệu ñã có. Mẫu chung cho việc ñịnh nghĩa kiểu dữ liệu bằng typedef như nhau:
typedef <kiểu> <danh sách tên>;
Ví dụ, như chúng ta ñã biết trong C không ñịnh nghĩa kiểu dữ liệu logic, mà kiểu dữ liệu
này ñược biểu diễn thông qua bất cứ kiểu dữ liệu nào. Trong ví dụ này, chúng ta sẽ sử dụng
kiểu số nguyên ñể biểu diễn kiểu logic, ñịnh nghĩa như sau:
typedef int BOOL, BIT;
Sau ñịnh nghĩa này, chúng ta ñã có các kiểu dữ liệu mới là BOOL, BIT, mà thực chất là
kiểu int. Kiểu BOOL, BIT có thể dùng ñể khai báo các biến như sau:
BOOL tiep_tuc;
BIT ket_qua;
ðoạn lệnh trên khai báo các biến tiep_tuc kiểu BOOL và ket_qua kiểu BIT. Về mặt bản
chất, các biến này có kiểu nguyên, tuy nhiên ta ñã coi các biến này có kiểu logic nên các biến
này chỉ nên nhận hai giá trị là 0 (biểu diễn giá trị sai) và 1 (biểu diễn giá trị ñúng).

5.3.2 Sử dụng typedef ñể ñịnh nghĩa kiểu cấu trúc


Chúng ta có thể dùng từ khoá typedef ñể ñịnh nghĩa kiểu cấu trúc, cho phép viết ngắn
gọn hơn.

85
Giáo trình Tin học ðại cương

Giả sử chúng ta ñã ñịnh nghĩa kiểu struct Ngay, chúng ta có thể ñịnh nghĩa kiểu dữ liệu
mới tương ñương kiểu dữ liệu này như sau:
typdef struct Ngay KieuNgay;
Sau khi ñịnh nghĩa kiểu KieuNgay, có thể dùng kiểu dữ liệu này ñể khai báo các biến một
cách ngắn gọn như sau:
KieuNgay ngay_batdau, ngay_kethuc;
Chúng ta có thể kết hợp ñịnh nghĩa cấu trúc với từ khoá typedef ñể ñịnh nghĩa kiểu dữ
liệu cấu trúc theo mẫu sau:
typdef struct [Tên]
{
<Kiểu 1> <Tên thành phần 1>;
<Kiểu 2> <Tên thành phần 2>;
...
} <danh sách tên kiểu>;
Với cách này, tên cấu trúc có thể có, có thể không. Ví dụ sau ñịnh nghĩa kiểu KieuNgay
kết hợp với ñịnh nghĩa cấu trúc theo hai cách:
Cách 1: có tên cấu trúc:
typedef struct Ngay
{
int ngay;
int thang;
int nam;
} KieuNgay;
Cách 2: không có tên cấu trúc:
typedef struct
{
int ngay;
int thang;
int nam;
} KieuNgay;
Khác biệt của hai cách này là ở chỗ: với cách 1, chúng ta có thể sử dụng kiểu dữ liệu là
struct Ngay hoặc KieuNgay, còn với cách 2 thì chúng ta chỉ có kiểu dữ liêu KieuNgay.

5.4 Truy cập các thành phần của cấu trúc


Với một biến kiểu nguyên hay kiểu thực, thì nội dung biến chỉ có thể mang một giá trị
kiểu tương ứng. Một biến cấu trúc mang trong nó nhiều thành phần khác nhau và chúng ta có
thể làm việc với từng thành phần này.
Việc truy cập các thành phần của một biến cấu trúc có thể thực hiện bằng toán tử chấm
(.). Toán tử này cho phép truy cập ñến một thành phần cấu trúc khi biết tên biến cấu trúc và
tên thành phần. Cú pháp như sau:
<biến cấu trúc>.<tên thành phần>
Trong trường hợp thành phần của cấu trúc là một cấu trúc, khi ñó có thể áp dụng toán tử
này cho thành phần ñó ñể truy cập vào các thành phần sâu hơn.
Nếu chúng ta làm việc với biến cấu trúc thông qua con trỏ, khi ñó toán tử ñể truy cập ñến
các thành phần cấu trúc là toán tử ->.

5.5 Ví dụ minh hoạ

86
Giáo trình Tin học ðại cương

5.5.1 Ví dụ 1
Nhập toạ ñộ của N ñiểm trong mặt phẳng. Tính tổng ñộ dài ñường gấp khúc ñi qua các
ñiểm này theo thứ tự nhập vào.
Với ví dụ này, chúng ta có thể dùng 2 mảng số thực ñể lưu các toạ ñộ x và y của các
ñiểm. Một cách khác là dùng một cấu trúc mô tả ñiểm, trong ñó x và y là các thành phần của
cấu trúc này. Mảng các ñiểm là một mảng cấu trúc.
#include <stdio.h>
#include <math.h>
typedef struct
{
float x;
float y;
} DIEM, *PDIEM;

// Khai bao cac nguyen mau ham


void NhapDiem(PDIEM, int);
float TinhDoDai(PDIEM, int);

void main()
{
DIEM day[100];
int n;

printf("Nhap so diem: ");


scanf("%d", &n);
NhapDiem(day, n);
printf("Do dai duong gap khuc la: %.3f", TinhDoDai(day, n));
}

void NhapDiem(PDIEM pDiem, int n)


{
DIEM diem;
int i;
for (i = 0; i < n; i++)
{
printf("x[%d] = ", i + 1);
scanf("%f", &diem.x);
printf("y[%d] = ", i + 1);
scanf("%f", &diem.y);
pDiem[i] = diem;
}
}

float TinhDoDai(PDIEM pDiem, int n)


{
float do_dai, dx, dy;
int i;

do_dai = 0;
for (i = 0; i < n - 1; i++)
{
dx = (pDiem[i + 1].x - pDiem[i].x);
dy = (pDiem[i + 1].y - pDiem[i].y);
do_dai+= sqrt(dx*dx + dy*dy);
}
return do_dai;
}

5.5.2 Ví dụ 2

87
Giáo trình Tin học ðại cương

Nhập một danh sách gồm n thí sinh dự thi ñại học, mỗi thí sinh là một cấu trúc gồm các
trường: Họ và tên, Quê, ðiểm toán, ðiểm lý, ðiểm hoá
Yêu cầu:
- Nhập ñiểm chuẩn sau ñó tìm và in ra màn hình danh sách các thí sinh ñỗ ñại học
có quê ở “Ha Noi” (Thí sinh ñỗ ñại học nếu có tổng ñiểm không dưới ñiểm
chuẩn).
- Tìm và in ra màn hình danh sách các thí sinh có ñiểm toán cao nhất.
- In ra màn hình toàn bộ thông tin của n thí sinh..
ðể giải quyết bài toán này ta có chương trình sau:
#include <stdio.h>
#include <string.h>

// Dinh nghia kieu Ho so sinh vien


typedef struct {
char HoTen[30];
char Que[50];
float DiemToan;
float DiemLy;
float DiemHoa;
} HSSV, *PHSSV;

void NhapHSSV(PHSSV pSv, int n)


{
HSSV sv;
int i;
for (i = 0; i < n; i++)
{
printf("Ten sinh vien %d: ", i + 1);
fflush(stdin);
gets(sv.HoTen);
printf("Que sinh vien %d: ", i + 1);
fflush(stdin);
gets(sv.Que);
printf("Diem toan, ly, hoa sinh vien %d: ", i + 1);
scanf("%f%f%f", &sv.DiemToan, &sv.DiemLy, &sv.DiemHoa);
pSv[i] = sv;
}
}

void InHSSV(PHSSV pSv, int n)


{
int i;
printf("%4s %20s %20s %6s %6s %6s\n",
"STT", "Ho ten", "Que quan", "Toan", "Ly", "Hoa");
for (i = 0; i < n; i++)
printf("%4d %20s %20s %6.1f %6.1f %6.1f\n", i + 1, pSv[i].HoTen,
pSv[i].Que, pSv[i].DiemToan, pSv[i].DiemLy, pSv[i].DiemHoa);
}

void main()
{
HSSV day[50];
int n, i;
float chuan, max;

printf("Nhap so sinh vien: ");


scanf("%d", &n);
// Nhap ds sinh vien

88
Giáo trình Tin học ðại cương

NhapHSSV(day, n);
// In ds sinh vien vua nhap
InHSSV(day, n);

// Tim kiem cac sinh vien do que o Ha Noi


printf("Nhap diem chuan: ");
scanf("%f", &chuan);

printf("\nDanh sach sinh vien do, que o Ha Noi:\n");

printf("%4s %20s %20s %6s %6s %6s\n",


"STT", "Ho ten", "Que quan", "Toan", "Ly", "Hoa");

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


if ((day[i].DiemToan + day[i].DiemLy + day[i].DiemHoa >= chuan)&&
(strcmpi(day[i].Que, "Ha Noi") == 0))
printf("%4d %20s %20s %6.1f %6.1f %6.1f\n", i + 1, day[i].HoTen,
day[i].Que, day[i].DiemToan, day[i].DiemLy, day[i].DiemHoa);

// Tim diem toan cao nhat


max = day[0].DiemToan;
for (i = 1; i < n; i++)
if (max < day[i].DiemToan)
max = day[i].DiemToan;

// In ra danh sach sinh vien diem toan cao nhat


printf("\nDanh sach sinh vien diem toan cao nhat:\n");

printf("%4s %20s %20s %6s %6s %6s\n",


"STT", "Ho ten", "Que quan", "Toan", "Ly", "Hoa");

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


if (day[i].DiemToan == max)
printf("%4d %20s %20s %6.1f %6.1f %6.1f\n", i + 1, day[i].HoTen,
day[i].Que, day[i].DiemToan, day[i].DiemLy, day[i].DiemHoa);

Trong chương trình trên, ta xây dựng 2 hàm nhập (NhapHSSV) và in (InHSSV) danh sách
sinh viên. Sau ñó sử dụng chúng trong hàm main. ðộc giả có thể viết lại chương trình trên mà
không sử dụng 2 hàm trên bằng cách viết trực tiếp ñoạn chương trình nhập và in vào trong
hàm main.

BÀI TẬP CHƯƠNG 5


Bài 1. Xây dựng một cấu trúc (ứng với phiếu ñiểm của thí sinh) gồm các thành phần:
- Họ tên
- Quê quán
- Trường
- Tuổi
- Số báo danh
- ðiểm thi
trong ñó Họ tên lại là một cấu trúc gồm ba thành phần: Họ, tên ñệm và tên. Quê quán cũng là
một cấu trúc gồm ba thành phần: xã, huyện và tỉnh. ðiểm thi là một cấu trúc gồm ba thành
phần: toán, lý, hóa (ñiểm chấm chính xác ñến 1/4).

89
Giáo trình Tin học ðại cương

ðọc số liệu từ một phiếu ñiểm cụ thể và lưu trữ vào các thành phần của cấu trúc nói trên, sau
ñó in các số liệu ra màn hình.
Bài 2. Sử dụng ñịnh nghĩa cấu trúc ở bài 1 :
Nhập số liệu của 20 phiếu ñiểm và lưu trữ vào mảng cấu trúc nói trên.
Tìm kiếm và in ra các thí sinh có tổng số ñiểm ba môn lớn hơn 15.
Bài 3. Giả sử ñã nhập số liệu của 20 phiếu ñiểm theo như yêu cầu của bài 2. Hãy lập chương
trình sắp xếp lại các phần tử của mảng cấu trúc theo thứ tự giảm dần của tổng số ñiểm, sau ñó
in danh sách thí sinh (theo thứ tự nói trên). Mỗi thí sinh sẽ in trên một dòng gồm các thông
tin:
- Họ tên
- Quê quán
- Số báo danh
- ðiểm toán, lý, hóa.
Bài 4. Nhập danh sách n học sinh với các thuộc tính: họ tên, năm sinh và tổng ñiểm. Sắp xếp
danh sách theo thứ tự giảm của tổng ñiểm. Khi tổng ñiểm như nhau thì học sinh có năm sinh
nhỏ hơn ñược xếp trước. In danh sách học sinh ñã sắp xếp sao cho tất cả các chữ cái của họ
tên chuyển thành chữ hoa.
Bài 5. ðịnh nghĩa kiểu cấu trúc mô tả ña thức, sau ñó viết các hàm vào ña thức, in ña thức,
cộng ña thức và nhân ña thức. áp dụng trong hàm main() ñể thực hiện các việc:
Vào từ bàn phím ba ña thức P1, P2 và P3. Tính ña thức P theo công thức:
P = (P1 + P2)2 + P3
In P1, P2, P3 và P.
Vào từ bàn phím một dẫy n ña thức, sau ñó in chúng lên màn hình theo thứ tự giảm của bậc.

90
Giáo trình Tin học ðại cương

PHỤ LỤC 1 - BẢNG MÃ ASCII

Bộ ký tự ASCII (American Standard Code for Interchange Information) gồm 256 ký


ñược phân bố như sau:
- 32 ký tự ñầu tiên là các ký tự ñiều khiển không in ñược như ký tự Enter (mã 13),
ký tự ESC (mã 27).
- Các mã ASCII 32-47,58-64,91-96 và 123-127 là các ký tự ñặc biệt như dấu chấm,
dấu phẩy, dấu cách, dấu ngoặc, dấu móc, dấu hỏi,...
- Các mã ASCII 48-57 là 10 chữ số
- Các mã ASCII 65-90 là các chữ cái hoa từ A ñến Z
- Các mã ASCII 97-122 là các chữ cái thường từ a ñến z
- Các mã ASCII 128-255 là các ký tự ñồ hoạ.

MÃ KÝ TỰ MÃ KÝ TỰ MÃ KÝ TỰ
0 NUL 43 + 86 V
1 SOH 44 , 87 W
2 STX 45 - 88 X
3 ETX 46 . 89 Y
4 EOT 47 / 90 Z
5 ENQ 48 0 91 [
6 ACK 49 1 92 \
7 BEL 50 2 93 ]
8 BS 51 3 94 ^
9 HT 52 4 95 _
10 LF 53 5 96 `
11 VT 54 6 97 a
12 FF 55 7 98 b
13 CR 56 8 99 c
14 SO 57 9 100 d
15 SI 58 : 101 e
16 DLE 59 ; 102 f
17 DC1 60 < 103 g
18 DC2 61 = 104 h
19 DC3 62 > 105 i
20 DC4 63 ? 106 j
21 NAK 64 @ 107 k
22 SYN 65 A 108 l
23 ETB 66 B 109 m

91
Giáo trình Tin học ðại cương

24 CAN 67 C 110 n
25 EM 68 D 111 o
26 SUB 69 E 112 p
27 ESC 70 F 113 q
28 FS 71 G 114 r
29 GS 72 H 115 s
30 RS 73 I 116 t
31 US 74 J 117 u
32 Space 75 K 118 v
33 ! 76 L 119 w
34 ” 77 M 120 x
35 # 78 N 121 y
36 $ 79 O 122 z
37 % 80 P 123 {
38 & 81 Q 124 |
39 ’ 82 R 125 }
40 ( 83 S 126 ~
41 ) 84 T 127 DEL
42 * 85 U

92
Giáo trình Tin học ðại cương

PHỤ LỤC 2

DANH SÁCH MỘT SỐ HÀM CỦA TURBO C

(theo thứ tự ABC)

ðể biết chi tiết, ñề nghị ñộc giả sử dụng help của môi trường TC bằng cách ñánh tên hàm
trong môi trường TC sau ñó ñể con trỏ dưới tên hàm rối nhấn Ctrl + F1.

Hàm Tệp tiêu ñề Hàm Tệp tiêu ñề


1. _chmod <io.h> 28. coreleft <alloc.h>
2. _close <io.h> 29. cos <math.h>
3. _creat <io.h> 30. cosh <math.h>
4. _open <io.h> 31. cprintf <conio.h>
5. abort <process.h> 32. creat <io.h>
6. abs <stdlib.h> 33. cscanf <conio.h>
7. acos <math.h> 34. delay <dos.h>
8. arc <graphics.h> 35. delline <conio.h>
9. asin <math.h> 36. disable <dos.h>
10. atan <math.h> 37. drawpoly <graphics.h>
11. atan2 <math.h> 38. ecvt <ctype.h>
12. atof <ctype.h> 39. ellipse <graphics.h>
13. atoi <ctype.h> 40. enable <dos.h>
14. atol <ctype.h> 41. exit <process.h>
15. bar <graphics.h> 42. exp <math.h>
16. bar3d <graphics.h> 43. fabs <math.h>
17. cabs <math.h> 44. fclose <stdio.h>
18. calloc <alloc.h> 45. fcloseall <stdio.h>
19. ceil <math.h> 46. fcvt <ctype.h>
20. chdir <dir.h> 47. feof <stdio.h>
21. chmod <io.h> 48. ferror <stdio.h>
22. circle <graphics.h> 49. fflush <stdio.h>
23. cleardevive <graphics.h> 50. fflushall <stdio.h>
24. clearviewport <graphics.h> 51. fgetc <stdio.h>
25. close <io.h> 52. fgets <stdio.h>
26. clreol <conio.h> 53. fillpopy <graphics.h>
93
Giáo trình Tin học ðại cương

27. clrscr <conio.h> 54. findfirst <dir.h>


55. findnext <dir.h> 87. getpalette <graphics.h>
56. floodfill <graphics.h> 88. getpixel <graphics.h>
57. floor <math.h> 89. gets <stdio.h>
58. fmode <math.h> 90. gettextinfo <conio.h>
59. fopen <stdio.h> 91. gettime <dos.h>
60. FP_OFF <dos.h> 92. gettime <time.h>
61. FP_SEG <dos.h> 93. getvect <dos.h>
62. fprintf <stdio.h> 94. getviewport <graphics.h>
63. fprintf <stdio.h> 95. getw <stdio.h>
64. fputc <stdio.h> 96. gotoxy <conio.h>
65. fputs <stdio.h> 97. gotoxy <conio.h>
66. fread <stdio.h> 98. grapherrormsg <graphics.h>
67. free <alloc.h> 99. graphresult <graphics.h>
68. fscanf <stdio.h> 100. imagesize <graphics.h>
69. fseek <stdio.h> 101. initgraph <graphics.h>
70. fteel <stdio.h> 102. int86 <dos.h>
71. fwrite <stdio.h> 103. int86x <dos.h>
72. gcvt <ctype.h> 104. intdos <dos.h>
73. geninterrupt <dos.h> 105. intdosx <dos.h>
74. getbkcolor <graphics.h> 106. intr <dos.h>
75. getc <stdio.h> 107. inxdigit <ctype.h>
76. getch <conio.h> 108. isalnum <ctype.h>
77. getchar <stdio.h> 109. isalpha <ctype.h>
78. getche <conio.h> 110. iscntrl <ctype.h>
79. getcolor <graphics.h> 111. isdigit <ctype.h>
80. getcwd <dir.h> 112. isgraph <ctype.h>
81. getdate <time.h> 113. islower <ctype.h>
82. getimage <graphics.h> 114. isprint <ctype.h>
83. getlinesettings <graphics.h> 115. ispunct <ctype.h>
84. getmaxcolor <graphics.h> 116. isspace <ctype.h>
85. getmaxx <graphics.h> 117. isupper <ctype.h>
86. getmaxy <graphics.h> 118. itoa <ctype.h>
119. kbhit <conio.h> 145. peek <dos.h>
120. Keep <dos.h> 146. peekb <dos.h>
94
Giáo trình Tin học ðại cương

121. labs <stdlib.h> 147. perror <stdio.h>


122. line <graphics.h> 148. pieslice <graphics.h>
123. linerel <graphics.h> 149. poke <dos.h>
124. lineto <graphics.h> 150. pokeb <dos.h>
125. log <math.h> 151. pow <math.h>
126. log10 <math.h> 152. printf <stdio.h>
127. lseek <io.h> 153. putc <stdio.h>
128. Ltoa <ctype.h> 154. putch <conio.h>
129. malloc <alloc.h> 155. putchar <stdio.h>
130. memccpy <memory.h> hoặc 156. putimage <graphics.h>
<string.h>
131. memchr <memory.h> hoặc 157. putpixel <graphics.h>
<string.h>
132. memcmp <memory.h> hoặc 158. puts <stdio.h>
<string.h>
133. memcpy <memory.h> hoặc 159. putw <stdio.h>
<string.h>
134. memicmp <memory.h> hoặc 160. rand <stdlib.h>
<string.h>
135. memset <memory.h> hoặc 161. random <stdlib.h>
<string.h>
136. MK_FP <dos.h> 162. randomize <stdlib.h> và
<time.h>
137. mkdir <dir.h> 163. read <io.h>
138. movedata <mem.h> 164. realloc <alloc.h>
139. movedata <memory.h> hoặc 165. rectangle <graphics.h>
<string.h>
140. moveto <graphics.h> 166. remove <stdio.h>
141. nosound <dos.h> 167. rewind <stdio.h>
142. open <io.h> 168. rmdir <dir.h>
143. outtext <graphics.h> 169. scanf <stdio.h>
144. outtextxy <graphics.h> 170. segread <dos.h>
171. setbkcolor <graphics.h> 200. Strncat <string.h>
172. setcolor <graphics.h> 201. strncmp <string.h>
173. setdate <time.h> 202. strncpy <string.h>
174. setfillstyle <graphics.h> 203. strnicmp <string.h>

95
Giáo trình Tin học ðại cương

175. setlinestyle <graphics.h> 204. strnset <string.h>


176. setpalette <graphics.h> 205. strpbrk <string.h>
177. settextjustify <graphics.h> 206. strrchr <string.h>
178. settextstyle <graphics.h> 207. strrev <string.h>
179. settime <time.h> 208. strset <string.h>
180. setvect <dos.h> 209. strspn <string.h>
181. setviewport <graphics.h> 210. Strstr <string.h>
182. setwritemode <graphics.h> 211. strupr <string.h>
183. sin <math.h> 212. system <process.h>
184. Sinh <math.h> 213. tan <math.h>
185. sleep <dos.h> 214. Tanh <math.h>
186. sound <dos.h> 215. textbackground <conio.h>
187. sprintf <stdio.h> 216. textcolor <conio.h>
188. sqrt <math.h> 217. textheight <graphics.h>
189. srand <stdlib.h> 218. textmode <conio.h>
190. strcat <string.h> 219. textwidth <graphics.h>
191. strchr <string.h> 220. time <time.h>
192. strcmp <string.h> 221. tolower <ctype.h>
193. strcmpi <string.h> 222. toupper <ctype.h>
194. strcpy <string.h> 223. ultoa <ctype.h>
195. strcspn <string.h> 224. unlink <stdio.h>
196. strdup <string.h> 225. Wherex <conio.h>
197. stricmp <string.h> 226. wherey <conio.h>
198. strlen <string.h> 227. window <conio.h>
199. strlwr <string.h> 228. write <io.h>

96
Thông tin về giáo trình Tin học ĐC:
- Đối tượng sử dụng: sinh viên các ngành kỹ thuật
- Các từ khóa: Tin học Đại cương, Tin Đại cương, Lập trình cấu trúc, Ngôn
ngữ lập trình, Ngôn ngữ lập trình C, Kỹ thuật lập trình, Thuật toán, Lập
trình C, Sơ đồ khối, Ngôn ngữ C
- Kiến thức yêu cầu môn học trước: toán học cơ sở
- Tên nhà xuất bản: Nhà xuất bản Giao thông vận tải
Filename: Thông tin ve giao trinh TinDC.doc
Directory: C:\Documents and
Settings\Administrator\Desktop\GT80\TinDC_Ebook
Template: C:\Documents and Settings\Administrator\Application
Data\Microsoft\Templates\Normal.dot
Title: Thông tin về tác giả:
Subject:
Author: Nguyen Duc Du
Keywords:
Comments:
Creation Date: 12/12/2008 9:15 PM
Change Number: 4
Last Saved On: 12/15/2008 9:50 AM
Last Saved By: Nguyen Duc Du
Total Editing Time: 25 Minutes
Last Printed On: 1/14/2004 9:54 AM
As of Last Complete Printing
Number of Pages: 1
Number of Words: 53 (approx.)
Number of Characters: 307 (approx.)
TÀI LIỆU THAM KHẢO

[1] PGS.TS Phạm Văn Ất


Kỹ thuật lập trình C, cơ sở và nâng cao
Nhà xuất bản Khoa học và Kỹ thuật
[2] Robert Sedgewick
Cẩm nang thuật toán (bản dịch), tập 1
Nhà xuất bản Khoa học kỹ thuật
[3] Phần mềm Turbo C 3.0

You might also like