Professional Documents
Culture Documents
GIÁO TRÌNH
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
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
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.
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.
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
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, ...
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.
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, ...
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.
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.
13
Giáo trình Tin học ðại cương
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.
14
Giáo trình Tin học ðại cương
15
Giáo trình Tin học ðại cương
16
Giáo trình Tin học ðại cương
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.
18
Giáo trình Tin học ðại cươ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.
20
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)
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ị
22
Giáo trình Tin học ðại cương
Begin
Input: a, b, c
2
Delta = b – 4ac
ð
ð
x = -b/2a x1 = ( −b + Delta ) /(2 a )
x 2 = ( −b − Delta ) /(2 a )
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).
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
S
Biểu thức Lôgíc
24
Giáo trình Tin học ðại cương
begin
Input :a, b
S
a=0
S x = -b/a
b=0
end
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
ð 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
Begin
i = 1, 2, .., n
Input: n
i = 1, 2, .., n S
ai M2
ð
Input: ai
Dem = Dem +1
Output: Dem
Dem = 0
End
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
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.
Begin
Input: n
i = 1, 2, .., n i = 1, 2,..., n
Input: ai
S = S + ai
S=0
Output: S
End
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
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
33
Giáo trình Tin học ðại cương
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
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.
35
Giáo trình Tin học ðại cương
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)
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.
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
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.
41
Giáo trình Tin học ðại cương
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.
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.
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
44
Giáo trình Tin học ðại cương
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
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.
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ố
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)
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.
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;
51
Giáo trình Tin học ðại cương
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).
ðô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.
55
Giáo trình Tin học ðại cương
56
Giáo trình Tin học ðại cương
57
Giáo trình Tin học ðại cương
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.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.
58
Giáo trình Tin học ðại cương
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.
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
void main()
{
int i, j;
float max, min;
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;
}
}
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.
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.");
}
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);
}
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.");
}
66
Giáo trình Tin học ðại cương
void main()
{
int i, j, demD;
float tongD, maxD;
demD = 0;
tongD = 0;
maxD = 0;
67
Giáo trình Tin học ðại cương
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
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.
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));
}
- 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.
71
Giáo trình Tin học ðại cương
72
Giáo trình Tin học ðại cương
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.
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.
75
Giáo trình Tin học ðại cương
void main() {
int a[100];
int n;
printf("Nhap so phan tu: ");
scanf("%d", &n);
// Nhap day so
NhapDaySo(a, n);
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
#include <stdio.h>
#include <math.h>
void main()
{
float a, b, c, x1, x2;
int songhiem;
printf("Nhap a, b, c: ");
scanf("%f%f%f", &a, &b, &c);
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.
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>
void main()
{
int a, b;
printf("Nhap hai so nguyen: ");
scanf("%d%d", &a, &b);
81
Giáo trình Tin học ðại cương
void main()
{
int n;
printf("Nhap so tang: ");
scanf("%d", &n);
Chuyen(n, 'A', 'B', 'C');
}
82
Giáo trình Tin học ðại cương
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
ðể 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.
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.
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;
void main()
{
DIEM day[100];
int n;
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>
void main()
{
HSSV day[50];
int n, i;
float chuan, max;
88
Giáo trình Tin học ðại cương
NhapHSSV(day, n);
// In ds sinh vien vua nhap
InHSSV(day, n);
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.
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
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
ðể 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.
95
Giáo trình Tin học ðại cương
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