Tải bản đầy đủ (.pdf) (100 trang)

giao trinh tin hoc dai cuong

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.17 MB, 100 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

1


<b>Nguy</b>ễ<b>n Hi</b>ế<b>u C</b>ườ<b>ng – Nguy</b>ễ<b>n </b>ðứ<b>c D</b>ư<b> – Hồng V</b>ă<b>n Thơng </b>


<b>GIÁO TRÌNH </b>



<b>TIN H</b>

<b>C </b>

ðẠ

<b>I C</b>

ƯƠ

<b>NG </b>



</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

2


<b>M</b>Ụ<b>C L</b>Ụ<b>C </b>


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


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

3


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


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

3


L

I NĨI

ðẦ

U



<i><b>Tin h</b></i>

<i><b>c </b></i>

đạ

<i><b>i c</b></i>

ươ

<i><b>ng là m</b></i>

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

<i><b>n Giáo trình Tin h</b></i>

<i><b>c </b></i>

đạ

<i><b>i c</b></i>

ươ

<i><b>ng này </b></i>

ñượ

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 q có

đượ

c trong q 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.



</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

4


PH

N 1



</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

5


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



<b>1.1 </b>

ðố

<b>i t</b>

ượ

<b>ng nghiên c</b>

<b>u c</b>

<b>a Tin h</b>

<b>c </b>



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 ln gắn liền với mọi thao tác trong q 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
tốn học, thuật tốn, chương trình (gọi là phần mềm) và các thiết bị tính tố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 tốn học cho máy tính và các hệ thống tính tốn
- Thuật tốn và độ phức tạp của thuật tốn


- Cơ sở dữ liệu
- Trí tuệ nhân tạo
- . . .


<b>1.2 Thông tin và x</b>

<b> lý thông tin </b>



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.


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

6


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 tố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.


<b>1.3 H</b>

đế

<b>m và bi</b>

<b>u di</b>

<b>n thơng tin trong máy tính </b>



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ố ngun 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ử


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

7


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 tố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.


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


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 tố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
<b>1.3.2 Bi</b>ế<b>n </b>ñổ<b>i s</b>ốở<b> h</b>ệ<b> th</b>ậ<b>p phân sang h</b>ệñế<b>m c</b>ơ<b> s</b>ố<b> b</b>ấ<b>t k</b>ỳ<b>: </b>


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 ngun N, ta chia ngun 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 q 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



</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

8


Tiếp tục lặp lại q 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


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


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.


<b>1.4 Nguyên lý c</b>

<b>a h</b>

<b> x</b>

<b> lý thơng tin t</b>

độ

<b>ng </b>



<b>1.4.1 Ngun lý làm vi</b>ệ<b>c c</b>ủ<b>a máy tính </b>


Von Neumann là người đề xuất ra ngun 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 tố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ử


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

9


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>i là ngôn ng</i>ữ<i> b</i>ậ<i>c cao vì các ngơn ng</i>ữ 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 ln xuất hiện, ngày càng hồ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, ...


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


Lịch sử kỹ thuật tính tốn đã có từ lâu đời. Cơng cụ tính tố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 tố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


<i>B</i>ả<i>ng 1.1: M</i>ộ<i>t s</i>ố<i> m</i>ố<i>c trong l</i>ị<i>ch s</i>ử<i> phát tri</i>ể<i>n máy tính </i>



</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

10


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 tố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 tố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 tố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 tố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 tố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 chun 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ừ<i> PC v</i>ới từ<i> máy vi tính. </i>


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.


<b>1.5 C</b>

<b>u trúc máy tính </b>



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ớ ngồ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


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

11


<i>Hình 1.2 Máy vi tính Hình 1.3: Máy tính xách tay (laptop) </i>


<b>Thùng máy (case): </b>


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.


<b>Bo m</b>ạ<b>ch ch</b>ủ<b>: </b>


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, ...


<i>Hình 1.4: Bên trong máy vi tính </i>


<b>B</b>ộ<b> x</b>ử<b> lý trung tâm (CPU): </b>


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 tố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 tồn hệ thống máy tính. Tốc độ CPU chính là thể hiện nhịp


</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

12


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.


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


<b>B</b>ộ<b> nh</b>ớ


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), ...


<i>Hình 1.6: B</i>ộ<i> nh</i>ớ<i> RAM </i>


<b>B</b>ộ<b> ngu</b>ồ<b>n </b>


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.


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14>

13


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.


<b>Ph</b>ầ<b>m m</b>ề<b>m toán h</b>ọ<b>c: </b>


- Mathematica: là phần mềm cho phép tính tốn từ đơn giản như các tính tố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, ...
Ngồ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 tốn tương tự như


Mathematica. Ngồ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.


<b>Ph</b>ầ<b>n m</b>ề<b>m v</b>ă<b>n phịng: </b>


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, ...
<b>Ph</b>ầ<b>n m</b>ề<b>m thi</b>ế<b>t k</b>ế<b>: </b>


- AutoCAD: ñể tạo lập và quản lý các bản vẽ kỹ thuật.
- Soap: để tính tố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ế.


<b>CÂU H</b>Ỏ<b>I CH</b>ƯƠ<b>NG 1 </b>


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 tố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?


</div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15>

14


<b>CHƯƠNG 2 – HỆ ðIỀU HÀNH </b>



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.


<b>2.1 H</b>

ñ

<b>i</b>

<b>u hành MS-DOS </b>



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. Ngồ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ũ.


<b>2.1.1 M</b>ộ<b>t s</b>ố<b> khái ni</b>ệ<b>m </b>


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 q 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ạ<i>ng hình </i>
<i>cây, v</i>ớ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


</div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16>

15
<b>2.1.2 M</b>ộ<b>t s</b>ố<b> qui </b>ướ<b>c </b>


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.


<b>2.1.3 M</b>ộ<b>t s</b>ố<b> l</b>ệ<b>nh làm vi</b>ệ<b>c v</b>ớ<b>i th</b>ư<b> m</b>ụ<b>c: </b>
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.


<b>2.1.4 M</b>ộ<b>t s</b>ố<b> l</b>ệ<b>nh làm vi</b>ệ<b>c v</b>ớ<b>i t</b>ệ<b>p tin </b>
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>


</div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

16


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.


<b>2.2 H</b>

ñ

<b>i</b>

<b>u hành Windows </b>



<b>2.2.1 M</b>ộ<b>t s</b>ốñặ<b>c </b>ñ<b>i</b>ể<b>m </b>


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.


</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

17


<i>Hình 2.1: Màn hình desktop c</i>ủ<i>a Windows XP </i>



</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19>

18


<i>Hình 2.4: Sau khi ch</i>ọ<i>n Log Off Hình 2.5: Sau khi ch</i>ọ<i>n Turn Off Computer </i>
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.


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


</div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

19


<i>Hình 2.7: Windows Explorer </i>



<b>2.2.2 Các thao tác trong Windows Explorer </b>
<b>Hi</b>ể<b>n th</b>ị<b> n</b>ộ<b>i dung: </b>


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.


<i>Hình 2.8: Ch</i>ọ<i>n cách s</i>ắ<i>p x</i>ế<i>p các bi</i>ể<i>u t</i>ượ<i>ng t</i>ệ<i>p tin </i>
ð<b>óng m</b>ở<b> th</b>ư<b> m</b>ụ<b>c: </b>


ðể 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ừ .


<b>Ch</b>ọ<b>n </b>ñố<b>i t</b>ượ<b>ng (t</b>ệ<b>p tin và th</b>ư<b> m</b>ụ<b>c): </b>


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

20


<b>Sao chép </b>ựố<b>i t</b>ượ<b>ng (các t</b>ệ<b>p tin và th</b>ư<b> m</b>ụ<b>c t</b>ừ<b> th</b>ư<b> m</b>ụ<b>c ngu</b>ồ<b>n sang th</b>ư<b> m</b>ụ<b>c </b>ự<b>ắch): </b>
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.


<i> Hình 2.9: B</i>ả<i>ng ch</i>ọ<i>n khi Copy </i> <i>Hình 2.10: B</i>ả<i>ng ch</i>ọ<i>n khi Paste </i>
ðổ<b>i tên t</b>ệ<b>p tin, th</b>ư<b> m</b>ụ<b>c: </b>


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.


<b>Xóa t</b>ệ<b>p tin, th</b>ư<b> m</b>ụ<b>c: </b>


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ặ<i><b>c gõ phím Delete trên bàn phím. Chú ý: các t</b></i>ệ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.


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


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à hồn tồn khơng khó.


<b>CÂU H</b>Ỏ<b>I CH</b>ƯƠ<b>NG 2 </b>
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?



</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22>

21


<b>CHƯƠNG 3 – THUẬT TOÁN </b>



<b>3.1 Khái ni</b>

<b>m </b>



<b>Thuât toán là m</b>ộ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 tốn).


Ví dụ: Thuật tố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 tố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 tốn


- <i>Thu</i>ậ<i>t tốn ph</i>ả<i>i có tính d</i>ừ<i>ng: Thu</i>ật tốn phải kết thúc sau một số hữu hạn bước.
- <i>Tính xác </i>đị<i>nh: </i>Ở 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>i l</i>ượ<i>ng vào: M</i>ỗi thuật tốn phải có một hoặc nhiều dữ liệu ñầu vào


- ðạ<i>i l</i>ượ<i>ng ra: Sau khi k</i>ết thúc thuật tốn ta có thể thu được một sốđại lượng ra là
kết quả của bài tốn.


- <i>Tính hi</i>ệ<i>u qu</i>ả<i>: M</i>ỗi bài tốn có thể có nhiều thuật tốn khác nhau để giải. Một
thuật tố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.
- <i>Tính ph</i>ổ<i> d</i>ụ<i>ng: Thu</i>ật tốn có thể giải được một số bài toán trong một lớp bài


tốn.


- <i>Tính hình th</i>ứ<i>c hóa: Thu</i>ật tốn phải có thể hình thức được và cài đặt được trên
máy tính.


<b>3.2 M</b>

<b>t s</b>

<b> ph</b>

ươ

<b>ng pháp bi</b>

<b>u di</b>

<b>n thu</b>

<b>t tốn </b>



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 tố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 tố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 tốn nào đó thì ta cần phải cài đặt thuật tốn giải bài tốn đó cho máy,
theo đó máy thực hiện giải bài tốn. ðể cài đặt thuật tốn cho máy người cài đặt phải có thuật
tốn giải bài tốn đó.


Có nhiều cách biểu diễn thuật tốn nhưđặc tả tự nhiên (liệt kê từng bước), sơđồ khối, giả


</div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23>

22


Sử dụng ngơn ngữ tự nhiên để biểu diễn thuật tốn bằng cách chỉ ra từng bước cần thực


hiện của thuật tốn.


Ví dụ: Thuật tố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)


<b>3.2.2 S</b>ử<b> d</b>ụ<b>ng s</b>ơñồ<b> kh</b>ố<b>i </b>


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 Ký hiệu bắt ñầu thuật toán


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


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


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



5


Ký hiệu rẽ nhánh


Nếu Bt Lơgíc có giá trị ð<b>úng thì </b>
thực hiện theo nhánh ð
Nếu Bt Lơgíc có giá trị<b> Sai thì th</b>ực


hiệ<b>n theo nhánh S </b>


6


Ký hiệu vịng lặp với số lần xác


định trước.


Thực hiện cơng việc A n lần, ban


ñầ<i>u Bi</i>ế<i>n </i>ñược gán bằng 1, sau mỗi
lần lặp biến tăng lên 1 ñơn vị


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


thực hiện các cơng việc A


8 Kí hiệu gọi chương trình con A


thực hiện


A


Biến=1, 2, ..,n
Bt Lơgíc


S


ð


A
A


Input:


Output:
begin


</div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

23
9


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


<i>B</i>ả<i>ng 3.1: M</i>ộ<i>t s</i>ố<i> ký hi</i>ệ<i>u dùng trong v</i>ẽ<i> s</i>ơđồ<i> kh</i>ố<i>i </i>
Ví dụ: Biểu diễn thuật tốn giải phương trình bậc 2 bằng sơđồ khối.


<i>S</i>ơđồ<i> kh</i>ố<i>i bi</i>ể<i>u di</i>ễ<i>n thu</i>ậ<i>t gi</i>ả<i>i ph</i>ươ<i>ng trình b</i>ậ<i>c hai ax2+bx+c=0, a</i>≠<i>0, a, b, c, x ∈ R. </i>


<b>Nh</b>ậ<b>n xét: S</b>ử dụng sơñồ khối để biểu diễn thuật tố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 tố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 tốn đơn giản (ít thao tác).



<b>3.3 Các c</b>

<b>u trúc c</b>

ơ

<b> b</b>

<b>n c</b>

<b>a thu</b>

<b>t tốn </b>



Khi mơ tả thuật tố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
<b>3.3.1 C</b>ấ<b>u trúc tu</b>ầ<b>n t</b>ự


<b>Khái ni</b>ệ<b>m: C</b>ấ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 tố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.


S


Begin


Input: a, b, c


Delta = b2 – 4ac


Output: Pt có 2
nghiệm x1, x2
Delta < 0



Output: Pt vô nghiệm


Delta = 0


x = -b/2a


Output: Pt Có nghiệm kép x


1 ( ) /(2 )


2 ( ) /(2 )


<i>x</i> <i>b</i> <i>Delta</i> <i>a</i>


<i>x</i> <i>b</i> <i>Delta</i> <i>a</i>


= − +
= − −


ð


End


S


</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25>

24


Ví du: ðặc tả thuật tố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 tốn bằng sơđồ khối thì trình tự thực hiện của thuật tố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 tốn giải bài toán trên:


<b>3.3.2 C</b>ấ<b>u trúc r</b>ẽ<b> nhánh </b>


<b>Khái ni</b>ệ<b>m: C</b>ấ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 tố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
<b>S</b>ơđồ<b> kh</b>ố<b>i th</b>ể<b> hi</b>ệ<b>n c</b>ấ<b>u trúc r</b>ẽ<b> nhánh </b>


Ví dụ: Giải phương trình bậc nhất ax + b = 0
Sơđồ khối thể hiện thuật tốn:


Input: r


S = πr2
C = 2πr


Output: S, C
begin


End



Biểu thức Lơgíc


ð


</div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

25
<b>3.3.3 C</b>ấ<b>u trúc l</b>ặ<b>p </b>


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.


<b>C</b>ấ<b>u trúc l</b>ặ<b>p xác </b>ñị<b>nh: </b>


<b>Khái ni</b>ệ<b>m: C</b>ấ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


<b>C</b>ấ<b>u trúc l</b>ặ<b>p khơng xác </b>đị<b>nh: </b>


<b>Khái ni</b>ệ<b>m: C</b>ấ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.


Input :a, b


a = 0


b = 0



Output: Pt vô số nghiệm


ð


Ouput: Pt vô nghiệm


x = -b/a


Output: x


S


S


ð


begin


end


Biến = 1, 2, .. n


</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

26


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


Ví dụ: Tìm số tự nhiên n nhỏ nhất để tổng s = ... 1 2.5
3



1
2
1


1+ + + + ≥


<i>n</i>


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 tốn sau:


<b>S</b>ử<b> d</b>ụ<b>ng ph</b>ươ<b>ng pháp </b>đặ<b>c t</b>ả<b> t</b>ự<b> nhiên mơ t</b>ả<b> thu</b>ậ<b>t toán: </b>
Bước 1. Khởi tạo giá trị ban ñầu n = 0, s = 0.


Bước 2. Tăng giá trị n lên 1 ñơn vị (n = n + 1), tính s = s +1
<i>n</i>


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.
<b>S</b>ử<b> d</b>ụ<b>ng s</b>ơđồ<b> kh</b>ố<b>i mơ t</b>ả<b> thu</b>ậ<b>t tốn </b>


s = 0, n = 1


s < 2.5


s = s + 1/n
n = n +1


ð



S


s, n
begin


end
Miền tác ñộng


Miền tác động
Biểu thức lơgíc


Biểu thức lơgíc


ð


S


ð


S


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

27


<b>3.4 M</b>

<b>t s</b>

<b> thu</b>

<b>t toán gi</b>

<b>i m</b>

<b>t s</b>

<b> bài tốn </b>

đơ

<b>n gi</b>

<b>n </b>



<b>3.4.1 Bài tốn </b>đế<b>m </b>


<b>Bài toán: Cho m</b>ộ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 tố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ị.


<b>Thu</b>ậ<b>t toán </b>


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


<b>B</b>ướ<b>c 2. Kh</b>ởi tạo một biến ñếm với giá trị là 0


<b>B</b>ướ<b>c 3. Th</b>ự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 tố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.
<b>Mơ t</b>ả<b> thu</b>ậ<b>t tốn b</b>ằ<b>ng s</b>ơđồ<b> kh</b>ố<b>i </b>


Ví dụ 1: Cho một dãy n số nguyên. ðếm xem trong dãy có bao nhiêu số chẵn.
<b>Thu</b>ậ<b>t toán </b>


<b>S</b>ử<b> d</b>ụ<b>ng ph</b>ươ<b>ng pháp </b>đặ<b>c t</b>ả<b> t</b>ự<b> nhiên mơ t</b>ả<b> thu</b>ậ<b>t tốn </b>


n


i = 1, 2, .., n


ai


Dem = 0



i = 1, 2, .., n


Bt Lơgíc


Dem


S


ð


Dem = Dem +1
Begin


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

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


<b>B</b>ướ<b>c 2. Kh</b>ởi tạo một biến ñếm với giá trị là 0


<b>B</b>ướ<b>c 3. Th</b>ự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.


<b>S</b>ử<b> d</b>ụ<b>ng s</b>ơđồ<b> kh</b>ố<b>i mơ t</b>ả<b> thu</b>ậ<b>t tốn </b>


<i>Mơ t</i>ả<i> thu</i>ậ<i>t tốn </i>đế<i>m các s</i>ố<i> ch</i>ẵ<i>n trong m</i>ộ<i>t dãy s</i>ố


<b>3.4.2 Bài tốn tìm giá tr</b>ị<b> l</b>ớ<b>n nh</b>ấ<b>t, giá tr</b>ị<b> nh</b>ỏ<b> nh</b>ấ<b>t </b>


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 tốn giải bài tố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 tốn cụ thểđược phát biểu như sau:


<b>Bài tốn: Cho m</b>ộ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. Q trình tìm được thể hiện
bằng thuật tốn sau đây.


<b>Thu</b>ậ<b>t tốn </b>


<b>S</b>ử<b> d</b>ụ<b>ng ph</b>ươ<b>ng pháp </b>đặ<b>c t</b>ả<b> t</b>ự<b> nhiên mơt t</b>ả<b> thu</b>ậ<b>t tốn </b>
<b>B</b>ướ<b>c 1. Xác </b>định n và các số a1, a2, …, an


<b>B</b>ươ<b>c 2. S</b>ử 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>B</b>ướ<b>c 3. Duy</b>ệ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ố.


Input: n


i = 1, 2, .., n



Input: ai


Dem = 0


i = 1, 2, .., n


aiM 2


Dem = Dem +1


Output: Dem


S


ð


Begin


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

29
<b>S</b>ử<b> d</b>ụ<b>ng s</b>ơđồ<b> kh</b>ố<b>i mơ t</b>ả<b> thu</b>ậ<b>t tốn </b>


<i>Thu</i>ậ<i>t tốn tìm giá tr</i>ị<i> l</i>ớ<i>n nh</i>ấ<i>t c</i>ủ<i>a m</i>ộ<i>t dãy s</i>ố<i>. </i>


ðối với bài tố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ó.


<b>M</b>ộ<b>t s</b>ố<b> bài tốn qui v</b>ề<b> bài tốn tìm max, min </b>
Bài 1. Cho tọa ñộ của một dãy n ñiểm

{

}




1


, <i>n</i>


<i>i</i> <i>i</i> <i>i</i>


<i>x y</i> <sub>=</sub> trong mặt phẳng. Tìm diện tích đường
trịn tâm O(0,0) có bán kính nhỏ nhất chứa n điểm trên.


<i>G</i>ợ<i>i ý: Bài tốn này qui v</i>ề<i> bài tốn tìm Max </i>
Bài 2. Cho tọa độ của một dãy n ñiểm

{

}



1


, <i>n</i>


<i>i</i> <i>i</i> <i><sub>i</sub></i>


<i>x y</i> <sub>=</sub> trong mặt phẳng. Tìm hình chữ nhật có
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.


<i>G</i>ợ<i>i ý: Bài tốn này qui v</i>ề<i> bài tốn tìm c</i>ả<i> Min và Max. </i>


<b>3.4.3 Bài tốn tính t</b>ổ<b>ng m</b>ộ<b>t dãy s</b>ố


<b>Bài tốn: Cho 1 dãy n s</b>ố. Tính tổng tất cả các phần tử của dãy.
<b>Thu</b>ậ<b>t toán </b>


<b>S</b>ử<b> d</b>ụ<b>ng ph</b>ươ<b>ng pháp </b>đặ<b>c t</b>ả<b> t</b>ự<b> nhiên mơ t</b>ả<b> thu</b>ậ<b>t tốn </b>


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.
<b>S</b>ử<b> d</b>ụ<b>ng s</b>ơđồ<b> kh</b>ố<b>i mơ t</b>ả<b> thu</b>ậ<b>t toán </b>


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


i = 1, 2, .., n


Input: ai


Max = a1


Max<ai


Output: Max


S


ð


Max = ai


Begin



</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

30
<b>M</b>ộ<b>t s</b>ố<b> bài tốn qui v</b>ề<b> bài tốn tính t</b>ổ<b>ng </b>


Bài 1. Tính giá trị của đa thực Pn(x) = a0 + a1x + a2x2 + … +anxn


Bài 2. Tính tổng theo cơng thức (cơng thức tổng qt dạng S = f(x) +


=
<i>n</i>
<i>i</i>
<i>i</i>
<i>x</i>
<i>g</i>
1
)
,
( )


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


S = ex + 1
2
<i>x</i>
+
+
2
1
3
<i>x</i>
+



+ … + 1
1
<i>n</i>
<i>x</i>
<i>n</i>
+
+


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


1 2


2006 ... ( 1)


1! 2! !


<i>n</i>


<i>x</i> <i>x</i> <i>x</i> <i>n</i>


<i>s</i>


<i>n</i>


+ + +


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



2
2006 ...
2! !
<i>n</i>
<i>x</i> <i>x</i>
<i>S</i> <i>x</i>
<i>n</i>
= + + + +


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 ?


Input: n


i = 1, 2, .., n


Input: ai



S = 0


i = 1, 2,..., n


S = S + ai


Output: S
Begin


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

31


<b>3.4.4 Bài tốn tính tích m</b>ộ<b>t dãy s</b>ố


<b>Bài tốn: Cho 1 dãy n s</b>ố. Tính tích tất cả các phần tử của dãy.


Thuật tố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 tố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).


<b>Các bài tốn qui v</b>ề<b> thu</b>ậ<b>t tốn tính tích </b>
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


<b>CÂU H</b>Ỏ<b>I CH</b>ƯƠ<b>NG 3 </b>


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ố ngun 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]?


</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

32



PH

N 2



</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

33


<b>M</b>

<b>t s</b>

<b> gi</b>

<b>i thi</b>

<b>u m</b>

đầ

<b>u v</b>

<b> Ngơn ng</b>

<b> l</b>

<b>p trình C </b>



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 q 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 tốn tử rất quan trọng dùng để thể hiện các thuật tốn , đó
là tốn tử rẽ nhánh if, và các tố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, hố đơ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.


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

34


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



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. Ngồ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


<b>1.1 T</b>

<b>p ký t</b>

<b> </b>



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 tốn để giải một bài tố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: _ ( <i><b>chú ý: phân bi</b></i>ệ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ự.



<i><b>Chú ý: Khi vi</b></i>ế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.


<b>1.2 T</b>

<b> khóa </b>



Từ khóa là những từđược định nghĩa trước và có một ý nghĩa hồn tồ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 tố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


</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

35


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.


<b>1.3 Tên </b>



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)


<i><b>Chú ý: Trong các tên, ch</b></i>ữ hoa và chữ thường ñược xem là khác nhau, như vậy tên AB
khác tên ab.


<b>1.4 M</b>

<b>t s</b>

<b> khái ni</b>

<b>m </b>



<b>1.4.1 Bi</b>ế<b>n </b>


Biến là ñại lượng dùng ñể chứa (lưu trữ) các giá trị trong q trình tính tố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.


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

36


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 ln ln nhận
giá trị ngun trong q trình tính tốn cịn biến kiểu float có thể nhận cả các giá trị là các số


thực.
<b>1.4.2 H</b>ằ<b>ng </b>


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.
<b>1.4.3 Tốn t</b>ử<b> gán </b>


Câu lệnh gán sẽ nói kỹ trong chương 2. Ởđây ta có thể hiểu tố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 tố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.


<b>Ví d</b>ụ<b>: Sau khi th</b>ự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.


<i><b>Chú ý: khái ni</b></i>ệm gán không giống như khái niệm đẳng thức trong tốn học.
<b>1.4.4 Câu l</b>ệ<b>nh và kh</b>ố<b>i l</b>ệ<b>nh </b>


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);
}


<i><b>Chú ý: V</b></i>ề 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.


<b>Khai báo </b>ởđầ<b>u kh</b>ố<b>i l</b>ệ<b>nh </b>


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)


</div>
<span class='text_page_counter'>(38)</span><div class='page_container' data-page=38>

37
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);
}


<b>S</b>ự<b> l</b>ồ<b>ng nhau c</b>ủ<b>a các kh</b>ố<b>i l</b>ệ<b>nh </b>


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ế.


<b>Ph</b>ạ<b>m vi ho</b>ạ<b>t </b>ñộ<b>ng c</b>ủ<b>a các bi</b>ế<b>n và m</b>ả<b>ng </b>


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 ngồi khối lệnh đó.


- Từ bên ngồ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.


<b>V</b>ề<b> các kh</b>ố<b>i l</b>ệ<b>nh l</b>ồ<b>ng nhau </b>


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 ngồ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 ngồi.
<b>1.4.5 Chú thích </b>


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


</div>
<span class='text_page_counter'>(39)</span><div class='page_container' data-page=39>

38
- 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(); // xố màn hình


printf(“Hello”); // in ra màn hình dịng chữ Hello


<b>1.5 M</b>

<b>t s</b>

<b> ch</b>

ươ

<b>ng trình </b>

đơ

<b>n gi</b>

<b>n </b>



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 /* */.


<b>Ví d</b>ụ<b> 1. Vi</b>ế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 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ả */
}


<b>Nh</b>ậ<b>n xét: M</b>ỗ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.


<b>Ví d</b>ụ<b> 2. Ch</b>ươ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ề 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);



</div>
<span class='text_page_counter'>(40)</span><div class='page_container' data-page=40>

39


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ả */


}


<b>Ví d</b>ụ<b> 3: Tính x lu</b>ỹ 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);
}


<b>Ví d</b>ụ<b> 4: Minh ho</b>ạ 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


<b>1.6 M</b>

<b>t s</b>

<b> quy t</b>

<b>c c</b>

<b>n nh</b>

<b> khi vi</b>

ế

<b>t ch</b>

ươ

<b>ng trình </b>



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.


<i>Quy t</i>ắ<i>c </i>ñầ<i>u tiên c</i>ầ<i>n nh</i>ớ<i> là: M</i>ỗ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.


</div>
<span class='text_page_counter'>(41)</span><div class='page_container' data-page=41>

40


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");



<i>Quy t</i>ắ<i>c th</i>ứ<i> hai là quy t</i>ắ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.


<i>Qui t</i>ắ<i>c th</i>ứ<i> ba là qui t</i>ắ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 tốn tử


#include để gắn tệp đó vào tệp chương trình của ta.


<i>Qui t</i>ắ<i>c th</i>ứ<i> t</i>ư 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:


<b>1.7 Cách th</b>

<b>c hi</b>

<b>n các ch</b>

ươ

<b>ng trình trên máy tính </b>




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. Q 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 đi C và soạn thảo chương trình.
- Dịch và chạy chương trình.


<i>#include …… </i>


<i>khai báo các bi</i>ế<i>n, các m</i>ả<i>ng tồn c</i>ụ<i>c n</i>ế<i>u có </i>
<i>khai báo và xây d</i>ự<i>ng các hàm n</i>ế<i>u có </i>
<i>void main() </i>


<i>{ </i>


<i>.. các l</i>ệ<i>nh… </i>
<i>} </i>


</div>
<span class='text_page_counter'>(42)</span><div class='page_container' data-page=42>

41


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) .


<b>Th</b>ự<b>c hi</b>ệ<b>n ch</b>ươ<b>ng trình trong TC2.0 </b>


Giả sử TC2.0 ñã ñược cài ñặt trong thư mục C:\TC



<b>So</b>ạ<b>n th</b>ả<b>o ch</b>ươ<b>ng trình: Vào mơi tr</b>ườ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.


<b>D</b>ị<b>ch và ch</b>ạ<b>y ch</b>ươ<b>ng trình: B</b>ấm đồng thời 2 phím Ctrl và F9, hoặc chọn menu Run,
mục Run.


<b>Th</b>ự<b>c hi</b>ệ<b>n ch</b>ươ<b>ng trình trong TC++3.0 </b>


Giả sử TC++3.0 đã được cài đặt trong thư mục C:\TC++


<b>So</b>ạ<b>n th</b>ả<b>o ch</b>ươ<b>ng trình: Vào mơi tr</b>ườ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.


<b>D</b>ị<b>ch và ch</b>ạ<b>y ch</b>ươ<b>ng trình: B</b>ấm đồng thời 2 phím Ctrl và F9, hoặc chọn menu Run,
mục Run.


<b>BÀI T</b>

<b>P CH</b>

ƯƠ

<b>NG 1 </b>



<b>Bài 1. Th</b>ự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>Bài 2. L</b>ậ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>Bài 3. Cho bi</b>ết lương kỳ hai của cán bộ tính theo cơng thức:
lk2 = <i>bl</i> *<i>n</i>−<i>t</i>


26
540
*


</div>
<span class='text_page_counter'>(43)</span><div class='page_container' data-page=43>

42


<b>CHƯƠNG 2 - CÁC KIỂU DỮ LIỆU </b>



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 ngun 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.


<b>2.1 Các ki</b>

<b>u d</b>

<b> li</b>

<b>u c</b>

ơ

<b> b</b>

<b>n </b>



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.


<b>2.1.1 Các ki</b>ể<b>u s</b>ố<b> nguyên </b>


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.


<b>Ki</b>ể<b>u </b> <b>Ph</b>ạ<b>m vi bi</b>ể<b>u di</b>ễ<b>n </b> <b>Kích th</b>ướ<b>c </b>



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ố ngun khơng dấu. Các kiểu số


ngun 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:


<b>Ki</b>ể<b>u </b> <b>Ph</b>ạ<b>m vi bi</b>ể<b>u di</b>ễ<b>n </b> <b>Kích th</b>ướ<b>c </b>


unsigned char 0 → 255 1 byte


unsigned int 0 → 65535 2 byte


unsigned long 0 → 4294967295 4 byte


<b>2.1.2 Các ki</b>ể<b>u s</b>ố<b> th</b>ự<b>c </b>


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:


<b>Ki</b>ể<b>u </b> <b>Ph</b>ạ<b>m vi bi</b>ể<b>u di</b>ễ<b>n </b> <b>S</b>ố<b> ch</b>ữ<b> s</b>ố<b> có ngh</b>ĩ<b>a </b> <b>Kích th</b>ướ<b>c (byte) </b>


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


<b>Gi</b>ả<b>i thích: Máy có th</b>ể 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ự.


</div>
<span class='text_page_counter'>(44)</span><div class='page_container' data-page=44>

43


ðể 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ụ:


<b>Ký t</b>ự <b>Mã ASCII </b>


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).


<b>Ki</b>ể<b>u </b>ñ<b>úng sai </b>


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.


<b>2.2 H</b>

<b>ng </b>



Hằng là các đại lượng mà giá trị của nó khơng thay đổi trong q trình tính tốn. Dưới


đây trình bày cách biểu diễn các hằng trong C.
<b>2.2.1 H</b>ằ<b>ng s</b>ố<b> th</b>ự<b>c (float và double) </b>


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:


<b>Cách 1 (d</b>ạ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


<i><b>Chú ý: Ph</b></i>ầ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.


<b>Cách 2 (d</b>ạ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


</div>
<span class='text_page_counter'>(45)</span><div class='page_container' data-page=45>

44
-49.5e-2 (biểu diễn giá trị -0.495)
1e8 (biểu diễn giá trị 100000000.0)
<b>2.2.2 H</b>ằ<b>ng s</b>ố<b> nguyên ki</b>ể<b>u int </b>


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 ...


<i><b>Chú ý: phân bi</b></i>ệ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).


<b>2.2.3 H</b>ằ<b>ng ki</b>ể<b>u long </b>


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ị.
<b>2.2.4 Bi</b>ể<b>u di</b>ễ<b>n h</b>ằ<b>ng nguyên trong h</b>ệ<b> 8 </b>


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 ln ln 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


<b>2.2.5 Bi</b>ể<b>u di</b>ễ<b>n h</b>ằ<b>ng nguyên trong h</b>ệ<b> 16 </b>



Hệ cơ số 16 cần 16 ký tựñể biểu diễn các chữ số, vì vậy ngồ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


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


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ụ:


</div>
<span class='text_page_counter'>(46)</span><div class='page_container' data-page=46>

45
'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:


<b>Cách vi</b>ế<b>t </b> <b>Ký t</b>ự


<i>'\'' </i> <i>' </i>



<i>'\"' </i> <i>" </i>


<i>'\\' </i> <i>\ </i>


<i>'\n' </i> <i>\n (chuy</i>ể<i>n dòng) </i>
<i>'\0' </i> <i>\0 (null) </i>


<i>'\t' </i> <i>Tab </i>


<i>'\b' </i> <i>Backspace </i>


<i>'\r' </i> <i>CR (v</i>ềđầ<i>u dịng) </i>
<i>'\f' </i> <i>LF (sang trang) </i>


<b>2.2.7 H</b>ằ<b>ng xâu ký t</b>ự


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ự).


<i><b>Chú ý: C</b></i>ầ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.



<b>2.2.8 </b>ðặ<b>t tên cho h</b>ằ<b>ng </b>


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;


<b>2.3 Bi</b>

ế

<b>n </b>



<b>2.3.1. Khai báo </b>


</div>
<span class='text_page_counter'>(47)</span><div class='page_container' data-page=47>

46


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


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.



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


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);
}


<b>2.3.3 Vi</b>ệ<b>c kh</b>ở<b>i </b>ñầ<b>u cho các bi</b>ế<b>n </b>


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ờ tố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;


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


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ớ….


<b>2.3.5 L</b>ấ<b>y </b>ñị<b>a ch</b>ỉ<b> c</b>ủ<b>a bi</b>ế<b>n </b>


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


<b>2.4 M</b>

<b>ng </b>




<b>2.4.1 Khái ni</b>ệ<b>m v</b>ề<b> m</b>ả<b>ng, cách khai báo </b>


</div>
<span class='text_page_counter'>(48)</span><div class='page_container' data-page=48>

47


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.


<i><b>Chú ý: </b></i>


- 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.


</div>
<span class='text_page_counter'>(49)</span><div class='page_container' data-page=49>

48


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 q 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 ngun 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ố


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


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]


<b>2.5 Các phép toán trên các ki</b>

<b>u </b>



<b>2.5.1 Bi</b>ể<b>u th</b>ứ<b>c </b>


Biểu thức là một sự kết hợp giữa các phép tốn và các tốn hạng để diễn đạt một cơng
thức tố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 tố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).


<b>2.5.2 Phép tốn s</b>ố<b> h</b>ọ<b>c </b>


Các phép tốn hai ngơi số học là:


<b>Phép tốn </b> <b>Ý ngh</b>ĩ<b>a </b> <b>Ví d</b>ụ


+ Cộng a + b


- Trừ a - b



* Nhân a * b


/ Chia a / b


% Lấy phần dư a % b


Có phép tố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ố ngun đó là phần ngun của thương số), ví dụ:


</div>
<span class='text_page_counter'>(50)</span><div class='page_container' data-page=50>

49


Phép toán % cho phần dư của phép chia ngun, 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
tố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 tốn số học ñược thực
hiện từ trái sang phải.


Các phép tốn số học dùng để viết các cơng thức tốn học, ví dụ:
(a*a-b*b)/(x*x+y*y)


<b>2.5.3 Các phép tốn so sánh </b>


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 tốn so sánh cho trong bảng sau:


<b>Phép toán </b> <b>ý ngh</b>ĩ<b>a </b> <b>Ví d</b>ụ
> 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 tố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.


<b>2.5.4 Phép toán logic </b>


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 tố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


Khác không 0
Bằng không 1


</div>
<span class='text_page_counter'>(51)</span><div class='page_container' data-page=51>

50
Trong đó a và b có thể ngun 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 tốn so sánh và logic được dùng để thiết lập điều kiện rẽ nhánh trong tố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


<b>2.5.5 Chuy</b>ể<b>n ki</b>ể<b>u </b>



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).


Ngồ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)


<b>2.5.6 Các phép tốn t</b>ă<b>ng gi</b>ả<b>m </b>


C đưa ra hai phép tố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 tốn hạng của nó, tố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 tốn ++ và -- có thểđứng trước hoặc sau tố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.


<b>Ví d</b>ụ<b>: N</b>ế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.


</div>
<span class='text_page_counter'>(52)</span><div class='page_container' data-page=52>

51


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.


<b>2.5.7 Bi</b>ể<b>u th</b>ứ<b>c </b>ñ<b>i</b>ề<b>u ki</b>ệ<b>n </b>


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.


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


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.
<b>M</b>ộ<b>t s</b>ố<b> d</b>ạ<b>ng khác c</b>ủ<b>a toán t</b>ử<b> gán. </b>


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 tốn> = <biểu thức>;
Trong đó <phép tốn> là một phép tốn hai ngơi.


Ví dụ câu lệnh:


x = x*(y+3);
có thể viết thành:


x *= y+3;


<b>2.5.9 Th</b>ứ<b> t</b>ựư<b>u tiên các phép toán </b>


</div>
<span class='text_page_counter'>(53)</span><div class='page_container' data-page=53>

52


<b>STT </b> <b>Phép tốn </b> <b>Trình t</b>ự<b> k</b>ế<b>t h</b>ợ<b>p </b>


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 <b>? : </b> Phải qua trái



10 <b>= += -= *= /= %= <<= >>= &= ^= |= </b> Phải qua trái


11 <b>, </b> Trái qua phải


<b>Gi</b>ả<b>i thích: </b>


- Các phép tốn trên một dịng có cùng thứ tựưu tiên, các phép tốn ở hàng trên có
sốưu tiên cao hơn các phép tố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 tố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).


<b>2.6 Nh</b>

<b>p xu</b>

<b>t d</b>

<b> li</b>

<b>u </b>



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.


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


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ả.


</div>
<span class='text_page_counter'>(54)</span><div class='page_container' data-page=54>

53


đô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:
ðư<b>a ra các giá tr</b>ị<b> nguyên </b>


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);
}


}


</div>
<span class='text_page_counter'>(55)</span><div class='page_container' data-page=55>

54


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ịđó.


ðư<b>a ra các giá tr</b>ị<b> th</b>ự<b>c </b>


ðểđư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
ðư<b>a ra các xâu ký t</b>ự


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 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


</div>
<span class='text_page_counter'>(56)</span><div class='page_container' data-page=56>

55


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.
<b>2.6.2 Nh</b>ậ<b>p d</b>ữ<b> li</b>ệ<b>u t</b>ừ<b> bàn phím </b>


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ự.


<b>Nh</b>ậ<b>p s</b>ố<b> nguyên, s</b>ố<b> th</b>ự<b>c b</b>ằ<b>ng scanf </b>


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 tố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:


<b>Cách 1: M</b>ỗ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


<b>Cách 2: </b>ðặ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.
<b>Nh</b>ậ<b>p xâu ký t</b>ự<b> b</b>ằ<b>ng gets </b>


ðể 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.



</div>
<span class='text_page_counter'>(57)</span><div class='page_container' data-page=57>

56


<b>2.7 M</b>

<b>t s</b>

<b> hàm th</b>

ườ

<b>ng dùng </b>



ðộ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.


<b>2.7.1 Hàm toán h</b>ọ<b>c </b>


Các hàm thuộc thư viện math.h hoặc trong stdlib.h
<i>1. abs – Tính giá tr</i>ị tuyệt ñối của số nguyên x


<i>int abs(int x); </i>


<i>2. labs-Tính giá tr</i>ị tuyệt đối của số nguyên dài x
<i>long int labs(long int x) </i>


<i>3. cos – Tính cosine c</i>ủa x
<i>double cos(double x) </i>
<i>4. exp – Tính e m</i>ũ x


<i>double exp(double x) </i>
<i>5. fabs-Tính giá tr</i>ị tuyệt ñối của x


<i>double fabs(double x) </i>


<i>6. log – Tính logarit c</i>ơ số tự nhiên của x
<i>double log(double x) </i>



<i>7.log10 - Tính logarit c</i>ơ số10 của x
<i>double log10(double x) </i>
<i>8. pow – Tính x m</i>ũ y


<i>double pow(double x, double y) </i>
<i>9. sin – Tính sine c</i>ủa x


<i>double sin(double x) </i>
<i>10. sqrt – Tính c</i>ăn bậc hai của x


<i>double sqrt(double x) </i>


<b>2.7.2 Hàm x</b>ử<b> lý chu</b>ỗ<b>i ký t</b>ự


Các hàm khai báo trong string.h


<i>1. strcmp: so sánh 2 chu</i>ỗi s1, s2 phân biệt chữ thường và chữ hoa
<i> int strcmp(char * s1, char *s2) </i>


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.


<i>2. strcmpi: so sánh 2 chu</i>ỗi không phân biệt chữ thường và chữ hoa
<i>int strcmpi(char *s1, char *s2) </i>


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
<i>3. strcpy : sao chép chu</i>ỗi


<i>int strcpy(char *dest, char *sour) </i>


<i>4. stricmp: gi</i>ống hàm strcmpi


<i>5. strlen: tính </i>độ dài của chuỗi
<i> int strlen(char *s) </i>


hàm này trả về số nguyên là số ký tự của chuỗi s (ñộ dài của s)
<i>6. strrev: </i>ñảo ngược 1 chuỗi


<i> char * strrev( char *s) </i>


hàm này trả về chuỗi ñảo của chuỗi s


</div>
<span class='text_page_counter'>(58)</span><div class='page_container' data-page=58>

57


<b>BÀI T</b>

<b>P CH</b>

ƯƠ

<b>NG 2 </b>



<b>Bài 1. Tìm các ch</b>ỗ 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>Bài 2. Vi</b>ế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>Bài 3. Tìm các ch</b>ỗ sai trong đoạn chương trình
float a[3], b = 2;


a[0] = 5;


a[10] = 4, a[b] = 7;


<b>Bài 4. Tìm các ch</b>ỗ 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);


}


</div>
<span class='text_page_counter'>(59)</span><div class='page_container' data-page=59>

58


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




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)


Ngồ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 hồn chỉnh đã thử nghiệm trên máy.


<b> 3.1 Nh</b>

<b>c l</b>

<b>i khái ni</b>

<b>m v</b>

<b> câu l</b>

<b>nh và kh</b>

<b>i l</b>

<b>nh </b>



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).


<b>3.2. L</b>

<b>nh if </b>



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.


<b>3.2.1 Cú pháp c</b>ủ<b>a if </b>
Lệnh if có hai dạng sau:
<b>D</b>ạ<b>ng 1 </b>


if (<biểu thức ñiều kiện>)
<khối lệnh>


<b>D</b>ạ<b>ng 2 </b>


</div>
<span class='text_page_counter'>(60)</span><div class='page_container' data-page=60>

59
<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.
<b>3.2.2 Ho</b>ạ<b>t </b>ñộ<b>ng c</b>ủ<b>a if </b>


<b>S</b>ự<b> ho</b>ạ<b>t </b>ñộ<b>ng c</b>ủ<b>a l</b>ệ<b>nh if d</b>ạ<b>ng 1 </b>


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ó.


<b>S</b>ự<b> ho</b>ạ<b>t </b>độ<b>ng c</b>ủ<b>a l</b>ệ<b>nh if d</b>ạ<b>ng 2 </b>


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);
}


<b>3.2.3 S</b>ự<b> l</b>ồ<b>ng nhau c</b>ủ<b>a l</b>ệ<b>nh if </b>


</div>
<span class='text_page_counter'>(61)</span><div class='page_container' data-page=61>

60


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 ngun 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));
}


<i><b>Chú ý: </b></i>ñối với trường hợp cuối cùng có thể khơng cần if, nhưở ví dụ trên.
<b>3.2.4 Vi</b>ế<b>t ch</b>ươ<b>ng trình theo c</b>ấ<b>u trúc </b>


ðể 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).


</div>
<span class='text_page_counter'>(62)</span><div class='page_container' data-page=62>

61


<b>3.3 L</b>

<b>nh for </b>



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 tốn có tính chu trình, ví dụ như các bài tốn về dãy số, về ma trận.
<b>3.3.1 Cú pháp c</b>ủ<b>a for </b>


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.


<b>3.3.2 Ho</b>ạ<b>t </b>ñộ<b>ng c</b>ủ<b>a for </b>


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 thố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.
<i><b>Chú ý: </b></i>


- 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.


<b>3.3.3 Ví d</b>ụ<b> minh ho</b>ạ


<b>Ví d</b>ụ<b> 1: </b>ðả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


</div>
<span class='text_page_counter'>(63)</span><div class='page_container' data-page=63>

62


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]);
}


<b>Ví d</b>ụ<b> 2: Ch</b>ương trình dưới đây giải quyết bài tố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);


}
}


<b>Ví d</b>ụ<b> 3: Ch</b>ươ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]);
}


</div>
<span class='text_page_counter'>(64)</span><div class='page_container' data-page=64>

63
#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);


}
<b>} </b>


<b>3.4 L</b>

<b>nh while </b>




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.


<b>3.4.1 Cú pháp c</b>ủ<b>a while </b>
Cú pháp của while có dạng:


while (<biểu thức kiểm tra5<sub>>) </sub>


<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.
<b>3.4.2 Ho</b>ạ<b>t </b>ñộ<b>ng c</b>ủ<b>a while. </b>


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.


<b>Nh</b>ậ<b>n xét: Thân c</b>ủ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


</div>
<span class='text_page_counter'>(65)</span><div class='page_container' data-page=65>

64
<i><b>Chú ý: </b></i>


- ðể 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.


<b>3.4.3 Ví d</b>ụ<b> minh ho</b>ạ


<b>Ví d</b>ụ<b> 1: Tính tích vơ h</b>ướ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);
}


<b>Ví d</b>ụ<b> 2: Ch</b>ươ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);
}


<b>Ví d</b>ụ<b> 3: Tìm ph</b>ầ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)


</div>
<span class='text_page_counter'>(66)</span><div class='page_container' data-page=66>

65
else


printf("Khong co phan tu am.");
<b>} </b>


<b>3.5 L</b>

<b>nh do - while </b>



Trong các lệ<i>nh while và for, vi</i>ệ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.


<b>3.5.1 Cú pháp c</b>ủ<b>a do – while </b>
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).
<b>3.5.2 Ho</b>ạ<b>t </b>độ<b>ng c</b>ủ<b>a do while </b>


Lệ<i>nh do – while th</i>ự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ệ<i>nh do – while. </i>


<b>3.5.3 Ví d</b>ụ<b> minh ho</b>ạ


<b>Ví d</b>ụ<b> : Tính c</b>ă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 tốn trên được chương trình hố 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;


</div>
<span class='text_page_counter'>(67)</span><div class='page_container' data-page=67>

66
}


while (fabs((x-c)/c) >= 1e-5);


printf("Can bac hai cua %.4f la %.4f", a, x);
}


<b>3.6 L</b>

<b>nh break </b>




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 thố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.


<b>3.6.1 Cú pháp c</b>ủ<b>a break </b>
Lệnh break có dạng sau:
break;


<b>Ghi chú: </b>


- 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ó.


<b>3.6.2 Ho</b>ạ<b>t </b>độ<b>ng c</b>ủ<b>a break </b>


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.


<b>3.6.3 Ví d</b>ụ<b> minh ho</b>ạ


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.");
}


<b>3.7 L</b>

<b>nh continue </b>



</div>
<span class='text_page_counter'>(68)</span><div class='page_container' data-page=68>

67
<b>3.7.1 Cú pháp c</b>ủ<b>a continue </b>


Lệnh continue có dạng:
continue;


<b>Ghi chú: </b>


- 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.


<b>3.7.2 Ho</b>ạ<b>t </b>ñộ<b>ng c</b>ủ<b>a continue </b>


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.
<b>3.7.3 Ví d</b>ụ<b> minh ho</b>ạ



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);


</div>
<span class='text_page_counter'>(69)</span><div class='page_container' data-page=69>

68


<b>BÀI T</b>

<b>P CH</b>

ƯƠ

<b>NG 3 </b>



<b>Bài 1. L</b>ậ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>Bài 2. L</b>ậ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>Bài 3. L</b>ập chương trình tính ex theo công thức xấp xỉ


e x x x



n


x


n


= + +1 + +


1 2


2


! ... !


với độ chính xác 0.00001. Tức là n cần chọn sao cho
x


n


n


! <0 00001 .


<b>Bài 4. L</b>ập chương trình tính sin(x) với độ chính xác 0.0001 theo công thức:
sin( )


! ! ... ( ) ( )!


x x x x x



n
n
n
= − + + + −



3 5 2 1


3 5 1 2 1


<b>Bài 5. L</b>ậ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>Bài 6. L</b>ập chương trình tính tổ hợp chập m của n


C m n n n n m


m


( , ) .( ) ...( )


!


= −1 − +1



<b>Bài 7. L</b>ậ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>Bài 8. Nh</b>ậ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>Bài 9. L</b>ập chương trình tính


5
.
0
2
2
2
2


1 ... )


(<i>a</i> <i>a</i> <i>an</i>


<i>S</i>= + + +


trong đó n và a1,...,an nhận từ bàn phím.


<b>Bài 10. C</b>ầ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>Bài 11. L</b>ập chương trình tìm phần tử âm cuối cùng của dãy a1,...,an.



<b>Bài 12. Cho hai dãy s</b>ố: 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.


</div>
<span class='text_page_counter'>(70)</span><div class='page_container' data-page=70>

69
<b>Bài 14. S</b>ắp xếp một dãy số theo thứ tự tăng dần.


<b>Bài 15. Cho dãy s</b>ố 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>Bài 16. Cho hi</b>ện lên màn hình các kí tự có mã ASCII từ 33 đến 255.
<b>Bài 17. Vi</b>ết chương trình tính giá trị của đa thức và đạo hàm của nó.
<b>Bài 18. Vi</b>ết chương trình tính định thức của ma trận vuông cấp n.


</div>
<span class='text_page_counter'>(71)</span><div class='page_container' data-page=71>

70


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



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 tố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.


<b>4.1 T</b>

<b> ch</b>

<b>c ch</b>

ươ

<b>ng trình thành các hàm </b>




<b>4.1.1. Khái ni</b>ệ<b>m chung v</b>ề<b> hàm </b>


Xét bài tố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 */
}


<b>Ghi chú: </b>


- 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 ngun 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ụ


</div>
<span class='text_page_counter'>(72)</span><div class='page_container' data-page=72>

71


- 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. Ngồ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.


<b>4.1.2 Quy t</b>ắ<b>c xây d</b>ự<b>ng m</b>ộ<b>t hàm </b>


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:


<b>Nguyên m</b>ẫ<b>u hàm </b>


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.



ðị<b>nh ngh</b>ĩ<b>a hàm </b>


ðị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>];


</div>
<span class='text_page_counter'>(73)</span><div class='page_container' data-page=73>

72
<b>4.1.3 S</b>ử<b> d</b>ụ<b>ng hàm </b>


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. Q 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ẽ xố 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.


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


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


</div>
<span class='text_page_counter'>(74)</span><div class='page_container' data-page=74>

73


<b>4.2 Tham s</b>

<b> ki</b>

<b>u con tr</b>



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.


<b>4.2.1 </b>ðị<b>a ch</b>ỉ


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ố ngun nhưng khơng được đánh


đồng nó với các số ngun 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 tốn &. Ví dụđể lấy địa chỉ của biến alpha.
&alpha


<b>4.2.2 Con tr</b>ỏ


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 hồn tồ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ụ


</div>
<span class='text_page_counter'>(75)</span><div class='page_container' data-page=75>

74
<b>4.2.3 Qui t</b>ắ<b>c s</b>ử<b> d</b>ụ<b>ng con tr</b>ỏ<b> trong các bi</b>ể<b>u th</b>ứ<b>c </b>


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.


<b>S</b>ử<b> d</b>ụ<b>ng tên con tr</b>ỏ


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 tố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.


<b>S</b>ử<b> d</b>ụ<b>ng d</b>ạ<b>ng khai báo c</b>ủ<b>a con tr</b>ỏ
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.
<b>4.2.4 M</b>ả<b>ng và con tr</b>ỏ


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.


</div>
<span class='text_page_counter'>(76)</span><div class='page_container' data-page=76>

75


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.


<b>4.2.5 Hàm có </b>đố<b>i con tr</b>ỏ


ðố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ả.


<b>S</b>ử<b> d</b>ụ<b>ng hàm </b>ñể<b> thay </b>ñổ<b>i giá tr</b>ị<b> c</b>ủ<b>a m</b>ộ<b>t bi</b>ế<b>n </b>


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);


</div>
<span class='text_page_counter'>(77)</span><div class='page_container' data-page=77>

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


a = 13.50 b = 7.60


Ta hãy xem hàm hố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.


<b>Truy</b>ề<b>n m</b>ộ<b>t m</b>ả<b>ng m</b>ộ<b>t chi</b>ề<b>u vào cho hàm </b>


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]);


</div>
<span class='text_page_counter'>(78)</span><div class='page_container' data-page=78>

77
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ừ khố 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.
<b>Truy</b>ề<b>n m</b>ộ<b>t m</b>ả<b>ng nhi</b>ề<b>u chi</b>ề<b>u vào cho hàm </b>


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);


</div>
<span class='text_page_counter'>(79)</span><div class='page_container' data-page=79>

78


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");


}
}


<i><b>Chú ý: m</b></i>ộ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.


<b>Tr</b>ả<b> v</b>ề<b> nhi</b>ề<b>u k</b>ế<b>t qu</b>ả


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);


</div>
<span class='text_page_counter'>(80)</span><div class='page_container' data-page=80>

79


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;



}
}


<b>4.3 </b>

ðệ

<b> quy </b>



<b>4.3.1 Khái niêm chung v</b>ềđệ<b> quy </b>


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 hồn tồ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 thố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


</div>
<span class='text_page_counter'>(81)</span><div class='page_container' data-page=81>

80
#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.
<b>4.3.2 Cách dùng </b>đệ<b> quy </b>


<b>Bài tốn nào có th</b>ể<b> dùng </b>ñệ<b> quy </b>


Phương pháp ñệ quy thường áp dụng cho các bài tố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 tốn có thể quy về một bài tố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.
<b>Cách xây d</b>ự<b>ng hàm </b>ñệ<b> quy </b>


Hàm ñệ quy thường được viết theo thuật tốn sau:
if (trường hợp suy biến)


{


trình bày cách giải bài tố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ố


</div>
<span class='text_page_counter'>(82)</span><div class='page_container' data-page=82>

81
<b>4.3.3 Các ví d</b>ụ


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.
<b>Ví d</b>ụ<b> 1: Xét bài tốn tìm </b>ướ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;
}


<b>Ví d</b>ụ<b> 2: Bài tốn tháp Hà N</b>ội.


Bài tố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.


- Ln đả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 tố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.


</div>
<span class='text_page_counter'>(83)</span><div class='page_container' data-page=83>

82
Chương trình sau cài đặt thuật tố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);


</div>
<span class='text_page_counter'>(84)</span><div class='page_container' data-page=84>

83


<b>BÀI T</b>

<b>P CH</b>

ƯƠ

<b>NG 4 </b>



Viết hàm thực hiện các bài tốn dưới đây.
<b>Bài 1. Gi</b>ả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>Bài 2. Tính </b>đa thức cấp n


f(x) = a0 + a1x + ... + an-1 xn-1 + anxn


Hàm có hai đối là biến ngun n và mảng thực a.
<b>Bài 3. Tính c</b>ực đại và cực tiểu của một dãy số.


<b>Bài 4. Tính giá tr</b>ị 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


s x x


n


n


= + +1 ...



<i>n</i>


<i>s</i>
<i>x</i>
<i>s</i>


<i>x</i>


<i>d</i> <i>n</i>


2
2


1


2=( − ) +...+( − )


Trong đó x1, ..., xn là dãy quan sát nhận ñược.


<b>Bài 5. Nhân ma tr</b>ận A cấp mxn với véc tơ X cấp n.
<b>Bài 6. Chuy</b>ển vị một ma trận chữ nhật A cho trước.


<b>Bài 7. Tìm t</b>ọ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>Bài 8. Xây d</b>ựng 3 hàm số sau ñây bằng phương pháp ñệ qui
f(x,n) = xn


s(n) = (2n)!!



</div>
<span class='text_page_counter'>(85)</span><div class='page_container' data-page=85>

84


<b>CHƯƠNG 5 - CẤU TRÚC </b>



ðể 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.


<b>5.1 </b>

ðị

<b>nh ngh</b>

ĩ

<b>a c</b>

<b>u trúc và khai báo bi</b>

ế

<b>n c</b>

<b>u trúc </b>



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.


<b>5.2 K</b>

ế

<b>t h</b>

<b>p </b>

ñị

<b>nh ngh</b>

ĩ

<b>a c</b>

<b>u trúc và khai báo bi</b>

ế

<b>n c</b>

<b>u trúc </b>



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>;
...


</div>
<span class='text_page_counter'>(86)</span><div class='page_container' data-page=86>

85


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:


<b>Cách 1: có tên c</b>ấu trúc:
struct Ngay
{


int ngay;
int thang;
int nam;


} tu_ngay, den_ngay;


<b>Cách 2: khơng có tên c</b>ấ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.


<b>5.3 S</b>

<b> d</b>

<b>ng typedef </b>

ñể

ñị

<b>nh ngh</b>

ĩ

<b>a ki</b>

<b>u d</b>

<b> li</b>

<b>u c</b>

<b>u trúc </b>



<b>5.3.1 </b>ðị<b>nh ngh</b>ĩ<b>a ki</b>ể<b>u b</b>ằ<b>ng typedef </b>


Sử dụng từ khố 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 ngun, 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).


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


</div>
<span class='text_page_counter'>(87)</span><div class='page_container' data-page=87>

86


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ừ khố 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.


<b>5.4 Truy c</b>

<b>p các thành ph</b>

<b>n c</b>

<b>a c</b>

<b>u trúc </b>



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 tố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 đó tốn tửđể truy cập đến
các thành phần cấu trúc là tốn tử ->.


</div>
<span class='text_page_counter'>(88)</span><div class='page_container' data-page=88>

87
<b>5.5.1 Ví d</b>ụ<b> 1 </b>


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;
}


</div>
<span class='text_page_counter'>(89)</span><div class='page_container' data-page=89>

88


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 tốn cao nhất.
- In ra màn hình tồn bộ thơng tin của n thí sinh..


ðể giải quyết bài tố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);


</div>
<span class='text_page_counter'>(90)</span><div class='page_container' data-page=90>

89


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>BÀI T</b>

<b>P CH</b>

ƯƠ

<b>NG 5 </b>



<b>Bài 1. Xây d</b>ự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


</div>
<span class='text_page_counter'>(91)</span><div class='page_container' data-page=91>

90


ðọ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>Bài 2. S</b>ử 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>Bài 3. Gi</b>ả 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
- Q quán
- Số báo danh
- ðiểm toán, lý, hóa.


<b>Bài 4. Nh</b>ậ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>Bài 5. </b>ðị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.


</div>
<span class='text_page_counter'>(92)</span><div class='page_container' data-page=92>

91


<b>PHỤ LỤC 1 - BẢNG MÃ ASCII </b>



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


</div>
<span class='text_page_counter'>(93)</span><div class='page_container' data-page=93>

92


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


</div>
<span class='text_page_counter'>(94)</span><div class='page_container' data-page=94>

93


<b>PHỤ LỤC 2 </b>




<b>DANH SÁCH M</b>

<b>T S</b>

<b> HÀM C</b>

<b>A TURBO C </b>



<b>(theo th</b>

<b> t</b>

<b> ABC) </b>



ðể 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.


<b>Hàm </b> <b>T</b>ệ<b>p tiêu </b>ñề <b>Hàm </b> <b>T</b>ệ<b>p tiêu </b>ñề


</div>
<span class='text_page_counter'>(95)</span><div class='page_container' data-page=95>

94


</div>
<span class='text_page_counter'>(96)</span><div class='page_container' data-page=96>

95


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


<string.h>


156. putimage <graphics.h>


131. memchr <memory.h> hoặc


<string.h>


157. putpixel <graphics.h>


132. memcmp <memory.h> hoặc
<string.h>


158. puts <stdio.h>


133. memcpy <memory.h> hoặc
<string.h>


159. putw <stdio.h>


134. memicmp <memory.h> hoặc
<string.h>


160. rand <stdlib.h>


135. memset <memory.h> hoặc
<string.h>


161. random <stdlib.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



<string.h>


165. rectangle <graphics.h>


</div>
<span class='text_page_counter'>(97)</span><div class='page_container' data-page=97>

96


</div>
<span class='text_page_counter'>(98)</span><div class='page_container' data-page=98>

-

Đố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 tốn, Lập


trình C, Sơ đồ khối, Ngơn ngữ C



-

Kiến thức u cầu mơn học trước: tốn học cơ sở



</div>
<span class='text_page_counter'>(99)</span><div class='page_container' data-page=99>

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.)



</div>
<span class='text_page_counter'>(100)</span><div class='page_container' data-page=100>

[1] PGS.TS Ph

m V

ă

n

t



<i><b>K</b></i>

<i><b> thu</b></i>

<i><b>t l</b></i>

<i><b>p trình C, c</b></i>

ơ

<i><b> s</b></i>

<i><b> và nâng cao </b></i>



Nhà xu

t b

n Khoa h

c và K

thu

t



[2] Robert Sedgewick



<i><b>C</b></i>

<i><b>m nang thu</b></i>

<i><b>t toán (b</b></i>

<i><b>n d</b></i>

<i><b>ch), t</b></i>

<i><b>p 1 </b></i>



Nhà xu

t b

n Khoa h

c k

thu

t




</div>

<!--links-->

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×