Top Banner
(Build CHM file by Xuan Huy A10 07-10 Bac Dong Quan) Đ I H C QU C GIA HÀ N I TR NG Đ I H C CÔNG NGH ƯỜ Khoa Công ngh Thông tin Tác giPH M H NG THÁI Bài gi ng NGÔN NG L P TRÌNH C/C++ Hà N i – 2003
298

Giao Trinh C++ Toan Tap

Oct 23, 2015

Download

Documents

xuankien181991
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Giao Trinh C++ Toan Tap

(Build CHM file by Xuan Huy A10 07-10 Bac Dong Quan)

Đ I H C QU C GIA HÀ N IẠ Ọ Ố ỘTR NG Đ I H C CÔNG NGHƯỜ Ạ Ọ Ệ

Khoa Công ngh Thông tinệ

Tác giả

PH M H NG THÁIẠ Ồ

Bài gi ngả

NGÔN NG L P TRÌNH C/C++Ữ Ậ

Hà N i – 2003ộ

Page 2: Giao Trinh C++ Toan Tap

L I NÓI Đ UỜ Ầ

Ngôn ng l p trình (NNLT) C/C++ là m t trong nh ng ngôn ng l p trình h ng đ iữ ậ ộ ữ ữ ậ ướ ố

t ng m nh và ph bi n hi n nay do tính m m d o và đa năng c a nó. Không ch các ngượ ạ ổ ế ệ ề ẻ ủ ỉ ứ

d ng đ c vi t trên C/C++ mà c nh ng ch ng trình h th ng l n đ u đ c vi t h u h tụ ượ ế ả ữ ươ ệ ố ớ ề ượ ế ầ ế

trên C/C++. C++ là ngôn ng l p trình h ng đ i t ng đ c phát tri n trên n n t ng c a C,ữ ậ ướ ố ượ ượ ể ề ả ủ

không nh ng kh c ph c m t s nh c đi m c a ngôn ng C mà quan tr ng h n, C++ cungữ ắ ụ ộ ố ượ ể ủ ữ ọ ơ

c p cho ng i s d ng (NSD) m t ph ng ti n l p trình theo k thu t m i: l p trình h ngấ ườ ử ụ ộ ươ ệ ậ ỹ ậ ớ ậ ướ

đ i t ng. Đây là k thu t l p trình đ c s d ng h u h t trong các ngôn ng m nh hi nố ượ ỹ ậ ậ ượ ử ụ ầ ế ữ ạ ệ

nay, đ c bi t là các ngôn ng ho t đ ng trong môi tru ng Windows nh Microsoft Access,ặ ệ ữ ạ ộ ờ ư

Visual Basic, Visual Foxpro …

Hi n nay NNLT C/C++ đã đ c đ a vào gi ng d y trong h u h t các tr ng Đ i h c,ệ ượ ư ả ạ ầ ế ườ ạ ọ

Cao đ ng đ thay th m t s NNLT đã cũ nh FORTRAN, Pascal … T p bài gi ng này đ cẳ ể ế ộ ố ư ậ ả ượ

vi t ra v i m c đích đó, trang b ki n th c và k năng th c hành cho sinh viên b t đ u h cế ớ ụ ị ế ứ ỹ ự ắ ầ ọ

vào NNLT C/C++ t i Khoa Công ngh , Đ i h c Qu c gia Hà N i. Đ phù h p v i ch ngạ ệ ạ ọ ố ộ ể ợ ớ ươ

trình, t p bài gi ng này ch đ c p m t ph n nh đ n k thu t l p trình h ng đ i t ngậ ả ỉ ề ậ ộ ầ ỏ ế ỹ ậ ậ ướ ố ượ

trong C++, đó là các k thu t đóng gói d li u, ph ng th c và đ nh nghĩa m i các toán t .ỹ ậ ữ ệ ươ ứ ị ớ ử

Tên g i c a t p bài gi ng này nói lên đi u đó, có nghĩa n i dung c a bài gi ng th c ch t làọ ủ ậ ả ề ộ ủ ả ự ấ

NNLT C đ c m r ng v i m t s đ c đi m m i c a C++. V k thu t l p trình h ng đ iượ ở ộ ớ ộ ố ặ ể ớ ủ ề ỹ ậ ậ ướ ố

t ng (trong C++) s đ c trang b b i m t giáo trình khác. Tuy nhiên đ ng n g n, trong t pượ ẽ ượ ị ở ộ ể ắ ọ ậ

bài gi ng này tên g i C/C++ s đ c chúng tôi thay b ng C++.ả ọ ẽ ượ ằ

N i dung t p bài gi ng này g m 8 ch ng. Ph n đ u g m các ch ng t 1 đ n 6 chộ ậ ả ồ ươ ầ ầ ồ ươ ừ ế ủ

y u trình bày v NNLT C++ trên n n t ng c a k thu t l p trình c u trúc. Các ch ng cònế ề ề ả ủ ỹ ậ ậ ấ ươ

l i (ch ng 7 và 8) s trình bày các c u trúc c b n trong C++ đó là k thu t đóng gói (l p vàạ ươ ẽ ấ ơ ả ỹ ậ ớ

đ i t ng) và đ nh nghĩa phép toán m i cho l p.ố ượ ị ớ ớ

Tuy đã có nhi u c g ng nh ng do th i gian và trình đ ng i vi t có h n nên ch cề ố ắ ư ờ ộ ườ ế ạ ắ

ch n không tránh kh i sai sót, vì v y r t mong nh n đ c s góp ý c a b n đ c đ bài gi ngắ ỏ ậ ấ ậ ượ ự ủ ạ ọ ể ả

ngày càng m t hoàn thi n h n.ộ ệ ơ

Tác gi .ả

TÀI LI U THAM KH OỆ Ả

B.W. Kerninghan and D.M. Ritchie. The C Programming Language. Prentice-Hall, 1978. Ngô Trung Vi t (d ch). ệ ị Ngôn ng l p trình Cữ ậ . Vi n Tin h c, Hà N i 1990.ệ ọ ộ

Peter Norton. Advanced C Programming. Nguy n Vi t H i (d ch). ễ ệ ả ị L p trình C nâng caoậ . Nhà xu t b n Giao thông v n t i. Hà N i, 1995.ấ ả ậ ả ộ

Ph m Văn t. ạ Ấ K thu t l p trình C. C s và nâng caoỹ ậ ậ ơ ở . Nhà xu t b n Khoa h c và kấ ả ọ ỹ thu t. Hà N i, 1996.ậ ộ

Ph m Văn t. ạ Ấ C++ và l p trình h ng đ i t ng.ậ ướ ố ượ Nhà xu t b n Khoa h c và k thu t.ấ ả ọ ỹ ậ

Page 3: Giao Trinh C++ Toan Tap

Hà N i, 2000.ộScott Robert Ladd. Nguy n Hùng (d ch). ễ ị C++ K thu t và ng d ngỹ ậ ứ ụ . Công ty c ph nổ ầ

t v n và d ch v KHKT - SCITEC, 1992.ư ấ ị ụJan Skansholm. C++ From the Beginning. Addison-Wesley, 1997.

M C L CỤ Ụ

Ch ng 1. CÁC KHÁI NI M C B N C A C++ươ Ệ Ơ Ả Ủ

CÁC Y U T C B N Ế Ố Ơ Ả .....................................................................................................1

I.B ng ký t c a C++ả ự ủ ..................................................................................................1

II. T khoáừ ...................................................................................................................2

III. Tên g iọ ....................................................................................................................2

IV. Chú thích trong ch ng trìnhươ .................................................................................3

MÔI TR NG LÀM VI C C A C++ƯỜ Ệ Ủ ............................................................................3

1. Kh i đ ng - Thoát kh i C++ở ộ ỏ .................................................................................3

V. Giao di n và c a s so n th oệ ử ổ ạ ả ..............................................................................4

VI. C u trúc m t ch ng trình trong C++ấ ộ ươ ...................................................................7

CÁC B C Đ T O VÀ TH C HI N M T CH NG TRÌNHƯỚ Ể Ạ Ự Ệ Ộ ƯƠ ..............................8

1. Qui trình vi t và th c hi n ch ng trìnhế ự ệ ươ ..............................................................8

VII.So n th o t p ch ng trình ngu nạ ả ệ ươ ồ .......................................................................8

VIII.....................................................................................................D ch ch ng trìnhị ươ9

IX. Ch y ch ng trìnhạ ươ .................................................................................................9

VÀO/RA TRONG C++........................................................................................................9

1. Vào d li u t bàn phímữ ệ ừ ........................................................................................9

X. In d li u ra màn hìnhữ ệ ..........................................................................................10

Page 4: Giao Trinh C++ Toan Tap

XI. Đ nh d ng thông tin c n in ra màn hìnhị ạ ầ ..............................................................12

XII.Vào/ra trong C.......................................................................................................14

Ch ng 2. KI U D LI U, BI U TH C VÀ CÂU L NHươ Ể Ữ Ệ Ể Ứ Ệ

XIII. KI U D LI U Đ N GI NỂ Ữ Ệ Ơ Ả ................................................................................20

1. Khái ni m v ki u d li uệ ề ể ữ ệ ..................................................................................20

XIV.................................................................................................................Ki u ký tể ự21

XV.Ki u s nguyênể ố ....................................................................................................22

XVI.............................................................................................................Ki u s th cể ố ự22

H NG - KHAI BÁO VÀ S D NG H NGẰ Ử Ụ Ằ ..................................................................23

1. H ng nguyênằ ........................................................................................................23

XVII................................................................................................................H ng th cằ ự23

XVIII...............................................................................................................H ng kí tằ ự24

XIX..........................................................................................................H ng xâu kí tằ ự25

XX.Khai báo h ngằ .......................................................................................................26

BI N - KHAI BÁO VÀ S D NG BI NẾ Ử Ụ Ế .......................................................................27

1. Khai báo bi nế .......................................................................................................27

XXI.....................................................................................................Ph m vi c a bi nạ ủ ế28

XXII...............................................................................Gán giá tr cho bi n (phép gán)ị ế28

XXIII............................................................................M t s đi m l u ý v phép gánộ ố ể ư ề29

PHÉP TOÁN, BI U TH C VÀ CÂU L NHỂ Ứ Ệ .................................................................30

XXIV................................................................................................................Phép toán30

XXV............................................................................................................Các phép gán32

XXVI................................................................................................................Bi u th cể ứ33

XXVII..........................................................................................Câu l nh và kh i l nhệ ố ệ37

TH VI N CÁC HÀM TOÁN H C Ư Ệ Ọ .............................................................................38

Page 5: Giao Trinh C++ Toan Tap

1. Các hàm s h c ố ọ ...................................................................................................38

XXVIII.............................................................................................Các hàm l ng giácượ38

Ch ng 3. C U TRÚC ĐI U KHI N VÀ D LI U KI U M NGươ Ấ Ề Ể Ữ Ệ Ể Ả

I.C U TRÚC R NHÁNHẤ Ẽ ................................................................................................41

1. Câu l nh đi u ki n ifệ ề ệ ...........................................................................................41

II. Câu l nh l a ch n switchệ ự ọ ....................................................................................43

III. Câu l nh nh y gotoệ ả ..............................................................................................45

C U TRÚC L PẤ Ặ ................................................................................................................47

1. L nh l p forệ ặ .........................................................................................................47

IV. L nh l p whileệ ặ .....................................................................................................51

V. L nh l p do ... whileệ ặ ............................................................................................55

VI. L i ra c a vòng l p: break, continueố ủ ặ ...................................................................57

VII.So sánh cách dùng các câu l nh l pệ ặ .....................................................................58

M NG D LI UẢ Ữ Ệ ...............................................................................................................59

1. M ng m t chi uả ộ ề ...................................................................................................59

VIII....................................................................................................................Xâu kí tự63

M NG HAI CHI UẢ Ề ..........................................................................................................73

Ch ng 4. HÀM VÀ CH NG TRÌNHươ ƯƠ

I.CON TR VÀ S H C Đ A CHỎ Ố Ọ Ị Ỉ.................................................................................83

1. Đ a ch , phép toán &ị ỉ .............................................................................................83

II. Con trỏ..................................................................................................................84

III. Các phép toán v i con trớ ỏ....................................................................................86

IV. C p phát đ ng, toán t c p phát, thu h i new, deleteấ ộ ử ấ ồ .........................................88

V. Con tr và m ng, xâu kí tỏ ả ự..................................................................................90

VI. M ng con trả ỏ........................................................................................................94

HÀM95

1. Khai báo và đ nh nghĩa hàmị .................................................................................95

VII.L i g i và s d ng hàmờ ọ ử ụ .......................................................................................98

VIII..............................................................................................Hàm v i đ i m c đ nhớ ố ặ ị

Page 6: Giao Trinh C++ Toan Tap

100

IX. Khai báo hàm trùng tên.......................................................................................101

X. Bi n, đ i tham chi uế ố ế .........................................................................................102

XI. Các cách truy n tham đ iề ố ...................................................................................104

XII.Hàm và m ng d li uả ữ ệ ........................................................................................109

XIII...............................................................................................................Con tr hàmỏ119

Đ QUIỆ ..............................................................................................................................123

1. Khái ni m đ quiệ ệ ................................................................................................123

XIV.................................................................L p các bài toán gi i đ c b ng đ quiớ ả ượ ằ ệ124

XV.C u trúc chung c a hàm đ quiấ ủ ệ .........................................................................125

XVI...................................................................................................................Các ví dụ125

T CH C CH NG TRÌNHỔ Ứ ƯƠ .......................................................................................127

1. Các lo i bi n và ph m viạ ế ạ ...................................................................................127

XVII....................................................................................Bi n v i m c đích đ c bi tế ớ ụ ặ ệ132

XVIII..............................................................................................Các ch th ti n x lýỉ ị ề ử135

Ch ng 5. D LI U KI U C U TRÚC VÀ H Pươ Ữ Ệ Ể Ấ Ợ

I.KI U C U TRÚCỂ Ấ .........................................................................................................145

1. Khai báo, kh i t oở ạ ..............................................................................................145

II. Truy nh p các thành ph n ki u c u trúcậ ầ ể ấ ...........................................................147

III. Phép toán gán c u trúcấ .......................................................................................148

IV. Các ví d minh hoụ ạ............................................................................................150

V. Hàm v i c u trúcớ ấ ................................................................................................152

VI. C u trúc v i thành ph n ki u bitấ ớ ầ ể .......................................................................164

VII.Câu l nh typedefệ .................................................................................................165

VIII..............................................................................................................Hàm sizeof()166

C U TRÚC T TR VÀ DANH SÁCH LIÊN K TẤ Ự Ỏ Ế ..................................................166

1. C u trúc t trấ ự ỏ....................................................................................................167

IX. Khái ni m danh sách liên k tệ ế .............................................................................169

X. Các phép toán trên danh sách liên k tế ................................................................170

KI U H PỂ Ợ ........................................................................................................................176

Page 7: Giao Trinh C++ Toan Tap

1. Khai báo..............................................................................................................176

XI. Truy c pậ ..............................................................................................................176

KI U LI T KÊỂ Ệ ................................................................................................................177

Ch ng 6. Đ H A VÀ ÂM THANHươ Ồ Ọ

I.Đ HOỒ Ạ.........................................................................................................................184

1. Khái ni m đ hoệ ồ ạ..............................................................................................184

II. Vào/ra ch đ đ hoế ộ ồ ạ........................................................................................185

III. V đi m, đ ng, kh i, màu s cẽ ể ườ ố ắ .......................................................................188

IV. Vi t văn b n trong màn hình đ h aế ả ồ ọ .................................................................195

V. Chuy n đ ngể ộ ......................................................................................................197

VI. V đ th c a các hàm toán h cẽ ồ ị ủ ọ ........................................................................200

ÂM THANH......................................................................................................................207

Ch ng 7. L P VÀ Đ I T NGươ Ớ Ố ƯỢ

I.L P TRÌNH C U TRÚC VÀ L P TRÌNH H NG Đ I T NGẬ Ấ Ậ ƯỚ Ố ƯỢ .....................212

1. Ph ng pháp l p trình c u trúcươ ậ ấ .........................................................................212

II. Ph ng pháp l p trình h ng đ i t ngươ ậ ướ ố ượ ..........................................................214

L P VÀ Đ I T NG Ớ Ố ƯỢ ..................................................................................................216

1. Khai báo l pớ .......................................................................................................217

III. Khai báo các thành ph n c a l p (thu c tính và ph ng th c) ầ ủ ớ ộ ươ ứ ......................217

IV. Bi n, m ng và con tr đ i t ng ế ả ỏ ố ượ ....................................................................219

Đ I C A PH NG TH C, CON TR this Ố Ủ ƯƠ Ứ Ỏ .............................................................224

1. Con tr this là đ i th nh t c a ph ng th c ỏ ố ứ ấ ủ ươ ứ .................................................224

V. Tham s ng v i đ i con tr thisố ứ ớ ố ỏ ......................................................................225

VI. Các đ i khác c a ph ng th c ố ủ ươ ứ .........................................................................226

HÀM T O (Constructor)Ạ ................................................................................................230

1. Hàm t o (hàm thi t l p) ạ ế ậ .................................................................................. 230

VII.L p không có hàm t o và hàm t o m c đ nh ớ ạ ạ ặ ị .................................................. 235

VIII......................................................................Hàm t o sao chép (Copy constructor) ạ 238

HÀM H Y (Destructor) Ủ ................................................................................................ 246

1. Hàm h y m c đ nh ủ ặ ị ............................................................................................246

IX. Quy t c vi t hàm h y ắ ế ủ .......................................................................................246

X. Vai trò c a hàm h y trong l p DT ủ ủ ớ ....................................................................247

XI. Ví d ụ ................................................................................................................. 247

Page 8: Giao Trinh C++ Toan Tap

CÁC HÀM TR C TUY N (inline) Ự Ế ............................................................................. 253

1. u nh c đi m c a hàm Ư ượ ể ủ ................................................................................. 253

2. Các hàm tr c tuy n ự ế .......................................................................................... 253

3. Cách biên d ch và dùng hàm tr c tuy n ị ự ế ........................................................... 254

4. S h n ch c a trình biên d ch ự ạ ế ủ ị ........................................................................ 255

Ch ng 8. HÀM B N, Đ NH NGHĨA PHÉP TOÁN CHO L Pươ Ạ Ị Ớ

I.HÀM B N (friend function) Ạ ....................................................................................... 258

1. Hàm b n ạ ........................................................................................................... 258

II. Tính ch t c a hàm b n ấ ủ ạ .................................................................................... 259

III. Hàm b n c a nhi u l p ạ ủ ề ớ ....................................................................................261

Đ NH NGHĨA PHÉP TOÁN CHO L P Ị Ớ ..................................................................... 266

1. Tên hàm toán t ử ................................................................................................ 266

IV. Các đ i c a hàm toán t ố ủ ử .................................................................................. 266

V. Thân c a hàm toán t ủ ử ....................................................................................... 267

Ch ng 11. CÁC DÒNG NH P/XU T VÀ FILEươ Ậ Ấ

I.NH P/XU T V I CIN/COUTẬ Ấ Ớ ....................................................................................276

1. Toán t nh p >>ử ậ .................................................................................................276

II. Các hàm nh p kí t và xâu kí tậ ự ự........................................................................277

III. Toán t xu t <<ử ấ ..................................................................................................279

Đ NH D NGỊ Ạ .....................................................................................................................279

1. Các ph ng th c đ nh d ngươ ứ ị ạ ..............................................................................280

IV. Các c đ nh d ngờ ị ạ ................................................................................................281

V. Các b và hàm đ nh d ngộ ị ạ ...................................................................................283

IN RA MÁY IN.................................................................................................................283

LÀM VI C V I FILEỆ Ớ ....................................................................................................284

1. T o đ i t ng g n v i fileạ ố ượ ắ ớ ................................................................................284

VI. Đóng file và gi i phóng đ i t ngả ố ượ ....................................................................285

VII.Ki m tra s t n t i c a file, ki m tra h t fileể ự ồ ạ ủ ể ế ..................................................289

VIII.......................................................................................Đ c ghi đ ng th i trên fileọ ồ ờ290

IX. Di chuy n con tr fileể ỏ ........................................................................................290

NH P/XU T NH PHÂNẬ Ấ Ị ...............................................................................................292

Page 9: Giao Trinh C++ Toan Tap

1. Khái ni m v 2 lo i file: văn b n và nh phânệ ề ạ ả ị ..................................................292

X. Đ c, ghi kí tọ ự......................................................................................................293

XI. Đ c, ghi dãy kí tọ ự...............................................................................................293

XII.Đ c ghi đ ng th iọ ồ ờ ..............................................................................................294

Page 10: Giao Trinh C++ Toan Tap

CH NG 1ƯƠ

CÁC KHÁI NI M CỆ Ơ B N C A C++Ả Ủ

Các y u t cế ố ơ b n ảMôi tr ng làm vi c c a C++ườ ệ ủCác b c đ t o và th c hi n m t ch ng trình ướ ể ạ ự ệ ộ ươVào/ra trong C++

CÁC Y U T C B NẾ Ố Ơ Ả

M t ngôn ng l p trình (NNLT) b c cao cho phép ng i s d ng (NSD) bi u hi n ý t ngộ ữ ậ ậ ườ ử ụ ể ệ ưở c a mình đ gi i quy t m t v n đ , bài toán b ng cách di n đ t g n v i ngôn ng thôngủ ể ả ế ộ ấ ề ằ ễ ạ ầ ớ ữ th ng thay vì ph i di n đ t theo ngôn ng máy (dãy các kí hi u 0,1). Hi n nhiên, các ýườ ả ễ ạ ữ ệ ể t ng NSD mu n trình bày ph i đ c vi t theo m t c u trúc ch t ch th ng đ c g i làưở ố ả ượ ế ộ ấ ặ ẽ ườ ượ ọ thu t toánậ ho c ặ gi i thu tả ậ và theo đúng các qui t c c a ngôn ng g i là ắ ủ ữ ọ cú pháp ho c ặ văn ph mạ . Trong giáo trình này chúng ta bàn đ n m t ngôn ng l p trình nh v y, đó là ngôn ngế ộ ữ ậ ư ậ ữ l p trình C++ và làm th nào đ th hi n các ý t ng gi i quy t v n đ b ng cách vi t thànhậ ế ể ể ệ ưở ả ế ấ ề ằ ế ch ng trình trong C++. ươ

Tr c h t, trong m c này chúng ta s trình bày v các qui đ nh b t bu c đ n gi n và c b nướ ế ụ ẽ ề ị ắ ộ ơ ả ơ ả nh t. Thông th ng các qui đ nh này s đ c nh d n trong quá trình h c ngôn ng , tuy nhiênấ ườ ị ẽ ượ ớ ầ ọ ữ đ có m t vài khái ni m t ng đ i h th ng v NNLT C++ chúng ta trình bày s l c cácể ộ ệ ươ ố ệ ố ề ơ ượ khái ni m c b n đó. Ng i đ c đã t ng làm quen v i các NNLT khác có th đ c l t quaệ ơ ả ườ ọ ừ ớ ể ọ ướ ph n này.ầ

B ng ký t c a C++ả ự ủH u h t các ngôn ng l p trình hi n nay đ u s d ng các kí t ti ng Anh, các kí hi u thôngầ ế ữ ậ ệ ề ử ụ ự ế ệ d ng và các con s đ th hi n ch ng trình. Các kí t c a nh ng ngôn ng khác không đ cụ ố ể ể ệ ươ ự ủ ữ ữ ượ s d ng (ví d các ch cái ti ng Vi t). D i đây là b ng kí t đ c phép dùng đ t o nênử ụ ụ ữ ế ệ ướ ả ự ượ ể ạ nh ng câu l nh c a ngôn ng C++.ữ ệ ủ ữ

Các ch cái la tinh (vi t thữ ế ư ng và vi t hoa): a .. z và A .. Z. Cùng m t ch cái nh ngờ ế ộ ữ ư vi t th ng phân bi t v i vi t hoa. Ví d ch cái 'a' là khác v i 'A'. ế ườ ệ ớ ế ụ ữ ớ

D u g ch dấ ạ ư i: _ớ

Page 11: Giao Trinh C++ Toan Tap

Các ch s th p phân: 0, 1, . ., 9.ữ ố ậ

Các ký hi u toán h c: +, -, *, /, % , &, ||, !, >, <, = ...ệ ọ

Các ký hi u ệ đ c bi t khác: , ;: [ ], {}, #, d u cách, ...ặ ệ ấ

T khoáừM t t khoá là m t t đ c qui đ nh tr c trong NNLT v i m t ý nghĩa c đ nh, th ng dùngộ ừ ộ ừ ượ ị ướ ớ ộ ố ị ườ đ ch các lo i d li u ho c k t h p thành câu l nh. NSD có th t o ra nh ng t m i đ chể ỉ ạ ữ ệ ặ ế ợ ệ ể ạ ữ ừ ớ ể ỉ các đ i t ng c a mình nh ng không đ c phép trùng v i t khoá. D i đây chúng tôi li t kêố ượ ủ ư ượ ớ ừ ướ ệ m t vài t khoá th ng g p, ý nghĩa c a các t này, s đ c trình bày d n trong các đ m cộ ừ ườ ặ ủ ừ ẽ ượ ầ ề ụ liên quan.

auto, break, case, char, continue, default, do, double, else, externe, float,

for, goto, if, int, long, register, return, short, sizeof, static, struct, switch,

typedef, union, unsigned, while ...M t đ c tr ng c a C++ là các t khoá luôn luôn ộ ặ ư ủ ừ đư c vi t b ng ch th ng.ợ ế ằ ữ ườ

Tên g i ọĐ phân bi t các đ i t ng v i nhau chúng c n có m t tên g i. H u h t m t đ i t ng đ cể ệ ố ượ ớ ầ ộ ọ ầ ế ộ ố ượ ượ vi t ra trong ch ng trình thu c 2 d ng, m t d ng đã có s n trong ngôn ng (ví d các tế ươ ộ ạ ộ ạ ẵ ữ ụ ừ khoá, tên các hàm chu n ...), m t s do NSD t o ra dùng ẩ ộ ố ạ đ ể đ t tên cho h ng, bi n, ki u,ặ ằ ế ể hàm ... các tên g i do NSD t đ t ph i tuân theo m t s qui t c sau:ọ ự ặ ả ộ ố ắ

Là dãy ký t liên ti p (không ch a d u cách) và ph i b t ự ế ứ ấ ả ắ đ u b ng ch cái ho c g chầ ằ ữ ặ ạ dư i. ớ

Phân bi t kí t in hoa và thệ ự ư ng. ờ

Không đư c trùng v i t khóa. ợ ớ ừ

S lố ư ng ch cái dùng ợ ữ đ phân bi t tên g i có th ể ệ ọ ể đư c ợ đ t tuỳ ý.ặ

Chú ý các tên g i có s n c a C++ cũng tuân th theo đúng qui t c trên.ọ ẵ ủ ủ ắTrong m t ch ng trình n u NSD đ t tên sai thì trong quá trình x lý s b (tr c khi ch yộ ươ ế ặ ử ơ ộ ướ ạ ch ng trình) máy s báo l i (g i là l i văn ph m). ươ ẽ ỗ ọ ỗ ạ

:

Các tên g i sau đây là đúng (đ c phép): i, i1, j, tinhoc, tin_hoc, luu_luong ọ ượ

Các tên g i sau đây là sai (không đ c phép): 1i, tin hoc, luu-luong-nuoc ọ ượ

Các tên g i sau đây là khác nhau: ha_noi, Ha_noi, HA_Noi, HA_NOI, ... ọ

Chú thích trong ch ng trìnhươM t ch ng trình th ng đ c vi t m t cách ng n g n, do v y thông th ng bên c nh cácộ ươ ườ ượ ế ộ ắ ọ ậ ườ ạ câu l nh chính th c c a ch ng trình, NSD còn đ c phép vi t vào ch ng trình các câu ghiệ ứ ủ ươ ượ ế ươ chú, gi i thích đ làm rõ nghĩa h n ch ng trình. M t chú thích có th ghi chú v nhi m v ,ả ể ơ ươ ộ ể ề ệ ụ

Page 12: Giao Trinh C++ Toan Tap

m c đích, cách th c c a thành ph n đang đ c chú thích nh bi n, h ng, hàm ho c côngụ ứ ủ ầ ượ ư ế ằ ặ d ng c a m t đo n l nh ... Các chú thích s làm cho ch ng trình sáng s a, d đ c, d hi uụ ủ ộ ạ ệ ẽ ươ ủ ễ ọ ễ ể và vì v y d b o trì, s a ch a v sau. ậ ễ ả ử ữ ề

Có 2 cách báo cho ch ng trình bi t m t đo n chú thích:ươ ế ộ ạ

N u chú thích là m t đo n kí t b t kỳ liên ti p nhau (trong 1 dòng ho c trên nhi uế ộ ạ ự ấ ế ặ ề dòng) ta đ t đo n chú thích đó gi a c p d u đóng m chú thích /* (m ) và */ (đóng).ặ ạ ữ ặ ấ ở ở

N u chú thích b t đ u t m t v trí nào đó cho đ n h t dòng, thì ta đ t d u // v trí đó.ế ắ ầ ừ ộ ị ế ế ặ ấ ở ị Nh v y // s d ng cho các chú thích ch trên 1 dòng. ư ậ ử ụ ỉ

Nh đã nh c trên, vai trò c a đo n chú thích là làm cho ch ng trình d hi u đ i v i ng iư ắ ở ủ ạ ươ ễ ể ố ớ ườ đ c, vì v y đ i v i máy các đo n chú thích s đ c b qua. L i d ng đ c đi m này c a chúọ ậ ố ớ ạ ẽ ượ ỏ ợ ụ ặ ể ủ thích đôi khi đ t m th i b qua m t đo n l nh nào đó trong ch ng trình (nh ng không xoáể ạ ờ ỏ ộ ạ ệ ươ ư h n đ kh i ph i gõ l i khi c n dùng đ n) ta có th đ t các d u chú thích bao quanh đo nẳ ể ỏ ả ạ ầ ế ể ặ ấ ạ l nh này (ví d khi ch y th ch ng trình, g l i ...), khi c n s d ng l i ta có th b cácệ ụ ạ ử ươ ỡ ỗ ầ ử ụ ạ ể ỏ d u chú thích.ấ

Chú ý: C p d u chú thích /* ... */ không đ c phép vi t l ng nhau, ví d dòng chú thích sau làặ ấ ượ ế ồ ụ không đ c phépượ

/* Đây là đo n chú thích /* ch a đo n chú thích này */ nh đo n chú thích con */ạ ứ ạ ư ạc n ph i s a l i nh sau: ầ ả ử ạ ư

ho c ch gi l i c p d u chú thích ngoài cùng ặ ỉ ữ ạ ặ ấ

/* Đây là đo n chú thích ch a đo n chú thích này nh đo n chú thích con */ạ ứ ạ ư ạ

ho c chia thành các đo n chú thích liên ti p nhauặ ạ ế

/* Đây là đo n chú thích */ /*ch a đo n chú thích này*/ /*nh đo n chú thích con */ạ ứ ạ ư ạ

MÔI TR NG LÀM VI C C A C++ƯỜ Ệ Ủ

Kh i đ ng - Thoát kh i C++ở ộ ỏKh i đ ng C++ cũng nh m i ch ng trình khác b ng cách nh p đúp chu t lên bi u t ngở ộ ư ọ ươ ằ ấ ộ ể ượ c a ch ng trình. Khi ch ng trình đ c kh i đ ng s hi n ra giao di n g m có menu côngủ ươ ươ ượ ở ộ ẽ ệ ệ ồ vi c và m t khung c a s bên d i ph c v cho so n th o. M t con tr nh p nháy trongệ ộ ử ổ ướ ụ ụ ạ ả ộ ỏ ấ khung c a s và chúng ta b t đ u nh p n i dung (văn b n) ch ng trình vào trong khung c aử ổ ắ ầ ậ ộ ả ươ ử s so n th o này. M c đích c a giáo trình này là trang b nh ng ki n th c c b n c a l pổ ạ ả ụ ủ ị ữ ế ứ ơ ả ủ ậ trình thông qua NNLT C++ cho các sinh viên m i b t đ u nên chúng tôi v n ch n trình bàyớ ắ ầ ẫ ọ giao di n c a các trình biên d ch quen thu c là Turbo C ho c Borland C. V các trình biên d chệ ủ ị ộ ặ ề ị khác đ c gi có th t tham kh o trong các tài li u liên quan.ộ ả ể ự ả ệ

Đ k t thúc làm vi c v i C++ (so n th o, ch y ch ng trình ...) và quay v môi tr ngể ế ệ ớ ạ ả ạ ươ ề ườ Windows chúng ta n ấ Alt-X.

Page 13: Giao Trinh C++ Toan Tap

Giao di n và c a s so n th oệ ử ổ ạ ả

Mô t chungảKhi g i ch y C++ trên màn hình s xu t hi n m t menu x xu ng và m t c a s so n th o.ọ ạ ẽ ấ ệ ộ ổ ố ộ ử ổ ạ ả Trên menu g m có các nhóm ch c năng: ồ ứ File, Edit, Search, Run, Compile, Debug, Project, Options, Window, Help. Đ kích ho t các nhóm ch c năng, có th n ể ạ ứ ể ấ Alt+ch cáiữ bi u thể ị cho menu c a ch c năng đó (là ch cái có g ch d i). Ví d đ m nhóm ch c năng ủ ứ ữ ạ ướ ụ ể ở ứ File nấ Alt+F, sau đó d ch chuy n h p sáng đ n m c c n ch n r i n Enter. Đ thu n ti n cho NSD,ị ể ộ ế ụ ầ ọ ồ ấ ể ậ ệ m t s các ch c năng hay dùng còn đ c g n v i m t t h p các phím cho phép ng i dùngộ ố ứ ượ ắ ớ ộ ổ ợ ườ có th ch n nhanh ch c năng này mà không c n thông qua vi c m menu nh đã mô t trên.ể ọ ứ ầ ệ ở ư ả ở M t s t h p phím c th đó s đ c trình bày vào cu i ph n này. Các b ch ng trình d chộ ố ổ ợ ụ ể ẽ ượ ố ầ ộ ươ ị h tr ng i l p trình m t môi tr ng tích h p t c ngoài ch c năng so n th o, nó còn cungỗ ợ ườ ậ ộ ườ ợ ứ ứ ạ ả c p nhi u ch c năng, ti n ích khác giúp ng i l p trình v a có th so n th o văn b nấ ề ứ ệ ườ ậ ừ ể ạ ả ả ch ng trình v a g i ch y ch ng trình v a g l i … ươ ừ ọ ạ ươ ừ ỡ ỗ

Các ch c năng liên quan đ n so n th o ph n l n gi ng v i các b so n th o khác (nhứ ế ạ ả ầ ớ ố ớ ộ ạ ả ư WinWord) do v y chúng tôi ch trình bày tóm t t mà không trình bày chi ti t đây. ậ ỉ ắ ế ở

Các ch c năng so n th oứ ạ ảGi ng h u h t các b so n th o văn b n, b so n th o c a Turbo C ho c Borland C cũng số ầ ế ộ ạ ả ả ộ ạ ả ủ ặ ử d ng các phím sau cho quá trình so n th o: ụ ạ ả

D ch chuy n con tr : các phím mũi tên cho phép d ch chuy n con tr sang trái, ph i m tị ể ỏ ị ể ỏ ả ộ kí t ho c lên trên, xu ng d i 1 dòng. Đ d ch chuy n nhanh có các phím nhự ặ ố ướ ể ị ể ư Home (v đ u dòng), End (v cu i dòng), PgUp, PgDn (lên, xu ng m t trang mànề ầ ề ố ố ộ hình). Đ d ch chuy n xa h n có th k t h p các phím này cùng phím Control (Ctrl,ể ị ể ơ ể ế ợ ^) nh ^PgUp: v đ u t p, ^PgDn: v cu i t p.ư ề ầ ệ ề ố ệ

Chèn, xoá, s a: Phím Insert cho phép chuy n ch đ so n th o gi a chèn và đè. Cácử ể ế ộ ạ ả ữ phím Delete, Backspace cho phép xoá m t kí t t i v trí con tr và tr c v trí conộ ự ạ ị ỏ ướ ị tr (xoá lùi).ỏ

Các thao tác v i kh i dòng: Đ đánh d u kh i dòng (th c ch t là kh i kí t li n nhauớ ố ể ấ ố ự ấ ố ự ề b t kỳ) ta đ a con tr đ n v trí đ u n Ctrl-KB và Ctrl-KK t i v trí cu i. Cũng cóấ ư ỏ ế ị ầ ấ ạ ị ố th thao tác nhanh h n b ng cách gi phím Shift và dùng các phím d ch chuy n conể ơ ằ ữ ị ể tr quét t v trí đ u đ n v trí cu i, khi đó kh i kí t đu c đánh d u s chuy n m uỏ ừ ị ầ ế ị ố ố ự ợ ấ ẽ ể ầ n n. M t kh i đ c đánh d u có th dùng đ c t, dán vào m t n i khác trong vănề ộ ố ượ ấ ể ể ắ ộ ơ b n ho c xoá kh i văn b n. Đ th c hi n thao tác c t dán, đ u tiên ph i đ a kh iả ặ ỏ ả ể ự ệ ắ ầ ả ư ố đã đánh d u vào b nh đ m b ng nhóm phím Shift-Delete (c t), sau đó d ch chuy nấ ộ ớ ệ ằ ắ ị ể con tr đ n v trí m i c n hi n n i dung v a c t và n t h p phím Shift-Insert. M tỏ ế ị ớ ầ ệ ộ ừ ắ ấ ổ ợ ộ đo n văn b n đ c ghi vào b nh đ m có th đ c dán nhi u l n vào nhi u v tríạ ả ượ ộ ớ ệ ể ượ ề ầ ề ị khác nhau b ng cách l p l i t h p phím Shift-Insert t i các v trí khác nhau trongằ ặ ạ ổ ợ ạ ị văn b n. Đ xoá m t kh i dòng đã đánh d u mà không ghi vào b nh đ m, dùng tả ể ộ ố ấ ộ ớ ệ ổ h p phím Ctrl-Delete. Khi m t n i dung m i ghi vào b nh đ m thì nó s xoá (ghiợ ộ ộ ớ ộ ớ ệ ẽ đè) n i dung cũ đã có, do v y c n cân nh c đ s d ng phím Ctrl-Delete (xoá vàộ ậ ầ ắ ể ử ụ không l u l i n i dung v a xoá vào b đ m) và Shift-Delete (xoá và l u l i n i dungư ạ ộ ừ ộ ệ ư ạ ộ

Page 14: Giao Trinh C++ Toan Tap

v a xoá) m t cách phù h p.ừ ộ ợ

T h p phím Ctrl-A r t thu n l i khi c n đánh d u nhanh toàn b văn b n.ổ ợ ấ ậ ợ ầ ấ ộ ả

Ch c năng tìm ki m và thay thứ ế ếCh c năng này dùng đ d ch chuy n nhanh con tr văn b n đ n t c n tìm. Đ th c hi n tìmứ ể ị ể ỏ ả ế ừ ầ ể ự ệ ki m b m Ctrl-QF, tìm ki m và thay th b m Ctrl-QA. Vào t ho c nhóm t c n tìm vào c aế ấ ế ế ấ ừ ặ ừ ầ ử s Find, nhóm thay th (n u dùng Ctrl-QA) vào c a s Replace và đánh d u vào các tuỳ ch nổ ế ế ử ổ ấ ọ trong c a s bên d i sau đó n Enter. Các tuỳ ch n g m: không phân bi t ch hoa/th ng,ử ổ ướ ấ ọ ồ ệ ữ ườ tìm t đ c l p hay đ ng trong t khác, tìm trong toàn văn b n hay ch trong ph n đ c đánhừ ộ ậ ứ ừ ả ỉ ầ ượ d u, chi u tìm đi đ n cu i hay ng c v đ u văn b n, thay th có h i l i hay không h i l iấ ề ế ố ượ ề ầ ả ế ỏ ạ ỏ ạ … Đ d ch chuy n con tr đ n các vùng khác nhau trong m t menu hay c a s ch a các tuỳể ị ể ỏ ế ộ ử ổ ứ ch n ta s d ng phím Tab. ọ ử ụ

Các ch c năng liên quan đ n t pứ ế ệ

Ghi t p lên đĩa: Ch n menu File\Save ho c phím F2. N u tên t p ch a có (còn mang tênệ ọ ặ ế ệ ư Noname.cpp) máy s yêu c u cho tên t p. Ph n m r ng c a tên t p đ c m c đ nhẽ ầ ệ ầ ở ộ ủ ệ ượ ặ ị là CPP.

So n th o t p m i: Ch n menu File\New. Hi n ra c a s so n th o tr ng và tên fileạ ả ệ ớ ọ ệ ử ổ ạ ả ắ t m th i l y là Noname.cpp.ạ ờ ấ

So n th o t p cũ: Ch n menu File\Open ho c n phím F3, nh p tên t p ho c d chạ ả ệ ọ ặ ấ ậ ệ ặ ị chuy n con tr trong vùng danh sách t p bên d i đ n tên t p c n so n r i nể ỏ ệ ướ ế ệ ầ ạ ồ ấ Enter. Cũng có th áp d ng cách này đ so n t p m i khi không nh p vào tên t p cể ụ ể ạ ệ ớ ậ ệ ụ th .ể

Ghi t p đang so n th o lên đĩa v i tên m i: Ch n menu File\Save As và nh p tên t pệ ạ ả ớ ớ ọ ậ ệ m i vào r i n Enter.ớ ồ ấ

Ch c năng d ch và ch y ch ng trình ứ ị ạ ươ

Ctrl-F9: Kh i đ ng ch c năng d ch và ch y toàn b ch ng trình.ở ộ ứ ị ạ ộ ươ

F4: Ch y ch ng trình t đ u đ n dòng l nh hi n t i (đang ch a con tr )ạ ươ ừ ầ ế ệ ệ ạ ứ ỏ

F7: Ch y t ng l nh m t c a hàm main(), k c các l nh con trong hàm.ạ ừ ệ ộ ủ ể ả ệ

F8: Ch y t ng l nh m t c a hàm main(). Khi đó m i l i g i hàm đ c xem là m t l nhạ ừ ệ ộ ủ ỗ ờ ọ ượ ộ ệ (không ch y t ng l nh trong các hàm đ c g i).ạ ừ ệ ượ ọ

Các ch c năng liên quan đ n d ch ch ng trình có th đ c ch n thông qua menu Compile (Alt-ứ ế ị ươ ể ượ ọC).

Tóm t t m t s phím nóng hay dùngắ ộ ố

Các phím kích ho t menu: Alt+ch cái đ i di n cho nhóm menu đó. Ví d Alt-F mạ ữ ạ ệ ụ ở menu File đ ch n các ch c năng c th trong nó nh Open (m file), Save (ghi fileể ọ ứ ụ ể ư ở lên đĩa), Print (in n i dung văn b n ch ng trình ra máy in), … Alt-C m menuộ ả ươ ở Compile đ ch n các ch c năng d ch ch ng trình.ể ọ ứ ị ươ

Các phím d ch chuy n con tr khi so n th o.ị ể ỏ ạ ả

Page 15: Giao Trinh C++ Toan Tap

F1: m c a s tr giúp. Đây là ch c năng quan tr ng giúp ng i l p trình nh tên l nh,ở ử ổ ợ ứ ọ ườ ậ ớ ệ cú pháp và cách s d ng. ử ụ

F2: ghi t p lên đĩa.ệ

F3: m t p cũ ra s a ch a ho c so n th o t p m i.ở ệ ử ữ ặ ạ ả ệ ớ

F4: ch y ch ng trình đ n v trí con tr .ạ ươ ế ị ỏ

F5: Thu h p/m r ng c a s so n th o.ẹ ở ộ ử ổ ạ ả

F6: Chuy n đ i gi a các c a s so n th o.ể ổ ữ ử ổ ạ ả

F7: Ch y ch ng trình theo t ng l nh, k c các l nh trong hàm con.ạ ươ ừ ệ ể ả ệ

F8: Ch y ch ng trình theo t ng l nh trong hàm chính.ạ ươ ừ ệ

F9: D ch và liên k t ch ng trình. Th ng dùng ch c năng này đ tìm l i cú pháp c aị ế ươ ườ ứ ể ỗ ủ ch ng trình ngu n tr c khi ch y.ươ ồ ướ ạ

Alt-F7: Chuy n con tr v n i gây l i tr c đó.ể ỏ ề ơ ỗ ướ

Alt-F8: Chuy n con tr đ n l i ti p theo.ể ỏ ế ỗ ế

Ctrl-F9: Ch y ch ng trình.ạ ươ

Ctrl-Insert: L u kh i văn b n đ c đánh d u vào b nh đ m.ư ố ả ượ ấ ộ ớ ệ

Shift-Insert: Dán kh i văn b n trong b nh đ m vào văn b n t i v trí con tr .ố ả ộ ớ ệ ả ạ ị ỏ

Shift-Delete: Xoá kh i văn b n đ c đánh d u, l u nó vào b nh đ m.ố ả ượ ấ ư ộ ớ ệ

Ctrl-Delete: Xoá kh i văn b n đ c đánh d u (không l u vào b nh đ m).ố ả ượ ấ ư ộ ớ ệ

Alt-F5: Chuy n sang c a s xem k t qu c a ch ng trình v a ch y xong.ể ử ổ ế ả ủ ươ ừ ạ

Alt-X: thoát C++ v l i Windows.ề ạ

C u trúc m t ch ng trình trong C++ấ ộ ươM t ch ng trình C++ có th đ c đ t trong m t ho c nhi u file văn b n khác nhau. M i fileộ ươ ể ượ ặ ộ ặ ề ả ỗ văn b n ch a m t s ph n nào đó c a ch ng trình. V i nh ng ch ng trình đ n gi n vàả ứ ộ ố ầ ủ ươ ớ ữ ươ ơ ả ng n th ng ch c n đ t chúng trên m t file. ắ ườ ỉ ầ ặ ộ

M t ch ng trình g m nhi u hàm, m i hàm ph trách m t công vi c khác nhau c a ch ngộ ươ ồ ề ỗ ụ ộ ệ ủ ươ trình. Đ c bi t trong các hàm này có m t hàm duy nh t có tên hàm là main(). Khi ch y ch ngặ ệ ộ ấ ạ ươ trình, các câu l nh trong hàm main() s đ c th c hi n đ u tiên. Trong hàm main() có th cóệ ẽ ượ ự ệ ầ ể các câu l nh g i đ n các hàm khác khi c n thi t, và các hàm này khi ch y l i có th g i đ nệ ọ ế ầ ế ạ ạ ể ọ ế các hàm khác n a đã đ c vi t trong ch ng trình (tr vi c g i quay l i hàm main()). Sau khiữ ượ ế ươ ừ ệ ọ ạ ch y đ n l nh cu i cùng c a hàm main() ch ng trình s k t thúc.ạ ế ệ ố ủ ươ ẽ ế

C th , thông th ng m t ch ng trình g m có các n i dung sau:ụ ể ườ ộ ươ ồ ộ

Ph n khai báo các t p nguyên m u: khai báo tên các t p ch a nh ng thành ph n có s nầ ệ ẫ ệ ứ ữ ầ ẵ (nh các h ng chu n, ki u chu n và các hàm chu n) mà NSD s dùng trong ch ngư ằ ẩ ể ẩ ẩ ẽ ươ trình.

Page 16: Giao Trinh C++ Toan Tap

Ph n khai báo các ki u d li u, các bi n, h ng ... do NSD đ nh nghĩa và đ c dùngầ ể ữ ệ ế ằ ị ượ chung trong toàn b ch ng trình.ộ ươ

Danh sách các hàm c a ch ng trình (do NSD vi t, bao g m c hàm main()). C u trúcủ ươ ế ồ ả ấ chi ti t c a m i hàm s đ c đ c p đ n trong ch ng 4.ế ủ ỗ ẽ ượ ề ậ ế ươ

D i đây là m t đo n ch ng trình đ n gi n ch g m 1 hàm chính là hàm main(). N i dungướ ộ ạ ươ ơ ả ỉ ồ ộ c a ch ng trình dùng in ra màn hình dòng ch : ủ ươ ữ Chào các b n, bây gi là 2 giạ ờ ờ.

#include <iostream.h> // khai báo t p nguyên m u đệ ẫ ể

void main() // đ c s d ng toán t in cout <<ượ ử ụ ử

{

int h = 2, // Khai báo và kh i t o bi n h = 2ở ạ ế

cout << “Chào các b n, bây gi là ” << h << " gi " ; ạ ờ ờ // in ra màn hình

}Dòng đ u tiên c a ch ng trình là khai báo t p nguyên m u iostream.h. Đây là khai báo b tầ ủ ươ ệ ẫ ắ bu c vì trong ch ng trình có s d ng ph ng th c chu n “cout <<” (in ra màn hình), ph ngộ ươ ử ụ ươ ứ ẩ ươ th c này đ c khai báo và đ nh nghĩa s n trong iostream.h. ứ ượ ị ẵ

Không riêng hàm main(), m i hàm khác đ u ph i b t đ u t p h p các câu l nh c a mình b iọ ề ả ắ ầ ậ ợ ệ ủ ở d u { và k t thúc b i d u }. T p các l nh b t kỳ bên trong c p d u này đ c g i là kh iấ ế ở ấ ậ ệ ấ ặ ấ ượ ọ ố l nh. Kh i l nh là m t cú pháp c n thi t trong các câu l nh có c u trúc nh ta s th y trongệ ố ệ ộ ầ ế ệ ấ ư ẽ ấ các ch ng ti p theo. ươ ế

CÁC B C Đ T O VÀ TH C HI N M T CH NG TRÌNH ƯỚ Ể Ạ Ự Ệ Ộ ƯƠ

Qui trình vi t và th c hi n ch ng trìnhế ự ệ ươTr c khi vi t và ch y m t ch ng trình thông th ng chúng ta c n:ướ ế ạ ộ ươ ườ ầ

Xác đ nh yêu c u c a ch ng trình. Nghĩa là xác đ nh d li u đ u vào (input) cung c pị ầ ủ ươ ị ữ ệ ầ ấ cho ch ng trình và t p các d li u c n đ t đ c t c đ u ra (output). Các t p h pươ ậ ữ ệ ầ ạ ượ ứ ầ ậ ợ d li u này ngoài các tên g i còn c n xác đ nh ki u c a nó.Ví d đ gi i m tữ ệ ọ ầ ị ể ủ ụ ể ả ộ ph ng trình b c 2 d ng: axươ ậ ạ 2 + bx + c = 0, c n báo cho ch ng trình bi t d li uầ ươ ế ữ ệ đ u vào là a, b, c và đ u ra là nghi m x1 và x2 c a ph ng trình. Ki u c a a, b, c,ầ ầ ệ ủ ươ ể ủ x1, x2 là các s th c.ố ự

Xác đ nh thu t toán gi i.ị ậ ả

C th hoá các khai báo ki u và thu t toán thành dãy các l nh, t c vi t thành ch ngụ ể ể ậ ệ ứ ế ươ trình thông th ng là trên gi y, sau đó b t đ u so n th o vào trong máy. Quá trìnhườ ấ ắ ầ ạ ả này đ c g i là so n th o ch ng trình ngu n.ượ ọ ạ ả ươ ồ

D ch ch ng trình ngu n đ tìm và s a các l i g i là l i cú pháp. ị ươ ồ ể ử ỗ ọ ỗ

Ch y ch ng trình, ki m tra k t qu in ra trên màn hình. N u sai, s a l i ch ng trình,ạ ươ ể ế ả ế ử ạ ươ d ch và ch y l i đ ki m tra. Quá trình này đ c th c hi n l p đi l p l i cho đ nị ạ ạ ể ể ượ ự ệ ặ ặ ạ ế khi ch ng trình ch y t t theo yêu c u đ ra c a NSD. ươ ạ ố ầ ề ủ

Page 17: Giao Trinh C++ Toan Tap

So n th o t p ch ng trình ngu nạ ả ệ ươ ồSo n th o ch ng trình ngu n là m t công vi c đ n gi n: gõ n i dung c a ch ng trình (đãạ ả ươ ồ ộ ệ ơ ả ộ ủ ươ vi t ra gi y) vào trong máy và l u l i nó lên đĩa. Thông th ng khi đã l u l i ch ng trình lênế ấ ư ạ ườ ư ạ ươ đĩa l n sau s không c n ph i gõ l i. Có th so n ch ng trình ngu n trên các b so n th oầ ẽ ầ ả ạ ể ạ ươ ồ ộ ạ ả (editor) khác nhưng ph i ch y trong môi trả ạ ư ng tích h p C++ (Borland C, Turbo C). M c đíchờ ợ ụ c a so n th o là t o ra m t văn b n ch ng trình và đ a vào b nh c a máy. Văn b nủ ạ ả ạ ộ ả ươ ư ộ ớ ủ ả ch ng trình c n đ c trình bày sáng s a, rõ ràng. Các câu l nh c n gióng th ng c t theo c uươ ầ ượ ủ ệ ầ ẳ ộ ấ trúc c a l nh (các l nh ch a trong m t l nh c u trúc đ c trình bày th t vào trong so v iủ ệ ệ ứ ộ ệ ấ ượ ụ ớ đi m b t đ u c a l nh). Các chú thích nên ghi ng n g n, rõ nghĩa và phù h p.ể ắ ầ ủ ệ ắ ọ ợ

D ch ch ng trìnhị ươSau khi đã so n th o xong ch ng trình ngu n, b c ti p theo th ng là d ch ( n t h pạ ả ươ ồ ướ ế ườ ị ấ ổ ợ phím Alt-F9) đ tìm và s a các l i g i là l i cú pháp. Trong khi d ch C++ s đ t con tr vàoể ử ỗ ọ ỗ ị ẽ ặ ỏ n i gây l i (vi t sai cú pháp) trong văn b n. Sau khi s a xong m t l i NSD có th dùng Alt-F8ơ ỗ ế ả ử ộ ỗ ể đ chuy n con tr đ n l i ti p theo ho c d ch l i. Đ chuy n con tr v ng c l i l i tr cể ể ỏ ế ỗ ế ặ ị ạ ể ể ỏ ề ượ ạ ỗ ướ

đó có th dùng Alt-F7. Quá trình s a l i ể ử ỗ − d ch đ c l p l i cho đ n khi văn b n đã đ c s aị ượ ặ ạ ế ả ượ ử h t l i cú pháp.ế ỗ

S n ph m sau khi d ch là m t t p m i g i là ch ng trình đích có đuôi EXE t c là t p mãả ẩ ị ộ ệ ớ ọ ươ ứ ệ máy đ th c hi n.T p này có th l u t m th i trong b nh ph c v cho quá trình ch yể ự ệ ệ ể ư ạ ờ ộ ớ ụ ụ ạ ch ng trình ho c l u l i trên đĩa tuỳ theo tuỳ ch n khi d ch c a NSD. Trong và sau khi d ch,ươ ặ ư ạ ọ ị ủ ị C++ s hi n m t c a s ch a thông báo v các l i (n u có), ho c thông báo ch ng trình đãẽ ệ ộ ử ổ ứ ề ỗ ế ặ ươ đ c d ch thành công (không còn l i). Các l i này đ c g i là l i cú pháp.ượ ị ỗ ỗ ượ ọ ỗ

Đ d ch ch ng trình ta ch n menu \Compile\Compile ho c \Compile\Make ho c nhanh chóngể ị ươ ọ ặ ặ h n b ng cách n t h p phím Alt-F9.ơ ằ ấ ổ ợ

Ch y ch ng trìnhạ ươn Ctrl-F9 đ ch y ch ng trình, n u ch ng trình ch a d ch sang mã máy, máy s t đ ngẤ ể ạ ươ ế ươ ư ị ẽ ự ộ

d ch l i tr c khi ch y. K t qu c a ch ng trình s hi n ra trong m t c a s k t qu đị ạ ướ ạ ế ả ủ ươ ẽ ệ ộ ử ổ ế ả ể NSD ki m tra. N u k t qu ch a đ c nh mong mu n, quay l i văn b n đ s a và l i ch yể ế ế ả ư ượ ư ố ạ ả ể ử ạ ạ l i ch ng trình. Quá trình này đ c l p l i cho đ n khi ch ng trình ch y đúng nh yêu c uạ ươ ượ ặ ạ ế ươ ạ ư ầ đã đ ra. Khi ch ng trình ch y, c a s k t qu s hi n ra t m th i che khu t c a s so nề ươ ạ ử ổ ế ả ẽ ệ ạ ờ ấ ử ổ ạ th o. Sau khi k t thúc ch y ch ng trình c a s so n th o s t đ ng hi n ra tr l i và cheả ế ạ ươ ử ổ ạ ả ẽ ự ộ ệ ở ạ khu t c a s k t qu . Đ xem l i k t qu đã hi n n Alt-F5. Sau khi xem xong đ quay l iấ ử ổ ế ả ể ạ ế ả ệ ấ ể ạ c a s so n th o n phím b t kỳ. ử ổ ạ ả ấ ấ

Page 18: Giao Trinh C++ Toan Tap

VÀO/RA TRONG C++

Trong ph n này chúng ta làm quen m t s l nh đ n gi n cho phép NSD nh p d li u vào tầ ộ ố ệ ơ ả ậ ữ ệ ừ bàn phím ho c in k t qu ra màn hình. Trong ph n sau c a giáo trình chúng ta s kh o sát cácặ ế ả ầ ủ ẽ ả câu l nh vào/ra ph c t p h nệ ứ ạ ơ

Vào d li u t bàn phímữ ệ ừĐ nh p d li u vào cho các bi n có tên ể ậ ữ ệ ế bi n_1ế , bi n_2ế , bi n_3ế chúng ta s d ng câu l nh:ử ụ ệ

cin >> bi n_1 ;ế

cin >> bi n_2 ;ế

cin >> bi n_3 ;ếho c:ặ

cin >> bi n_1 >> bi n_2 >> bi n_3 ;ế ế ế bi n_1, bi n_2, bi n_3 là các ế ế ế bi nế đ c s d ng đ l u tr các giá tr NSD nh p vào t bànượ ử ụ ể ư ữ ị ậ ừ phím. Khái ni m bi n s đ c mô t c th h n trong ch ng 2, đây bi n_1, bi n_2,ệ ế ẽ ượ ả ụ ể ơ ươ ở ế ế bi n_3 đ c hi u là các tên g i đ ch 3 giá tr khác nhau. Hi n nhiên có th nh p d li uế ượ ể ọ ể ỉ ị ể ể ậ ữ ệ nhi u h n 3 bi n b ng cách ti p t c vi t tên bi n vào bên ph i sau d u >> c a câu l nh.ề ơ ế ằ ế ụ ế ế ả ấ ủ ệ

Khi ch y ch ng trình n u g p các câu l nh trên ch ng trình s "t m d ng" đ chạ ươ ế ặ ệ ươ ẽ ạ ừ ể ờ NSD nh p d li u vào cho các bi n. Sau khi NSD nh p xong d li u, ch ng trình s ti pậ ữ ệ ế ậ ữ ệ ươ ẽ ế t c ch y t câu l nh ti p theo sau c a các câu l nh trên.ụ ạ ừ ệ ế ủ ệCách th c nh p d li u c a NSD ph thu c vào lo i giá tr c a bi n c n nh p mà ta g i làứ ậ ữ ệ ủ ụ ộ ạ ị ủ ế ầ ậ ọ ki u,ể ví d nh p m t s có cách th c khác v i nh p m t chu i kí t . Gi s c n nh p đ dàiụ ậ ộ ố ứ ớ ậ ộ ỗ ự ả ử ầ ậ ộ hai c nh c a m t hình ch nh t, trong đó c nh dài đ c qui c b ng tên bi n cd và chi uạ ủ ộ ữ ậ ạ ượ ướ ằ ế ề r ng đ c qui c b i tên bi n cr. Câu l nh nh p s nh sau:ộ ượ ướ ở ế ệ ậ ẽ ư

cin >> cd >> cr ;Khi máy d ng ch nh p d li u NSD s gõ giá tr c th c a các chi u dài, r ng theo đúngừ ờ ậ ữ ệ ẽ ị ụ ể ủ ề ộ th t trong câu l nh. Các giá tr này c n cách nhau b i ít nh t m t d u tr ng (ta qui c g iứ ự ệ ị ầ ở ấ ộ ấ ắ ướ ọ d u tr ng là m t trong 3 lo i d u đ c nh p b i các phím sau: phím spacebar (d u cách),ấ ắ ộ ạ ấ ượ ậ ở ấ phím tab (d u tab) ho c phím Enter (d u xu ng dòng)). Các giá tr NSD nh p vào cũng đ cấ ặ ấ ố ị ậ ượ hi n th trên màn hình đ NSD d theo dõi.ể ị ể ễ

Ví d n u NSD nh p vào 23 11 ¿ thì ch ng trình s gán giá tr 23 cho bi n cd và 11 cho bi nụ ế ậ ươ ẽ ị ế ế cr.

Chú ý: gi s NSD nh p 2311 ¿ (không có d u cách gi a 23 và 11) thì ch ng trình s xemả ử ậ ấ ữ ươ ẽ 2311 là m t giá tr và gán cho cd. Máy s t m d ng ch NSD nh p ti p giá tr cho bi n cr.ộ ị ẽ ạ ừ ờ ậ ế ị ế

In d li u ra màn hìnhữ ệĐ in giá tr c a các ể ị ủ bi u th cể ứ ra màn hình ta dùng câu l nh sau:ệ

Page 19: Giao Trinh C++ Toan Tap

cout << bt_1 ;

cout << bt_2 ;

cout << bt_3 ;ho c:ặ

cout << bt_1 << bt_2 << bt_3 ;cũng gi ng câu l nh nh p đây chúng ta cũng có th m r ng l nh in v i nhi u h n 3 bi uố ệ ậ ở ể ở ộ ệ ớ ề ơ ể th c. Câu l nh trên cho phép in giá tr c a các bi u th c bt_1, bt_2, bt_3. Các giá tr này có thứ ệ ị ủ ể ứ ị ể là tên c a bi n ho c các k t h p tính toán trên bi n.ủ ế ặ ế ợ ế

Ví d đ in câu "Chi u dài là " và s 23 và ti p theo là ch "mét", ta có th s d ng 3 l nhụ ể ề ố ế ữ ể ử ụ ệ sau đây:

cout << "Chi u dài là" ;ề

cout << 23 ;

cout << "mét";ho c có th ch b ng 1 l nh:ặ ể ỉ ằ ệ

cout << "Chi u dài là 23 mét" ;ềTr ng h p ch a bi t giá tr c th c a chi u dài, ch bi t hi n t i giá tr này đã đ c l uườ ợ ư ế ị ụ ể ủ ề ỉ ế ệ ạ ị ượ ư trong bi n cd (ví d đã đ c nh p vào là 23 t bàn phím b i câu l nh cin >> cd tr c đó) vàế ụ ượ ậ ừ ở ệ ướ ta c n bi t giá tr này là bao nhiêu thì có th s d ng câu l nh in ra màn hình.ầ ế ị ể ử ụ ệ

cout << "Chi u dài là" << cd << "mét" ;ềKhi đó trên màn hình s hi n ra dòng ch : "Chi u dài là 23 mét". Nh v y trong tr ng h pẽ ệ ữ ề ư ậ ườ ợ này ta ph i dùng đ n ba l n d u phép toán << ch không ph i m t nh câu l nh trên. Ngoài raả ế ầ ấ ứ ả ộ ư ệ ph thu c vào giá tr hi n đ c l u trong bi n cd, ch ng trình s in ra s chi u dài thíchụ ộ ị ệ ượ ư ế ươ ẽ ố ề h p ch không ch in c đ nh thành "chi u dài là 23 mét". Ví d n u cd đ c nh p là 15 thìợ ứ ỉ ố ị ề ụ ế ượ ậ l nh trên s in câu "chi u dài là 15 mét".ệ ẽ ề

M t giá tr c n in không ch là m t bi n nh cd, cr, ... mà còn có th là m t bi u th c,ộ ị ầ ỉ ộ ế ư ể ộ ể ứ đi u này cho phép ta d dàng yêu c u máy in ra di n tích và chu vi c a hình ch nh t khi đãề ễ ầ ệ ủ ữ ậ bi t cd và cr b ng các câu l nh sau:ế ằ ệ

cout << "Di n tích = " << cd * cr ;ệ

cout << "Chu vi = " << 2 * (cd + cr) ;ho c g p t t c thành 1 câu l nh:ặ ộ ấ ả ệ

cout << Di n tích = " << cd * cr << ‘\n’ << " Chu vi = " << 2 * (cd + cr) ;ệ đây có m t kí t đ c bi t: đó là kí t '\n' kí hi u cho kí t xu ng dòng, khi g p kí t nàyở ộ ự ặ ệ ự ệ ự ố ặ ự

ch ng trình s in các ph n ti p theo đ u dòng k ti p. Do đó k t qu c a câu l nh trên làươ ẽ ầ ế ở ầ ế ế ế ả ủ ệ 2 dòng sau đây trên màn hình:

Di n tích = 253ệ

Chu vi = 68

Page 20: Giao Trinh C++ Toan Tap

đây 253 và 68 l n l t là các giá tr mà máy tính đ c t các ở ầ ượ ị ượ ừ bi u th cể ứ cd * cr, và 2 * (cd + cr) trong câu l nh in trên.ệ ở

Chú ý: đ s d ng các câu l nh nh p và in trong ph n này, đ u ch ng trình ph i có dòngể ử ụ ệ ậ ầ ầ ươ ả khai báo #include <iostream.h>.

Thông th ng ta hay s d ng l nh in đ in câu thông báo nh c NSD nh p d li u tr cườ ử ụ ệ ể ắ ậ ữ ệ ướ khi có câu l nh nh p. Khi đó trên màn hình s hi n dòng thông báo này r i m i t m d ng chệ ậ ẽ ệ ồ ớ ạ ừ ờ d li u nh p vào t bàn phím. Nh vào thông báo này NSD s bi t ph i nh p d li u, nh pữ ệ ậ ừ ờ ẽ ế ả ậ ữ ệ ậ n i dung gì và nh th nào ... ví d :ộ ư ế ụ

cout << "Hãy nh p chi u dài: "; cin >> cd;ậ ề

cout << "Và nh p chi u r ng: "; cin >> cr;ậ ề ộkhi đó máy s in dòng thông báo "Hãy nh p chi u dài: " và ch sau khi NSD nh p xong 23 ¿,ẽ ậ ề ờ ậ máy s th c hi n câu l nh ti p theo t c in dòng thông báo "Và nh p chi u r ng: " và ch đ nẽ ự ệ ệ ế ứ ậ ề ộ ờ ế khi NSD nh p xong 11 ¿ ch ng trình s ti p t c th c hi n các câu l nh ti p theo. ậ ươ ẽ ế ụ ự ệ ệ ế

Ví d 2 ụ : T các th o lu n trên ta có th vi t m t cách đ y đ ch ng trình tính di n tích vàừ ả ậ ể ế ộ ầ ủ ươ ệ chu vi c a m t hình ch nh t. Đ ch ng trình có th tính v i các b giá tr khác nhau c aủ ộ ữ ậ ể ươ ể ớ ộ ị ủ chi u dài và r ng ta c n l u giá tr này vào trong các bi n (ví d cd, cr). ề ộ ầ ư ị ế ụ

#include <iostream.h> // khai báo t p nguyên m u đ dùng đ c cin, coutệ ẫ ể ượ

void main() // đây là hàm chính c a ch ng trìnhủ ươ

{

float cd, cr ; // khai báo các bi n có tên cd, cr đ ch a đ dài các c nhế ể ứ ộ ạ

cout << "Hãy nh p chi u dài: " ; cin >> cd ;ậ ề // nh p d li uậ ữ ệ

cout << "Hãy nh p chi u r ng: " ; cin >> cr ;ậ ề ộ

cout << "Di n tích = " << cd * cr << '\n' ;ệ // in k t quế ả

cout << "Chu vi = " << 2 * (cd + cr) << '\n';

return ;

}Ch ng trình này có th gõ vào máy và ch y. Khi ch y đ n câu l nh nh p, ch ng trìnhươ ể ạ ạ ế ệ ậ ươ d ng đ ch nh n chi u dài và chi u r ng, NSD nh p các giá tr c th , ch ng trình s ti pừ ể ờ ậ ề ề ộ ậ ị ụ ể ươ ẽ ế t c th c hi n và in ra k t qu . Thông qua câu l nh nh p d li u và 2 bi n cd, cr NSD có thụ ự ệ ế ả ệ ậ ữ ệ ế ể yêu c u ch ng trình cho k t qu c a m t hình ch nh t b t kỳ ch không ch trong tr ngầ ươ ế ả ủ ộ ữ ậ ấ ứ ỉ ườ h p hình có chi u dài 23 và chi u r ng 11 nh trong ví d c th trên. ợ ề ề ộ ư ụ ụ ể

Đ nh d ng thông tin c n in ra màn hìnhị ạ ầ

Page 21: Giao Trinh C++ Toan Tap

M t s đ nh d ng đ n gi n đ c chúng tôi trình bày tr c đây. Các đ nh d ng chi ti t vàộ ố ị ạ ơ ả ượ ướ ở ị ạ ế ph c t p h n s đ c trình bày trong các ph n sau c a giáo trình. Đ s d ng các đ nh d ngứ ạ ơ ẽ ượ ầ ủ ể ử ụ ị ạ này c n khai báo file nguyên m u <iomanip.h> đ u ch ng trình b ng ch th #includeầ ẫ ở ầ ươ ằ ỉ ị <iomanip.h>.

endl: T ng đ ng v i kí t xu ng dòng '\n'.ươ ươ ớ ự ố

setw(n): Bình th ng các giá tr đ c in ra b i l nh cout << s th ng theo l trái v i đườ ị ượ ở ệ ẽ ẳ ề ớ ộ r ng ph thu c vào đ r ng c a giá tr đó. Ph ng th c này qui đ nh đ r ng dànhộ ụ ộ ộ ộ ủ ị ươ ứ ị ộ ộ đ in ra các giá tr là n c t màn hình. N u n l n h n đ dài th c c a giá tr , giá tr sể ị ộ ế ớ ơ ộ ự ủ ị ị ẽ in ra theo l ph i, đ tr ng ph n th a (d u cách) tr c. ề ả ể ố ầ ừ ấ ở ướ

setprecision(n): Ch đ nh s ch s c a ph n th p phân in ra là n. S s đ c làm trònỉ ị ố ữ ố ủ ầ ậ ố ẽ ượ tr c khi in ra.ướ

setiosflags(ios::showpoint): Ph ng th c setprecision ch có tác d ng trên m t dòng in.ươ ứ ỉ ụ ộ Đ c đ nh các giá tr đã đ t cho m i dòng in (cho đ n khi đ t l i giá tr m i) ta sể ố ị ị ặ ọ ế ặ ạ ị ớ ử d ng ph ng th c setiosflags(ios::showpoint).ụ ươ ứ

Ví d sau minh ho cách s d ng các ph ng th c trên. ụ ạ ử ụ ươ ứVí d 3 ụ :

#include <iostream.h> // đ s d ng cout <<ể ử ụ

#include <iomanip.h> // đ s d ng các đ nh d ngể ử ụ ị ạ

#include <conio.h> // đ s d ng các hàm clrscr() vàể ử ụ getch()

void main()

{

clrscr(); // xoá màn hình

cout << "CHI TIÊU" << endl << "=======" << endl ;

cout << setiosflags(ios::showpoint) << setprecision(2) ;

cout << "Sách v " << setw(20) << 123.456 << endl;ở

cout << "Th c ăn" << setw(20) << 2453.6 << endl;ứ

cout << "Qu n áo l nh" << setw(15) << 3200.0 << endl;ầ ạ

getch(); // t m d ng (đ xem k t qu )ạ ừ ể ế ả

return ; // k t thúc th c hi n hàm main()ế ự ệ

}Ch ng trình này khi ch y s in ra b ng sau:ươ ạ ẽ ả

CHI TIÊU========

Page 22: Giao Trinh C++ Toan Tap

Sách vở 123.46

Th c ănứ 2453.60

Qu n áo l nhầ ạ 3200.00

Chú ý: toán t nh p >> ch y u làm vi c v i d li u ki u s . Đ nh p kí t ho c xâu kí t ,ử ậ ủ ế ệ ớ ữ ệ ể ố ể ậ ự ặ ự C++ cung c p các ph ng th c (hàm) sau:ấ ươ ứ

cin.get(c): cho phép nh p m t kí t vào bi n kí t c,ậ ộ ự ế ự

cin.getline(s,n): cho phép nh p t i đa n-1 kí t vào xâu s.ậ ố ựcác hàm trên khi th c hi n s l y các kí t còn l i trong b nh đ m (c a l n nh p tr c) đự ệ ẽ ấ ự ạ ộ ớ ệ ủ ầ ậ ướ ể gán cho c ho c s. Do toán t cin >> x s đ l i kí t xu ng dòng trong b đ m nên kí t nàyặ ử ẽ ể ạ ự ố ộ ệ ự s làm trôi các l nh sau đó nh cin.get(c), cin.getline(s,n) (máy không d ng đ nh p cho cẽ ệ ư ừ ể ậ ho c s). Vì v y tr c khi s d ng các ph ng th c cin.get(c) ho c cin.getline(s,n) nên sặ ậ ướ ử ụ ươ ứ ặ ử d ng ph ng th c cin.ignore(1) đ l y ra kí t xu ng dòng còn sót l i trong b đ m. Ví dụ ươ ứ ể ấ ự ố ạ ộ ệ ụ đo n l nh sau cho phép nh p m t s nguyên x (b ng toán t >>) và m t kí t c (b ng ph ngạ ệ ậ ộ ố ằ ử ộ ự ằ ươ th c cin.get(c)): ứ

int x;

char c;

cin >> x; cin.ignore(1);

cin.get(c);

Vào/ra trong CTrong ph n trên chúng tôi đã trình bày 2 toán t vào/ra và m t s ph ng th c, hàm nh p vàầ ử ộ ố ươ ứ ậ đ nh d ng trong C++. Ph n này chúng tôi trình bày các câu lênh nh p xu t theo khuôn d ng cũị ạ ầ ậ ấ ạ trong C. Hi n nhiên các câu l nh này v n dùng đ c trong ch ng trình vi t b ng C++, tuyể ệ ẫ ượ ươ ế ằ nhiên ch nên s d ng ho c các câu l nh c a C++ ho c c a C, không nên dùng l n l n c haiỉ ử ụ ặ ệ ủ ặ ủ ẫ ộ ả vì d gây nh m l n. Do đó m c này ch có giá tr tham kh o đ b n đ c có th hi u đ c cácễ ầ ẫ ụ ỉ ị ả ể ạ ọ ể ể ượ câu l nh vào/ra trong các ch ng trình vi t theo NNLT C cũ. ệ ươ ế

In k t qu ra màn hìnhế ảĐ in các giá tr bt_1, bt_2, …, bt_n ra màn hình theo m t khuôn d ng mong mu n ta có th sể ị ộ ạ ố ể ử d ng câu l nh sau đây: ụ ệ

printf(dòng đ nh d ng, bt_1, bt_2, ..., bt_n) ;ị ạtrong đó dòng đ nh d ng là m t dãy kí t đ t trong c p d u nháy kép (“”) qui đ nh khuôn d ngị ạ ộ ự ặ ặ ấ ị ạ c n in c a các giá tr bt_1, bt_2, …, bt_n. Các bt_i có th là các h ng, bi n hay các bi u th cầ ủ ị ể ằ ế ể ứ tính toán. Câu l nh trên s in giá tr c a các bt_i này theo th t xu t hi n c a chúng và theoệ ẽ ị ủ ứ ự ấ ệ ủ qui đ nh đ c cho trong dòng đ nh d ng.ị ượ ị ạ

Page 23: Giao Trinh C++ Toan Tap

Ví d , gi s x = 4, câu l nh:ụ ả ử ệ

printf(“%d %0.2f”, 3, x + 1) ;s in các s 3 và 5.00 ra màn hình, trong đó 3 đ c in d i d ng s nguyên (đ c qui đ nh b iẽ ố ượ ướ ạ ố ượ ị ở “%d”) và x + 1 (có giá tr là 5) đ c in d i d ng s th c v i 2 s l th p phân (đ c quiị ượ ướ ạ ố ự ớ ố ẻ ậ ượ đ nh b i “%0.2f”). C th , các kí t đi sau kí hi u % dùng đ đ nh d ng vi c in g m có:ị ở ụ ể ự ệ ể ị ạ ệ ồ

d in s nguyên d i d ng h th p phânố ướ ạ ệ ậ

o in s nguyên d ng h 8ố ạ ệ

x, X in s nguyên d ng h 16ố ạ ệ

u in s nguyên d ng không d uố ạ ấ

c in kí tự

s in xâu kí tự

e, E in s th c d ng d u ph y đ ngố ự ạ ấ ẩ ộ

f in s th c d ng d u ph y tĩnhố ự ạ ấ ẩ

Các kí t trên ph i đi sau d u %. Các kí t n m trong dòng đ nh d ng n u không đi sauự ả ấ ự ằ ị ạ ế % thì s đ c in ra màn hình. Mu n in % ph i vi t 2 l n (t c %%).ẽ ượ ố ả ế ầ ứ

Ví d câu l nh: printf(“T l h c sinh gi i: %0.2f %%”, 32.486) ;ụ ệ ỉ ệ ọ ỏ

s in câu “T l h c sinh gi i: “, ti p theo s in s 32.486 đ c làm tròn đ n 2 s l th pẽ ỉ ệ ọ ỏ ế ẽ ố ượ ế ố ẻ ậ phân l p vào v trí c a “%0.2f”, và cu i cùng s in d u “%” (do có %% trong dòng đ nh d ng).ấ ị ủ ố ẽ ấ ị ạ Câu đ c in ra màn hình s là:ượ ẽ

T l h c sinh gi i: 32.49%ỉ ệ ọ ỏChú ý: M i bt_i c n in ph i có m t đ nh d ng t ng ng trong dòng đ nh d ng. Ví d câuỗ ầ ả ộ ị ạ ươ ứ ị ạ ụ l nh trên cũng có th vi t:ệ ể ế

printf(“%s %0.2f” , “T l h c sinh gi i: “, 32.486);ỉ ệ ọ ỏtrong câu l nh này có 2 bi u th c c n in. Bi u th c th nh t là xâu kí t “T l h c sinhệ ể ứ ầ ể ứ ứ ấ ự ỉ ệ ọ gi i:” đ c in v i khuôn d ng %s (in xâu kí t ) và bi u th c th hai là 32.486 đ c in v iỏ ượ ớ ạ ự ể ứ ứ ượ ớ khuôn d ng %0.2f (in s th c v i 2 s l ph n th p phân).ạ ố ự ớ ố ẻ ầ ậ

N u gi a kí t % và kí t đ nh d ng có s bi u th đ r ng c n in thì giá tr in ra sế ữ ự ự ị ạ ố ể ị ộ ộ ầ ị ẽ đ c gióng c t sang l ph i, đ tr ng các d u cách phía tr c. N u đ r ng âmượ ộ ề ả ể ố ấ ướ ế ộ ộ (thêm d u tr ấ ừ - phía tr cướ ) s gióng c t sang l trái. N u không có đ r ng ho c đẽ ộ ề ế ộ ộ ặ ộ r ng b ng 0 (ví d %0.2f) thì đ r ng đ c t đi u ch nh đúng b ng đ r ng c aộ ằ ụ ộ ộ ượ ự ề ỉ ằ ộ ộ ủ giá tr c n in.ị ầ

D u + tr c đ r ng đ in giá tr s kèm theo d u (d ng ho c âm)ấ ướ ộ ộ ể ị ố ấ ươ ặ

Tr c các đ nh d ng s c n thêm kí t l (ví d ld, lf) khi in s nguyên dài long ho c sướ ị ạ ố ầ ự ụ ố ặ ố th c v i đ chính xác g p đôi double.ự ớ ộ ấ

Ví d 4 ụ :

main()

Page 24: Giao Trinh C++ Toan Tap

{

int i = 2, j = 3 ;

printf(“Ch ng trình tính t ng 2 s nguyên:\ni + j = %d”, i+j);ươ ổ ố

}s in ra: ẽ

Ch ng trình tính t ng 2 s nguyên:ươ ổ ố

i + j = 5.

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

scanf(dòng đ nh d ng, bi n_1, bi n_2, ..., bi n_n) ;ị ạ ế ế ếL nh này cho phép nh p d li u vào cho các bi n bi n_1, …, bi n_n. Trong đó dòng đ nhệ ậ ữ ệ ế ế ế ị d ng ch a các đ nh d ng v ki u bi n (nguyên, th c, kí t …) đ c vi t nh trong mô t câuạ ứ ị ạ ề ể ế ự ự ượ ế ư ả l nh printf. Các bi n đ c vi t d i d ng đ a ch c a chúng t c có d u & tr c m i tên bi n.ệ ế ượ ế ướ ạ ị ỉ ủ ứ ấ ướ ỗ ế Ví d câu l nh:ụ ệ

scanf(“%d %f %ld”, &x, &y, &z) ;cho phép nh p giá tr cho các bi n x, y, z trong đó x là bi n nguyên, y là bi n th c và z là bi nậ ị ế ế ế ự ế nguyên dài (long). Câu l nh:ệ

scanf(“%2d %f %lf %3s”, &i, &x, &d, s);cho phép nh p giá tr cho các bi n i, x, d, s, trong đó i là bi n nguyên có 2 ch s , f là bi nậ ị ế ế ữ ố ế th c (đ dài tùy ý), d là bi n nguyên dài và s là xâu kí t có 3 kí t . Gi s NSD nh p vào dãyự ộ ế ự ự ả ử ậ d li u: 12345 67abcd ữ ệ ¿ thì các bi n trên s đ c gán các giá tr nh sau: i = 12, x = 345, d =ế ẽ ượ ị ư 67 và s = “abc”. Kí t d và d u enter (ự ấ ¿) s đ c l u l i trong b nh và t đ ng gán cho cácẽ ượ ư ạ ộ ớ ự ộ bi n c a l n nh p sau.ế ủ ầ ậ

Cu i cùng, ch ng trình trong ví d 3 đ c vi t l i v i printf() và scanf() nh sau:ố ươ ụ ượ ế ạ ớ ư

Ví d 5 ụ :

#include <stdio.h> // đ s d ng các hàm printf() và scanf()ể ử ụ

#include <conio.h> // đ s d ng các hàm clrscr() và getch()ể ử ụ

void main()

{

clrscr(); // xoá màn hình

printf("CHI TIÊU\n=======\n") ;

printf("Sách v %20.2f\n" , 123.456) ;ở

printf("Th c ăn %20.2f\n" , 2453.6) ;ứ

Page 25: Giao Trinh C++ Toan Tap

printf(“Qu n áo l nh %15.2f\n" , 3200.0) ;ầ ạ

getch(); // t m d ng (đ xem k t qu )ạ ừ ể ế ả

return ; // k t thúc th c hi n hàm main()ế ự ệ

}

BÀI T PẬ

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

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

- RADIUS - one.0 - number# - Radius - nam2000

B n hãy th vi t m t chạ ử ế ộ ương trình ng n nh t có th ắ ấ ể đư c.ợ

Tìm các l i cú pháp trong chỗ ương trình sau:

#include (iostream.h)

void main(); / Gi i phả ương trình b c 1ậ

{

cout << 'Day la chương trình: Gptb1.\nXin chao cac ban';

getch();

}

Vi t chế ương trình in n i dung m t bài th nào đó.ộ ộ ơ

Vi t chế ương trình in ra 4 dòng, 2 c t g m các s sau và gióng c t:ộ ồ ố ộ- th ng theo l tráiẳ ề 0.63 64.1

- th ng theo l ph iẳ ề ả 12.78 -11.678

- th ng theo d u ch m th p phânẳ ấ ấ ậ -124. 6 59.002

65.7 -1200.654

Hãy vi t và ch y các chế ạ ương trình trong các ví d 3, 5.ụ

Ch ng trình sau khai báo 5 bi n kí t a, b, c, d, e và m t bi n s nam. Hãy đi n thêm các câuươ ế ự ộ ế ố ề l nh vào các dòng … đ ch ng trình th c hi n nhi m v sau:ệ ể ươ ự ệ ệ ụ

Nh p giá tr cho bi n namậ ị ế

Nh p giá tr cho các bi n kí t a, b, c, d, e.ậ ị ế ự

In ra màn hình dòng ch đ c ghép b i 5 kí t đã nh p và ch "năm" sau đó in s đãữ ượ ở ự ậ ữ ố nh p (nam). Ví d n u 5 ch cái đã nh p là 'H', 'A', 'N', 'O', 'I' và nam đ c nhap làậ ụ ế ữ ậ ượ

Page 26: Giao Trinh C++ Toan Tap

2000, thì màn hình in ra dòng ch : HANOI năm 2000.ữ

Nh p ch ng trình đã s a vào máy và ch y đ ki m tra k t qu .ậ ươ ử ạ ể ể ế ả

#include <iostream.h>

#include <conio.h>

main()

{

int nam;

char a, b, c, d, e;

clrscr();

cin >> nam ;

… ;

cin.get(a); cin.get(b); cin.get(c); … ; … ;

// in k t quế ả

cout << a << … << … << … << … << " nam " << … ;

getch();

}

CH NG 2ƯƠ

KI U D LI U, BI U TH C VÀ CÂU L NH Ể Ữ Ệ Ể Ứ Ệ

Ki u d li u đ n gi nể ữ ệ ơ ảH ng - khai báo và s d ng h ngằ ử ụ ằBi n - khai báo và s d ng bi nế ử ụ ếPhép toán, bi u th c và câu l nhể ứ ệTh vi n các hàm toán h cư ệ ọ

KI U D LI U Đ N GI NỂ Ữ Ệ Ơ Ả

Khái ni m v ki u d li uệ ề ể ữ ệThông th ng d li u hay dùng là s và ch . Tuy nhiên vi c phân chia ch 2 loai d li u làườ ữ ệ ố ữ ệ ỉ ữ ệ không đ . Đ d dàng h n cho l p trình, h u h t các NNLT đ u phân chia d li u thànhủ ể ễ ơ ậ ầ ế ề ữ ệ nhi u ki u khác nhau đ c g i là các ki u c b n hay chu n. Trên c s k t h p các ki u dề ể ượ ọ ể ơ ả ẩ ơ ở ế ợ ể ữ li u chu n, NSD có th t đ t ra các ki u d li u m i đ ph c v cho ch ng trình gi iệ ẩ ể ự ặ ể ữ ệ ớ ể ụ ụ ươ ả quy t bài toán c a mình. Có nghĩa lúc đó m i đ i t ng đ c qu n lý trong ch ng trình sế ủ ỗ ố ượ ượ ả ươ ẽ

Page 27: Giao Trinh C++ Toan Tap

là m t t p h p nhi u thông tin h n và đ c t o thành t nhi u lo i (ki u) d li u khác nhau.ộ ậ ợ ề ơ ượ ạ ừ ề ạ ể ữ ệ D i đây chúng ta s xét đ n m t s ki u d li u chu n đ c qui đ nh s n b i C++. ướ ẽ ế ộ ố ể ữ ệ ẩ ượ ị ẵ ở

M t bi n nh đã bi t là m t s ô nh liên ti p nào đó trong b nh dùng đ l u tr d li uộ ế ư ế ộ ố ớ ế ộ ớ ể ư ữ ữ ệ (vào, ra hay k t qu trung gian) trong quá trình ho t đ ng c a ch ng trình. Đ qu n lý ch tế ả ạ ộ ủ ươ ể ả ặ ch các bi n, NSD c n khai báo cho ch ng trình bi t tr c tên bi n và ki u c a d li uẽ ế ầ ươ ế ướ ế ể ủ ữ ệ đ c ch a trong bi n. Vi c khai báo này s làm ch ng trình qu n lý các bi n d dàng h nượ ứ ế ệ ẽ ươ ả ế ễ ơ nh trong vi c phân b b nh cũng nh qu n lý các tính toán trên bi n theo nguyên t c: chư ệ ố ộ ớ ư ả ế ắ ỉ có các d li u cùng ki u v i nhau m i đ c phép làm toán v i nhau. Do đó, khi đ c p đ nữ ệ ể ớ ớ ượ ớ ề ậ ế m t ki u chu n c a m t NNLT, thông th ng chúng ta s xét đ n các y u t sau:ộ ể ẩ ủ ộ ườ ẽ ế ế ố

tên ki u: là m t t dành riêng đ ch đ nh ki u c a d li u.ể ộ ừ ể ỉ ị ể ủ ữ ệ

s byte trong b nh đ l u tr m t đ n v d li u thu c ki u này: Thông th ng số ộ ớ ể ư ữ ộ ơ ị ữ ệ ộ ể ườ ố byte này ph thu c vào các trình biên d ch và h th ng máy khác nhau, đây ta chụ ộ ị ệ ố ở ỉ xét đ n h th ng máy PC thông d ng hi n nay. ế ệ ố ụ ệ

Mi n giá tr c a ki u: Cho bi t m t đ n v d li u thu c ki u này s có th l y giá trề ị ủ ể ế ộ ơ ị ữ ệ ộ ể ẽ ể ấ ị trong mi n nào, ví d nh nh t và l n nh t là bao nhiêu. Hi n nhiên các giá tr nàyề ụ ỏ ấ ớ ấ ể ị ph thu c vào s byte mà h th ng máy qui đ nh cho t ng ki u. NSD c n nh đ nụ ộ ố ệ ố ị ừ ể ầ ớ ế mi n giá tr này đ khai báo ki u cho các bi n c n s d ng m t cách thích h p. ề ị ể ể ế ầ ử ụ ộ ợ

D i đây là b ng tóm t t m t s ki u chu n đ n gi n và các thông s c a nó đ c s d ngướ ả ắ ộ ố ể ẩ ơ ả ố ủ ượ ử ụ trong C++.

Lo i d li uạ ữ ệ Tên ki uể S ô nhố ớ Mi n giá trề ị

Kí tự char 1 byte - 128 .. 127

unsigned char 1 byte 0 .. 255

S nguyênố int 2 byte - 32768 .. 32767

unsigned int 2 byte 0 .. 65535

short 2 byte - 32768 .. 32767

long 4 byte - 215 .. 215 – 1

S th cố ự float 4 byte ± 10 -37 . . ± 10 +38

double 8 byte ± 10 -307 . . ± 10 +308

B ng 1. Các lo i ki u đ n gi nả ạ ể ơ ả

Trong ch ng này chúng ta ch xét các lo i ki u đ n gi n trên đây. Các lo i ki u có c u trúcươ ỉ ạ ể ơ ả ạ ể ấ do ng i dùng đ nh nghĩa s đ c trình bày trong các ch ng sau.ườ ị ẽ ượ ươ

Ki u ký tể ựM t kí t là m t kí hi u trong b ng mã ASCII. Nh đã bi t m t s kí t có m t ch trên bànộ ự ộ ệ ả ư ế ộ ố ự ặ ữ phím (ví d các ch cái, ch s ) trong khi m t s kí t l i không (ví d kí t bi u di n vi cụ ữ ữ ố ộ ố ự ạ ụ ự ể ễ ệ

Page 28: Giao Trinh C++ Toan Tap

lùi l i m t ô trong văn b n, kí t ch vi c k t thúc m t dòng hay k t thúc m t văn b n). Doạ ộ ả ự ỉ ệ ế ộ ế ộ ả v y đ bi u di n m t kí t ng i ta dùng chính mã ASCII c a kí t đó trong b ng mã ASCIIậ ể ể ễ ộ ự ườ ủ ự ả và th ng g i là giá tr c a kí t . Ví d phát bi u "Cho kí t 'A'" là cũng t ng đ ng v iườ ọ ị ủ ự ụ ể ự ươ ươ ớ phát bi u "Cho kí t 65" (65 là mã ASCII c a kí t 'A'), ho c "Xoá kí t xu ng dòng" là cũngể ự ủ ự ặ ự ố t ng đ ng v i phát bi u "Xoá kí t 13" vì 13 là mã ASCII c a kí t xu ng dòng.ươ ươ ớ ể ự ủ ự ố

Nh v y m t bi n ki u kí t có th ư ậ ộ ế ể ự ể đư c nh n giá tr theo 2 cách tợ ậ ị ương đương - ch ho cữ ặ giá tr s : ví d gi s c là m t bi n kí t thì câu l nh gán c = 'A' cũng tị ố ụ ả ử ộ ế ự ệ ương đương v i câuớ l nh gán c = 65. Tuy nhiên đ s d ng giá tr s c a m t kí t c nào đó ta ph i yêu c u đ i cệ ể ử ụ ị ố ủ ộ ự ả ầ ổ sang giá tr s b ng câu l nh int(c).ị ố ằ ệ

Theo b ng trên ta th y có 2 lo i kí t là char v i mi n giá tr t -128 đ n 127 và unsigned charả ấ ạ ự ớ ề ị ừ ế (kí t không d u) v i mi n giá tr t 0 đ n 255. Tr ng h p m t bi n đ c gán giá tr v tự ấ ớ ề ị ừ ế ườ ợ ộ ế ượ ị ượ

ra ngoài mi n giá tr c a ki u thì giá tr c a bi n s ề ị ủ ể ị ủ ế ẽ đư c tính theo mã bù ợ − (256 - c). Ví dụ n u gán cho char c giá tr 179 (v t kh i mi n giá tr đã đ c qui đ nh c a char) thì giá trế ị ượ ỏ ề ị ượ ị ủ ị th c s đ c l u trong máy s là ự ự ượ ư ẽ - (256 - 179) = -77.

Ví d 1 ụ :

char c, d ; // c, d đ c phép gán giá tr t -128 đ nượ ị ừ ế 127

unsigned e ; // e đ c phép gán giá tr t 0 đ n 255ượ ị ừ ế

c = 65 ; d = 179 ; // d có giá tr ngoài mi n cho phépị ề

e = 179; f = 330 ; // f có giá tr ngoài mi n cho phépị ề

cout << c << int(c) ; // in ra ch cái 'A' và giá tr s 65ữ ị ố

cout << d << int(d) ; // in ra là kí t '|' và giá tr s -77 ự ị ố

cout << e << int(e) // in ra là kí t '|' và giá tr s 179 ự ị ố

cout << f << int(f) // in ra là kí t 'J' và giá tr s 74 ự ị ố

Chú ý: Qua ví d trên ta th y m t bi n n u đ c gán giá tr ngoài mi n cho phép s d n đ nụ ấ ộ ế ế ượ ị ề ẽ ẫ ế k t qu không theo suy nghĩ thông th ng. Do v y nên tuân th qui t c ch gán giá tr choế ả ườ ậ ủ ắ ỉ ị bi n thu c mi n giá tr mà ki u c a bi n đó qui đ nh. Ví d n u mu n s d ng bi n có giá trế ộ ề ị ể ủ ế ị ụ ế ố ử ụ ế ị t 128 .. 255 ta nên khai báo bi n dừ ế ư i d ng kí t không d u (unsigned char), còn n u giá trớ ạ ự ấ ế ị v t quá 255 ta nên chuy n sang ki u nguyên (int) ch ng h n.ượ ể ể ẳ ạ

Ki u s nguyên ể ốCác s nguyên đ c phân chia thành 4 lo i ki u khác nhau v i các mi n giá tr t ng ngố ượ ạ ể ớ ề ị ươ ứ đ c cho trong b ng 1. Đó là ki u s nguyên ng n (short) t ng đ ng v i ki u s nguyênượ ả ể ố ắ ươ ươ ớ ể ố (int) s d ng 2 byte và s nguyên dài (long int) s d ng 4 byte. Ki u s nguyên th ng đ cử ụ ố ử ụ ể ố ườ ượ chia làm 2 lo i có d u (int) và không d u (unsigned int ho c có th vi t g n h n là unsigned).ạ ấ ấ ặ ể ế ọ ơ Qui t c mã bù cũng đ c áp d ng n u giá tr c a bi n v t ra ngoài mi n giá tr cho phép, vìắ ượ ụ ế ị ủ ế ượ ề ị

Page 29: Giao Trinh C++ Toan Tap

v y c n cân nh c khi khai báo ki u cho các bi n. Ta th ng s d ng ki u int cho các sậ ầ ắ ể ế ườ ử ụ ể ố nguyên trong các bài toán v i mi n giá tr v a ph i (có giá tr tuy t đ i bé h n 32767), ch ngớ ề ị ừ ả ị ệ ố ơ ẳ h n các bi n đ m trong các vòng l p, ... ạ ế ế ặ

Ki u s th cể ố ựĐ s d ng s th c ta c n khai báo ki u float ho c double mà mi n giá tr c a chúng đ cể ử ụ ố ự ầ ể ặ ề ị ủ ượ cho trong b ng 1. Các giá tr s ki u double đ c g i là s th c v i đ chính xác g p đôi vìả ị ố ể ượ ọ ố ự ớ ộ ấ v i ki u d li u này máy tính có cách bi u di n khác so v i ki u float đ đ m b o s s lớ ể ữ ệ ể ễ ớ ể ể ả ả ố ố ẻ sau m t s th c có th tăng lên đ m b o tính chính xác cao h n so v i s ki u float. Tuyộ ố ự ể ả ả ơ ớ ố ể nhiên, trong các bài toán thông d ng th ng ngày đ chính xác c a s ki u float là đ dùng. ụ ườ ộ ủ ố ể ủ

Nh đã nh c đ n trong ph n các l nh vào/ra ch ng 1, liên quan đ n vi c in n sư ắ ế ầ ệ ở ươ ế ệ ấ ố th c ta có m t vài cách thi t đ t d ng in theo ý mu n, ví d đ r ng t i thi u đ in m t sự ộ ế ặ ạ ố ụ ộ ộ ố ể ể ộ ố hay s s l th p phân c n in ...ố ố ẻ ậ ầVí d 2 ụ : Ch ng trình sau đây s in di n tích và chu vi c a m t hình tròn có bán kính 2cm v iươ ẽ ệ ủ ộ ớ 3 s l .ố ẻ

#include <iostream.h>

#include <iomanip.h>

void main()

{

float r = 2 ; // r là tên bi n dùng đ ch a bán kínhế ể ứ

cout << "Di n tích = " << setiosflags(ios::showpoint) ;ệ

cout << setprecision(3) << r * r * 3.1416 ;

getch() ;

}

H NG - KHAI BÁO VÀ S D NG H NGẰ Ử Ụ Ằ

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

H ng nguyên ằ

ki u short, int: 3, -7, ...ể

ki u unsigned: 3, 123456, ...ể

ki u long, long int: 3L, -7L, 123456L, ... (vi t L vào cu i m i giá tr )ể ế ố ỗ ịCác cách vi t trên là th hi n c a s nguyên trong h th p phân, ngoài ra chúng còn đ c vi tế ể ệ ủ ố ệ ậ ượ ế d i các h đ m khác nh h c s 8 ho c h c s 16. M t s nguyên trong c s 8 luônướ ệ ế ư ệ ơ ố ặ ệ ơ ố ộ ố ơ ố luôn đ c vi t v i s 0 đ u, t ng t v i c s 16 ph i vi t v i 0x đ u. Ví d ta bi t 65ượ ế ớ ố ở ầ ươ ự ớ ơ ố ả ế ớ ở ầ ụ ế

Page 30: Giao Trinh C++ Toan Tap

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

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

D ng d u ph y tĩnhạ ấ ảTheo cách vi t thông th ng. Ví d : 3.0, -7.0, 3.1416, ...ế ườ ụ

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

p = … = 0.031416e2 = 0.31416e1 = 3.1416e0 = 31.416e-1 = 314.16e-2 = …

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

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

H ng kí tằ ự

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

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

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

'\xkk': không quá 2 ch s trong h 16. Ví d '\x1B' bi u di n kí t có mã 27. ữ ố ệ ụ ể ễ ựTóm l i, m t kí t có th có nhi u cách vi t, ch ng h n 'A' có giá tr là 65 (h 10) ho c 101ạ ộ ự ể ề ế ẳ ạ ị ệ ặ (h 8) ho c 41 (h 16), do đó kí t 'A' có th vi t b i m t trong các d ng sau:ệ ặ ệ ự ể ế ở ộ ạ

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

Page 31: Giao Trinh C++ Toan Tap

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

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

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

'\t' : kí t tabự

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

'\r' : xu ng dòngố

'\f' : kéo trang

'\\' : d u \ấ

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

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

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

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

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

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

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

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

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

Page 32: Giao Trinh C++ Toan Tap

t nào) ta ph i vi t "" (2 d u nháy kép li n nhau).ự ả ế ấ ềTóm l i m t giá tr có th đ c vi t d i nhi u ki u d li u khác nhau và do đó cách sạ ộ ị ể ượ ế ướ ề ể ữ ệ ử d ng chúng cũng khác nhau. Ví d liên quan đ n khái ni m 3 đ n v có th có các cách vi tụ ụ ế ệ ơ ị ể ế sau tuy nhiên chúng hoàn toàn khác nhau:

3 : s nguyên 3 đ n vố ơ ị

3L : s nguyên dài 3 đ n vố ơ ị

3.0 : s th c 3 đ n v ố ự ơ ị

'3' : ch s 3ữ ố

"3" : xâu ch a kí t duy nh t là 3 ứ ự ấ

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

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

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

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

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

ho c:ặ

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

Ví d :ụ

Page 33: Giao Trinh C++ Toan Tap

#define sosv 50 ;

#define MAX 100 ;

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

Ví d :ụ

const int sosv = 50 ;

const float nhiet_do_soi = 100.0 ;

BI N - KHAI BÁO VÀ S D NG BI NẾ Ử Ụ Ế

Khai báo bi nếBi n là các tên g i ế ọ đ lể ưu giá tr khi làm vi c trong chị ệ ương trình. Các giá tr ị đư c lợ ưu có thể là các giá tr d li u ban ị ữ ệ đ u, các giá tr trung gian t m th i trong quá trình tính toán ho c cácầ ị ạ ờ ặ giá tr k t qu cu i cùng. Khác v i h ng, giá tr c a bi n có th thay ị ế ả ố ớ ằ ị ủ ế ể đ i trong quá trình làmổ vi c b ng các l nh đ c vào t bàn phím ho c gán. Hình nh c th c a bi n là m t s ô nhệ ằ ệ ọ ừ ặ ả ụ ể ủ ế ộ ố ớ trong b nh ộ ớ đư c s d ng ợ ử ụ đ lể ưu các giá tr c a bi n.ị ủ ế

M i bi n ph i đ c khai báo trọ ế ả ượ ư c khi s d ng. M t khai báo nh v y s báo cho ch ngớ ử ụ ộ ư ậ ẽ ươ trình bi t v m t bi n m i g m có: tên c a bi n, ki u c a bi n (t c ki u c a giá tr d li uế ề ộ ế ớ ồ ủ ế ể ủ ế ứ ể ủ ị ữ ệ mà bi n s l u gi ). Thông th ng v i nhi u NNLT t t c các bi n ph i đ c khai báo ngayế ẽ ư ữ ườ ớ ề ấ ả ế ả ượ t đ u ch ng trình hay đ u c a hàm, tuy nhiên đ thu n ti n C++ cho phép khai báo bi nừ ầ ươ ầ ủ ể ậ ệ ế ngay bên trong ch ng trình ho c hàm, có nghĩa b t kỳ lúc nào NSD th y c n thi t s d ngươ ặ ấ ấ ầ ế ử ụ bi n m i, h có quy n khai báo và s d ng nó t đó tr đi. ế ớ ọ ề ử ụ ừ ở

Cú pháp khai báo bi n g m tên ki u, tên bi n và có th có hay không kh i t o giá tr ban ế ồ ể ế ể ở ạ ị đ uầ cho bi n. ế Đ kh i t o ho c thay ể ở ạ ặ đ i giá tr c a bi n ta dùng l nh gán (=). ổ ị ủ ế ệ

Khai báo không kh i t oở ạ

tên_ki u tên_bi n_1 ;ể ế

tên_ki u tên_bi n_2 ;ể ế

tên_ki u tên_bi n_3 ;ể ếNhi u bi n cùng ki u có th đ c khai báo trên cùng m t dòng:ề ế ể ể ượ ộ

tên_ki u tên_bi n_1, tên_bi n_2, tên_bi n_3 ;ể ế ế ếVí d :ụ

void main()

{

Page 34: Giao Trinh C++ Toan Tap

int i, j ; // khai báo 2 bi n i, j có ki u nguyên ế ể

float x ; // khai báo bi n th c x ế ự

char c, d[100] ; // bi n kí t c, xâu d ch a t i đa 100 kí t ế ự ứ ố ự

unsigned int u ; // bi n nguyên không d u u ế ấ

}

Khai báo có kh i t oở ạTrong câu l nh khai báo, các bi n có th đ c gán ngay giá tr ban đ u b i phép toán gán (=)ệ ế ể ượ ị ầ ở theo cú pháp:

tên_ki u tên_bi n_1 = gt_1, tên_bi n_2 = gt_2, tên_bi n_3 = gt_3 ;ể ế ế ếtrong đó các giá tr gt_1, gt_2, gt_3 có th là các h ng, bi n ho c bi u th c.ị ể ằ ế ặ ể ứ

Ví d :ụ

const int n = 10 ;

void main()

{

int i = 2, j , k = n + 5; // khai báo i và kh i t o b ng 2, k b ng 15ở ạ ằ ằ

float eps = 1.0e-6 ; // khai báo bi n th c epsilon kh i t o b ng 10ế ự ở ạ ằ -6

char c = 'Z'; // khai báo bi n kí t c và kh i t o b ng 'A'ế ự ở ạ ằ

char d[100] = "Tin h c";ọ // khai báo xâu kí t d ch a dòng ch "Tin h c" ự ứ ữ ọ

}

Ph m vi c a bi nạ ủ ếNh đã bi t ch ng trình là m t t p h p các hàm, các câu l nh cũng nh các khai báo. Ph mư ế ươ ộ ậ ợ ệ ư ạ vi tác d ng c a m t bi n là n i mà bi n có tác d ng, t c hàm nào, câu l nh nào đ c phép sụ ủ ộ ế ơ ế ụ ứ ệ ượ ử d ng bi n đó. M t bi n xu t hi n trong ch ng trình có th đ c s d ng b i hàm nàyụ ế ộ ế ấ ệ ươ ể ượ ử ụ ở nh ng không đ c b i hàm khác ho c b i c hai, đi u này ph thu c ch t ch vào v trí n iư ượ ở ặ ở ả ề ụ ộ ặ ẽ ị ơ bi n đ c khai báo. M t nguyên t c đ u tiên là bi n s có tác d ng k t v trí nó đ c khaiế ượ ộ ắ ầ ế ẽ ụ ể ừ ị ượ báo cho đ n h t kh i l nh ch a nó. Chi ti t c th h n s đ c trình bày trong ch ng 4 khiế ế ố ệ ứ ế ụ ể ơ ẽ ượ ươ nói v hàm trong C++.ề

Gán giá tr cho bi n (phép gán)ị ếTrong các ví d tr c chúng ta đã s d ng phép gán dù nó ch a đ c trình bày, đ n gi n m tụ ướ ử ụ ư ượ ơ ả ộ phép gán mang ý nghĩa t o giá tr m i cho m t bi n. Khi bi n đ c gán giá tr m i, giá tr cũạ ị ớ ộ ế ế ượ ị ớ ị s đ c t đ ng xoá đi b t k tr c đó nó ch a giá tr nào (ho c ch a có giá tr , ví d chẽ ượ ự ộ ấ ể ướ ứ ị ặ ư ị ụ ỉ m i v a khai báo xong). Cú pháp c a phép gán nh sau:ớ ừ ủ ư

Page 35: Giao Trinh C++ Toan Tap

tên_bi n = bi u th c ;ế ể ứKhi g p phép gán ch ng trình s tính toán giá tr c a bi u th c sau đó gán giá tr này choặ ươ ẽ ị ủ ể ứ ị bi n. Ví d : ế ụ

int n, i = 3; // kh i t o i b ng 3ở ạ ằ

n = 10; // gán cho n giá tr 10ị

cout << n <<", " << i << endl; // in ra: 10, 3

i = n / 2; // gán l i giá tr c a i b ng n/2 = 5ạ ị ủ ằ

cout << n <<", " << i << endl; // in ra: 10, 5Trong ví d trên n đ c gán giá tr b ng 10; trong câu l nh ti p theo bi u th c n/2 đ c tínhụ ượ ị ằ ệ ế ể ứ ượ (b ng 5) và sau đó gán k t qu cho bi n i, t c i nh n k t qu b ng 5 dù tr c đó nó đã có giáằ ế ả ế ứ ậ ế ả ằ ướ tr là 2 (trong tr ng h p này vi c kh i t o giá tr 2 cho bi n i là không có ý nghĩa). ị ườ ợ ệ ở ạ ị ế

M t khai báo có kh i t o cũng t ng đ ng v i m t khai báo và sau đó thêm l nh gán choộ ở ạ ươ ươ ớ ộ ệ bi n (ví d int i = 3 cũng t ng đ ng v i 2 câu l nh int i; i = 3) tuy nhiên v m t b n ch tế ụ ươ ươ ớ ệ ề ặ ả ấ kh i t o giá tr cho bi n v n khác v i phép toán gán nh ta s th y trong các ph n sau.ở ạ ị ế ẫ ớ ư ẽ ấ ầ

M t s đi m l u ý v phép gánộ ố ể ư ềV i ý nghĩa thông th ng c a phép toán (nghĩa là tính toán và cho l i m t giá tr ) thì phép toánớ ườ ủ ạ ộ ị gán còn m t nhi m v n a là tr l i m t giá tr . Giá tr tr l i c a phép toán gán chính là giáộ ệ ụ ữ ả ạ ộ ị ị ả ạ ủ tr c a bi u th c sau d u b ng. L i d ng đi u này C++ cho phép chúng ta gán "kép" choị ủ ể ứ ấ ằ ợ ụ ề nhi u bi n nh n cùng m t giá tr b i cú pháp:ề ế ậ ộ ị ở

bi n_1 = bi n_2 = … = bi n_n = gt ;ế ế ếv i cách gán này t t c các bi n s nh n cùng giá tr gt. Ví d : ớ ấ ả ế ẽ ậ ị ụ

int i, j, k ;

i = j = k = 1;Bi u th c gán trên có th đ c vi t l i nh (i = (j = (k = 1))), có nghĩa đ u tiên đ th c hi nể ứ ể ượ ế ạ ư ầ ể ự ệ phép toán gán giá tr cho bi n i ch ng trình ph i tính bi u th c (j = (k = 1)), t c ph i tính k =ị ế ươ ả ể ứ ứ ả 1, đây là phép toán gán, gán giá tr 1 cho k và tr l i giá tr 1, giá tr tr l i này s đ c gán choị ả ạ ị ị ả ạ ẽ ượ j và tr l i giá tr 1 đ ti p t c gán cho i.ả ạ ị ể ế ụ

Ngoài vi c gán kép nh trên, phép toán gán còn đ c phép xu t hi n trong b t kỳ bi u th cệ ư ượ ấ ệ ấ ể ứ nào, đi u này cho phép trong m t bi u th c có phép toán gán, nó không ch tính toán mà cònề ộ ể ứ ỉ gán giá tr cho các bi n, ví d n = 3 + (i = 2) s cho ta i = 2 và n = 5. Vi c s d ng nhi u ch cị ế ụ ẽ ệ ử ụ ề ứ năng c a m t câu l nh làm cho ch ng trình g n gàng h n (trong m t s tr ng h p) nh ngủ ộ ệ ươ ọ ơ ộ ố ườ ợ ư cũng tr nên khó đ c, ch ng h n câu l nh trên có th vi t tách thành 2 câu l nh i = 2; n = 3 +ở ọ ẳ ạ ệ ể ế ệ i; s d đ c h n ít nh t đ i v i các b n m i b t đ u tìm hi u v l p trình.ẽ ễ ọ ơ ấ ố ớ ạ ớ ắ ầ ể ề ậ

Page 36: Giao Trinh C++ Toan Tap

PHÉP TOÁN, BI U TH C VÀ CÂU L NHỂ Ứ Ệ

Phép toánC++ có r t nhi u phép toán lo i 1 ngôi, 2 ngôi và th m chí c 3 ngôi. Đ h th ng, chúng tôiấ ề ạ ậ ả ể ệ ố t m phân chia thành các l p và trình bày ch m t s trong chúng. Các phép toán còn l i sạ ớ ỉ ộ ố ạ ẽ đ c tìm hi u d n trong các ph n sau c a giáo trình. Các thành ph n tên g i tham gia trongượ ể ầ ầ ủ ầ ọ phép toán đ c g i là h ng th c ho c toán h ng, các kí hi u phép toán đ c g i là toán t . Víượ ọ ạ ứ ặ ạ ệ ượ ọ ử d trong phép toán a + b; a, b đ c g i là toán h ng và + là toán t . Phép toán 1 ngôi là phépụ ượ ọ ạ ử toán ch có m t toán h ng, ví d -a (đ i d u s a), &x (l y đ a ch c a bi n x) … M t s kíỉ ộ ạ ụ ổ ấ ố ấ ị ỉ ủ ế ộ ố hi u phép toán cũng đ c s d ng chung cho c 1 ngôi l n 2 ngôi (hi n nhiên v i ng nghĩaệ ượ ử ụ ả ẫ ể ớ ữ

khác nhau), ví d kí hi u - đ c s d ng cho phép toán tr 2 ngôi a ụ ệ ượ ử ụ ừ − b, ho c phép & còn đ cặ ượ s d ng cho phép toán l y h i các bit (a & b) c a 2 s nguyên a và b …ử ụ ấ ộ ủ ố

Các phép toán s h c: +, -, *, /, %ố ọ

Các phép toán + (c ng), - (tr ), * (nhân) đ c hi u theo nghĩa thông th ng trong sộ ừ ượ ể ườ ố h c.ọ

Phép toán a / b (chia) đ c th c hi n theo ki u c a các toán h ng, t c n u c hai toánượ ự ệ ể ủ ạ ứ ế ả h ng là s nguyên thì k t qu c a phép chia ch l y ph n nguyên, ng c l i n u 1ạ ố ế ả ủ ỉ ấ ầ ượ ạ ế trong 2 toán h ng là th c thì k t qu là s th c. Ví d : ạ ự ế ả ố ự ụ

13/5 = 2 // do 13 và 5 là 2 s nguyênố

13.0/5 = 13/5.0 = 13.0/5.0 = 2.6 // do có ít nh t 1 toán h ng là th cấ ạ ự

Phép toán a % b (l y ph n d ) tr l i ph n d c a phép chia a/b, trong đó a và b là 2 sấ ầ ư ả ạ ầ ư ủ ố nguyên. Ví d :ụ

13%5 = 3 // ph n d c a 13/5ầ ư ủ

5%13 = 5 // ph n d c a 5/13ầ ư ủ

Các phép toán t tự ăng, gi m: i++, ++i, i--, --iả

Phép toán ++i và i++ s cùng tăng i lên 1 đ n v t c t ng đ ng v i câu l nh i = i+1.ẽ ơ ị ứ ươ ươ ớ ệ Tuy nhiên n u 2 phép toán này n m trong câu l nh ho c bi u th c thì ++i khác v iế ằ ệ ặ ể ứ ớ i++. C th ++i s tăng i, sau đó i m i đ c tham gia vào tính toán trong bi u th c.ụ ể ẽ ớ ượ ể ứ Ng c l i i++ s tăng i sau khi bi u th c đ c tính toán xong (v i giá tr i cũ). Đi mượ ạ ẽ ể ứ ượ ớ ị ể khác bi t này đ c minh ho thông qua ví d sau, gi s i = 3, j = 15.ệ ượ ạ ụ ả ử

Phép toán Tương đương K t quế ả

i = ++j ; // tăng trư cớ j = j + 1 ; i = j ; i = 16 , j = 16

i = j++ ; // tăng sau i = j ; j = j + 1 ; i = 15 , j = 16

j = ++i + 5 ; i = i + 1 ; j = i + 5 ; i = 4, j = 9

j = i++ + 5 ; j = i + 5; i = i + 1; i = 4, j = 8

Page 37: Giao Trinh C++ Toan Tap

Ghi chú: Vi c k t h p phép toán t tăng gi m vào trong bi u th c ho c câu l nh (nh ví dệ ế ợ ự ả ể ứ ặ ệ ư ụ trong ph n sau) s làm ch ng trình g n nh ng khó hi u h n.ầ ẽ ươ ọ ư ể ơ

Các phép toán so sánh và lôgicĐây là các phép toán mà giá tr tr l i là đúng ho c sai. N u giá tr c a bi u th c là đúng thì nóị ả ạ ặ ế ị ủ ể ứ nh n giá tr 1, ng c l i là sai thì bi u th c nh n giá tr 0. Nói cách khác 1 và 0 là giá tr cậ ị ượ ạ ể ứ ậ ị ị ụ th c a 2 khái ni m "đúng", "sai". M r ng h n C++ quan ni m m t giá tr b t kỳ khác 0 làể ủ ệ ở ộ ơ ệ ộ ị ấ "đúng" và giá tr 0 là "sai".ị

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

== (b ng nhau), != (khác nhau), > (l n h n), < (nh h n), >= (l n h n ho cằ ớ ơ ỏ ơ ớ ơ ặ b ng), <= (nh h n ho c b ng).ằ ỏ ơ ặ ằ

Hai toán h ng c a các phép toán này ph i cùng ki u. Ví d :ạ ủ ả ể ụ

3 == 3 ho c 3 == (4 -1)ặ // nh n giá tr 1 vì đúngậ ị

3 == 5 // = 0 vì sai

3 != 5 // = 1

3 + (5 < 2) // = 3 vì 5<2 b ng 0 ằ

3 + (5 >= 2) // = 4 vì 5>=2 b ng 1ằChú ý: c n phân bi t phép toán gán (=) và phép toán so sánh (==). Phép gán v a gán giáầ ệ ừ

tr cho bi n v a tr l i giá tr b t kỳ (là giá tr c a toán h ng bên ph i), trong khi phép so sánhị ế ừ ả ạ ị ấ ị ủ ạ ả luôn luôn tr l i giá tr 1 ho c 0.ả ạ ị ặ

Các phép toán lôgic: && (và), || (ho c ), ! (không, ph đ nh)ặ ủ ị

Hai toán h ng c a lo i phép toán này ph i có ki u lôgic t c ch nh n m t trong hai giá trạ ủ ạ ả ể ứ ỉ ậ ộ ị "đúng" (đ c th hi n b i các s nguyên khác 0) ho c "sai" (th hi n b i 0). Khi đó giá tr trượ ể ệ ở ố ặ ể ệ ở ị ả l i c a phép toán là 1 ho c 0 và đ c cho trong b ng sau:ạ ủ ặ ượ ả

a b a && b a || b ! a

1 1 1 1 0

1 0 0 1 0

0 1 0 1 1

0 0 0 0 1Tóm l i:ạ

Phép toán "và" đúng khi và ch khi hai toán h ng cùng đúngỉ ạ

Phép toán "ho c" sai khi và ch khi hai toán h ng cùng saiặ ỉ ạ

Phép toán "không" (ho c "ph đ nh") đúng khi và ch khi toán h ng c a nó sai.ặ ủ ị ỉ ạ ủ

Page 38: Giao Trinh C++ Toan Tap

Ví d :ụ

3 && (4 > 5) // = 0 vì có h ng th c (4>5) saiạ ứ

(3 >= 1) && (7) // = 1 vì c hai h ng th c cùng đúngả ạ ứ

!1 // = 0

! (4 + 3 < 7) // = 1 vì (4+3<7) b ng 0ằ

5 || (4 >= 6) // = 1 vì có m t h ng th c (5) đúng ộ ạ ứ

(5 < !0) || (4 >= 6) // = 0 vì c hai h ng th c đ u saiả ạ ứ ềChú ý: vi c ệ đánh giá bi u th c ể ứ đư c ti n hành t trái sang ph i và s d ng khi bi t k t quợ ế ừ ả ẽ ừ ế ế ả mà không ch đánh giá h t bi u th c. Cách đánh giá này s cho nh ng k t qu ph khác nhauờ ế ể ứ ẽ ữ ế ả ụ n u trong bi u th c ta "tranh th " đ a thêm vào các phép toán t tăng gi m. Ví d cho i = 2, jế ể ứ ủ ư ự ả ụ = 3, xét 2 bi u th c sau đây:ể ứ

x = (++i < 4 && ++j > 5) cho k t qu x = 0 , i = 3 , j = 4ế ả

y = (++j > 5 && ++i < 4) cho k t qu y = 0 , i = 2 , j = 4ế ảcách vi t hai bi u th c là nh nhau (ngo i tr hoán đ i v trí 2 toán h ng c a phép toán &&).ế ể ứ ư ạ ừ ổ ị ạ ủ V i gi thi t i = 2 và j = 3 ta th y c hai bi u th c trên cùng nh n giá tr 0. Tuy nhiên các giáớ ả ế ấ ả ể ứ ậ ị tr c a i và j sau khi th c hi n xong hai bi u th c này s có k t qu khác nhau. C th v iị ủ ự ệ ể ứ ẽ ế ả ụ ể ớ bi u th c đ u vì ++i < 4 là đúng nên ch ng trình ph i ti p t c tính ti p ++j > 5 đ đánh giáể ứ ầ ươ ả ế ụ ế ể đ c bi u th c. Do v y sau khi đánh giá xong c i và j đ u đ c tăng 1 (i=3, j=4). Trong khiượ ể ứ ậ ả ề ượ đó v i bi u th c sau do ++j > 5 là sai nên ch ng trình có th k t lu n đ c toàn b bi uớ ể ứ ươ ể ế ậ ượ ộ ể th c là sai mà không c n tính ti p ++i < 4. Có nghĩa ch ng trình sau khi đánh giá xong ++j >ứ ầ ế ươ 5 s d ng và vì v y ch có bi n j đ c tăng 1, t đó ta có i = 2, j = 4 khác v i k t qu c aẽ ừ ậ ỉ ế ượ ừ ớ ế ả ủ bi u th c trên. Ví d này m t l n n a nh c ta chú ý ki m soát k vi c s d ng các phép toánể ứ ụ ộ ầ ữ ắ ể ỹ ệ ử ụ t tăng gi m trong bi u th c và trong câu l nh.ự ả ể ứ ệ

Các phép gán

Phép gán thông th ng: Đây là phép gán đã đ c trình bày trong m c tr c.ườ ượ ụ ướ

Phép gán có đi u ki n: ề ệ

bi n = (ế đi u_ki n) ? a: b ;ề ệđi u_ki n là m t bi u th c logic, a, b là các bi u th c b t kỳ cùng ki u v i ki u c a bi n.ề ệ ộ ể ứ ể ứ ấ ể ớ ể ủ ế Phép toán này gán giá tr a cho bi n n u đi u ki n ị ế ế ề ệ đúng và b n u ngế ư c l i.ợ ạ

Ví d : ụ

x = (3 + 4 < 7) ? 10: 20 // x = 20 vì 3+4<7 là sai

x = (3 + 4) ? 10: 20 // x = 10 vì 3+4 khác 0, t c đi u ki n đúngứ ề ệ

x = (a > b) ? a: b // x = s l n nh t trong 2 s a, b.ố ớ ấ ố

Cách vi t g n c a phép gán: M t phép gán d ng x = x @ a ; có th đ c vi t g n d iế ọ ủ ộ ạ ể ượ ế ọ ướ

Page 39: Giao Trinh C++ Toan Tap

d ng x @= a trong ạ đó @ là các phép toán s h c, x lý bit ... Ví d : ố ọ ử ụ

thay cho vi t x = x + 2 có th vi t x += 2; ế ể ế

ho c x = x/2 ; x = x*2 có th đ c vi t l i nh x /= 2; x *= 2;ặ ể ượ ế ạ ưCách vi t g n này có nhi u thu n l i khi vi t và đ c ch ng trình nh t là khi tên bi n quá dàiế ọ ề ậ ợ ế ọ ươ ấ ế ho c đi kèm nhi u ch s … thay vì ph i vi t hai l n tên bi n trong câu l nh thì ch ph i vi tặ ề ỉ ố ả ế ầ ế ệ ỉ ả ế m t l n, đi u này tránh vi t l p l i tên bi n d gây ra sai sót. Ví d thay vì vi t: ộ ầ ề ế ặ ạ ế ễ ụ ế

ngay_quoc_te_lao_dong = ngay_quoc_te_lao_dong + 365;có th vi t g n h n b i: ể ế ọ ơ ở

ngay_quoc_te_lao_dong += 365;ho c thay cho vi t : ặ ế

Luong[Nhanvien[3][2*i+1]] = Luong[Nhanvien[3][2*i+1]] * 290 ;có th đ c vi t l i b i:ể ượ ế ạ ở

Luong[Nhanvien[3][2*i+1]] *= 290;

Bi u th cể ứBi u th c là dãy kí hi u k t h p gi a các toán h ng, phép toán và c p d u () theo m t qui t cể ứ ệ ế ợ ữ ạ ặ ấ ộ ắ nh t đ nh. Các toán h ng là h ng, bi n, hàm. Bi u th c cung c p m t cách th c đ tính giá trấ ị ạ ằ ế ể ứ ấ ộ ứ ể ị m i d a trên các toán h ng và toán t trong bi u th c. Ví d :ớ ự ạ ử ể ứ ụ

(x + y) * 2 - 4 ; 3 - x + sqrt(y) ; (-b + sqrt(delta)) / (2*a) ;

Th t ứ ự ưu tiên c a các phép toán ủĐ tính giá tr c a m t bi u th c c n có m t tr t t tính toán c th và th ng nh t. Ví d xétể ị ủ ộ ể ứ ầ ộ ậ ự ụ ể ố ấ ụ bi u th c x = 3 + 4 * 2 + 7 ể ứ

n u tính theo đúng tr t t t trái sang ph i, ta có x = ((3+4) * 2) + 7 = 21,ế ậ ự ừ ả

n u u tiên d u + đ c th c hi n tr c d u *, x = (3 + 4) * (2 + 7) = 63,ế ư ấ ượ ự ệ ướ ấ

n u u tiên d u * đ c th c hi n tr c d u +, x = 3 + (4 * 2) + 7 = 18.ế ư ấ ượ ự ệ ướ ấNh v y cùng m t bi u th c tính x nh ng cho 3 k t qu khác nhau theo nh ng cách hi uư ậ ộ ể ứ ư ế ả ữ ể khác nhau. Vì v y c n có m t cách hi u th ng nh t d a trên th t u tiên c a các phép toán,ậ ầ ộ ể ố ấ ự ứ ự ư ủ t c nh ng phép toán nào s đ c u tiên tính tr c và nh ng phép toán nào đ c tính sau ... ứ ữ ẽ ượ ư ướ ữ ượ

C++ qui đ nh tr t t tính toán theo các m c ị ậ ự ứ đ ộ ưu tiên nh sau:ư

Các bi u th c trong c p d u ngo c ()ể ứ ặ ấ ặ

Các phép toán 1 ngôi (t tăng, gi m, l y đ a ch , l y n i dung con tr …)ự ả ấ ị ỉ ấ ộ ỏ

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

Các phép toán quan h , logic.ệ

Các phép gán.

Page 40: Giao Trinh C++ Toan Tap

N u có nhi u c p ngo c l ng nhau thì c p trong cùng (sâu nh t) đ c tính tr c. Các phépế ề ặ ặ ồ ặ ấ ượ ướ toán trong cùng m t l p có đ u tiên theo th t : l p nhân (*, /, &&), l p c ng (+, -, ||). N uộ ớ ộ ư ứ ự ớ ớ ộ ế các phép toán có cùng th t u tiên thì ch ng trình s th c hi n t trái sang ph i. Các phépứ ự ư ươ ẽ ự ệ ừ ả gán có đ u tiên cu i cùng và đ c th c hi n t ph i sang trái. Ví d . theo m c u tiên đãộ ư ố ượ ự ệ ừ ả ụ ứ ư qui đ nh, bi u th c tính x trong ví d trên s đ c tính nh x = 3 + (4 * 2) + 7 = 18.ị ể ứ ụ ẽ ượ ư

Ph n l n các tr ng h p mu n tính toán theo m t tr t t nào đó ta nên s d ng c th cácầ ớ ườ ợ ố ộ ậ ự ử ụ ụ ể d u ngo c (vì các bi u th c trong d u ngo c đ c tính tr c). Ví d :ấ ặ ể ứ ấ ặ ượ ướ ụ

Đ tính D = bể 2 - 4ac ta vi t delta = b * b - 4 * a * c ;ế

Đ tính nghi m ph ng trình b c 2: x = ể ệ ươ ậ a

b

2

∆+−

vi t : x = -b + sqrt(delta) / 2*a; là saiế vì theo m c đ u tiên x s đ c tính nh -b + ((sqrt(delta)/2) * a) (th t tính s làứ ộ ư ẽ ượ ư ứ ự ẽ phép toán 1 ngôi đ i d u -b, đ n phép chia, phép nhân và cu i cùng là phép c ng).ổ ấ ế ố ộ Đ tính chính xác c n ph i vi t (-b + sqrt(delta)) / (2*a).ể ầ ả ế

Cho a = 1, b = 2, c = 3. Bi u th c a += b += c cho giá tr c = 3, b = 5, a = 6. Th t tínhể ứ ị ứ ự s là t ph i sang trái, t c câu l nh trên t ng đ ng v i các câu l nh sau:ẽ ừ ả ứ ệ ươ ươ ớ ệ

a = 1 ; b = 2 ; c = 3 ;

b = b + c ; // b = 5

a = a + b ; // a = 6Đ rõ ràng, t t nh t nên vi t bi u th c c n tính trể ố ấ ế ể ứ ầ ư c trong các d u ngo c.ớ ấ ặ

Phép chuy n đ i ki uể ổ ểKhi tính toán m t bi u th c ph n l n các phép toán đ u yêu c u các toán h ng ph i cùngộ ể ứ ầ ớ ề ầ ạ ả ki u. Ví d đ phép gán th c hi n đ c thì giá tr c a bi u th c ph i có ể ụ ể ự ệ ượ ị ủ ể ứ ả cùng ki uể v i bi n.ớ ế Trong tr ng h p ki u c a giá tr bi u th c khác v i ki u c a phép gán thì ho c là ch ngườ ợ ể ủ ị ể ứ ớ ể ủ ặ ươ trình s t đ ng chuy n ki u giá tr bi u th c v thành ki u c a bi n đ c gán (n u đ c)ẽ ự ộ ể ể ị ể ứ ề ể ủ ế ượ ế ượ ho c s báo l i. Do v y khi c n thi t NSD ph i s d ng các câu l nh đ chuy n ki u c aặ ẽ ỗ ậ ầ ế ả ử ụ ệ ể ể ể ủ bi u th c cho phù h p v i ki u c a bi n.ể ứ ợ ớ ể ủ ế

Chuy n ki u t đ ng: v m t nguyên t c, khi c n thi t các ki u có giá tr th p s đ cể ể ự ộ ề ặ ắ ầ ế ể ị ấ ẽ ượ ch ng trình t đ ng chuy n lên ki u cao h n cho phù h p v i phép toán. C thươ ự ộ ể ể ơ ợ ớ ụ ể phép chuy n ki u có th đ c th c hi n theo s đ nh sau:ể ể ể ượ ự ệ ơ ồ ư

char « int ® long int ® float ® doubleVí d :ụ

int i = 3;

float f ;

f = i + 2;trong ví d trên i có ki u nguyên và vì v y i+2 cũng có ki u nguyên trong khi f có ki uụ ể ậ ể ể

th c. Tuy v y phép toán gán này là h p l vì ch ng trình s t đ ng chuy n ki u cu i+2ự ậ ợ ệ ươ ẽ ự ộ ể ể ả

Page 41: Giao Trinh C++ Toan Tap

(b ng 5) sang ki u th c (b ng 5.0) r i m i gán cho f.ằ ể ự ằ ồ ớ

Ép ki u: trong chuy n ki u t đ ng, ch ng trình chuy n các ki u t th p đ n cao, tuyể ể ể ự ộ ươ ể ể ừ ấ ế nhiên chi u ng c l i không th th c hi n đ c vì nó có th gây m t d li u. Doề ượ ạ ể ự ệ ượ ể ấ ữ ệ đó n u c n thi t NSD ph i ra l nh cho ch ng trình. Ví d :ế ầ ế ả ệ ươ ụ

int i;

float f = 3 ; // t đ ng chuy n 3 thành 3.0 và gán cho fự ộ ể

i = f + 2 ; // sai vì m c dù f + 2 = 5 nh ng không gán đ c cho i ặ ư ượTrong ví d trên đ câu l nh i = f+2 th c hi n đ c ta ph i ép ki u c a bi u th c f+2 vụ ể ệ ự ệ ượ ả ể ủ ể ứ ề thành ki u nguyên. Cú pháp t ng quát nh sau:ể ổ ư

(tên_ki u)bi u_th cể ể ứ // cú pháp cũ trong Cho c: ặ

tên_ki u(bi u_th c)ể ể ứ // cú pháp m i trong C++ớtrong đó tên_ki u là ki u c n đ c chuy n sang. Nh v y câu l nh trên ph i đ c vi t l i:ể ể ầ ượ ể ư ậ ệ ả ượ ế ạ

i = int(f + 2) ;khi đó f+2 (b ng 5.0) đ c chuy n thành 5 và gán cho i.ằ ượ ể

D i đây ta s xét m t s ví d v l i ích c a vi c ép ki u.ướ ẽ ộ ố ụ ề ợ ủ ệ ể

Phép ép ki u t m t s th c v s nguyên s c t b t t c ph n th p phân c a s th c,ể ừ ộ ố ự ề ố ẽ ắ ỏ ấ ả ầ ậ ủ ố ự ch đ l i ph n nguyên. Nh v y đ tính ph n nguyên c a m t s th c x ta ch c nỉ ể ạ ầ ư ậ ể ầ ủ ộ ố ự ỉ ầ ép ki u c a x v thành ki u nguyên, có nghĩa int(x) là ph n nguyên c a s th c xể ủ ề ể ầ ủ ố ự b t kỳ. Ví d đ ki m tra m t s nguyên n có ph i là s chính ph ng, ta c n tínhấ ụ ể ể ộ ố ả ố ươ ầ căn b c hai c a n. N u căn b c hai x c a n là s nguyên thì n là s chính ph ng,ậ ủ ế ậ ủ ố ố ươ t c n u int(x) = x thì x nguyên và n là chính ph ng, ví d : ứ ế ươ ụ

int n = 10 ;

float x = sqrt(n) ; // hàm sqrt(n) tr l i căn b c hai c a s nả ạ ậ ủ ố

if (int(x) == x) cout << "n chính ph ng" ; ươ

else cout << "n không chính ph ng" ; ươ

Đ bi t mã ASCII c a m t kí t ta ch c n chuy n kí t đó sang ki u nguyên.ể ế ủ ộ ự ỉ ầ ể ự ể

char c ;

cin >> c ;

cout << "Mã c a kí t v a nh p là " << int(c) ; ủ ự ừ ậGhi chú: Xét ví d sau:ụ

int i = 3 , j = 5 ;

float x ;

x = i / j * 10; // x = 6 ?

cout << x ;

Page 42: Giao Trinh C++ Toan Tap

trong ví d này m c dù x đ c khai báo là th c nh ng k t qu in ra s là 0 thay vì 6 nhụ ặ ượ ự ư ế ả ẽ ư mong mu n. Lý do là vì phép chia gi a 2 s nguyên i và j s cho l i s nguyên, t c i/j = 3/5 =ố ữ ố ẽ ạ ố ứ 0. T đó x = 0*10 = 0. Đ phép chia ra k t qu th c ta c n ph i ép ki u ho c i ho c j ho c cừ ể ế ả ự ầ ả ể ặ ặ ặ ả 2 thành s th c, khi đó phép chia s cho k t qu th c và x đ c tính đúng giá tr . C th câuố ự ẽ ế ả ự ượ ị ụ ể l nh x = i/j*10 đ c đ i thành: ệ ượ ổ

x = float(i) / j * 10 ; // đúng

x = i / float(j) * 10 ; // đúng

x = float(i) / float(j) * 10 ; // đúng

x = float(i/j) * 10 ; // saiPhép ép ki u: x = float(i/j) * 10 ; v n cho k t qu sai vì trong d u ngo c phép chia i/jể ẫ ế ả ấ ặ

v n là phép chia nguyên, k t qu x v n là 0. ẫ ế ả ẫ

Câu l nh và kh i l nhệ ố ệM t ộ câu l nhệ trong C++ đ c thi t l p t các t khoá và các bi u th c … và luôn luôn đ cượ ế ậ ừ ừ ể ứ ượ k t thúc b ng d u ch m ph y. Các ví d vào/ra ho c các phép gán t o thành nh ng câu l nhế ằ ấ ấ ẩ ụ ặ ạ ữ ệ đ n gi n nh :ơ ả ư

cin >> x >> y ;

x = 3 + x ; y = (x = sqrt(x)) + 1 ;

cout << x ;

cout << y ;Các câu l nh đ c phép vi t trên cùng m t ho c nhi u dòng. M t s câu l nh đ c g i làệ ượ ế ộ ặ ề ộ ố ệ ượ ọ l nh có c u trúc, t c bên trong nó l i ch a dãy l nh khác. Dãy l nh này ph i đ c bao gi aệ ấ ứ ạ ứ ệ ệ ả ượ ữ c p d u ngo c {} và đ c g i là ặ ấ ặ ượ ọ kh i l nhố ệ . Ví d t t c các l nh trong m t hàm (nh hàmụ ấ ả ệ ộ ư main()) luôn luôn là m t kh i l nh. M t đ c đi m c a kh i l nh là các bi n đ c khai báoộ ố ệ ộ ặ ể ủ ố ệ ế ượ trong kh i l nh nào thì ch có tác d ng trong kh i l nh đó. Chi ti t h n v các đ c đi m c aố ệ ỉ ụ ố ệ ế ơ ề ặ ể ủ l nh và kh i l nh s đ c trình bày trong các ch ng ti p theo c a giáo trình.ệ ố ệ ẽ ượ ươ ế ủ

TH VI N CÁC HÀM TOÁN H CƯ Ệ Ọ

Trong ph n này chúng tôi tóm t t m t s các hàm toán h c hay dùng. Các hàm này đ u đ cầ ắ ộ ố ọ ề ượ khai báo trong file nguyên m u math.h.ẫ

Các hàm s h cố ọ

abs(x), labs(x), fabs(x) : tr l i giá tr tuy t đ i c a m t s nguyên, s nguyên dài và sả ạ ị ệ ố ủ ộ ố ố ố th c.ự

pow(x, y) : hàm mũ, tr l i giá tr x lũy th a y (xả ạ ị ừ y).

exp(x) : hàm mũ, tr l i giá tr e mũ x (eả ạ ị x).

log(x), log10(x) : tr l i lôgarit c s e và lôgarit th p phân c a x (lnx, logx) .ả ạ ơ ố ậ ủ

sqrt(x) : tr l i căn b c 2 c a x.ả ạ ậ ủ

Page 43: Giao Trinh C++ Toan Tap

atof(s_number) : tr l i s th c ng v i s vi t d i d ng xâu kí t s_number.ả ạ ố ự ứ ớ ố ế ướ ạ ự

Các hàm l ng giácượ

sin(x), cos(x), tan(x) : tr l i các giá tr sinx, cosx, tgx.ả ạ ị

BÀI T PẬ

Vi t câu l nh khai báo bi n ế ệ ế đ lể ưu các giá tr sau:ị

Tu i c a m t ngổ ủ ộ ư iờ - S lố ư ng cây trong thành phợ ố

Đ dài c nh m t tam giácộ ạ ộ - Kho ng cách gi a các hành tinhả ữ

M t ch sộ ữ ố - Nghi m x c a phệ ủ ương trình b c 1ậ

M t ch cáiộ ữ - Bi t th c D c a phệ ứ ủ ương trình b c 2ậ

Vi t câu l nh nh p vào 4 giá tr l n lế ệ ậ ị ầ ư t là s th c, nguyên, nguyên dài và kí t . In ra mànợ ố ự ự hình các giá tr này đ ki m tra.ị ể ể

Vi t câu l nh in ra màn hình các dòng sau (không k các s th t và d u: ế ệ ể ố ứ ự ấ ở đ u m i dòng)ầ ỗ1: B Giáo d c và ộ ụ Đào t oạ C ng hoà xã h i ch nghĩa Vi t Namộ ộ ủ ệ

2:

3: S Giáo d c Hà N iở ụ ộ Đ c l p - T do - H nh phúcộ ậ ự ạ

Chú ý: kho ng tr ng gi a ch ả ố ữ ữ Đào t o và C ng hoà (dòng 1) là 2 tab. Dòng 2: ạ ộ đ tr ng.ể ố

Vi t chế ương trình nh p vào m t kí t . In ra kí t ậ ộ ự ự đó và mã ascii c a nó.ủ

Vi t chế ương trình nh p vào hai s th c. In ra hai s th c ậ ố ự ố ự đó v i 2 s l và cách nhau 5 c t.ớ ố ẻ ộ

Nh p, ch y và gi i thích k t qu ậ ạ ả ế ả đ t ạ đư c c a ợ ủ đo n chạ ương trình sau:

#include <iostream.h>

void main()

{

char c1 = 200; unsigned char c2 = 200 ;

cout << "c1 = " << c1 << ", c2 = " << c2 << "\n" ;

cout << "c1+100 = " << c1+100 << ", c2+100 = " << c2+100 ;

}

Nh p a, b, c. In ra màn hình dòng ch phậ ữ ương trình có d ng ax^2 + bx + c = 0, trong ạ đó các giá

Page 44: Giao Trinh C++ Toan Tap

tr a, b, c ch in 2 s l (ví d v i a = 5.141, b = -2, c = 0.8 in ra 5.14 x^2 -2.00 x + 0.80).ị ỉ ố ẻ ụ ớ

Vi t chế ương trình tính và in ra giá tr các bi u th c sau v i 2 s l :ị ể ứ ớ ố ẻ

333 ++b. 2

12

12

1

++

Nh p a, b, c là các s th c. In ra giá tr c a các bi u th c sau v i 3 s l :ậ ố ự ị ủ ể ứ ớ ố ẻ

a2 - 2b + ab/c c. 3a - b3 - 2 c

a

acb

2

42 −

d. 142 +− bc/ab/a

In ra t ng, tích, hi u và thổ ệ ương c a 2 s ủ ố đư c nh p vào t bàn phím.ợ ậ ừ

In ra trung bình c ng, trung bình nhân c a 3 s ộ ủ ố đư c nh p vào t bàn phím.ợ ậ ừ

Vi t chế ương trình nh p c nh, bán kính và in ra di n tích, chu vi c a các hình: vuông, chậ ạ ệ ủ ữ nh t, tròn. ậ

Nh p a, b, c là ậ đ dài 3 c nh c a tam giác (chú ý ộ ạ ủ đ m b o t ng 2 c nh ph i l n hả ả ổ ạ ả ớ ơn c nh cònạ l i). Tính chu vi, di n tích, ạ ệ đ dài 3 ộ đư ng cao, 3 ờ đư ng trung tuy n, 3 ờ ế đư ng phân giác,ờ bán kính đư ng tròn n i ti p, ngo i ti p l n lờ ộ ế ạ ế ầ ư t theo các công th c sau:ợ ứ

C = 2p = a + b + c ; S = )cp)(bp)(ap(p −−−

;

a

Sha

2= ; ma =

222 222

1acb −+

; ga = )ap(bcp

cb−

+2

;

p

Sr =

; S

abcR

4=

;

Tính di n tích và th tích c a hình c u bán kính R theo công th c:ệ ể ủ ầ ứS = 4pR2 ; V = RS/3

Nh p vào 4 ch s . In ra t ng c a 4 ch s này và ch s hàng ch c, hàng ậ ữ ố ổ ủ ữ ố ữ ố ụ đơn v c a t ng (víị ủ ổ d 4 ch s 3, 1, 8, 5 có t ng là 17 và ch s hàng ch c là 1 và hàng ụ ữ ố ổ ữ ố ụ đơn v là 7, c n in raị ầ 17, 1, 7).

Nh p vào m t s nguyên (có 4 ch s ). In ra t ng c a 4 ch s này và ch s ậ ộ ố ữ ố ổ ủ ữ ố ữ ố đ u, ch sầ ữ ố cu i (ví d s 3185 có t ng các ch s là 17, ố ụ ố ổ ữ ố đ u và cu i là 3 và 5, k t qu in ra là: 17, 3,ầ ố ế ả 5).

Hãy nh p 2 s a và b. Vi t ch ng trình đ i giá tr c a a và b theo 2 cách: ậ ố ế ươ ổ ị ủ

dùng bi n ph t: t = a; a = b; b = t;ế ụ

Page 45: Giao Trinh C++ Toan Tap

không dùng bi n ph : a = a + b; b = a - b; a = a - b; ế ụIn k t qu ra màn hình ế ả đ ki m tra.ể ể

Vi t chế ương trình đoán s c a ngố ủ ư i chờ ơi đang nghĩ, b ng cách yêu c u ngằ ầ ư i chờ ơi nghĩ m tộ s , sau ố đó th c hi n m t lo t các tính toán trên s ự ệ ộ ạ ố đã nghĩ r i cho bi t k t qu . Máy sồ ế ế ả ẽ in ra s mà ngố ư i chờ ơi đã nghĩ. (ví d yêu c u ngụ ầ ư i chờ ơi l y s ấ ố đã nghĩ nhân đôi, tr 4,ừ bình phương, chia 2 và tr 7 r i cho bi t k t qu , máy s in ra s ng i ch i đã nghĩ).ừ ồ ế ế ả ẽ ố ườ ơ

M t sinh viên g m có các thông tin: h tên, tu i, ộ ồ ọ ổ đi m toán (h s 2), ể ệ ố đi m tin (h s 1). Hãyể ệ ố nh p các thông tin trên cho 2 sinh viên. In ra b ng ậ ả đi m g m các chi ti t nêu trên và ể ồ ế đi mể trung bình c a m i sinh viên.ủ ỗ

M t nhân viên g m có các thông tin: h tên, h s lộ ồ ọ ệ ố ương, ph n trầ ăm ph c p (theo lụ ấ ưong) và ph n trầ ăm ph i ả đóng BHXH. Hãy nh p các thông tin trên cho 2 nhân viên. In ra b ngậ ả lương g m các chi ti t nêu trên và t ng s ti n cu i cùng m i nhân viên ồ ế ổ ố ề ố ỗ đư c nh n.ợ ậ

CH NG 3ƯƠ

C U TRÚC Ấ ĐI U KHI N VÀ D LI U KI U M NGỀ Ể Ữ Ệ Ể Ả

C u trúc r nhánhấ ẽC u trúc l p ấ ặM ng d li uả ữ ệM ng hai chi uả ề

C U TRÚC R NHÁNHẤ Ẽ

Nói chung vi c th c hi n ch ng trình là ho t đ ng tu n t , t c th c hi n t ng l nh m t tệ ự ệ ươ ạ ộ ầ ự ứ ự ệ ừ ệ ộ ừ câu l nh b t đ u c a ch ng trình cho đ n câu l nh cu i cùng. Tuy nhiên, đ vi c l p trìnhệ ắ ầ ủ ươ ế ệ ố ể ệ ậ hi u qu h n h u h t các NNLT b c cao đ u có các câu l nh r nhánh và các câu l nh l pệ ả ơ ầ ế ậ ề ệ ẽ ệ ặ cho phép th c hi n các câu l nh c a ch ng trình không theo trình t tu n t nh trong vănự ệ ệ ủ ươ ự ầ ự ư b n. ả

Ph n này chúng tôi s trình bày các câu l nh cho phép r nhánh nh v y. Đ th ng nh t m iầ ẽ ệ ẽ ư ậ ể ố ấ ỗ câu l nh đ c trình bày v cú pháp (t c cách vi t câu l nh), cách s d ng, đ c đi m, ví dệ ượ ề ứ ế ệ ử ụ ặ ể ụ minh ho và m t vài đi u c n chú ý khi s d ng l nh.ạ ộ ề ầ ử ụ ệ

Câu l nh ệ đi u ki n ifề ệ

Ý nghĩaM t câu l nh ộ ệ if cho phép ch ng trình có th th c hi n kh i l nh này hay kh i l nh khác phươ ể ự ệ ố ệ ố ệ ụ thu c vào m t đi u ki n đ c vi t trong câu l nh là đúng hay sai. Nói cách khác câu l nh ộ ộ ề ệ ượ ế ệ ệ if cho phép ch ng trình r nhánh (ch th c hi n 1 trong 2 nhánh).ươ ẽ ỉ ự ệ

Page 46: Giao Trinh C++ Toan Tap

Cú pháp - if (đi u ki n) { kh i l nh 1; } else { kh i l nh 2; }ề ệ ố ệ ố ệ

- if (đi u ki n) { kh i l nh 1; } ề ệ ố ệ

Trong cú pháp trên câu l nh if có hai d ng: có else và không có else. đi u ki n là m t bi uệ ạ ề ệ ộ ể th c lôgic t c nó có giá tr đúng (khác 0) ho c sai (b ng 0).ứ ứ ị ặ ằ

Khi ch ng trình th c hi n câu l nh if nó s tính bi u th c đi u ki n. N u đi u ki n đúngươ ự ệ ệ ẽ ể ứ ề ệ ế ề ệ ch ng trình s ti p t c th c hi n các l nh trong kh i l nh 1, ng c l i n u đi u ki n saiươ ẽ ế ụ ự ệ ệ ố ệ ượ ạ ế ề ệ ch ng trình s th c hi n kh i l nh 2 (n u có else) ho c không làm gì (n u không có else).ươ ẽ ự ệ ố ệ ế ặ ế

Đ c đi mặ ể

Đ c đi m chung c a các câu l nh có c u trúc là b n thân nó ch a các câu l nh khác.ặ ể ủ ệ ấ ả ứ ệ Đi u này cho phép các câu l nh if có th l ng nhau.ề ệ ể ồ

N u nhi u câu l nh if (có else và không else) l ng nhau vi c hi u if và else nào đi v iế ề ệ ồ ệ ể ớ nhau c n ph i chú ý. Qui t c là else s đi v i if g n nó nh t mà ch a đ c ghép c pầ ả ắ ẽ ớ ầ ấ ư ượ ặ v i else khác. Ví d câu l nh ớ ụ ệ

if (n>0) if (a>b) c = a;

else c = b;là tương đương v i ớ

if (n>0) { if (a>b) c = a; else c = b;}

Ví d minh hoụ ạ

: B ng phép toán gán có đi u ki n có th tìm s l n nh t max trong 2 s a, b nh sau: max =ằ ề ệ ể ố ớ ấ ố ư (a > b) ? a: b ;ho c max đ c tìm b i dùng câu l nh if:ặ ượ ở ệ

if (a > b) max = a; else max = b;

: Tính năm nhu n. Năm th n là nhu n n u nó chia h t cho 4, nh ng không chia h t cho 100ậ ứ ậ ế ế ư ế ho c chia h t 400. Chú ý: m t s nguyên a là chia h t cho b n u ph n d c a phép chia b ngặ ế ộ ố ế ế ầ ư ủ ằ 0, t c a%b == 0. ứ

#include <iostream.h>

void main()

{

int nam;

cout << “Nam = “ ; cin >> nam ;

if (nam%4 == 0 && year%100 !=0 || nam%400 == 0)

cout << nam << "la nam nhuan” ;

else

Page 47: Giao Trinh C++ Toan Tap

cout << nam << "la nam khong nhuan” ;

}

: Gi i ph ng trình b c 2. Cho ph ng trình axả ươ ậ ươ 2 + bx + c = 0 (a ¹ 0), tìm x.

#include <iostream.h> // t p ch a các ph ng th c vào/raệ ứ ươ ứ

#include <math.h> // t p ch a các hàm toán h cệ ứ ọ

void main()

{

float a, b, c; // khai báo các h sệ ố

float delta;

float x1, x2; // 2 nghiem

cout << “Nhap a, b, c:\n” ; cin >> a >> b >> c ; // qui c nh p a ¹ 0ướ ậ

delta = b*b - 4*a*c ;

if (delta < 0) cout << “ph. trình vô nghi m\n” ;ệ

else if (delta==0) cout<<“ph. trình có nghi m kép:" << -b/(2*a) << '\n';ệ

else

{

x1 = (-b+sqrt(delta))/(2*a);

x2 = (-b-sqrt(delta))/(2*a);

cout << “nghiem 1 = " << x1 << " và nghiem 2 = " << x2 ;

}

}Chú ý: do C++ quan ni m "đúng" là m t giá tr khác 0 b t kỳ và "sai" là giá tr 0 nên thay vìệ ộ ị ấ ị vi t if (x != 0) ho c if (x == 0) ta có th vi t g n thành if (x) ho c if (!x) vì n u (x != 0) đúngế ặ ể ế ọ ặ ế thì ta có x ¹ 0 và vì x ¹ 0 nên (x) cũng đúng. Ng c l i n u (x) đúng thì x ¹ 0, t đó (x != 0) cũngượ ạ ế ừ đúng. T ng t ta d dàng th y đ c (x == 0) là t ng đ ng v i (!x).ươ ự ễ ấ ượ ươ ươ ớ

Câu l nh l a ch n switchệ ự ọ

Ý nghĩaCâu l nh if cho ta kh năng đ c l a ch n m t trong hai nhánh đ th c hi n, do đó n u sệ ả ượ ự ọ ộ ể ự ệ ế ử d ng nhi u l nh if l ng nhau s cung c p kh năng đ c r theo nhi u nhánh. Tuy nhiênụ ề ệ ồ ẽ ấ ả ượ ẽ ề trong tr ng h p nh v y ch ng trình s r t khó đ c, do v y C++ còn cung c p m t câuườ ợ ư ậ ươ ẽ ấ ọ ậ ấ ộ l nh c u trúc khác cho phép ch ng trình có th ch n m t trong nhi u nhánh đ th c hi n, đóệ ấ ươ ể ọ ộ ề ể ự ệ là câu l nh switch. ệ

Cú pháp

Page 48: Giao Trinh C++ Toan Tap

switch (bi u th c ể ứ đi u khi n)ề ể

{

case bi u_th c_1: dãy l nh 1 ;ể ứ ệ

case bi u_th c_2: dãy l nh 2 ;ể ứ ệ

case ……………...: ............... ;

case bi u_th c_n: dãy l nh n ;ể ứ ệ

default: dãy l nh n+1;ệ

}

bi u th c đi u khi n: ph i có ki u nguyên ho c kí t ,ể ứ ề ể ả ể ặ ự

các bi u_th c_i: đ c t o t các h ng nguyên ho c kí t ,ể ứ ượ ạ ừ ằ ặ ự

các dãy l nh có th r ng. Không c n bao dãy l nh b i c p d u {},ệ ể ỗ ầ ệ ở ặ ấ

nhánh default có th có ho c không và v trí c a nó có th n m b t kỳ trong câu l nhể ặ ị ủ ể ằ ấ ệ (gi a các nhánh case), không nh t thi t ph i n m cu i cùng.ữ ấ ế ả ằ ố

Cách th c hi nự ệĐ th c hi n câu l nh ể ự ệ ệ switch đ u tiên ch ng trình tính giá tr c a bi u th c đi u khi nầ ươ ị ủ ể ứ ề ể (btđk), sau đó so sánh k t qu c a btế ả ủ đk v i giá tr c a các bi u_th c_i bên d i l n l t tớ ị ủ ể ứ ướ ầ ượ ừ bi u th c đ u tiên (th nh t) cho đ n bi u th c cu i cùng (th n), n u giá tr c a btđk b ngể ứ ầ ứ ấ ế ể ứ ố ứ ế ị ủ ằ giá tr c a bi u th c th i đ u tiên nào đó thì ch ng trình s th c hi n dãy l nh th i và ti pị ủ ể ứ ứ ầ ươ ẽ ự ệ ệ ứ ế t c th c hi n t t c dãy l nh còn l i (t dãy l nh th i+1) cho đ n h t (g p d u ngo cụ ự ệ ấ ả ệ ạ ừ ệ ứ ế ế ặ ấ ặ đóng } c a l nh switch). N u quá trình so sánh không g p bi u th c (nhánh case) nào b ngủ ệ ế ặ ể ứ ằ v i giá tr c a btđk thì ch ng trình th c hi n dãy l nh trong default và ti p t c cho đ n h tớ ị ủ ươ ự ệ ệ ế ụ ế ế (sau default có th còn nh ng nhánh case khác). Tr ng h p câu l nh switch không có nhánhể ữ ườ ợ ệ default và btđk không kh p v i b t c nhánh case nào thì ch ng trình không làm gì, coi nhớ ớ ấ ứ ươ ư đã th c hi n xong l nh switch. ự ệ ệ

N u mu n l nh switch ch th c hi n nhánh th i (khi btđk = bi u_th c_i) mà không ph i th cế ố ệ ỉ ự ệ ứ ể ứ ả ự hi n thêm các l nh còn l i thì cu i dãy l nh th i thông th ng ta đ t thêm l nh ệ ệ ạ ố ệ ứ ườ ặ ệ break; đây là l nh cho phép thoát ra kh i m t l nh c u trúc b t kỳ.ệ ỏ ộ ệ ấ ấ

Ví d minh hoụ ạ

: In s ngày c a m t tháng b t kỳ nào đó đ c nh p t bàn phím.ố ủ ộ ấ ượ ậ ừ

int th;

cout << “Cho bi t tháng c n tính: “ ; cin >> th ;ế ầ

switch (th)

Page 49: Giao Trinh C++ Toan Tap

{

case 1: case 3: case 5: case 7: case 8: case 10:

case 12: cout << "tháng này có 31 ngày" ; break ;

case 2: cout << "tháng này có 28 ngày" ; break;

case 4: case 6: case 9:

case 11: cout << "tháng này có 30 ngày" ; break;

default: cout << "B n đã nh p sai tháng, không có tháng này" ;ạ ậ

}

Trong ch ng trình trên gi s NSD nh p tháng là 5 thì ch ng trình b t đ u th c hi n dãyươ ả ử ậ ươ ắ ầ ự ệ l nh sau case 5 (không có l nh nào) sau đó ti p t c th c hi n các l nh còn l i, c th là b tệ ệ ế ụ ự ệ ệ ạ ụ ể ắ đ u t dãy l nh trong case 7, đ n case 12 ch ng trình g p l nh in k t qu "tháng này có 31ầ ừ ệ ế ươ ặ ệ ế ả ngày", sau đó g p l nh break nên ch ng trình thoát ra kh i câu l nh switch (đã th c hi nặ ệ ươ ỏ ệ ự ệ xong). Vi c gi i thích cũng t ng t cho các tr ng h p khác c a tháng. N u NSD nh p saiệ ả ươ ự ườ ợ ủ ế ậ tháng (ví d tháng n m ngoài ph m vi 1..12), ch ng trình th y th không kh p v i b t kỳụ ằ ạ ươ ấ ớ ớ ấ nhánh case nào nên s th c hi n câu l nh trong default, in ra màn hình dòng ch "B n đã nh pẽ ự ệ ệ ữ ạ ậ sai tháng, không có tháng này" và k t thúc l nh.ế ệ

: Nh p 2 s a và b vào t bàn phím. Nh p kí t th hi n m t trong b n phép toán: c ng, tr ,ậ ố ừ ậ ự ể ệ ộ ố ộ ừ nhân, chia. In ra k t qu th c hi n phép toán đó trên 2 s a, b.ế ả ự ệ ố

void main()

{

float a, b, c ; // các toán h ng a, b và k t qu cạ ế ả

char dau ; // phép toán đ c cho d i d ng kí tượ ướ ạ ự

cout << "Hãy nh p 2 s a, b: " ; cin >> a >> b ;ậ ố

cout << "và d u phép toán: " ; cin >> dau ;ấ

switch (dau)

{

case '+': c = a + b ; break ;

case '-': c = a - b ; break ;

case 'x': case '.': case '*': c = a * b ; break ;

case ':': case '/': c = a / b ; break ;

}

cout << setiosflags(ios::showpoint) << setprecision(4) ; // in 4 s lố ẻ

cout << "K t qu là: " << c ;ế ả

}

Page 50: Giao Trinh C++ Toan Tap

Trong ch ng trình trên ta ch p nh n các kí t x, ., * th hi n cho phép toán nhân và :, / thươ ấ ậ ự ể ệ ể hi n phép toán chia.ệ

Câu l nh nh y gotoệ ả

Ý nghĩaM t d ng khác c a r nhánh là câu l nh nh y ộ ạ ủ ẽ ệ ả goto cho phép ch ng trình chuy n đ n th cươ ể ế ự hi n m t đo n l nh khác b t đ u t m t đi m đ c đánh d u b i m t nhãn trong ch ngệ ộ ạ ệ ắ ầ ừ ộ ể ượ ấ ở ộ ươ trình. Nhãn là m t tên g i do NSD t đ t theo các qui t t đ t tên g i. L nh goto th ng đ cộ ọ ự ặ ắ ặ ọ ệ ườ ượ s d ng đ t o vòng l p. Tuy nhiên vi c xu t hi n nhi u l nh goto d n đ n vi c khó theoử ụ ể ạ ặ ệ ấ ệ ề ệ ẫ ế ệ dõi trình t th c hi n ch ng trình, vì v y l nh này th ng đ c s d ng r t h n ch . ự ự ệ ươ ậ ệ ườ ượ ử ụ ấ ạ ế

Cú phápGoto <nhãn> ;

V trí ch ng trình chuy n đ n th c hi n là đo n l nh đ ng sau nhãn và d u hai ch m (:).ị ươ ể ế ự ệ ạ ệ ứ ấ ấ

Ví d minh hoụ ạ

: Nhân 2 s nguyên theo phố ương pháp n Ấ đ . ộPh ng pháp n đ cho phép nhân 2 s nguyên b ng cách ch dùng các phép toán nhân đôi,ươ Ấ ộ ố ằ ỉ chia đôi và c ng. Các phép nhân đôi và chia đôi th c ch t là phép toán d ch bit v bên tráiộ ự ấ ị ề (nhân) ho c bên ph i (chia) 1 bit. Đây là các phép toán c s trong b x lý, do v y dùngặ ả ơ ở ộ ử ậ ph ng pháp này s làm cho vi c nhân các s nguyên đ c th c hi n r t nhanh. Có th tómươ ẽ ệ ố ượ ự ệ ấ ể t t ph ng pháp nh sau: Gi s c n nhân m v i n. Ki m tra m n u l thì c ng thêm n vào kqắ ươ ư ả ử ầ ớ ể ế ẻ ộ (đ u tiên kq đ c kh i t o b ng 0), sau đó l y m chia 2 và n nhân 2. Quay l i ki m tra m vàầ ượ ở ạ ằ ấ ạ ể th c hi n nh trên. Quá trình d ng khi không th chia đôi m đ c n a (m = 0), khi đó kq làự ệ ư ừ ể ượ ữ k t qu c n tìm (t c kq = m*n). Đ d hi u ph ng pháp này chúng ta ti n hành tính trên víế ả ầ ứ ể ễ ể ươ ế d v i các s m, n c th . Gi s m = 21 và n = 11. Các b c ti n hành đ c cho trong b ngụ ớ ố ụ ể ả ử ướ ế ượ ả d i đây:ướ

B cướ m (chia 2) n (nhân 2) kq (kh i t o kq = 0) ở ạ

1 21 11 m l , c ng thêm 11 vào kq = 0 + 11 = 11ẻ ộ

2 10 22 m ch n, b quaẵ ỏ

3 5 44 m l , c ng thêm 44 vào kq = 11 + 44 = 55ẻ ộ

4 2 88 m ch n, b quaẵ ỏ

5 1 176 m l , c ng thêm 176 vào kq = 55 + 176 = 231ẻ ộ

6 0 m = 0, d ng cho k t qu kq = 231ừ ế ả

Sau đây là ch ng trình đ c vi t v i câu l nh goto.ươ ượ ế ớ ệ

Page 51: Giao Trinh C++ Toan Tap

void main()

{

long m, n, kq = 0; // Các s c n nhân và k t qu kqố ầ ế ả

cout << “Nh p m và n: “ ; cin >> m >> n ;ậ

lap: // đây là nhãn đ ch ng trình quay l iể ươ ạ

if (m%2) kq += n; // n u m l thì c ng thêm n vào kqế ẻ ộ

m = m >> 1; // d ch m sang ph i 1 bit t c m = m / 2ị ả ứ

n = n << 1; // d ch m sang trái 1 bit t c m = m * 2ị ứ

if (m) goto lap; // quay l i n u m ¹ 0ạ ế

cout << “m nhân n =” << kq ;

}

C U TRÚC L PẤ Ặ

M t trong nh ng c u trúc quan tr ng c a l p trình c u trúc là các câu l nh cho phép l pộ ữ ấ ọ ủ ậ ấ ệ ặ nhi u l n m t đo n l nh nào đó c a ch ng trình. Ch ng h n trong ví d v bài toán nhânề ầ ộ ạ ệ ủ ươ ẳ ạ ụ ề theo ph ng pháp n đ , đ l p l i m t đo n l nh chúng ta đã s d ng câu l nh goto. Tuyươ Ấ ộ ể ặ ạ ộ ạ ệ ử ụ ệ nhiên nh đã l u ý vi c dùng nhi u câu l nh này làm ch ng trình r t khó đ c. Do v y c nư ư ệ ề ệ ươ ấ ọ ậ ầ có nh ng câu l nh khác tr c quan h n và th c hi n các phép l p m t cách tr c ti p. C++ cungữ ệ ự ơ ự ệ ặ ộ ự ế c p cho chúng ta 3 l nh l p nh v y. V th c ch t 3 l nh này là t ng đ ng (cũng nh cóấ ệ ặ ư ậ ề ự ấ ệ ươ ươ ư th dùng goto thay cho c 3 l nh l p này), tuy nhiên đ ch ng trình vi t đ c sáng s a, rõể ả ệ ặ ể ươ ế ượ ủ ràng, C++ đã cung c p nhi u ph ng án cho NSD l a ch n câu l nh khi vi t ch ng trìnhấ ề ươ ự ọ ệ ế ươ phù h p v i tính ch t l p. M i bài toán l p có m t đ c tr ng riêng, ví d l p cho đ n khi đãợ ớ ấ ặ ỗ ặ ộ ặ ư ụ ặ ế đ s l n đ nh tr c thì d ng ho c l p cho đ n khi m t đi u ki n nào đó không còn thoủ ố ầ ị ướ ừ ặ ặ ế ộ ề ệ ả mãn n a thì d ng … vi c s d ng câu l nh l p phù h p s làm cho ch ng trình d đ c vàữ ừ ệ ử ụ ệ ặ ợ ẽ ươ ễ ọ d b o trì h n. Đây là ý nghĩa chung c a các câu l nh l p, do v y trong các trình bày v câuễ ả ơ ủ ệ ặ ậ ề l nh ti p theo sau đây chúng ta s không c n ph i trình bày l i ý nghĩa c a chúng. ệ ế ẽ ầ ả ạ ủ

L nh l p forệ ặ

Cú phápfor (dãy bi u th c 1 ; ể ứ đi u ki n l p ; dãy bi u th c 2) { kh i l nh l p; }ề ệ ặ ể ứ ố ệ ặ

Các bi u th c trong các dãy bi u th c 1, 2 cách nhau b i d u ph y (,). Có th có nhi uể ứ ể ứ ở ấ ả ể ề bi u th c trong các dãy này ho c dãy bi u th c cũng có th tr ng. ể ứ ặ ể ứ ể ố

Đi u ki n l p: là bi u th c lôgic (có giá tr đúng, sai).ề ệ ặ ể ứ ị

Các dãy bi u th c và/ho c đi u ki n có th tr ng tuy nhiên v n gi l i các d u ch mể ứ ặ ề ệ ể ố ẫ ữ ạ ấ ấ ph y (;) đ ngăn cách các thành ph n v i nhau.ả ể ầ ớ

Cách th c hi nự ệ

Page 52: Giao Trinh C++ Toan Tap

Khi g p câu l nh ặ ệ for trình t th c hi n c a ch ng trình nh sau:ự ự ệ ủ ươ ư

Th c hi n dãy bi u th c 1 (thông th ng là các l nh kh i t o cho m t s bi n),ự ệ ể ứ ườ ệ ở ạ ộ ố ế

Ki m tra đi u ki n l p, n u đúng thì th c hi n kh i l nh l p ® th c hi n dãy bi uể ề ệ ặ ế ự ệ ố ệ ặ ự ệ ể th c 2 ® quay lai ki m tra đi u ki n l p và l p l i quá trình trên cho đ n b c nàoứ ể ề ệ ặ ặ ạ ế ướ đó vi c ki m tra đi u ki n l p cho k t qu sai thì d ng. ệ ể ề ệ ặ ế ả ừ

Tóm l i, bi u th c 1 s đ c th c hi n 1 l n duy nh t ngay t đ u quá trình l p sau đó th cạ ể ứ ẽ ượ ự ệ ầ ấ ừ ầ ặ ự hi n các câu l nh l p và dãy bi u th c 2 cho đ n khi nào không còn tho đi u ki n l p n aệ ệ ặ ể ứ ế ả ề ệ ặ ữ thì d ng.ừ

Ví d minh hoụ ạ

: Nhân 2 s nguyên theo ph ng pháp n đố ươ Ấ ộ

void main()

{

long m, n, kq; // Các s c n nhân và k t qu kqố ầ ế ả

cout << “Nh p m và n: “ ; cin >> m >> n ;ậ

for (kq = 0 ; m ; m >>= 1, n <<= 1) if (m%2) kq += n ;

cout << “m nhân n =” << kq ;

}So sánh ví d này v i ví d dùng goto ta th y ch ng trình đ c vi t r t g n. Đ b n đ c dụ ớ ụ ấ ươ ượ ế ấ ọ ể ạ ọ ễ hi u câu l nh for, m t l n n a chúng ta nh c l i cách ho t đ ng c a nó thông qua ví d này,ể ệ ộ ầ ữ ắ ạ ạ ộ ủ ụ trong đó các thành ph n đ c vi t trong cú pháp là nh sau:ầ ượ ế ư

Dãy bi u th c 1: kq = 0,ể ứ

Đi u ki n l p: m. đây đi u ki n là đúng n u m ¹ 0 và sai n u m = 0.ề ệ ặ Ở ề ệ ế ế

Dãy bi u th c 2: m >>= 1 và n <<= 1. 2 bi u th c này có nghĩa m = m >> 1 (t ngể ứ ể ứ ươ đ ng v i m = m / 2) và n = n << 1 (t ng đ ng v i n = n * 2).ươ ớ ươ ươ ớ

Kh i l nh l p: ch có m t l nh duy nh t if (m%2) kq += n ; (n u ph n d c a m chia 2ố ệ ặ ỉ ộ ệ ấ ế ầ ư ủ là khác 0, t c m l thì c ng thêm n vào kq).ứ ẻ ộ

Cách th c hi n c a ch ng trình nh sau:ự ệ ủ ươ ư

Đ u tiên th c hi n bi u th c 1 t c gán kq = 0. Chú ý r ng n u kq đã đ c kh i t oầ ự ệ ể ứ ứ ằ ế ượ ở ạ tr c b ng 0 trong khi khai báo (gi ng nh trong ví d 6) thì thành ph n bi u th c 1ướ ằ ố ư ụ ầ ể ứ

đây có th đ tr ng (nh ng v n gi l i d u ; đ phân bi t v i các thành ph nở ể ể ố ư ẫ ữ ạ ấ ể ệ ớ ầ khác).

Ki m tra đi u ki n: gi s m ¹ 0 (t c đi u ki n đúng) for s th c hi n l nh l p t cể ề ệ ả ử ứ ề ệ ẽ ự ệ ệ ặ ứ ki m tra n u m l thì c ng thêm n vào cho kq.ể ế ẻ ộ

Quay l i th c hi n các bi u th c 2 t c chia đôi m và nhân đôi n và vòng l p đ c ti pạ ự ệ ể ứ ứ ặ ượ ế t c l i b t đ u b ng vi c ki m tra m …ụ ạ ắ ầ ằ ệ ể

Đ n m t b c l p nào đó m s b ng 0 (vì b chia đôi liên ti p), đi u ki n không tho ,ế ộ ướ ặ ẽ ằ ị ế ề ệ ả

Page 53: Giao Trinh C++ Toan Tap

vòng l p d ng và cho ta k t qu là kq. ặ ừ ế ả

: Tính t ng c a dãy các s t 1 đ n 100.ổ ủ ố ừ ếCh ng trình dùng m t bi n đ m i đ c kh i t o t 1, và m t bi n kq đ ch a t ng. M iươ ộ ế ế ượ ở ạ ừ ộ ế ể ứ ổ ỗ b c l p ch ng trình c ng i vào kq và sau đó tăng i lên 1 đ n v . Ch ng trình còn l p khiướ ặ ươ ộ ơ ị ươ ặ nào i còn ch a v t qua 100. Khi i l n h n 100 ch ng trình d ng. Sau đây là văn b nư ượ ớ ơ ươ ừ ả ch ng trình. ươ

void main()

{

int i, kq = 0;

for (i = 1 ; i <= 100 ; i ++) kq += i ;

cout << "T ng = " << kq;ổ

}

: In ra màn hình dãy s l bé h n m t s n nào đó đ c nh p vào t bàn phím.ố ẻ ơ ộ ố ượ ậ ừCh ng trình dùng m t bi n đ m i đ c kh i t o t 1, m i b c l p ch ng trình s in i sauươ ộ ế ế ượ ở ạ ừ ỗ ướ ặ ươ ẽ đó tăng i lên 2 đ n v . Ch ng trình còn l p khi nào i còn ch a v t qua n. Khi i l n h n nơ ị ươ ặ ư ượ ớ ơ ch ng trình d ng. Sau đây là văn b n ch ng trình. ươ ừ ả ươ

void main()

{

int n, i ;

cout << "Hãy nh p n = " ; cin >> n ;ậ

for (i = 1 ; i < n ; i += 2) cout << i << '\n' ;

}

Đ c đi mặ ểThông qua ph n gi i thích cách ho t đ ng c a câu l nh for trong ví d 7 có th th y các thànhầ ả ạ ộ ủ ệ ụ ể ấ ph n c a for có th đ tr ng, tuy nhiên các d u ch m ph y v n gi l i đ ngăn cách cácầ ủ ể ể ố ấ ấ ẩ ẫ ữ ạ ể thành ph n v i nhau. Ví d câu l nh for (kq = 0 ; m ; m >>= 1, n <<= 1) if (m%2) kq += n ;ầ ớ ụ ệ trong ví d 7 có th đ c vi t l i nh sau:ụ ể ượ ế ạ ư

kq = 0;

for ( ; m ; ) { if (m%2) kq += n; m >>= 1; n <<= 1; } T ng t , câu l nh for (i = 1 ; i <= 100 ; i ++) kq += i ; trong ví d 8 cũng có th đ c vi t l iươ ự ệ ụ ể ượ ế ạ nh sau:ư

i = 1;

for ( ; i <= 100 ; ) kq += i ++ ; (câu l nh kq += i++; đ c th c hi n theo 2 b c: c ng i vào kq và tăng i (tăng sau)).ệ ượ ự ệ ướ ộ

Page 54: Giao Trinh C++ Toan Tap

Trong tr ng h p đi u ki n trong for cũng đ tr ng ch ng trình s ng m đ nh là đi u ki nườ ợ ề ệ ể ố ươ ẽ ầ ị ề ệ luôn luôn đúng, t c vòng l p s l p vô h n l n (!). Trong tr ng h p này đ d ng vòng l pứ ặ ẽ ặ ạ ầ ườ ợ ể ừ ặ trong kh i l nh c n có câu l nh ki m tra d ng và câu l nh break. ố ệ ầ ệ ể ừ ệ

Ví d câu l nh for (i = 1 ; i <= 100 ; i ++) kq += i ; đ c vi t l i nh sau:ụ ệ ượ ế ạ ư

i = 1;

for ( ; ; )

{

kq += i++;

if (i > 100) break;

}Tóm l i, vi c s d ng d ng vi t nào c a for ph thu c vào thói quen c a NSD, tuyạ ệ ử ụ ạ ế ủ ụ ộ ủ

nhiên vi c vi t đ y đ các thành ph n c a for làm cho vi c đ c ch ng trình tr nên d dàngệ ế ầ ủ ầ ủ ệ ọ ươ ở ễ h n. ơ

L nh for l ng nhauệ ồTrong dãy l nh l p có th ch a c l nh for, t c các l nh for cũng đ c phép l ng nhau nhệ ặ ể ứ ả ệ ứ ệ ượ ồ ư các câu l nh có c u trúc khác.ệ ấ

: Bài toán c : v a gà v a chó bó l i cho tròn đ m đ 100 chân. H i có m y gà và m y conổ ừ ừ ạ ế ủ ỏ ấ ấ chó, bi t t ng s con là 36. ế ổ ốĐ gi i bài toán này ta g i g là s gà và c là s chó. Theo đi u ki n bài toán ta th y g có th điể ả ọ ố ố ề ệ ấ ể t 0 (không có con nào) và đ n t i đa là 50 (vì ch có 100 chân), t ng t c có th đi t 0 đ nừ ế ố ỉ ươ ự ể ừ ế 25. Nh v y ta có th cho g ch y t 0 đ n 50 và v i m i giá tr c th c a g l i cho c ch y tư ậ ể ạ ừ ế ớ ỗ ị ụ ể ủ ạ ạ ừ 0 đ n 25, l n l t v i m i c p (g, c) c th đó ta ki m tra 2 đi u ki n: g + c == 36 ? (s con)ế ầ ượ ớ ỗ ặ ụ ể ể ề ệ ố và 2g + 4c == 100 ? (s chân). N u c 2 đi u ki n đ u tho thì c p (g, c) c th đó chính làố ế ả ề ệ ề ả ặ ụ ể nghi m c n tìm. T đó ta có ch ng trình v i 2 vòng for l ng nhau, m t vòng for cho g vàệ ầ ừ ươ ớ ồ ộ m t vòng cho c. ộ

void main()

{

int g, c ;

for (g = 0 ; g <= 50 ; g++)

for (c = 0 ; c <= 25 ; c++)

if (g+c == 36 && 2*g+4*c == 100) cout << "gà=" << g << ", chó=" << c ;

}Ch ng trình trên có th đ c gi i thích m t cách ng n g n nh sau: Đ u tiên cho g = 0, th cươ ể ượ ả ộ ắ ọ ư ầ ự hi n l nh for bên trong t c l n l t cho c = 0, 1, …, 25, v i c=0 và g=0 ki m tra đi u ki n,ệ ệ ứ ầ ượ ớ ể ề ệ n u tho thì in k t qu n u không thì b qua, quay l i tăng c, cho đ n khi nào c>25 thì k tế ả ế ả ế ỏ ạ ế ế thúc vòng l p trong quay v vòng l p ngoài tăng g lên 1, l i th c hi n vòng l p trong v i g=1ặ ề ặ ạ ự ệ ặ ớ

Page 55: Giao Trinh C++ Toan Tap

này (t c l i cho c ch y t 0 đ n 25). Khi g c a vòng l p ngoài v t quá 50 thì d ng. T đó taứ ạ ạ ừ ế ủ ặ ượ ừ ừ th y s vòng l p c a ch ng trình là 50 x 25 = 1000 l n l p.ấ ố ặ ủ ươ ầ ặ

Chú ý: Có th gi m b t s l n l p b ng nh n xét s gà không th v t quá 36 (vì t ng sể ả ớ ố ầ ặ ằ ậ ố ể ượ ổ ố con là 36). M t vài nh n xét khác cũng có th làm gi m s vòng l p, ti t ki m th i gian ch yộ ậ ể ả ố ặ ế ệ ờ ạ c a ch ng trình. B n đ c t nghĩ thêm các ph ng án gi i khác đ gi m s vòng l p đ n ítủ ươ ạ ọ ự ươ ả ể ả ố ặ ế nh t. ấ

: Tìm t t c các phấ ả ương án đ có 100ể đ t các t gi y b c lo i 10đ, 20đ và 50đ.ừ ờ ấ ạ ạ

main()

{

int t10, t20, t50; // s t 10đ, 20đ, 50đố ờ

sopa = 0; // s ph ng ánố ươ

for (t10 = 0 ; t10 <= 10 ; t10++)

for (t20 = 0 ; t20 <= 5 ; t20++)

for (t50 = 0 ; t50 <= 2 ; t50++)

if (t10*10 + t20*20 + t50*50 == 100) // n u tho thìế ả

{

sopa++; // tăng s ph ng ánố ươ

if (t10) cout << t10 << "t 10ờ đ “ ; // in s t 10đ n u ¹ 0 ố ờ ế

if (t20) cout << "+" << t20 << "t 20ờ đ “ ; // thêm s t 20đ n u¹0 ố ờ ế

if (t50) cout << "+" << t50 << "t 50ờ đ “ ; // thêm s t 50đ n u¹0 ố ờ ế

cout << '\n' ; // xu ng dòngố

}

cout << “Tong so phuong an = ” << sopa ;

}

L nh l p whileệ ặ

Cú phápwhile (đi u ki n) { kh i l nh l p ; }ề ệ ố ệ ặ

Th c hi nự ệKhi g p l nh while ch ng trình th c hi n nh sau: đ u tiên ch ng trình s ki m tra đi uặ ệ ươ ự ệ ư ầ ươ ẽ ể ề ki n, n u đúng thì th c hi n kh i l nh l p, sau đó quay l i ki m tra đi u ki n và ti p t c.ệ ế ự ệ ố ệ ặ ạ ể ề ệ ế ụ N u đi u ki n sai thì d ng vòng l p. Tóm l i có th mô t m t cách ng n g n v câu l nhế ề ệ ừ ặ ạ ể ả ộ ắ ọ ề ệ while nh sau: ư l p l i các l nh trong khi đi u ki n v n còn đúngặ ạ ệ ề ệ ẫ .

Page 56: Giao Trinh C++ Toan Tap

Đ c đi mặ ể

Kh i l nh l p có th không đ c th c hi n l n nào n u đi u ki n sai ngay t đ u.ố ệ ặ ể ượ ự ệ ầ ế ề ệ ừ ầ

Đ vòng l p không l p vô h n thì trong kh i l nh thông th ng ph i có ít nh t m t câuể ặ ặ ạ ố ệ ườ ả ấ ộ l nh nào đó gây nh h ng đ n k t qu c a đi u ki n, ví d làm cho đi u ki nệ ả ưở ế ế ả ủ ề ệ ụ ề ệ đang đúng tr thành sai.ở

N u đi u ki n luôn luôn nh n giá tr đúng (ví d bi u th c đi u ki n là 1) thì trong kh iế ề ệ ậ ị ụ ể ứ ề ệ ố l nh l p ph i có câu l nh ki m tra d ng và l nh break. ệ ặ ả ệ ể ừ ệ

Ví d minh hoụ ạ

: Nhân 2 s nguyên theo ph ng pháp n đố ươ Ấ ộ

void main()

{

long m, n, kq; // Các s c n nhân và k t qu kqố ầ ế ả

cout << “Nh p m và n: “ ; cin >> m >> n ;ậ

kq = 0 ;

while (m)

{

if (m%2) kq += n ;

m >>= 1;

n <<= 1;

}

cout << “m nhân n =” << kq ;

}Trong ch ng trình trên câu l nh while (m) … đ c đ c là "trong khi m còn khác 0 th c hi nươ ệ ượ ọ ự ệ …", ta th y trong kh i l nh l p có l nh m >>= 1, l nh này s nh h ng đ n đi u ki n (m),ấ ố ệ ặ ệ ệ ẽ ả ưở ế ề ệ đ n lúc nào đó m b ng 0 t c (m) là sai và ch ng trình s d ng l p.ế ằ ứ ươ ẽ ừ ặ

Câu l nh while (m) … cũng có th đ c thay b ng while (1) … nh sau:ệ ể ượ ằ ư

void main()

{

long m, n, kq; // Các s c n nhân và k t qu kqố ầ ế ả

cout << “Nh p m và n: “ ; cin >> m >> n ;ậ

kq = 0 ;

while (1) {

if (m%2) kq += n ;

Page 57: Giao Trinh C++ Toan Tap

m >>= 1;

n <<= 1;

if (!m) break ; // n u m = 0 thì thoát kh i vòng l pế ỏ ặ

}

cout << “m nhân n =” << kq ;

}

: Bài toán c : v a gà v a chó bó l i cho tròn đ m d 100 chân. H i có m y gà và m y conổ ừ ừ ạ ế ủ ỏ ấ ấ chó, bi t t ng s con là 36.ế ổ ố

void main()

{

int g, c ;

g = 0 ;

while (g <= 36) {

c = 0 ;

while (c <= 50) {

if (g + c == 36 && 2*g + 4*c == 100) cout << g << c ;

c++;

}

g++;

}

}

: Tìm c chung l n nh t (UCLN) c a 2 s nguyên m và n.ướ ớ ấ ủ ốÁp d ng thu t toán Euclide b ng cách liên ti p l y s l n tr đi s nh khi nào 2 s b ngụ ậ ằ ế ấ ố ớ ừ ố ỏ ố ằ nhau thì đó là UCLN. Trong ch ng trình ta qui c m là s l n và n là s nh . Thêm bi nươ ướ ố ớ ố ỏ ế ph r đ tính hi u c a 2 s . Sau đó đ t l i m ho c n b ng r sao cho m > n và l p l i. Vòngụ ể ệ ủ ố ặ ạ ặ ằ ặ ạ l p d ng khi m = n.ặ ừ

void main()

{

int m, n, r;

cout << "Nh p m, n: " ; cin >> m >> n ;ậ

if (m < n) { int t = m; m = n; n = t; } // n u m < n thì đ i vai trò hai sế ổ ố

while (m != n) {

r = m - n ;

Page 58: Giao Trinh C++ Toan Tap

if (r > n) m = r; else { m = n ; n = r ; }

}

cout << "UCLN = " << m ;

}

: Tìm nghi m x p x c a ph ng trình eệ ấ ỉ ủ ươ x - 1.5 = 0, trên đo n [0, 1] v i đ chính xác 10ạ ớ ộ -6 b ngằ ph ng pháp chia đôi.ươĐ vi t ch ng trình này chúng ta nh c l i ph ng pháp chia đôi. Cho hàm f(x) liên t c vàể ế ươ ắ ạ ươ ụ đ i d u trên m t đo n [a, b] nào đó (t c f(a), f(b) trái d u nhau hay f(a)*f(b) < 0). Ta đã bi tổ ấ ộ ạ ứ ấ ế v i đi u ki n này ch c ch n đ th c a hàm f(x) s c t tr c hoành t i m t đi m xớ ề ệ ắ ắ ồ ị ủ ẽ ắ ụ ạ ộ ể 0 nào đó trong đo n [a, b], t c xạ ứ 0 là nghi m c a ph ng trình f(x) = 0. Tuy nhiên vi c tìm chính xác xệ ủ ươ ệ 0

là khó, vì v y ta có th tìm x p x x' c a nó sao cho x' càng g n xậ ể ấ ỉ ủ ầ 0 càng t t. L y c là đi mố ấ ể gi a c a đo n [a, b], c s chia đo n [a, b] thành 2 đo n con [a, c] và [c, b] và do f(a), f(b) tráiữ ủ ạ ẽ ạ ạ d u nên ch c ch n m t trong hai đo n con cũng ph i trái d u, t c nghi m xấ ắ ắ ộ ạ ả ấ ứ ệ 0 s n m trongẽ ằ đo n này. Ti p t c quá trình b ng cách chia đôi đo n v a tìm đ c … cho đ n khi ta nh nạ ế ụ ằ ạ ừ ượ ế ậ đ c m t đo n con (trái d u, ch a xượ ộ ạ ấ ứ 0) sao cho đ dài c a đo n con này bé h n đ x p x choộ ủ ạ ơ ộ ấ ỉ tr c thì d ng. Khi đó l y b t kỳ đi m nào trên đo n con này (ví d hai đi m mút ho c đi mướ ừ ấ ấ ể ạ ụ ể ặ ể gi a c a a và b) thì ch c ch n kho ng cách c a nó đ n xữ ủ ắ ắ ả ủ ế 0 cũng bé h n đ x p x cho tr c,ơ ộ ấ ỉ ướ t c có th l y đi m này làm nghi m x p x c a ph ng trình f(x) = 0. ứ ể ấ ể ệ ấ ỉ ủ ươ

Trong ví d này hàm f(x) chính là eụ x - 1.5 và đ x p x là 10ộ ấ ỉ -6. Đây là hàm liên t c trên toànụ tr c s và đ i d u trên đo n [0, 1] (vì f(0) = 1 - 1.5 < 0 còn f(1) = e - 1.5 > 0). Sau đây làụ ố ổ ấ ạ ch ng trình.ươ

void main()

{

float a = 0, b = 1, c; // các đi m mút a, b và đi m gi a cể ể ữ

float fa, fc; // giá tr c a f(x) t i các đi m a, cị ủ ạ ể

while (b-a > 1.0e-6) // trong khi đ dài đo n còn l n h n eộ ạ ớ ơ

{

c = (a + b)/2; // tìm đi m c gi a đo n [a,b]ể ữ ạ

fa = exp(a) - 1.5; fc = exp(c) - 1.5; // tính f(a) và f(c)

if (fa*fc == 0) break; // f(c) = 0 t c c là nghi mứ ệ

if (fa*fc > 0) a = c; else b = c;

}

cout << "Nghiem xap xi cua phuong trinh = " << c ;

}Trong ch ng trình trên câu l nh if (fa*fc > 0) a = c; else b = c; dùng đ ki m tra f(a) và f(c),ươ ệ ể ể n u cùng d u (f(a)*f(c) > 0) thì hàm f(x) ph i trái d u trên đo n con [c, b] do đó đ t l i đo nế ấ ả ấ ạ ặ ạ ạ

Page 59: Giao Trinh C++ Toan Tap

này là [a, b] (đ quay l i vòng l p) t c đ t a = c và b gi nguyên, ng c l i n u hàm f(x) tráiể ạ ặ ứ ặ ữ ượ ạ ế d u trên đo n con [a, c] thì đ t l i b = c còn a gi nguyên. Sau đó vòng l p quay l i ki m traấ ạ ặ ạ ữ ặ ạ ể đ dài đo n [a, b] (m i) n u đã bé h n đ x p x thì d ng và l y c làm nghi m x p x , n uộ ạ ớ ế ơ ộ ấ ỉ ừ ấ ệ ấ ỉ ế không thì tính l i c và ti p t c quá trình.ạ ế ụ

Đ tính f(a) và f(c) ch ng trình đã s d ng hàm exp(x), đây là hàm cho l i k t qu eể ươ ử ụ ạ ế ả x, để dùng hàm này ho c các hàm toán h c nói chung, c n khai báo file nguyên m u math.h.ặ ọ ầ ẫ

L nh l p do ... whileệ ặ

Cú pháp do { kh i l nh l p } while (ố ệ ặ đi u ki n) ;ề ệ

Th c hi nự ệĐ u tiên ch ng trình s th c hi n kh i l nh l p, ti p theo ki m tra đi u ki n, n u đi uầ ươ ẽ ự ệ ố ệ ặ ế ể ề ệ ế ề ki n còn đúng thì quay l i th c hi n kh i l nh và quá trình ti p t c cho đ n khi đi u ki n trệ ạ ự ệ ố ệ ế ụ ế ề ệ ở thành sai thì d ng. ừ

Đ c đi mặ ểCác đ c đi m c a câu l nh do … while cũng gi ng v i câu l nh l p while tr đi m khác bi t,ặ ể ủ ệ ố ớ ệ ặ ừ ể ệ đó là kh i l nh trong do … while s đ c th c hi n ít nh t m t l n, trong khi trong câu l nhố ệ ẽ ượ ự ệ ấ ộ ầ ệ while có th không đ c th c hi n l n nào (vì l nh while ph i ki m tra đi u ki n tr c khiể ượ ự ệ ầ ệ ả ể ề ệ ướ th c hi n kh i l nh, do đó n u đi u ki n sai ngay t đ u thì l nh s d ng, kh i l nh khôngự ệ ố ệ ế ề ệ ừ ầ ệ ẽ ừ ố ệ đ c th c hi n l n nào. Trong khi đó l nh do … while s th c hi n kh i l nh r i m i ki mượ ự ệ ầ ệ ẽ ự ệ ố ệ ồ ớ ể tra đi u ki n l p đ cho phép th c hi n ti p ho c d ng).ề ệ ặ ể ự ệ ế ặ ừ

Ví d minh hoụ ạ

: Tính x p x s pi theo công th c Euler ấ ỉ ố ứ2222

2 1

3

1

2

1

1

1

6 n... ++++=π

, v i ớ

62

101 −<n .

void main()

{

int n = 1; float S = 0;

do S += 1.0/(n*n) while 1.0/(n*n) < 1.0e-6;

float pi = sqrt(6*S);

cout << "pi = " << pi ;

}

: Ki m tra m t s n có là s nguyên t . ể ộ ố ố ốĐ ki m tra m t s n > 3 có ph i là s nguyên t ta l n l t chia n cho các s i đi t 2 đ nể ể ộ ố ả ố ố ầ ượ ố ừ ế m t n a c a n. N u có i sao cho n chia h t cho i thì n là h p s ng c l i n là s nguyên t . ộ ử ủ ế ế ợ ố ượ ạ ố ố

Page 60: Giao Trinh C++ Toan Tap

void main()

{

int i, n ; // n: s c n ki m traố ầ ể

cout << "Cho bi t s c n ki m tra: " ; cin >> n ;ế ố ầ ể

i = 2 ;

do {

if (n%i == 0) {

cout << n << "là h p s " ;ợ ố

return ; // d ng ch ng trìnhừ ươ

}

i++;

} while (i <= n/2);

cout << n << "là s nguyên t " ;ố ố

}

: Nh p dãy kí t và th ng kê các lo i ch hoa, th ng, ch s và các lo i khác còn l i ậ ự ố ạ ữ ườ ữ ố ạ ạ đ n khiế g p ENTER thì d ng.ặ ừ

void main()

{

char c; // kí t dùng cho nh pự ậ

int n1, n2, n3, n4 ; // s l ng các lo i kí tố ượ ạ ự

n1 = n2 = n3 = n4 = 0;

cout << “Hãy nh p dãy kí t : \n” ;ậ ự

do

{

cin >> c;

if (‘a’ <= c && c <= ‘z’) n1++; // n u c là ch th ng thì tăng n1ế ữ ườ

else if (‘A’ <= c && c <= ‘Z’) n2++; // ch hoa, tăng n2ữ

else if (‘0’ <= c && c <= ‘9’) n3++; // ch s , tăng n3ữ ố

else n4++; // lo i khác, tăng n4ạ

cout << n1 << n2 << n3 << n4 ; // in k t qu ế ả

} while (c != 10) ; // còn l p khi c còn khác kí t ặ ự ¿

}

Page 61: Giao Trinh C++ Toan Tap

L i ra c a vòng l p: break, continueố ủ ặ

L nh breakệCông d ng c a l nh dùng đ thoát ra kh i (ch m d t) các câu l nh c u trúc, ch ng trình sụ ủ ệ ể ỏ ấ ứ ệ ấ ươ ẽ ti p t c th c hi n các câu l nh ti p sau câu l nh v a thoát. Các ví d minh ho b n đ c cóế ụ ự ệ ệ ế ệ ừ ụ ạ ạ ọ th xem l i trong các ví d v câu l nh switch, for, while.ể ạ ụ ề ệ

L nh continueệL nh dùng đ quay l i đ u vòng l p mà không ch th c hi n h t các l nh trong kh i l nhệ ể ạ ầ ặ ờ ự ệ ế ệ ố ệ l p.ặ

: Gi s v i m i i t 1 đ n 100 ta c n th c hi n m t lo t các l nh nào đó tr nh ng s i là sả ử ớ ỗ ừ ế ầ ự ệ ộ ạ ệ ừ ữ ố ố chính ph ng. Nh v y đ ti t ki m th i gian, vòng l p s ki m tra n u i là s chínhươ ư ậ ể ế ệ ờ ặ ẽ ể ế ố ph ng thì s quay l i ngay t đ u đ th c hi n v i i ti p theo. ươ ẽ ạ ừ ầ ể ự ệ ớ ế

int i ;

for (i = 1; i <= 100; i++) {

if (i là s chính ph ng) continue;ố ươ

{ // dãy l nh khác ệ

.

.

.

}

}(Đ ki m tra i có là s chính ph ng chúng ta so sánh căn b c hai c a i v i ph n nguyên c aể ể ố ươ ậ ủ ớ ầ ủ nó. N u hai s này b ng nhau thì i là s chính ph ng. C th n u sqrt(i) = int(sqrt(i)) thì i làế ố ằ ố ươ ụ ể ế s chính ph ng. đây sqrt(x) là hàm tr l i căn b c hai c a x. Đ s d ng hàm này c nố ươ Ở ả ạ ậ ủ ể ử ụ ầ ph i khai báo file nguyên m u math.h.)ả ẫ

So sánh cách dùng các câu l nh l pệ ặThông qua các ví d đã trình bày b n đ c có th th y r ng v m t th c ch t đ t ch c m tụ ạ ọ ể ấ ằ ề ặ ự ấ ể ổ ứ ộ vòng l p chúng ta có th ch n m t trong các câu l nh goto, for, while, do … while, có nghĩaặ ể ọ ộ ệ v m t kh năng th c hi n các câu l nh này là nh nhau. Tuy nhiên, trong m t ng c nh cề ặ ả ự ệ ệ ư ộ ữ ả ụ th vi c s d ng câu l nh phù h p trong chúng làm cho ch ng trình sáng s a, rõ ràng và tăngể ệ ử ụ ệ ợ ươ ủ đ tin c y lên cao h n. Theo thói quen l p trình trong m t s ngôn ng có tr c và d a trênộ ậ ơ ậ ộ ố ữ ướ ự đ c tr ng riêng c a t ng câu l nh, các l nh l p th ng đ c dùng trong các ng c nh c thặ ư ủ ừ ệ ệ ặ ườ ượ ữ ả ụ ể nh sau:ư

FOR th ng đ c s d ng trong nh ng vòng l p mà s l n l p đ c bi t tr c, nghĩaườ ượ ử ụ ữ ặ ố ầ ặ ượ ế ướ

Page 62: Giao Trinh C++ Toan Tap

là vòng l p th ng đ c t ch c d i d ng m t (ho c nhi u) bi n đ m ch y tặ ườ ượ ổ ứ ướ ạ ộ ặ ề ế ế ạ ừ m t giá tr nào đó và đ n khi đ t đ c đ n m t giá tr khác cho tr c thì d ng. Víộ ị ế ạ ượ ế ộ ị ướ ừ d d ng th ng dùng c a câu l nh for là nh sau:ụ ạ ườ ủ ệ ư

for (i = gt1 ; i <= gt2 ; i++) … t c i tăng t gt1 đ n gt2 ho cứ ừ ế ặ

for (i = gt2 ; i >= gt1 ; i--) … t c i gi m t gt2 xu ng gt1ứ ả ừ ố

Ng c l i v i FOR, WHILE và DO … WHILE th ng dùng trong các vòng l p mà sượ ạ ớ ườ ặ ố l n l p không bi t tr c, chúng th ng đ c s d ng khi vi c l p hay d ng phầ ặ ế ướ ườ ượ ử ụ ệ ặ ừ ụ thu c vào m t bi u th c lôgic. ộ ộ ể ứ

WHILE đ c s d ng khi kh năng th c hi n kh i l p không x y ra l n nào, t c n uượ ử ụ ả ự ệ ố ặ ả ầ ứ ế đi u ki n l p có giá tr sai ngay t đ u, trong khi đó DO … WHILE đ c s d ngề ệ ặ ị ừ ầ ượ ử ụ khi ta bi t ch c ch n kh i l nh l p ph i đ c th c hi n ít nh t m t l n.ế ắ ắ ố ệ ặ ả ượ ự ệ ấ ộ ầ

M NG D LI UẢ Ữ Ệ

M ng m t chi uả ộ ề

Ý nghĩaKhi c n l u tr m t dãy n ph n t d li u chúng ta c n khai báo n bi n t ng ng v i n tênầ ư ữ ộ ầ ử ữ ệ ầ ế ươ ứ ớ g i khác nhau. Đi u này s r t khó khăn cho ng i l p trình đ có th nh và qu n lý h tọ ề ẽ ấ ườ ậ ể ể ớ ả ế đ c t t c các bi n, đ c bi t khi n l n. Trong th c t , hi n nhiên chúng ta g p r t nhi u dượ ấ ả ế ặ ệ ớ ự ế ể ặ ấ ề ữ li u có liên quan đ n nhau v m t m t nào đó, ví d chúng có cùng ki u và cùng th hi n m tệ ế ề ộ ặ ụ ể ể ệ ộ đ i t ng: nh các to đ c a m t vect , các s h ng c a m t ma tr n, các sinh viên c aố ượ ư ạ ộ ủ ộ ơ ố ạ ủ ộ ậ ủ m t l p ho c các dòng kí t c a m t văn b n … L i d ng đ c đi m này toàn b d li uộ ớ ặ ự ủ ộ ả ợ ụ ặ ể ộ ữ ệ (cùng ki u và cùng mô t m t đ i t ng) có th ch c n chung m t tên g i đ phân bi t v iể ả ộ ố ượ ể ỉ ầ ộ ọ ể ệ ớ các đ i t ng khác, và đ phân bi t các d li u trong cùng đ i t ng ta s d ng cách đánh số ượ ể ệ ữ ệ ố ượ ử ụ ố th t cho chúng, t đó vi c qu n lý bi n s d dàng h n, ch ng trình s g n và có tính hứ ự ừ ệ ả ế ẽ ễ ơ ươ ẽ ọ ệ th ng h n.ố ơ

Gi s ta có 2 vect trong không gian ba chi u, m i vec t c n 3 bi n đ l u 3 to đ , vì v yả ử ơ ề ỗ ơ ầ ế ể ư ạ ộ ậ đ l u to đ c a 2 vect chúng ta ph i dùng đ n 6 bi n, ví d x1, y1, z1 cho vect th nh tể ư ạ ộ ủ ơ ả ế ế ụ ơ ứ ấ và x2, y2, z2 cho vect th hai. M t ki u d li u m i đ c g i là m ng m t chi u cho phépơ ứ ộ ể ữ ệ ớ ượ ọ ả ộ ề ta ch c n khai báo 2 bi n v1 và v2 đ ch 2 vect , trong đó m i v1 ho c v2 s ch a 3 d li uỉ ầ ế ể ỉ ơ ỗ ặ ẽ ứ ữ ệ đ c đánh s th t t 0 đ n 2, trong đó ta có th ng m đ nh thành ph n 0 bi u di n to đượ ố ứ ự ừ ế ể ầ ị ầ ể ễ ạ ộ x, thành ph n 1 bi u di n to đ y và thành ph n có s th t 2 s bi u di n to đ z.ầ ể ễ ạ ộ ầ ố ứ ự ẽ ể ễ ạ ộ

Tóm l i, m ng là m t dãy các thành ph n có cùng ki u đ c s p k nhau liên t c trong bạ ả ộ ầ ể ượ ắ ề ụ ộ nh . T t c các thành ph n đ u có cùng tên là tên c a m ng. Đ phân bi t các thành ph n v iớ ấ ả ầ ề ủ ả ể ệ ầ ớ nhau, các thành ph n s đ c đánh s th t t 0 cho đ n h t m ng. Khi c n nói đ n thànhầ ẽ ượ ố ứ ự ừ ế ế ả ầ ế ph n c th nào c a m ng ta s dùng tên m ng và kèm theo s th t c a thành ph n đó. ầ ụ ể ủ ả ẽ ả ố ứ ự ủ ầ

D i đây là hình nh c a m t m ng g m có 9 thành ph n, các thành ph n đ c đánh s t 0ướ ả ủ ộ ả ồ ầ ầ ượ ố ừ đ n 8.ế

Page 63: Giao Trinh C++ Toan Tap

0 1 2 3 4 5 6 7 8

Khai báo<tên ki u> <tên m ng>[s thành ph n] ;ể ả ố ầ // không kh i t oở ạ

<tên ki u> <tên m ng>[s thành ph n] = { dãy giá tr } ; ể ả ố ầ ị // có kh i t oở ạ

<tên ki u> <tên m ng>[ ] = { dãy giá tr } ;ể ả ị // có kh i t oở ạ

Tên ki u là ki u d li u c a các thành ph n, các thành ph n này có ki u gi ng nhau.ể ể ữ ệ ủ ầ ầ ể ố Th nh tho ng ta cũng g i các thành ph n là ph n t .ỉ ả ọ ầ ầ ử

Cách khai báo trên gi ng nh khai báo tên bi n bình th ng nh ng thêm s thành ph nố ư ế ườ ư ố ầ trong m ng gi a c p d u ngo c vuông [] còn đ c g i là kích th c c a m ng. M iả ữ ặ ấ ặ ượ ọ ướ ủ ả ỗ tên m ng là m t bi n và đ phân bi t v i các bi n thông th ng ta còn g i là bi nả ộ ế ể ệ ớ ế ườ ọ ế m ng.ả

M t m ng d li u đ c l u trong b nh b i dãy các ô liên ti p nhau. S l ng ô b ngộ ả ữ ệ ượ ư ộ ớ ở ế ố ượ ằ v i s thành ph n c a m ng và đ dài (byte) c a m i ô đ đ ch a thông tin c aớ ố ầ ủ ả ộ ủ ỗ ủ ể ứ ủ m i thành ph n. Ô đ u tiên đ c đánh th t b i 0, ô ti p theo b i 1, và ti p t c choỗ ầ ầ ượ ứ ự ở ế ở ế ụ đ n h t. Nh v y n u m ng có n thành ph n thì ô cu i cùng trong m ng s đ cế ế ư ậ ế ả ầ ố ả ẽ ượ đánh s là n - 1.ố

D ng khai báo th 2 cho phép kh i t o m ng b i dãy giá tr trong c p d u {}, m i giáạ ứ ở ạ ả ở ị ặ ấ ỗ tr cách nhau b i d u ph y (,), các giá tr này s đ c gán l n l t cho các ph n tị ở ấ ả ị ẽ ượ ầ ượ ầ ử c a m ng b t đ u t ph n t th 0 cho đ n h t dãy. S giá tr có th bé h n sủ ả ắ ầ ừ ầ ử ứ ế ế ố ị ể ơ ố ph n t . Các ph n t m ng ch a có giá tr s không đ c xác đ nh cho đ n khi trongầ ử ầ ử ả ư ị ẽ ượ ị ế ch ng trình nó đ c gán m t giá tr nào đó.ươ ượ ộ ị

D ng khai báo th 3 cho phép v ng m t s ph n t , tr ng h p này s ph n t đ cạ ứ ắ ặ ố ầ ử ườ ợ ố ầ ử ượ xác đ nh b i s giá tr c a dãy kh i t o. Do đó n u v ng m t c dãy kh i t o làị ở ố ị ủ ở ạ ế ắ ặ ả ở ạ không đ c phép (ch ng h n khai báo int a[] là sai). ượ ẳ ạ

Ví d :ụ

Khai báo bi n ch a 2 vect a, b trong không gian 3 chi u: ế ứ ơ ềfloat a[3] , b[3] ;

Khai báo 3 phân s a, b, c; trong đó a = 1/3 và b = 3/5:ốint a[2] = {1, 3} , b[2] = {3, 5} , c[2] ;

đây ta ng m qui c thành ph n đ u tiên (s th t 0) là t và thành ph n th haiở ầ ướ ầ ầ ố ứ ự ử ầ ứ (s th t 1) là m u c a phân s . ố ứ ự ẫ ủ ố

Khai báo m ng L ch a đ c t i đa 100 s nguyên dài:ả ứ ượ ố ốlong L[100] ;

Khai báo m ng dong (dòng), m i dòng ch a đ c t i đa 80 kí t :ả ỗ ứ ượ ố ự

Page 64: Giao Trinh C++ Toan Tap

char dong[80] ;

Khai báo dãy Data ch a đ c 5 s th c đ chính xác g p đôi:ứ ượ ố ự ộ ấdouble Data[] = { 0,0,0,0,0 }; // kh i t o t m th i b ng 0ở ạ ạ ờ ằ

Cách s d ngử ụ

Đ ch thành ph n th i (hay ch s i) c a m t m ng ta vi t tên m ng kèm theo ch sể ỉ ầ ứ ỉ ố ủ ộ ả ế ả ỉ ố trong c p ngo c vuông []. Ví d v i các phân s trên a[0], b[0], c[0] đ ch t s vàặ ặ ụ ớ ố ể ỉ ử ố a[1], b[1], c[1] đ ch m u s c a 3 phân s a,b,c. ể ỉ ẫ ố ủ ố

Tuy m i m ng bi u di n m t đ i t ng nh ng chúng ta không th áp d ng các thao tácỗ ả ể ễ ộ ố ượ ư ể ụ lên toàn b m ng mà ph i th c hi n thao tác thông qua t ng thành ph n c a m ng.ộ ả ả ự ệ ừ ầ ủ ả Ví d chúng ta không th nh p d li u cho m ng a[10] b ng câu l nh:ụ ể ậ ữ ệ ả ằ ệcin >> a ; // sai

mà ph i nh p cho t ng ph n t t a[0] đ n a[9] c a a. Dĩ nhiên trong tr ng h pả ậ ừ ầ ử ừ ế ủ ườ ợ này chúng ta ph i c n đ n l nh l p for:ả ầ ế ệ ặ

int i ;

for (i = 0 ; i < 10 ; i++) cin >> a[i] ;T ng t , gi s chúng ta c n c ng 2 phân s a, b và đ t k t qu vào c. ươ ự ả ử ầ ộ ố ặ ế ả

Không th vi t:ể ế

c = a + b ; // sai

mà c n ph i tính t ng ph n t c a c:ầ ả ừ ầ ử ủ

c[0] = a[0] * b[1] + a[1] * b[0] ; // t sử ố

c[1] = a[1] * b[1] ; // m u sẫ ốĐ kh c ph c nh c đi m này, trong các ch ng sau C++ cung c p m t ki u d li uể ắ ụ ượ ể ươ ấ ộ ể ữ ệ

m i g i là l p, và cho phép NSD có th đ nh nghĩa riêng phép c ng cho 2 m ng tuỳ ý, khi đóớ ọ ớ ể ị ộ ả có th vi t m t cách đ n gi n và quen thu c c = a + b đ c ng 2 phân s .ể ế ộ ơ ả ộ ể ộ ố

Ví d minh ho ụ ạ

: Tìm t ng, tích 2 phân s .ổ ố

void main()

{

int a[2], b[2], tong[2], tich[2] ;

cout << "Nh p a. T = " ; cin >> a[0] ; cout << "m u = " ; cin >> a[1] ;ậ ử ẫ

cout << "Nh p b. T = " ; cin >> b[0] ; cout << "m u = " ; cin >> b[1] ;ậ ử ẫ

tong[0] = a[0]*b[1] + a[1]*b[0] ; tong[1] = a[1] * b[1] ;

tich[0] = a[0]*b[0]; tich[1] = a[1] * b[1] ;

Page 65: Giao Trinh C++ Toan Tap

cout << "T ng = " << tong[0] << '/' << tong[1] ;ổ

cout << "Tích = " << tich[0] << '/' << tich[1] ;

}

: Nh p dãy s nguyên, tính: s s h ng d ng, âm, b ng không c a dãy.ậ ố ố ố ạ ươ ằ ủ

void main()

{

float a[50], i, n, sd, sa, s0; // a ch a t i đa 50 sứ ố ố

cout << "Nh p s ph n t c a dãy: " ; cin >> n;ậ ố ầ ử ủ // nh p s ph n t ậ ố ầ ử

for (i=0; i<n; i++) { cout << "a[" << i << "] = " ; cin >> a[i]; } // nh p dãy s ậ ố

sd = sa = s0 = 0 ;

for (i=1; i<n; i++) {

if (a[i] > 0 ) sd++;

if (a[i] < 0 ) sa++;

if (a[i] == 0 ) s0++;

}

cout << "S s d ng = " << sd << " s s âm = " << sa ;ố ố ươ ố ố

cout << "S s b ng 0 = " << s0 ;ố ố ằ

}

: Tìm s bé nh t c a m t dãy s . In ra s này và v trí c a nó trong dãy.ố ấ ủ ộ ố ố ị ủCh ng trình s d ng m ng a đ l u dãy s , n là s ph n t th c s trong dãy, min l u s béươ ử ụ ả ể ư ố ố ầ ử ự ự ư ố nh t tìm đ c và k là v trí c a min trong dãy. min đ c kh i t o b ng giá tr đ u tiên (a[0]),ấ ượ ị ủ ượ ở ạ ằ ị ầ sau đó l n l t so sánh v i các s h ng còn l i, n u g p s h ng nh h n, min s nh n giáầ ượ ớ ố ạ ạ ế ặ ố ạ ỏ ơ ẽ ậ tr c a s h ng này. Quá trình so sánh ti p t c cho đ n h t dãy. Vì s s h ng c a dãy là bi tị ủ ố ạ ế ụ ế ế ố ố ạ ủ ế tr c (n), nên s l n l p cũng đ c bi t tr c (n-1 l n l p), do v y chúng ta s s d ng câuướ ố ầ ặ ượ ế ướ ầ ặ ậ ẽ ử ụ l nh for cho ví d này. ệ ụ

void main()

{

float a[100], i, n, min, k; // a ch a t i đa 100 sứ ố ố

cout << "Nh p s ph n t c a dãy: " ; cin >> n;ậ ố ầ ử ủ

for (i=0; i<n; i++) { cout << "a[" << i << "] = " ; cin >> a[i]; }

min = a[0]; k = 0;

for (i=1; i<n; i++) if (a[i] < min ) { min = a[i]; k = i; }

Page 66: Giao Trinh C++ Toan Tap

cout << "S bé nh t là " << min << "t i v trí " << k;ố ấ ạ ị

}

: Nh p và s p x p tăng d n m t dãy s . Thu t toán đ c ti n hành b ng cách s p x p d nậ ắ ế ầ ộ ố ậ ượ ế ằ ắ ế ầ t ng s h ng bé nh t lên đ u dãy. Gi s đã s p đ c i-1 v trí, ta s tìm s bé nh t trong dãyừ ố ạ ấ ầ ả ử ắ ượ ị ẽ ố ấ còn l i (t v trí th i đ n n-1) và đ a s này l p vào v trí th i. Đ th c hi n, chúng ta soạ ừ ị ứ ế ư ố ắ ị ứ ể ự ệ sánh a[i] l n l t v i t ng s a[j] trong dãy còn l i (t c j đi t i+1 đ n n), n u g p a[j] bé h nầ ượ ớ ừ ố ạ ứ ừ ế ế ặ ơ a[i] thì đ i ch hai s này v i nhau. ổ ỗ ố ớ

void main()

{

float a[100], i, j, n, tam;

cout << "Cho bi t s ph n t n = " ; cin >> n ;ế ố ầ ử

for (i=0; i<n; i++) {cout<<"a[" <<i<< "] = "; cin >> a[i] ;} // nh p d li u ậ ữ ệ

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

for (j=i+1; j<n; j++)

if (a[i] > a[j]) { tam = a[i]; a[i] = a[j]; a[j] = tam; } // đ i chổ ỗ

}

for (i=0; i<n; i++) cout << a[i] ; // in k t quế ả

getch();

}

Xâu kí tựM t xâu kí t là m t dãy b t kỳ các kí t (k c d u cách) do v y nó có th đ c l u b ngộ ự ộ ấ ự ể ả ấ ậ ể ượ ư ằ m ng kí t . Tuy nhiên đ máy có th nh n bi t đ c m ng kí t này là m t xâu, c n thi tả ự ể ể ậ ế ượ ả ự ộ ầ ế ph i có kí t k t thúc xâu, theo qui c là kí t có mã 0 (t c '\0') t i v trí nào đó trong m ng.ả ự ế ướ ự ứ ạ ị ả Khi đó xâu là dãy kí t b t đ u t ph n t đ u tiên (th 0) đ n kí t k t thúc xâu đ u tiênự ắ ầ ừ ầ ử ầ ứ ế ự ế ầ (không k các kí t còn l i trong m ng).ể ự ạ ả

0 1 2 3 4 5 6 7

H E L L O \0

H E L \0 L O \0

\0 H E L L O \0

Hình v trên minh ho 3 xâu, m i xâu đ c ch a trong m ng kí t có đ dài t i đa là 8. N iẽ ạ ỗ ượ ứ ả ự ộ ố ộ dung xâu th nh t là "Hello" có đ dài th c t là 5 kí t , chi m 6 ô trong m ng (thêm ô ch aứ ấ ộ ự ế ự ế ả ứ kí t k t thúc '\0'). Xâu th hai có n i dung "Hel" v i đ dài 3 (chi m 4 ô) và xâu cu i cùngự ế ứ ộ ớ ộ ế ố

Page 67: Giao Trinh C++ Toan Tap

bi u th m t xâu r ng (chi m 1 ô). Chú ý m ng kí t đ c khai báo v i đ dài 8 tuy nhiên cácể ị ộ ỗ ế ả ự ượ ớ ộ xâu có th ch chi m m t s kí t nào đó trong m ng này và t i đa là 7 kí t .ể ỉ ế ộ ố ự ả ố ự

Khai báo char <tên xâu>[đ dài] ;ộ // không kh i t oở ạ

char <tên xâu>[đ dài] = xâu kí t ;ộ ự // có kh i t oở ạ

char <tên xâu>[] = xâu kí t ;ự // có kh i t oở ạ

Đ dài m ng là s kí t t i đa có th có trong xâu. Đ dài th c s c a xâu ch tính tộ ả ố ự ố ể ộ ự ự ủ ỉ ừ đ u m ng đ n d u k t thúc xâu (không k d u k t thúc xâu ‘\0’). ầ ả ế ấ ế ể ấ ế

Do m t xâu ph i có d u k t thúc xâu nên trong khai báo đ dài c a m ng c n ph i khaiộ ả ấ ế ộ ủ ả ầ ả báo th a ra m t ph n t . Th c ch t đ dài t i đa c a xâu = đ dài m ng - 1. Ví dừ ộ ầ ử ự ấ ộ ố ủ ộ ả ụ n u mu n khai báo m ng s ch a đ c xâu có đ dài t i đa 80 kí t , ta c n ph i khaiế ố ả ứ ượ ộ ố ự ầ ả báo char s[81].

Cách khai báo th hai có kèm theo kh i t o xâu, đó là dãy kí t đ t gi a c p d u nháyứ ở ạ ự ặ ữ ặ ấ kép. Ví d : ụ

char hoten[26] ; // xâu h tên ch a t i đa 25 kí tọ ứ ố ự

char monhoc[31] = "NNLT C++" ;

xâu môn h c ch a t i đa 30 kí t , đ c kh i t o v i n i dung "NNLT C++" v i đ dài th cọ ứ ố ự ượ ở ạ ớ ộ ớ ộ ự s là 10 kí t (chi m 11 ô đ u tiên trong m ng monhoc[31]).ự ự ế ầ ả

Cách khai báo th 3 t ch ng trình s quy t đ nh đ dài c a m ng b i xâu kh i t oứ ự ươ ẽ ế ị ộ ủ ả ở ở ạ (b ng đ dài xâu + 1). Ví d :ằ ộ ụ

char thang[] = "M i hai" ; ườ // đ dài m ng = 9ộ ả

Cách s d ngử ụT ng t nh các m ng d li u khác, xâu kí t có nh ng đ c tr ng nh m ng, tuy nhiênươ ự ư ả ữ ệ ự ữ ặ ư ư ả chúng cũng có nh ng đi m khác bi t. D i đây là các đi m gi ng và khác nhau đó.ữ ể ệ ướ ể ố

Truy c p m t kí t trong xâu: cú pháp gi ng nh m ng. Ví d :ậ ộ ự ố ư ả ụ

char s[50] = "I\'m a student" ; // chú ý kí t ' ph i đ c vi t là \'ự ả ượ ế

cout << s[0] ; // in kí t đ u tiên, t c kí t 'I'ự ầ ứ ự

s[1] = 'a' ; // đ t l i kí t th 2 là 'a'ặ ạ ự ứ

Không đ c th c hi n các phép toán tr c ti p trên xâu nh :ượ ự ệ ự ế ư

char s[20] = "Hello", t[20] ; // khai báo hai xâu s và t

t = "Hello" ; // sai, ch gán đ c khi khai báoỉ ượ

t = s ; // sai, không gán đ c toàn bượ ộ m ngả

Page 68: Giao Trinh C++ Toan Tap

if (s < t) … // sai, không so sánh đ c hai m ngượ ả

Toán t nh p d li u >> v n dùng đ c nh ng có nhi u h n ch . Ví d ử ậ ữ ệ ẫ ượ ư ề ạ ế ụ

char s[60] ;

cin >> s ;

cout << s ;n u xâu nh p vào là "Tin h c hoá" ch ng h n thì toán t >> ch nh p "Tin" cho s (b t tế ậ ọ ẳ ạ ử ỉ ậ ỏ ấ

c các kí t đ ng sau d u tr ng), vì v y khi in ra trên màn hình ch có t "Tin".ả ự ứ ấ ắ ậ ỉ ừVì các phép toán không dùng đ c tr c ti p trên xâu nên các ch ng trình d ch đã vi t s n cácượ ự ế ươ ị ế ẵ hàm th vi n đ c khai báo trong file nguyên m u string.h. Các hàm này gi i quy t đ c h uư ệ ượ ẫ ả ế ượ ầ h t các công vi c c n thao tác trên xâu. Nó cung c p cho NSD ph ng ti n đ thao tác trênế ệ ầ ấ ươ ệ ể xâu nh gán, so sánh, sao chép, tính đ dài xâu, nh p, in, … Đ s d ng đ c các hàm nàyư ộ ậ ể ử ụ ượ đ u ch ng trình c n có khai báo string.h. Ph n l n các hàm này s đ c gi i thi u trongầ ươ ầ ầ ớ ẽ ượ ớ ệ ph n ti p sau.ầ ế

Ph ng th c nh p xâu (#include <iostream.h>)ươ ứ ậDo toán t nh p >> có h n ch đ i v i xâu kí t nên C++ đ a ra hàm riêng (còn g i làử ậ ạ ế ố ớ ự ư ọ ph ng th c) ươ ứ cin.getline(s,n) đ nh p xâu kí t . Hàm có 2 đ i v i s là xâu c n nh p n i dungể ậ ự ố ớ ầ ậ ộ và n-1 là s kí t t i đa c a xâu. Gi ng ph ng th c nh p kí t cin.get(c), khi g p hàmố ự ố ủ ố ươ ứ ậ ự ặ cin.getline(s,n) ch ng trình s nhìn vào b đ m bàn phím l y ra n-1 kí t (n u đ ho c l yươ ẽ ộ ệ ấ ự ế ủ ặ ấ t t c kí t còn l i, tr kí t enter) và gán cho s. N u t i th i đi m đó b đ m đang r ng,ấ ả ự ạ ừ ự ế ạ ờ ể ộ ệ ỗ ch ng trình s t m d ng ch NSD nh p d li u (dãy kí t ) vào t bàn phím. NSD có thươ ẽ ạ ừ ờ ậ ữ ệ ự ừ ể nh p vào dãy v i đ dài b t kỳ cho đ n khi nh n Enter, ch ng trình s l y ra n-1 kí t đ uậ ớ ộ ấ ế ấ ươ ẽ ấ ự ầ tiên gán cho s, ph n còn l i v n đ c l u trong b đ m (k c kí t Enter) đ dùng cho l nầ ạ ẫ ượ ư ộ ệ ể ả ự ể ầ nh p sau. Hi n nhiên, sau khi gán các kí t cho s, ch ng trình s t đ ng đ t kí t k t thúcậ ể ự ươ ẽ ự ộ ặ ự ế xâu vào ô ti p theo c a xâu s.ế ủ

: Xét đo n l nh sau ạ ệ

char s[10] ;

cin.getline(s, 10) ;

cout << s << endl ;

cin.getline(s, 10) ;

cout << s << endl ;gi s ta nh p vào bàn phím dòng kí t : 1234567890abcd ¿. Khi đó l nh cin.getline(s,10) đ uả ử ậ ự ệ ầ tiên s gán xâu "123456789" (9 kí t ) cho s, ph n còn l i v n l u trong b đ m bàn phím.ẽ ự ầ ạ ẫ ư ộ ệ Ti p theo s đ c in ra màn hình. Đ n l nh cin.getline(s,10) th hai NSD không ph i nh pế ượ ế ệ ứ ả ậ thêm d li u, ch ng trình t đ ng l y n t s d li u còn l i (vì ch a đ 9 kí t ) "0abcd" đữ ệ ươ ự ộ ấ ố ố ữ ệ ạ ư ủ ự ể gán cho s. Sau đó in ra màn hình. Nh v y trên màn hình s xu t hi n hai dòng:ư ậ ẽ ấ ệ

Page 69: Giao Trinh C++ Toan Tap

123456789

0abcd

: Nh p m t ngày tháng d ng M (mm/dd/yy), đ i sang ngày tháng d ng Vi t Nam r i in raậ ộ ạ ỹ ổ ạ ệ ồ màn hình.

#include <iostream.h>

main()

{

char US[9], VN[9] = " / / " ; // kh i t o tr c hai d u /ở ạ ướ ấ

cin.getline(US, 9) ; // nh p ngày tháng, ví d "05/01/99"ậ ụ

VN[0] = US[3]; VN[1] = US[4] ; // ngày

VN[3] = US[0]; VN[4] = US[1] ; // tháng

VN[6] = US[6]; VN[7] = US[7] ; // năm

cout << VN << endl ;

}

M t s hàm x lí xâu (#include <string.h>)ộ ố ử

strcpy(s, t) ; Gán n i dung c a xâu t cho xâu s (thay cho phép gán = không đ c dùng). Hàm s sao chépộ ủ ượ ẽ toàn b n i dung c a xâu t (k c kí t k t thúc xâu) vào cho xâu s. Đ s d ng hàm này c nộ ộ ủ ể ả ự ế ể ử ụ ầ đ m b o đ dài c a m ng s ít nh t cũng b ng đ dài c a m ng t. Trong tr ng h p ng cả ả ộ ủ ả ấ ằ ộ ủ ả ườ ợ ượ l i kí t k t thúc xâu s không đ c ghi vào s và đi u này có th gây treo máy khi ch yạ ự ế ẽ ượ ề ể ạ ch ng trình.ươ

Ví d : ụ

char s[10], t[10] ;

t = "Face" ; // không đ c dùngượ

s = t ; // không đ c dùngượ

strcpy(t, "Face") ; // đ c, gán "Face" cho tượ

strcpy(s, t) ; // đ c, sao chép t sang sượ

cout << s << " to " << t ; // in ra: Face to Face

strncpy(s, t, n) ;Sao chép n kí t c a t vào s. Hàm này ch làm nhi m v sao chép, không t đ ng g n kí t k tự ủ ỉ ệ ụ ự ộ ắ ự ế thúc xâu cho s. Do v y NSD ph i thêm câu l nh đ t kí t '\0' vào cu i xâu s sau khi sao chépậ ả ệ ặ ự ố xong.

Ví d :ụ

Page 70: Giao Trinh C++ Toan Tap

char s[10], t[10] = "Steven";

strncpy(s, t, 5) ; // copy 5 kí t "Steve" vào sự

s[5] = '\0' ; // đ t d u k t thúc xâuặ ấ ế

// in câu: Steve is young brother of Steven

cout << s << " is young brother of " << t ;M t s d ng có ích c a hàm này là copy m t xâu con b t kỳ c a t và đ t vào s. Ví d c nộ ử ụ ủ ộ ấ ủ ặ ụ ầ copy xâu con dài 2 kí t b t đ u t kí t th 3 c a xâu t và đ t vào s, ta vi t ự ắ ầ ừ ự ứ ủ ặ ế strncpy(s, t+3, 2). Ngoài ra xâu con đ c copy có th đ c đ t vào v trí b t kỳ c a s (không nh t thi t ph i tượ ể ượ ặ ị ấ ủ ấ ế ả ừ đ u xâu s) ch ng h n đ t vào t v trí th 5, ta vi t: ầ ẳ ạ ặ ừ ị ứ ế strncpy(s+5, t+3, 2). Câu l nh này cóệ nghĩa: l y 2 kí t th 3 và th 4 c a xâu t đ t vào 2 ô th 5 và th 6 c a xâu s. Trên c s nàyấ ự ứ ứ ủ ặ ứ ứ ủ ơ ở chúng ta có th vi t các đo n ch ng trình ng n đ thay th m t đo n con b t kỳ nào đóể ế ạ ươ ắ ể ế ộ ạ ấ trong s b i m t đo n con b t kỳ (có đ dài t ng đ ng) trong t. Ví d các dòng l nh chuy nở ộ ạ ấ ộ ươ ươ ụ ệ ể đ i ngày tháng trong ví d tr c có th vi t l i b ng cách dùng hàm strncpy nh sau:ổ ụ ướ ể ế ạ ằ ư

strncpy(VN+0, US+3, 2) ; // ngày

strncpy(VN+3, US+0, 2) ; // tháng

strncpy(VN+6, US+6, 2); // năm

strcat(s, t);N i m t b n sao c a t vào sau s (thay cho phép +). Hi n nhiên hàm s lo i b kí t k t thúcố ộ ả ủ ể ẽ ạ ỏ ự ế xâu s tr c khi n i thêm t. Vi c n i s đ m b o l y c kí t k t thúc c a xâu t vào cho sướ ố ệ ố ẽ ả ả ấ ả ự ế ủ (n u s đ ch ) vì v y NSD không c n thêm kí t này vào cu i xâu. Tuy nhiên, hàm khôngế ủ ỗ ậ ầ ự ố ki m tra xem li u đ dài c a s có đ ch đ n i thêm n i dung, vi c ki m tra này ph i doể ệ ộ ủ ủ ỗ ể ố ộ ệ ể ả NSD đ m nhi m. Ví d :ả ệ ụ

char a[100] = "M n", b[4] = "tôi";ẫ

strcat(a, “ và ”);

strcat(a, b);

cout << a // M n và tôiẫ

char s[100] , t[100] = "Steve" ;

strncpy(s, t, 3); s[3] = '\0'; // s = "Ste"

strcat(s, "p"); // s = "Step"

cout << t << " goes "<< s << " by " <<s // Steve goes Step by Step

strncat(s, t, n);N i b n sao n kí t đ u tiên c a xâu t vào sau xâu s. Hàm t đ ng đ t thêm d u k t thúc xâuố ả ự ầ ủ ự ộ ặ ấ ế vào s sau khi n i xong (t ng ph n v i strncpy()). Cũng gi ng strcat hàm đòi h i đ dài c a số ươ ả ớ ố ỏ ộ ủ ph i đ ch a k t qu . T ng t , có th s d ng cách vi t ả ủ ứ ế ả ươ ự ể ử ụ ế strncat(s, t+k, n) đ n i n kí t tể ố ự ừ v trí th k c a xâu t cho s.ị ứ ủ

Page 71: Giao Trinh C++ Toan Tap

Ví d :ụ

char s[20] = "Nhà " ;

char t[] = "vua chúa"

strncat(s, t, 3) ; // s = "Nhà vua"

ho c: ặ

strncat(s, t+4, 4) ; // s = "Nhà chúa"

strcmp(s, t); Hàm so sánh 2 xâu s và t (thay cho các phép toán so sánh). Giá tr tr l i là hi u 2 kí t khácị ả ạ ệ ự nhau đ u tiên c a s và t. T đó, n u s1 < s2 thì hàm tr l i giá tr âm, b ng 0 n u s1==s2, vàầ ủ ừ ế ả ạ ị ằ ế dương n u s1 > s2. Trong tr ng h p ch quan tâm đ n so sánh b ng, n u hàm tr l i giá tr 0ế ườ ợ ỉ ế ằ ế ả ạ ị là 2 xâu b ng nhau và n u giá tr tr l i khác 0 là 2 xâu khác nhau.ằ ế ị ả ạ

Ví d :ụ

if (strcmp(s,t)) cout << "s khác t"; else cout << "s b ng t" ; ằ

strncmp(s, t) ;Gi ng hàm strcmp(s, t) nh ng ch so sánh t i đa n kí t đ u tiên c a hai xâu.ố ư ỉ ố ự ầ ủ

Ví d :ụ

char s[] = "Hà N i" , t[] = "Hà n i" ;ộ ộ

cout << strcmp(s,t) ; // -32 (vì 'N' = 78, 'n' = 110)

cout << strncmp(s, t, 3) ; // 0 (vì 3 kí t đ u c a s và t là nh nhau)ự ầ ủ ư

strcmpi(s, t) ; Như strcmp(s, t) nhưng không phân bi t ch hoa, thệ ữ ư ng. ờ

Ví d :ụ

char s[] = "Hà N i" , t[] = "hà n i" ;ộ ộ

cout << strcmpi(s, t) ; // 0 (vì s = t)

strupr(s); Hàm đ i xâu s thành in hoa, và cũng tr l i xâu in hoa đó.ổ ả ạ

Ví d :ụ

char s[10] = "Ha noi" ;

cout << strupr(s) ; // HA NOI

cout << s ; // HA NOI (s cũng thành in hoa)

strlwr(s);

Page 72: Giao Trinh C++ Toan Tap

Hàm đ i xâu s thành in thu ng, k t qu tr l i là xâu s.ổ ờ ế ả ả ạ

Ví d :ụ

char s[10] = "Ha Noi" ;

cout << strlwr(s) ; // ha noi

cout << s ; // ha noi (s cũng thành in th ng)ườ

strlen(s) ; Hàm tr giá tr là ả ị đ dài c a xâu s. ộ ủ

Ví d :ụ

char s[10] = "Ha Noi" ;

cout << strlen(s) ; // 5

Sau đây là m t s ví d s d ng t ng h p các hàm trên.ộ ố ụ ử ụ ổ ợ

: Th ng kê s ch 'a' xu t hi n trong xâu s. ố ố ữ ấ ệ

main()

{

const int MAX = 100;

char s[MAX+1];

int sokitu = 0;

cin.getline(s, MAX+1);

for (int i=0; i < strlen(s); i++) if (s[i] = 'a ') sokitu++;

cout << "S kí t = " << sokitu << endl ;ố ự

}

: Tính đ dài xâu b ng cách đ m t ng kí t (t ng đ ng v i hàm strlen())ộ ằ ế ừ ự ươ ươ ớ

main()

{

char s[100]; // đ dài t i đa là 99 kí tộ ố ự

cin.getline(s, 100); // nh p xâu sậ

for (int i=0 ; s[i] != '\0' ; i++) ; // ch y t đ u đ n cu i xâuạ ừ ầ ế ố

cout << "Đ dài xâu = " << i ;ộ

}

: Sao chép xâu s sang xâu t (t ng đ ng v i hàm strcpy(t,s))ươ ươ ớ

Page 73: Giao Trinh C++ Toan Tap

void main()

{

char s[100], t[100];

cin.getline(s, 100); // nh p xâu sậ

int i=0;

while ((t[i] = s[i]) != '\0') i++; // copy c d u k t thúc xâu '\0'ả ấ ế

cout << t << endl ;

}

: C t d u cách 2 đ u c a xâu s. Ch ng trình s d ng bi n i ch y t đ u xâu đ n v trí đ uắ ấ ầ ủ ươ ử ụ ế ạ ừ ầ ế ị ầ tiên có kí t khác d u tr ng. T v trí này sao chép t ng kí t còn l i c a xâu v đ u xâu b ngự ấ ắ ừ ị ừ ự ạ ủ ề ầ ằ cách s d ng thêm bi n j đ làm ch s cho xâu m i. K t thúc sao chép j s v trí cu i xâuử ụ ế ể ỉ ố ớ ế ẽ ở ị ố (m i). Cho j ch y ng c v đ u xâu cho đ n khi g p kí t đ u tiên khác d u tr ng. Đ t d uớ ạ ượ ề ầ ế ặ ự ầ ấ ắ ặ ấ k t thúc xâu t i đây. ế ạ

main()

{

char s[100];

cin.getline(s, 100); // nh p xâu sậ

int i, j ;

i = j = 0;

while (s[i++] == ' '); i-- ; // b qua các d u cách đ u tiênỏ ấ ầ

while (s[i] != '\0') s[j++] = s[i++] ; // sao chép ph n còn l i vào sầ ạ

while (s[--j] == ' ') ; // b qua các d u cách cu iỏ ấ ố

s[j+1] = '\0' ; // đ t d u k t thúc xâuặ ấ ế

cout << s ;

}

: Ch y dòng ch qu ng cáo vòng tròn t ph i sang trái gi a màn hình. ạ ữ ả ừ ả ữGi s hi n 30 kí t c a xâu qu ng cáo. Ta s d ng vòng l p. C t 30 kí t đ u tiên c a xâuả ử ệ ự ủ ả ử ụ ặ ắ ự ầ ủ cho vào bi n hien, hi n bi n này ra màn hình. B c l p ti p theo c t ra 30 kí t c a xâuế ệ ế ướ ặ ế ắ ự ủ nh ng d ch sang ph i 1 kí t cho vào bi n hien và hi n ra màn hình. Quá trình ti p t c, m iư ị ả ự ế ệ ế ụ ỗ b c l p ta d ch chuy n n i dung c n hi n ra màn hình 1 kí t , do hi u ng c a m t ta th yướ ặ ị ể ộ ầ ệ ự ệ ứ ủ ắ ấ dòng ch s ch y t biên ph i v biên trái c a màn hình. Đ quá trình ch y theo vòng trònữ ẽ ạ ừ ả ề ủ ể ạ (khi hi n đ n kí t cu i c a xâu s hi n quay l i t kí t đ u c a xâu) ch ng trình s d ngệ ế ự ố ủ ẽ ệ ạ ừ ự ầ ủ ươ ử ụ bi n i đánh d u đi m đ u c a xâu con c n c t cho vào hien, khi i b ng đ dài c a xâuế ấ ể ầ ủ ầ ắ ằ ộ ủ

Page 74: Giao Trinh C++ Toan Tap

ch ng trình đ t l i i = 0 (c t l i t đ u xâu). Ngoài ra, đ ph n cu i xâu n i v i ph n đ uươ ặ ạ ắ ạ ừ ầ ể ầ ố ố ớ ầ ầ (t o thành vòng tròn) ngay t đ u ch ng trình, xâu qu ng cáo s đ c n i thành g p đôi.ạ ừ ầ ươ ả ẽ ượ ố ấ

Vòng l p ti p t c đ n khi nào NSD n phím b t kỳ (ch ng trình nh n bi t đi u này nh vàoặ ế ụ ế ấ ấ ươ ậ ế ề ờ hàm kbhit() thu c file nguyên m u conio.h) thì d ng. Đ dòng ch ch y không quá nhanhộ ẫ ừ ể ữ ạ ch ng trình s d ng hàm tr delay(n) (thu c dos.h, t m d ng trong n ph n nghìn giây) v i nươ ử ụ ễ ộ ạ ừ ầ ớ đ c đi u ch nh thích h p theo t c đ c a máy. Hàm gotoxy(x, y) (thu c conio.h) trongượ ề ỉ ợ ố ộ ủ ộ ch ng trình đ t con tr màn hình t i v trí c t x dòng y đ đ m b o dòng ch luôn luôn hi nươ ặ ỏ ạ ị ộ ể ả ả ữ ệ ra t i đúng m t v trí trên màn hình.ạ ộ ị

#include <iostream.h>

#include <conio.h>

#include <dos.h>

main()

{

char qc[100] = "Qu ng cáo mi n phí: Không có ti n thì không có kem. ";ả ễ ề

int dd = strlen(qc);

char tam[100] ; strcpy(tam, qc) ;

strcat(qc, tam) ; // nhân đôi dòng qu ng cáoả

clrscr(); // xoá màn hình

char hien[31] ; // ch a xâu dài 30 kí t đ hi nứ ự ể ệ

i = 0;

while (!kbhit()) { // trong khi ch a n phím b t kỳư ấ ấ

strncpy(hien, s+i, 30);

hien[30] = '\0'; // copy 30 kí t t qc[i] sang hienự ừ

gotoxy(20,10); cout << hien ; // in hien t i dòng 10 cot 20ạ

delay(100); // t m d ng 1/10 giâyạ ừ

i++; if (i==dd) i = 0; // tăng i

}

}

: Nh p m t kh u (không quá 10 kí t ). In ra "đúng" n u là "HaNoi2000", "sai" n u ng c l i.ậ ậ ẩ ự ế ế ượ ạ Ch ng trình cho phép nh p t i đa 3 l n. Nh p riêng r t ng kí t (b ng hàm getch()) choươ ậ ố ầ ậ ẽ ừ ự ằ m t kh u. Hàm getch() không hi n kí t NSD gõ vào, thay vào đó ch ng trình ch hi n kí tậ ẩ ệ ự ươ ỉ ệ ự 'X' đ che gi u m t kh u. Sau khi NSD đã gõ xong (9 kí t ) ho c đã Enter, ch ng trình soể ấ ậ ẩ ự ặ ươ sánh xâu v a nh p v i "HaNoi2000", n u đúng ch ng trình ti p tuc, n u sai tăng s l nừ ậ ớ ế ươ ế ế ố ầ nh p (cho phép không quá 3 l n).ậ ầ

#include <iostream.h>

Page 75: Giao Trinh C++ Toan Tap

#include <conio.h>

#include <string.h>

void main()

{

char pw[11]; int solan = 0; // Cho phep nhap 3 lan

do {

clrscr(); gotoxy(30,12) ;

int i = 0;

while ((pw[i]=getch()) != 13 && ++i < 10) cout << 'X' ; // 13 = Enter

pw[i] = '\0' ;

cout << endl ;

if (!strcmp(pw, "HaNoi2000")) { cout << "M i vào" ; break; }ờ

else { cout << "Sai m t kh u. Nh p l i") ; solan++ ; }ậ ẩ ậ ạ

} while (solan < 3);

}

M NG HAI CHI UẢ Ề

Đ thu n ti n trong vi c bi u di n các lo i d li u ph c t p nh ma tr n ho c các b ngể ậ ệ ệ ể ễ ạ ữ ệ ứ ạ ư ậ ặ ả bi u có nhi u ch tiêu, C++ đ a ra ki u d li u m ng nhi u chi u. Tuy nhiên, vi c s d ngể ề ỉ ư ể ữ ệ ả ề ề ệ ử ụ m ng nhi u chi u r t khó l p trình vì v y trong m c này chúng ta ch bàn đ n m ng haiả ề ề ấ ậ ậ ụ ỉ ế ả chi u. Đ i v i m ng m t chi u m thành ph n, n u m i thành ph n c a nó l i là m ng m tề ố ớ ả ộ ề ầ ế ỗ ầ ủ ạ ả ộ chi u n ph n t thì ta g i m ng là hai chi u v i s ph n t (hay kích th c) m i chi u là mề ầ ử ọ ả ề ớ ố ầ ử ướ ỗ ề và n. Ma tr n là m t minh ho cho hình nh c a m ng hai chi u, nó g m m dòng và n c t, t cậ ộ ạ ả ủ ả ề ồ ộ ứ ch a m x n ph n t , và hi n nhiên các ph n t này có cùng ki u. Tuy nhiên, v m t b n ch tứ ầ ử ể ầ ử ể ề ặ ả ấ m ng hai chi u không ph i là m t t p h p v i m x n ph n t cùng ki u mà là t p h p v i mả ề ả ộ ậ ợ ớ ầ ử ể ậ ợ ớ thành ph n, trong đó m i thành ph n là m t m ng m t chi u v i n ph n t . Đi m nh nầ ỗ ầ ộ ả ộ ề ớ ầ ử ể ấ m nh này s đ c gi i thích c th h n trong các ph n trình bày v con tr c a ch ng sau. ạ ẽ ượ ả ụ ể ơ ầ ề ỏ ủ ươ

0 1 2 3

0

1

2

Hình trên minh ho hình th c m t m ng hai chi u v i 3 dòng, 4 c t. Th c ch t trong b nhạ ứ ộ ả ề ớ ộ ự ấ ộ ớ t t c 12 ph n t c a m ng đ c s p liên ti p theo t ng dòng c a m ng nh minh ho trongấ ả ầ ử ủ ả ượ ắ ế ừ ủ ả ư ạ hình d i đây.ướ

Page 76: Giao Trinh C++ Toan Tap

dòng 0 dòng 1 dòng 2

Khai báo<ki u thành ph n > <tên m ng>[m][n] ;ể ầ ả

m, n là s hàng, s c t c a m ng.ố ố ộ ủ ả

ki u thành ph n là ki u c a m x n ph n t trong m ng.ể ầ ể ủ ầ ử ả

Trong khai báo cũng có th đ c kh i t o b ng dãy các dòng giá tr , các dòng cách nhauể ượ ở ạ ằ ị b i d u ph y, m i dòng đ c bao b i c p ngo c {} và toàn b giá tr kh i t o n mở ấ ẩ ỗ ượ ở ặ ặ ộ ị ở ạ ằ trong c p d u {}.ặ ấ

S d ngử ụ

T ng t m ng m t chi u các chi u trong m ng cũng đ c đánh s t 0.ươ ự ả ộ ề ề ả ượ ố ừ

Không s d ng các thao tác trên toàn b m ng mà ph i th c hi n thông qua t ng ph nử ụ ộ ả ả ự ệ ừ ầ t c a m ng.ử ủ ả

Đ truy nh p ph n t c a m ng ta s d ng tên m ng kèm theo 2 ch s ch v trí hàngể ậ ầ ử ủ ả ử ụ ả ỉ ố ỉ ị và c t c a ph n t . Các ch s này có th là các bi u th c th c, khi đó C++ s tộ ủ ầ ử ỉ ố ể ể ứ ự ẽ ự chuy n ki u sang nguyên.ể ể

Ví d :ụ

Khai báo 2 ma tr n 4 hàng 5 c t A, B ch a các s nguyên:ậ ộ ứ ốint A[3][4], B[3][4] ;

Khai báo có kh i t o: ở ạint A[3][4] = { {1,2,3,4}, {3,2,1,4}, {0,1,1,0} };

v i kh i t o này ta có ma tr n: ớ ở ạ ậ

1 2 3 4

3 2 1 4

0 1 1 0trong đó: A[0][0] = 1, A[0][1] = 2, A[1][0] = 3, A[2][3] = 0 …

Trong khai báo có th v ng s hàng (không đ c v ng s c t), s hàng này đ c xácể ắ ố ượ ắ ố ộ ố ượ đ nh thông qua kh i t o.ị ở ạ

float A[][3] = { {1,2,3}, {0,1,0} } ;

Page 77: Giao Trinh C++ Toan Tap

trong khai báo này ch ng trình t đ ng xác đ nh s hàng là 2.ươ ự ộ ị ố

Phép khai báo và kh i t o sau đây là cũng h p l : ở ạ ợ ệfloat A[][3] = { {1,2}, {0} } ;

ch ng trình cũng xác đ nh s hàng là 2 và s c t (b t bu c ph i khai báo) là 3 m c dù trongươ ị ố ố ộ ắ ộ ả ặ kh i t o không th xác đ nh đ c s c t. Các ph n t ch a kh i t o s ch a đ c xác đ nhở ạ ể ị ượ ố ộ ầ ử ư ở ạ ẽ ư ượ ị cho đ n khi nào nó đ c nh p ho c gán giá tr c th . Trong ví d trên các ph n t A[0][2],ế ượ ậ ặ ị ụ ể ụ ầ ử A[1][1] và A[1][2] là ch a đ c xác đ nh.ư ượ ị

Ví d minh hoụ ạ

: Nh p, in và tìm ph n t l n nh t c a m t ma tr n.ậ ầ ử ớ ấ ủ ộ ậ

#include <iostream.h>

#include <iomanip.h>

#include <conio.h>

main()

{

float a[10][10] ;

int m, n ; // s hàng, c t c a ma tr nố ộ ủ ậ

int i, j ; // các ch s trong vòng l pỉ ố ặ

int amax, imax, jmax ; // s l n nh t và ch s c a nóố ớ ấ ỉ ố ủ

clrscr(); cout << "Nh p s hàng và c t: " ; cin >> m >> n ;ậ ố ộ

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

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

{

cout << "a[" << i << "," << j << "] = " ; cin >> a[i][j] ;

}

amax = a[0][0]; imax = 0; jmax = 0;

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

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

if (amax < a[i][j])

{

amax = a[i][j]; imax = i; jmax = j;

}

cout << "Ma tr n đã nh p\n" ;ậ ậ

Page 78: Giao Trinh C++ Toan Tap

cout << setiosflags(ios::showpoint) << setprecision(1) ;

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

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

{

if (j==0) cout << endl;

cout << setw(6) << a[i][j] ;

}

cout << "S l n nh t là " << setw(6) << amax << endl;ố ớ ấ

cout << "t i v trí (" << imax << "," << jmax << ")" ;ạ ị

getch();

}Ghi chú: Khi làm vi c v i m ng (1 chi u, 2 chi u) do thói quen chúng ta th ng tính ch s tệ ớ ả ề ề ườ ỉ ố ừ 1 (thay vì 0), do v y trong m ng ta có th b qua hàng 0, c t 0 b ng cách khai báo s hàng vàậ ả ể ỏ ộ ằ ố c t tăng lên 1 so v i s hàng, c t th c t c a m ng và t đó có th làm vi c t hàng 1, c t 1ộ ớ ố ộ ự ế ủ ả ừ ể ệ ừ ộ tr đi.ở

: Nhân 2 ma tr n. Cho 2 ma tr n A (m x n) và B (n x p). Tính ma tr n C = A x B, trong đó C cóậ ậ ậ kích th c là m x p. Ta l p vòng l p tính t ng ph n t c a C. Giá tr c a ph n t C t i hàng i,ướ ậ ặ ừ ầ ử ủ ị ủ ầ ử ạ c t j chính là tích vô h ng c a hàng i ma tr n A v i c t j ma tr n B. Đ tránh nh m l n taộ ướ ủ ậ ớ ộ ậ ể ầ ẫ qui c b các hàng, c t 0 c a các ma tr n A, B, C (t c các ch s đ c tính t 1 tr đi).ướ ỏ ộ ủ ậ ứ ỉ ố ượ ừ ở

#include <iostream.h>

#include <iomanip.h>

#include <conio.h>

main()

{

float A[10][10], B[10], C[10][10] ;

int m, n, p ; // s hàng, c t c a ma tr nố ộ ủ ậ

int i, j, k ; // các ch s trong vòng l pỉ ố ặ

clrscr();

cout << "Nh p s hàng và c t c a 2 ma tr n: " ; cin >> m >> n >> p;ậ ố ộ ủ ậ

// Nh p ma tr n Aậ ậ

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

for (j=1; j<=n; j++)

{

cout << "A[" << i << "," << j << "] = " ; cin >> A[i][j] ;

Page 79: Giao Trinh C++ Toan Tap

}

// Nh p ma tr n Bậ ậ

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

for (j=1; j<=p; j++)

{

cout << "B[" << i << "," << j << "] = " ; cin >> B[i][j] ;

}

// Tính ma tr n C = A x Bậ

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

for (j=1; j<=p; j++)

{

C[i][j] = 0; for (k=1; k<=n; k++) C[i][j] += A[i][k]*B[k][j] ;

}

// In k t quế ả

cout << "Ma tr n k t qu \n" ;ậ ế ả

cout << setiosflags(ios::showpoint) << setprecision(2) ;

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

for (j=1; j<n; j++)

{

if (j==1) cout << endl;

cout << setw(6) << a[i][j] ;

}

getch();

}

BÀI T PẬ

L nh r nhánhệ ẽ

Nh p m t kí t . Cho bi t kí t ậ ộ ự ế ự đó có ph i là ch cái hay không.ả ữ

Nh p vào m t s nguyên. Tr l i s nguyên ậ ộ ố ả ờ ố đó: âm hay dương, ch n hay l ?ẵ ẻ

Cho n = x = y và b ng: ằ a. 1 b. 2 c. 3 d. 4Hãy cho bi t giá tr c a x, y sau khi ch y xong câu l nh: ế ị ủ ạ ệ

if (n % 2 == 0) if (x > 3) x = 0;

Page 80: Giao Trinh C++ Toan Tap

else y = 0;

Tính giá tr hàm ị

≤+>+=

04

03

x,e

x,xx)x(f

x

−≤−+<<−+

≥+=

112

1153

11

2

2

x,xx

x,x

x,x

)x(f

Vi t chế ương trình gi i h phả ệ ương trình b c nh t 2 n: ậ ấ ẩ

=+=+

feydx

cbyax

Nh p 2 s a, b. In ra max, min c a 2 s ậ ố ủ ố đó. M r ng v i 3 s , 4 s ?ở ộ ớ ố ố

Nh p 3 s a, b, c. Hãy cho bi t 3 s trên có th là ậ ố ế ố ể đ dài 3 c nh c a m t tam giác ? N u làộ ạ ủ ộ ế m t tam giác thì ộ đó là tam giác gì: vuông, đ u, cân, vuông cân hay tam giác thề ư ng ?ờ

Nh p vào m t s , in ra th tậ ộ ố ứ ương ng v i s ứ ớ ố đó (qui ư c 2 là th hai, …, 8 là ch nh t).ớ ứ ủ ậ

Nh p 2 s bi u th tháng và nậ ố ể ị ăm. In ra s ngày c a tháng nố ủ ăm đó (có ki m tra nể ăm nhu n). ậ

L y ngày tháng hi n t i làm chu n. Hãy nh p m t ngày b t kỳ trong tháng. Cho bi t th c aấ ệ ạ ẩ ậ ộ ấ ế ứ ủ ngày v a nh p ?ừ ậ

L nh l pệ ặ

Giá tr c a i b ng bao nhiêu sau khi th c hi n c u trúc for sau: ị ủ ằ ự ệ ấfor (i = 0; i < 100; i++);

Giá tr c a x b ng bao nhiêu sau khi th c hi n c u trúc for sau: ị ủ ằ ự ệ ấfor (x = 2; i < 10; x+=3) ;

B n b sung gì vào l nh for sau: ạ ổ ệfor ( ; nam < 1997 ; ) ;

đ khi k t thúc nam có giá tr 2000.ể ế ị

Bao nhiêu kí t ‘X’ ự đư c in ra màn hình khi th c hi n ợ ự ệ đo n chạ ương trình sau:for (x = 0; x < 10; x ++) for (y = 5; y > 0; y --) cout << ‘X’;

Nh p vào tu i cha và tu i con hi n nay sao cho tu i cha l n hậ ổ ổ ệ ổ ớ ơn 2 l n tu i con. Tìm xem baoầ ổ nhiêu năm n a tu i cha s b ng ữ ổ ẽ ằ đúng 2 l n tu i con (ví d 30 và 12, sau 6 nầ ổ ụ ăm n a tu iữ ổ cha là 36 g p ấ đôi tu i con là 18).ổ

Nh p s nguyên dậ ố ương N. Tính:

Page 81: Giao Trinh C++ Toan Tap

N

N...S

++++= 3211

22222 321 N...S ++++=

Nh p s nguyên dậ ố ương n. Tính:

33331 ++++= ...S n d u cănấ

2

12

12

12

12

...

S

++

+=

n d u chiaấ

Nh p s t nhiên n. In ra màn hình bi u di n c a n d ng nh phân.ậ ố ự ể ễ ủ ở ạ ị

In ra màn hình các s có 2 ch s sao cho tích c a 2 ch s này b ng 2 l n t ng c a 2 ch số ữ ố ủ ữ ố ằ ầ ổ ủ ữ ố đó (ví d s 36 có tích 3*6 = 18 g p 2 l n t ng c a nó là 3 + 6 = 9).ụ ố ấ ầ ổ ủ

S ố hoàn ch nhỉ là s b ng t ng m i ố ằ ổ ọ ư c c a nó (không k chính nó). Ví d 6 = 1 + 2 + 3 làớ ủ ể ụ m t s hoàn ch nh. Hãy in ra màn hình t t c các s hoàn ch nh < 1000.ộ ố ỉ ấ ả ố ỉ

Các s ố sinh đôi là các s nguyên t mà kho ng cách gi a chúng là 2. Hãy in t t c c p s sinhố ố ả ữ ấ ả ặ ố đôi < 1000.

Nh p dãy kí t ậ ự đ n khi g p kí t ‘.’ thì d ng. Th ng kê s ch cái vi t hoa, vi t thế ặ ự ừ ố ố ữ ế ế ư ng, sờ ố ch s và t ng s các kí t khác đã nh p. Lo i kí t nào nhi u nh t ?ữ ố ổ ố ự ậ ạ ự ề ấ

Tìm s nguyên dố ương n l n nh t tho mãn ớ ấ ả đi u ki n:ề ệ

101999212

1

5

1

3

11 .

n... <

−++++

.

20001999 10 <− nlogen

.

Cho e = 1e-6. Tính g n ầ đúng các s sau:ố

S pi theo công th c Euler: ố ứ2222

2 1

3

1

2

1

1

1

6 n... ++++=π

d ng l p khi ừ ặ

62

101 −<n .

ex theo công th c: ứ !n

x...

!

x

!

xe

nx ++++=

211

21

d ng l p khi ừ ặ

610−<!n

xn

.

)!n(

x)(...

!

x

!

xxxsin

nn

121

53

1253

+−+++−=

+

, d ng l p khi ừ ặ

612

1012

−+

<+ )!n(

x n

.

Page 82: Giao Trinh C++ Toan Tap

)a(a 0> theo công th c: ứ

>+=

=−− 02

0

12

1 ns/)as(

nas

nnn

, d ng khiừ 6

1 10−− <− nn ss

.

In ra mã c a phím b t kỳ ủ ấ đư c nh n. Chợ ấ ương trình l p cho ặ đ n khi nh n ESC ế ấ đ thoát.ể

B ng phằ ương pháp chia đôi, hãy tìm nghi m x p x (ệ ấ ỉ đ chính xác 10ộ -6) c a các phủ ương trình sau:

ex - 1.5 = 0, trên đo n [0, 1]. ạ

x2x - 1 = 0, trên đo n [0, 1].ạ

a0xn + a1xn-1 + ... + an = 0, trên đo n [a, b]. Các s th c aạ ố ự i, a, b đư c nh p t bàn phím saoợ ậ ừ cho f(a) và f(b) trái d u.ấ

M ngả

Nh p vào dãy n s th c. Tính t ng dãy, trung bình dãy, t ng các s âm, dậ ố ự ổ ổ ố ương và t ng các sổ ố v trí ch n, v trí l trong dãy. Tìm ph n t g n s trung bình nh t c a dãy.ở ị ẵ ị ẻ ầ ử ầ ố ấ ủ

Tìm và ch ra v trí xu t hi n ỉ ị ấ ệ đ u tiên c a ph n t x trong dãy.ầ ủ ầ ử

Nh p vào dãy n s . Hãy in ra s l n nh t, bé nh t c a dãy.ậ ố ố ớ ấ ấ ủ

Nh p vào dãy s . In ra dãy ậ ố đã đư c s p x p tợ ắ ế ăng d n, gi m d n.ầ ả ầ

Cho dãy đã đư c s p tợ ắ ăng d n. Chèn thêm vào dãy ph n t x sao cho dãy v n s p x p tầ ầ ử ẫ ắ ế ăng d n.ầ

Hãy nh p vào 16 s nguyên. In ra thành 4 dòng, 4 c t.ậ ố ộ

Nh p ma tr n A và in ra ma tr n ậ ậ ậ đ i x ng c a nó.ố ứ ủ

Cho m t ma tr n nguyên kích thộ ậ ư c m*n. Tính:ớ

T ng t t c các ph n t c a ma tr n.ổ ấ ả ầ ử ủ ậ

T ng t t c các ph n t dổ ấ ả ầ ử ương c a ma tr n.ủ ậ

T ng t t c các ph n t âm c a ma tr n.ổ ấ ả ầ ử ủ ậ

T ng t t c các ph n t ch n c a ma tr n.ổ ấ ả ầ ử ẵ ủ ậ

T ng t t c các ph n t l c a ma tr n.ổ ấ ả ầ ử ẻ ủ ậ

Cho m t ma tr n th c kích thộ ậ ự ư c m*n. Tìm:ớ

S nh nh t, l n nh t (kèm ch s ) c a ma tr n.ố ỏ ấ ớ ấ ỉ ố ủ ậ

S nh nh t, l n nh t (kèm ch s ) c a t ng hàng c a ma tr n.ố ỏ ấ ớ ấ ỉ ố ủ ừ ủ ậ

S nh nh t, l n nh t (kèm ch s ) c a t ng c t c a ma tr n.ố ỏ ấ ớ ấ ỉ ố ủ ừ ộ ủ ậ

S nh nh t, l n nh t (kèm ch s ) c a ố ỏ ấ ớ ấ ỉ ố ủ đư ng chéo chính c a ma tr n.ờ ủ ậ

S nh nh t, l n nh t (kèm ch s ) c a ố ỏ ấ ớ ấ ỉ ố ủ đư ng chéo ph c a ma tr n.ờ ụ ủ ậ

Nh p 2 ma tr n vuông c p n A và B. Tính A + B, A - B, A * B và Aậ ậ ấ 2 - B2.

Page 83: Giao Trinh C++ Toan Tap

Xâu kí t ự

Hãy nh p m t xâu kí t . In ra màn hình ậ ộ ự đ o ngả ư c c a xâu đó.ợ ủ

Nh p xâu. Th ng kê s các ch s '0', s ch s '1', …, s ch s '9' trong xâu.ậ ố ố ữ ố ố ữ ố ố ữ ố

In ra v trí kí t tr ng ị ự ắ đ u tiên t bên trái (ph i) m t xâu kí t .ầ ừ ả ộ ự

Nh p xâu. In ra t t các các v trí c a ch 'a' trong xâu và t ng s l n xuât hi n c a nó.ậ ấ ị ủ ữ ổ ố ầ ệ ủ

Nh p xâu. Tính s t có trong xâu. In m i dòng m t t .ậ ố ừ ỗ ộ ừ

Nh p xâu h tên, in ra h , tên dậ ọ ọ ư i d ng vi t hoa.ớ ạ ế

Thay kí t x trong xâu s b i kí t y (s, x, y ự ở ự đư c ợ đ c vào t bàn phím) ọ ừ

Xoá m i kí t x có trong xâu s (s, x ọ ự đư c ợ đ c vào t bàn phím). (G i ý: nên xoá ngọ ừ ợ ư c t cu iợ ừ ố xâu v ề đ u xâu).ầ

Nh p xâu. Không phân bi t vi t hoa hay vi t thậ ệ ế ế ư ng, hãy in ra các kí t có m t trong xâu vàờ ự ặ s l n xu t hi n c a nó (ví d xâu “Trach - Van ố ầ ấ ệ ủ ụ − Doanh” có ch a xu t hi n 3 l n, c(1),ữ ấ ệ ầ d(1), h(2), n(2), o(1), r(1), t(1), -(2), space(4)).

CH NG 4ƯƠ

HÀM VÀ CHƯ NG TRÌNHƠ

Con tr và s h c đ a ch ỏ ố ọ ị ỉHàmĐ quiệT ch c ch ng trình ổ ứ ươ

CON TR VÀ S H C Đ A CHỎ Ố Ọ Ị Ỉ

Tr c khi bàn v hàm và ch ng trình, trong ph n này chúng ta s nói v m t lo i bi n m iướ ề ươ ầ ẽ ề ộ ạ ế ớ g i là con tr , ý nghĩa, công d ng và s d ng nó nh th nào. Bi n con tr là m t đ c tr ngọ ỏ ụ ử ụ ư ế ế ỏ ộ ặ ư m nh c a C++, nó cho phép chúng ta thâm nh p tr c ti p vào b nh đ x lý các bài toánạ ủ ậ ự ế ộ ớ ể ử khó b ng ch vài câu l nh đ n gi n c a ch ng trình. Đi u này cũng góp ph n làm cho C++ằ ỉ ệ ơ ả ủ ươ ề ầ tr thành ngôn ng g n gũi v i các ngôn ng c p th p nh h p ng . Tuy nhiên, vì tính đ nở ữ ầ ớ ữ ấ ấ ư ợ ữ ơ gi n, ng n g n nên vi c s d ng con tr đòi h i tính c n th n cao và giàu kinh nghi m c aả ắ ọ ệ ử ụ ỏ ỏ ẩ ậ ệ ủ ng i l p trình. ườ ậ

Đ a ch , phép toán &ị ỉ

Page 84: Giao Trinh C++ Toan Tap

M i ch ng trình tr c khi ch y đ u ph i b trí các bi n do NSD khai báo vào đâu đó trongọ ươ ướ ạ ề ả ố ế b nh . Đ t o đi u ki n truy nh p d dàng tr l i các bi n này, b nh đ c đánh s , m iộ ớ ể ạ ề ệ ậ ễ ở ạ ế ộ ớ ượ ố ỗ byte s đ c ng v i m t s nguyên, đ c g i là đ a ch c a byte đó t 0 đ n h t b nh . Tẽ ượ ứ ớ ộ ố ượ ọ ị ỉ ủ ừ ế ế ộ ớ ừ đó, m i bi n (v i tên bi n) đ c g n v i m t s nguyên là đ a ch c a byte đ u tiên mà bi nỗ ế ớ ế ượ ắ ớ ộ ố ị ỉ ủ ầ ế đó đ c phân ph i. S l ng các byte phân ph i cho bi n là khác nhau (nh ng đ t li n nhauượ ố ố ượ ố ế ư ặ ề t th p đ n cao) tuỳ thu c ki u d li u c a bi n (và tuỳ thu c vào quan ni m c a t ngừ ấ ế ộ ể ữ ệ ủ ế ộ ệ ủ ừ NNLT), tuy nhiên ch c n bi t tên bi n ho c đ a ch c a bi n ta có th đ c/vi t d li u vào/raỉ ầ ế ế ặ ị ỉ ủ ế ể ọ ế ữ ệ các bi n đó. T đó ngoài vi c thông qua tên bi n chúng ta còn có th thông qua đ a ch c aế ừ ệ ế ể ị ỉ ủ chúng đ truy nh p vào n i dung. Tóm l i bi n, ô nh và đ a ch có quan h khăng khít v iể ậ ộ ạ ế ớ ị ỉ ệ ớ nhau. C++ cung c p m t toán t m t ngôi & đ l y đ a ch c a các bi n (ngo i tr bi n m ngấ ộ ử ộ ể ấ ị ỉ ủ ế ạ ừ ế ả và xâu kí t ). N u x là m t bi n thì &x là đ a ch c a x. T đó câu l nh sau cho ta bi t x đ cự ế ộ ế ị ỉ ủ ừ ệ ế ượ b trí đâu trong b nh :ố ở ộ ớ

int x ;

cout << &x ; // đ a ch s đ c hi n d i d ng c s 16. Ví d 0xfff4ị ỉ ẽ ượ ệ ướ ạ ơ ố ụĐ i v i bi n ki u m ng, thì tên m ng chính là đ a ch c a m ng, do đó không c n dùng đ nố ớ ế ể ả ả ị ỉ ủ ả ầ ế toán t &. Ví d đ a ch c a m ng a chính là a (không ph i &a). M t khác đ a ch c a m ng aử ụ ị ỉ ủ ả ả ặ ị ỉ ủ ả cũng chính là đ a ch c a byte đ u tiên mà m ng a chi m và nó cũng chính là đ a ch c a ph nị ỉ ủ ầ ả ế ị ỉ ủ ầ t đ u tiên c a m ng a. Do v y đ a ch c a m ng a là đ a ch c a ph n t a[0] t c &a[0]. Tómử ầ ủ ả ậ ị ỉ ủ ả ị ỉ ủ ầ ử ứ l i, đ a ch c a m ng a là a ho c &a[0].ạ ị ỉ ủ ả ặ

Tóm l i, c n nh :ạ ầ ớint x; // khai báo bi n nguyên xế

long y; // khai báo bi n nguyên dài yế

cout << &x << &y; // in đ a ch các bi n x, yị ỉ ế

char s[9]; // khai báo m ng kí t sả ự

cout << a; // in đ a ch m ng sị ỉ ả

cout << &a[0]; // in đ a ch m ng s (t c đ a ch s[0])ị ỉ ả ứ ị ỉ

cout << &a[2]; // in đ a ch kí t s[2]ị ỉ ự

Hình v sau đây minh ho m t vài bi n và đ a ch c a nó trong b nh .ẽ ạ ộ ế ị ỉ ủ ộ ớ

200

201

500

501

502

503

650

651

… … 658

1 2 4 3 2 1 H E L L O \0

Page 85: Giao Trinh C++ Toan Tap

x y s

Bi n x chi m 2 byte nh , có đ a ch là 200, bi n y có đ a ch là 500 và chi m 4 byteế ế ớ ị ỉ ế ị ỉ ế nh . Xâu s chi m 9 byte nh t i đ a ch 650. Các byte nh c a m t bi n là li n nhau. ớ ế ớ ạ ị ỉ ớ ủ ộ ế ề

Các phép toán liên quan đ n đ a ch đ c g i là s h c đ a ch . Tuy nhiên, chúng ta v n khôngế ị ỉ ượ ọ ố ọ ị ỉ ẫ đ c phép thao tác tr c ti p trên các đ a ch nh đ t bi n vào đ a ch này hay khác (công vi cượ ự ế ị ỉ ư ặ ế ị ỉ ệ này do ch ng trình d ch đ m nhi m), hay vi c c ng, tr hai đ a ch v i nhau là vô nghĩa …ươ ị ả ệ ệ ộ ừ ị ỉ ớ Các thao tác đ c phép trên đ a ch v n ph i thông qua các bi n trung gian ch a đ a ch , đ cượ ị ỉ ẫ ả ế ứ ị ỉ ượ g i là bi n con tr .ọ ế ỏ

Con trỏ

Ý nghĩa

Con tr là m t bi n ch a ỏ ộ ế ứ đ a ch c a bi n khác. N u p là con tr ch a đ a ch c a bi n xị ỉ ủ ế ế ỏ ứ ị ỉ ủ ế ta g i p tr t i x và x đ c tr b i p. Thông qua con tr ta có th làm vi c đ c v iọ ỏ ớ ượ ỏ ở ỏ ể ệ ượ ớ n i dung c a nh ng ô nh mà p tr đ n. ộ ủ ữ ớ ỏ ế

Đ con tr p tr t i x ta ph i gán đ a ch c a x cho p.ể ỏ ỏ ớ ả ị ỉ ủ

Đ làm vi c v i đ a ch c a các bi n c n ph i thông qua các bi n con tr tr đ n bi nể ệ ớ ị ỉ ủ ế ầ ả ế ỏ ỏ ế ế đó.

Khai báo bi n con trế ỏ<ki u ể đư c tr > <*tên bi n> ;ợ ỏ ế

Đ a ch c a m t bi n là đ a ch byte nh đ u tiên c a bi n đó. Vì v y đ l y đ c n i dungị ỉ ủ ộ ế ị ỉ ớ ầ ủ ế ậ ể ấ ượ ộ c a bi n, con tr ph i bi t đ c s byte c a bi n, t c ki u c a bi n mà con tr s tr t i.ủ ế ỏ ả ế ượ ố ủ ế ứ ể ủ ế ỏ ẽ ỏ ớ Ki u này cũng đ c g i là ki u c a con tr . Nh v y khai báo bi n con tr cũng gi ng nhể ượ ọ ể ủ ỏ ư ậ ế ỏ ố ư khai báo m t bi n th ng ngo i tr c n thêm d u * tr c tên bi n (ho c sau tên ki u). Víộ ế ườ ạ ừ ầ ấ ướ ế ặ ể d : ụ

int *p ; // khai báo bi n p là bi n con tr tr đ n ki u d li u nguyên.ế ế ỏ ỏ ế ể ữ ệ

float *q, *r ; // hai con tr th c q và r.ỏ ự

S d ng con tr , phép toán *ử ụ ỏ

Đ con tr p tr đ n bi n x ta ph i dùng phép gán p = đ a ch c a x. ể ỏ ỏ ế ế ả ị ỉ ủ

N u x không ph i là m ng ta vi t: p = &x.ế ả ả ế

N u x là m ng ta vi t: p = x ho c p = &x[0].ế ả ế ặ

Không gán p cho m t h ng đ a ch c th . Ví d vi t p = 200 là sai.ộ ằ ị ỉ ụ ể ụ ế

Phép toán * cho phép l y n i dung n i p tr đ n, ví d đ gán n i dung n i p tr đ nấ ộ ơ ỏ ế ụ ể ộ ơ ỏ ế cho bi n f ta vi t f = *p.ế ế

& và * là 2 phép toán ng c nhau. C th n u p = &x thì x = *p. T đó n u p tr đ n xượ ụ ể ế ừ ế ỏ ế

Page 86: Giao Trinh C++ Toan Tap

thì b t kỳ n i nào xu t hi n x đ u có th thay đ c b i *p và ng c l i.ấ ơ ấ ệ ề ể ượ ở ượ ạ

:

int i, j ; // khai báo 2 bi n nguyên i, jế

int *p, *q ; // khai báo 2 con tr nguyên p, qỏ

p = &i; // cho p tr t i i ỏ ớ

q = &j; // cho q tr t i jỏ ớ

cout << &i ; // h i đ a ch bi n iỏ ị ỉ ế

cout << q ; // h i đ a ch bi n j (thông qua q)ỏ ị ỉ ế

i = 2; // gán i b ng 2ằ

*q = 5; // gán j b ng 5 (thông qua q)ằ

i++ ; cout << i ; // tăng i và h i i, i = 3ỏ

(*q)++ ; cout << j ; // tăng j (thông qua q) và h i j, j = 6ỏ

(*p) = (*q) * 2 + 1; // gán l i i (thông qua p)ạ

cout << i ; // 13 Qua ví d trên ta th y m i thao tác v i i là t ng đ ng v i *p, v i j là t ng đ ng v i *qụ ấ ọ ớ ươ ươ ớ ớ ươ ươ ớ và ng c l i.ượ ạ

Các phép toán v i con trớ ỏTrên đây ta đã trình bày v 2 phép toán m t ngôi liên quan đ n đ a ch và con tr là & và *.ề ộ ế ị ỉ ỏ Ph n này chúng ta ti p t c xét v i các phép toán khác làm vi c v i con tr . ầ ế ụ ớ ệ ớ ỏ

Phép toán gán

Gán con tr v i đ a ch m t bi n: p = &x ;ỏ ớ ị ỉ ộ ế

Gán con tr v i con tr khác: p = q ; (sau phép toán gán này p, q ch a cùng m t đ a ch ,ỏ ớ ỏ ứ ộ ị ỉ cùng tr đ n m t n i).ỏ ế ộ ơ

:

int i = 10 ; // khai báo và kh i t o bi n i = 10ở ạ ế

int *p, *q, *r ; // khai báo 3 con tr nguyên p, q, rỏ

p = q = r = &i ; // cùng tr t i iỏ ớ

*p = q**q + 2**r + 1 ; // i = 10*10 + 2*10 + 1

cout << i ; // 121

Phép toán tăng gi m ả đ a chị ỉp ± n: con tr tr đ n thành ph n th n sau (tr c) p.ỏ ỏ ế ầ ứ ướ

Page 87: Giao Trinh C++ Toan Tap

M t ộ đơn v tị ăng gi m c a con tr b ng kích thả ủ ỏ ằ ư c c a bi n ớ ủ ế đư c tr . Ví d gi s p là conợ ỏ ụ ả ử tr nguyên (2 byte) đang tr đ n đ a ch 200 thì p+1 là con tr tr đ n đ a ch 202. T ng t , pỏ ỏ ế ị ỉ ỏ ỏ ế ị ỉ ươ ự + 5 là con tr tr đ n đ a ch 210. p - 3 ch a đ a ch 194. ỏ ỏ ế ị ỉ ứ ị ỉ

194 195 196 197 198 199 200 201 202203204205206207208209210211_p-3p-2p-1pp+1p+2p+4p+4p+5

p − 3

p p + 1

Nh v y, phép toán tăng, gi m con tr cho phép làm vi c thu n l i trên m ng. N u con trư ậ ả ỏ ệ ậ ợ ả ế ỏ đang tr đ n m ng (t c đang ch a đ a ch đ u tiên c a m ng), vi c tăng con tr lên 1 đ n vỏ ế ả ứ ứ ị ỉ ầ ủ ả ệ ỏ ơ ị s d ch chuy n con tr tr đ n ph n t th hai, … T đó ta có th cho con tr ch y t đ uẽ ị ể ỏ ỏ ế ầ ử ứ ừ ể ỏ ạ ừ ầ đ n cu i m ng b ng cách tăng con tr lên t ng đ n v nh trong câu l nh for d i đây.ế ố ả ằ ỏ ừ ơ ị ư ệ ướ

:

int a[100] = { 1, 2, 3, 4, 5, 6, 7 }, *p, *q;

p = a; cout << *p ; // cho p tr đ n m ng a, *p = a[0] = 1ỏ ế ả

p += 5; cout << *p ; // *p = a[5] = 6 ;

q = p - 4 ; cout << *q ; // q = a[1] = 2 ;

for (int i=0; i<100; i++) cout << *(p+i) ; // in toàn b m ng aộ ả

Phép toán t tăng gi mự ảp++, p--, ++p, --p: t ng t p+1 và p-1, có chú ý đ n tăng (gi m) tr c, sau.ươ ự ế ả ướ

: Ví d sau minh ho k t qu k t h p phép t tăng gi m v i l y giá tr n i con tr tr đ n. aụ ạ ế ả ế ợ ự ả ớ ấ ị ơ ỏ ỏ ế là m t m ng g m 2 s , p là con tr tr đ n m ng a. Các l nh d i đây đ c qui c là đ cộ ả ồ ố ỏ ỏ ế ả ệ ướ ượ ướ ộ l p v i nhau (t c l nh sau không b nh h ng b i l nh tr c, đ i v i m i l nh p luôn luônậ ớ ứ ệ ị ả ưở ở ệ ướ ố ớ ỗ ệ tr đ n ph n t đ u (a[0]) c a a.ỏ ế ầ ử ầ ủ

int a[2] = {3, 7}, *p = a;

(*p)++ ; // tăng (sau) giá tr n i p tr º tăng a[0] thành 4ị ơ ỏ

++(*p) ; // tăng (tr c) giá tr n i p tr º tăng a[0] thành 4ướ ị ơ ỏ

*(p++) ; // l y giá tr n i p tr (3) và tăng tr p (tăng sau), p ® a[1]ấ ị ơ ỏ ỏ

*(++p) ; // tăng tr p (tăng tr c), p ® a[1] và l y giá tr n i p tr (7) ỏ ướ ấ ị ơ ỏChú ý:

Phân bi t p+1 và p++ (ho c ++p):ệ ặ

Page 88: Giao Trinh C++ Toan Tap

p+1 đ c xem nh m t con tr khác v i p. p+1 tr đ n ph n t sau p.ượ ư ộ ỏ ớ ỏ ế ầ ử

p++ là con tr p nh ng tr đ n ph n t khác. p++ tr đ n ph n t đ ng sau ph n t pỏ ư ỏ ế ầ ử ỏ ế ầ ử ứ ầ ử tr đ n ban đ u.ỏ ế ầ

Phân bi t *(p++) và *(++p):ệCác phép toán t tăng gi m cũng là m t ngôi, m c u tiên c a chúng là cao h n các phép toánự ả ộ ứ ư ủ ơ hai ngôi khác và cao h n phép l y giá tr (*). C th :ơ ấ ị ụ ể

*p++ º *(p++)

*++p º *(++p)

++*p º ++(*p)Cũng gi ng các bi n nguyên vi c k t h p các phép toán này v i nhau r t d gây nh mố ế ệ ế ợ ớ ấ ễ ầ

l n, do v y c n s d ng c p d u ngo c đ qui đ nh trình t tính toán. ẫ ậ ầ ử ụ ặ ấ ặ ể ị ự

Hi u c a 2 con trệ ủ ỏPhép toán này ch th c hi n đ c khi p và q là 2 con tr cùng tr đ n các ph n t c a m t dãyỉ ự ệ ượ ỏ ỏ ế ầ ử ủ ộ d li u nào đó trong b nh (ví d cùng tr đ n 1 m ng d li u). Khi đó hi u p - q là sữ ệ ộ ớ ụ ỏ ế ả ữ ệ ệ ố thành ph n gi a p và q (chú ý p - q không ph i là hi u c a 2 đ a ch mà là s thành ph n gi aầ ữ ả ệ ủ ị ỉ ố ầ ữ p và q).

Ví d : gi s p và q là 2 con tr nguyên, p có đ a ch 200 và q có đ a ch 208. Khi đó p - q = -4ụ ả ử ỏ ị ỉ ị ỉ và q - p = 4 (4 là s thành ph n nguyên t đ a ch 200 đ n 208). ố ầ ừ ị ỉ ế

Phép toán so sánhCác phép toán so sánh cũng đ c áp d ng đ i v i con tr , th c ch t là so sánh gi a đ a chượ ụ ố ớ ỏ ự ấ ữ ị ỉ c a hai n i đ c tr b i các con tr này. Thông th ng các phép so sánh <, <=, >, >= ch ápủ ơ ượ ỏ ở ỏ ườ ỉ d ng cho hai con tr tr đ n ph n t c a cùng m t m ng d li u nào đó. Th c ch t c a phépụ ỏ ỏ ế ầ ử ủ ộ ả ữ ệ ự ấ ủ so sánh này chính là so sánh ch s c a 2 ph n t đ c tr b i 2 con tr đó.ỉ ố ủ ầ ử ượ ỏ ở ỏ

:

float a[100], *p, *q ;

p = a ; // p tr đ n m ng (t c p tr đ n a[0])ỏ ế ả ứ ỏ ế

q = &a[3] ; // q tr đ n ph n t th 3 (a[3]) c aỏ ế ầ ử ứ ủ m ngả

cout << (p < q) ; // 1

cout << (p + 3 == q) ; // 1

cout << (p > q - 1) ; // 0

cout << (p >= q - 2) ; // 0

for (p=a ; p < a+100; p++) cout << *p ; // in toàn b m ng aộ ả

C p phát ấ đ ng, toán t c p phát, thu h i new, deleteộ ử ấ ồ

Page 89: Giao Trinh C++ Toan Tap

Khi ti n hành ch y ch ng trình, ch ng trình d ch s b trí các ô nh c th cho các bi nế ạ ươ ươ ị ẽ ố ớ ụ ể ế đ c khai báo trong ch ng trình. V trí cũng nh s l ng các ô nh này t n t i và c đ nhượ ươ ị ư ố ượ ớ ồ ạ ố ị trong su t th i gian ch y ch ng trình, chúng xem nh đã b chi m d ng và s không đ cố ờ ạ ươ ư ị ế ụ ẽ ượ s d ng vào m c đích khác và ch đ c gi i phóng sau khi ch m d t ch ng trình. Vi c phânử ụ ụ ỉ ượ ả ấ ứ ươ ệ b b nh nh v y đ c g i là c p phát tĩnh (vì đ c c p s n tr c khi ch y ch ng trìnhổ ộ ớ ư ậ ượ ọ ấ ượ ấ ẵ ướ ạ ươ và không th thay đ i tăng, gi m kích th c ho c v trí trong su t quá trình ch y ch ngể ổ ả ướ ặ ị ố ạ ươ trình). Ví d n u ta khai báo m t m ng nguyên ch a 1000 s thì trong b nh s có m t vùngụ ế ộ ả ứ ố ộ ớ ẽ ộ nh liên t c 2000 bytes đ ch a d li u c a m ng này. Khi đó dù trong ch ng trình ta chớ ụ ể ứ ữ ệ ủ ả ươ ỉ nh p vào m ng và làm vi c v i m t vài s thì ph n m ng r i còn l i v n không đ c sậ ả ệ ớ ộ ố ầ ả ỗ ạ ẫ ượ ử d ng vào vi c khác. Đây là h n ch th nh t c a ki u m ng. m t h ng khác, m t l nụ ệ ạ ế ứ ấ ủ ể ả Ở ộ ướ ộ ầ nào đó ch y ch ng trình ta l i c n làm vi c v i h n 1000 s nguyên. Khi đó vùng nh màạ ươ ạ ầ ệ ớ ơ ố ớ ch ng trình d ch đã dành cho m ng là không đ đ s d ng. Đây chính là h n ch th haiươ ị ả ủ ể ử ụ ạ ế ứ c a m ng đ c khai báo tr c.ủ ả ượ ướ

Kh c ph c các h n ch trên c a ki u m ng, bây gi chúng ta s không khai báo (b trí) tr cắ ụ ạ ế ủ ể ả ờ ẽ ố ướ m ng d li u v i kích th c c đ nh nh v y. Kích th c c th s đ c c p phát trong quáả ữ ệ ớ ướ ố ị ư ậ ướ ụ ể ẽ ượ ấ trình ch y ch ng trình theo đúng yêu c u c a NSD. Nh v y chúng ta có đ s ô nh đ làmạ ươ ầ ủ ờ ậ ủ ố ớ ể vi c mà v n ti t ki m đ c b nh , và khi không dùng n a ta có th thu h i (còn g i là gi iệ ẫ ế ệ ượ ộ ớ ữ ể ồ ọ ả phóng) s ô nh này đ ch ng trình s d ng vào vi c khác. Hai công vi c c p phát và thuố ớ ể ươ ử ụ ệ ệ ấ h i này đ c th c hi n thông qua các toán t new, delete và con tr p. Thông qua p ta có thồ ượ ự ệ ử ỏ ể làm vi c v i b t kỳ đ a ch nào c a vùng đ c c p phát. Cách th c b trí b nh nh th nàyệ ớ ấ ị ỉ ủ ượ ấ ứ ố ộ ớ ư ế đ c g i là c p phát đ ng. Sau đây là cú pháp c a câu l nh new.ượ ọ ấ ộ ủ ệ

p = new <ki u> ;ể // c p phát 1 ph n tấ ầ ử

p = new <ki u>[n] ; ể // c p phát n ph n tấ ầ ử

Ví d : ụ

int *p ;

p = new int ; // c p phát vùng nh ch a đ c 1 s nguyên ấ ớ ứ ượ ố

p = float int[100] ; // c p phát vùng nh ch a đ c 100 s th cấ ớ ứ ượ ố ựKhi g p toán t new, ch ng trình s tìm trong b nh m t l ng ô nh còn r i và liênặ ử ươ ẽ ộ ớ ộ ượ ớ ỗ

t c v i s l ng đ theo yêu c u và cho p tr đ n đ a ch (byte đ u tiên) c a vùng nh này.ụ ớ ố ượ ủ ầ ỏ ế ị ỉ ầ ủ ớ N u không có vùng nh v i s l ng nh v y thì vi c c p phát là th t b i và p = NULLế ớ ớ ố ượ ư ậ ệ ấ ấ ạ (NULL là m t đ a ch r ng, không xác đ nh). Do v y ta có th ki m tra vi c c p phát có thànhộ ị ỉ ỗ ị ậ ể ể ệ ấ công hay không thông qua ki m tra con tr p b ng hay khác NULL. Ví d :ể ỏ ằ ụ

float *p ;

int n ;

cout << "S l ng c n c p phát = "; cin >> n;ố ượ ầ ấ

p = new double[n];

if (p == NULL) {

Page 90: Giao Trinh C++ Toan Tap

cout << "Không đ b nh " ; ủ ộ ớ

exit(0) ;

} Ghi chú: l nh exit(0) cho phép thoát kh i ch ng trình, đ s d ng l nh này c n khaiệ ỏ ươ ể ử ụ ệ ầ

báo file tiêu đ <process.h>.ềĐ gi i phóng b nh đã c p phát cho m t bi n (khi không c n s d ng n a) ta sể ả ộ ớ ấ ộ ế ầ ử ụ ữ ử

d ng câu l nh delete.ụ ệdelete p ; // p là con tr đ c s d ng trong newỏ ượ ử ụ

và đ gi i phóng toàn b m ng đ c c p pháp thông qua con tr p ta dùng câu l nh:ể ả ộ ả ượ ấ ỏ ệ

delete[] p ; // p là con tr tr đ n m ngỏ ỏ ế ả

D i đây là ví d s d ng t ng h p các phép toán trên con tr .ướ ụ ử ụ ổ ợ ỏ

: Nh p dãy s (không dùng m ng). S p x p và in ra màn hình.ậ ố ả ắ ếTrong ví d này ch ng trình xin c p phát b nh đ ch a n s nguyên và đ c tr b i conụ ươ ấ ộ ớ ủ ứ ố ượ ỏ ở tr head. Khi đó đ a ch c a s nguyên đ u tiên và cu i cùng s là head và head+n-1. p và q làỏ ị ỉ ủ ố ầ ố ẽ 2 con tr ch y trên dãy s này, so sánh và đ i n i dung c a các s này v i nhau đ s p thànhỏ ạ ố ổ ộ ủ ố ớ ể ắ dãy tăng d n và cu i cùng in k t qu .ầ ố ế ả

main()

{

int *head, *p, *q, n, tam; // head tr đ n (đánh d u) đ u dãyỏ ế ấ ầ

cout << "Cho bi t s s h ng c a dãy: "); cin >> n ;ế ố ố ạ ủ

head = new int[n] ; // c p phát b nh ch a n s nguyênấ ộ ớ ứ ố

for (p=head; p<head+n; p++) // nh p dãyậ

{

cout << "So thu " << p-head+1 << ": " ; cin >> *p ;

}

for (p=head; p<head+n-1; p++) // s p x pắ ế

for (q=p+1; q<head+n; q++)

if (*q < *p) { tam = *p; *p = *q; *q = tam; } // đ i chổ ỗ

for (p=head; p<head+n; p++) cout << *p ; // in k t quế ả

}

Con tr và m ng, xâu kí t ỏ ả ự

Con tr và m ng 1 chi uỏ ả ề

Page 91: Giao Trinh C++ Toan Tap

Vi c cho con tr tr đ n m ng cũng t ng t tr đ n các bi n khác, t c gán đ a ch c aệ ỏ ỏ ế ả ươ ự ỏ ế ế ứ ị ỉ ủ m ng (chính là tên m ng) cho con tr . Chú ý r ng ả ả ỏ ằ đ a ch c a m ng cũng là đ a ch c a thànhị ỉ ủ ả ị ỉ ủ ph n th 0 nên a+i s là đ a ch thành ph n th i c a m ng. T ng t , n u p tr đ n m ng aầ ứ ẽ ị ỉ ầ ứ ủ ả ươ ự ế ỏ ế ả thì p+i là đ a ch thành ph n th i c a m ng a và do đó *(p+i) = a[i] = *(a+i).ị ỉ ầ ứ ủ ả

Chú ý khi vi t *(p+1) = *(a+1) ta th y vai trò c a p và a trong bi u th c này là nh nhau, cùngế ấ ủ ể ứ ư truy c p đ n giá tr c a ph n t a[1]. Tuy nhiên khi vi t *(p++) thì l i khác v i *(a++), c thậ ế ị ủ ầ ử ế ạ ớ ụ ể vi t p++ là h p l còn a++ là không đ c phép. Lý do là tuy p và a cùng th hi n đ a ch c aế ợ ệ ượ ể ệ ị ỉ ủ m ng a nh ng p th c s là m t bi n, nó có th thay đ i đ c giá tr còn a là m t h ng, giá trả ư ự ự ộ ế ể ổ ượ ị ộ ằ ị không đ c phép thay đ i. Ví d vi t x = 3 và sau đó có th tăng x b i x++ nh ng không thượ ổ ụ ế ể ở ư ể vi t x = 3++.ế

: In toàn b m ng thông qua con tr .ộ ả ỏ

int a[5] = {1,2,3,4,5}, *p, i;

1: p = a; for (i=1; i<=5; i++) cout << *(p+i); // p không thay đ iổho c: ặ

2: for (p=a; p<=a+4; p++) cout << *p ; // thay đ i pổTrong ph ng án 1, con tr p không thay đ i trong su t quá trình làm vi c c a l nh for, đươ ỏ ổ ố ệ ủ ệ ể truy nh p đ n ph n t th i c a m ng a ta s d ng cú pháp *(p+i).ậ ế ầ ử ứ ủ ả ử ụ

Đ i v i ph ng án 2 con tr s d ch chuy n d c theo m ng a b t đ u t đ a ch a (ph n tố ớ ươ ỏ ẽ ị ể ọ ả ắ ầ ừ ị ỉ ầ ử đ u tiên) đ n ph n t cu i cùng. T i b c th i, p s tr vào ph n t a[i], do đó ta ch c n inầ ế ầ ử ố ạ ướ ứ ẽ ỏ ầ ử ỉ ầ giá tr *p. Đ ki m tra khi nào p đ t đ n ph n t cu i cùng, ta có th so sánh p v i đ a chị ể ể ạ ế ầ ử ố ể ớ ị ỉ cu i m ng chính là đ a ch đ u m ng c ng thêm s ph n t trong a ố ả ị ỉ ầ ả ộ ố ầ ử và trừ 1 (t c a+4 trong víứ d trên). ụ

Con tr và xâu kí tỏ ựM t con tr kí t có th xem nh m t bi n xâu kí t , trong đó xâu chính là t t c các kí t kộ ỏ ự ể ư ộ ế ự ấ ả ự ể t byte con tr tr đ n cho đ n byte '\0' g p đ u tiên. Vì v y ta có th khai báo các xâu d iừ ỏ ỏ ế ế ặ ầ ậ ể ướ d ng con tr kí t nh sau.ạ ỏ ự ư

char *s ;

char *s = "Hello" ;

Các hàm trên xâu v n đ c s d ng nh khi ta khai báo nó d i d ng m ng kí t . Ngoài raẫ ượ ử ụ ư ướ ạ ả ự khác v i m ng kí t , ta đ c phép s d ng phép gán cho 2 xâu d i d ng con tr , ví d :ớ ả ự ượ ử ụ ướ ạ ỏ ụ

char *s, *t = "Tin h c" ; s = t;ọ // thay cho hàm strcpy(s, t) ;

Th c ch t phép gán trên ch là gán 2 con tr v i nhau, nó cho phép s bây gi cũng đ c trự ấ ỉ ỏ ớ ờ ượ ỏ đ n n i mà t tr (t c dãy kí t "Tin h c" đã b trí s n trong b nh )ế ơ ỏ ứ ự ọ ố ẵ ộ ớ

Page 92: Giao Trinh C++ Toan Tap

Khi khai báo xâu d ng con tr nó v n ch a có b nh c th , vì v y thông th ng kèm theoạ ỏ ẫ ư ộ ớ ụ ể ậ ườ khai báo ta c n ph i xin c p phát b nh cho xâu v i đ dài c n thi t. Ví d :ầ ả ấ ộ ớ ớ ộ ầ ế ụ

char *s = new char[30], *t ;

strcpy(s, "Hello") ; // trong tr ng h p này không c n c p phát bườ ợ ầ ấ ộ

t = s ; // nh cho t vì t và s cùng s d ng chung vùng nh ớ ử ụ ớ

nh ng:ư

char *s = new char[30], *t ;

strcpy(s, "Hello") ;

t = new char[30]; // trong tr ng h p này ph i c p b nh cho t vìườ ợ ả ấ ộ ớ

strcpy(t, s) ; // có ch đ strcpy sao chép sang n i dung c a s. ỗ ể ộ ủ

Con tr và m ng hai chi uỏ ả ềĐ d hi u vi c s d ng con tr tr đ n m ng hai chi u, chúng ta nh c l i v m ng 2 chi uể ễ ể ệ ử ụ ỏ ỏ ế ả ề ắ ạ ề ả ề thông qua ví d . Gi s ta có khai báo:ụ ả ử

float a[2][3], *p;

khi đó a đ c b trí trong b nh nh là m t dãy 6 ph n t float nh sau ượ ố ộ ớ ư ộ ầ ử ư

a a+1tuy nhiên a không đ c xem là m ng 1 chi u v i 6 ph n t mà đ c quan ni m nh m ngượ ả ề ớ ầ ử ượ ệ ư ả m t chi u g m 2 ph n t , m i ph n t là 1 b 3 s th c. Do đó đ a ch c a m ng a chính làộ ề ồ ầ ử ỗ ầ ử ộ ố ự ị ỉ ủ ả đ a ch c a ph n t đ u tiên a[0][0], và a+1 không ph i là đ a ch c a ph n t ti p theo a[0][1]ị ỉ ủ ầ ử ầ ả ị ỉ ủ ầ ử ế mà là đ a ch c a ph n t a[1][0]. Nói cách khác a+1 cũng là tăng đ a ch c a a lên m t thànhị ỉ ủ ầ ử ị ỉ ủ ộ ph n, nh ng 1 thành ph n đây đ c hi u là toàn b m t dòng c a m ng. ầ ư ầ ở ượ ể ộ ộ ủ ả

M t khác, vi c l y đ a ch c a t ng ph n t (float) trong a th ng là không chính xác. Ví d :ặ ệ ấ ị ỉ ủ ừ ầ ử ườ ụ vi t &a[i][j] (đ a ch c a ph n t dòng i c t j) là đ c đ i v i m ng nguyên nh ng l i khôngế ị ỉ ủ ầ ử ộ ượ ố ớ ả ư ạ đúng đ i v i m ng th c. ố ớ ả ự

T các th o lu n trên, phép gán p = a là d gây nh m l n vì p là con tr float còn a là đ a chừ ả ậ ễ ầ ẫ ỏ ị ỉ m ng (1 chi u). Do v y tr c khi gán ta c n ép ki u c a a v ki u float. Tóm l i cách gán đ aả ề ậ ướ ầ ể ủ ề ể ạ ị ch c a a cho con tr p đ c th c hi n nh sau: ỉ ủ ỏ ượ ự ệ ư

Cách sai:

p = a ; // sai vì khác ki uể

Page 93: Giao Trinh C++ Toan Tap

Các cách đúng:

p = (float*)a; // ép ki u c a a v con tr float (cũng là ki u c a p)ể ủ ề ỏ ể ủ

p = a[0]; // gán v i đ a ch c a m ng a[0] ớ ị ỉ ủ ả

p = &a[0][0]; // gán v i đ a ch s th c đ u tiên trong a ớ ị ỉ ố ự ầtrong đó cách dùng p = (float*)a; là tr c quan và đúng trong m i tr ng h p nên đ cự ọ ườ ợ ượ

dùng thông d ng h n c .ụ ơ ảSau khi gán a cho p (p là con tr th c), vi c tăng gi m p chính là d ch chuy n con tr trên t ngỏ ự ệ ả ị ể ỏ ừ ph n t (th c) c a a. T c:ầ ử ự ủ ứ

p tr t i a[0][0]ỏ ớ

p+1 tr t i a[0][1]ỏ ớ

p+2 tr t i a[0][2]ỏ ớ

p+3 tr t i a[1][0]ỏ ớ

p+4 tr t i a[1][1]ỏ ớ

p+5 tr t i a[1][2]ỏ ớT ng quát, đ i v i m ng m x n ph n t :ổ ố ớ ả ầ ử

p + i*n + j tr t i a[i][j] ỏ ớ ho c ặ a[i][j] = *(p + i*n + j)T đó đ truy nh p đ n ph n t a[i][j] thông qua con tr p ta nên s d ng cách vi t sau:ừ ể ậ ế ầ ử ỏ ử ụ ế

p = (float*)a;

cin >> *(p+i*n+j) ; // nh p cho a[i][j]ậ

cout << *(p+i*n+j); // in a[i][j]Ví d sau đây cho phép nh p và in m t m ng 2 chi u m*n (m dòng, n c t) thông qua conụ ậ ộ ả ề ộ

tr p. Nh p liên ti p m*n s vào m ng và in thành ma tr n m dòng, n c t.ỏ ậ ế ố ả ậ ộ

main()

{

clrscr();

float a[m][n], *p;

int i, j;

p = (float*) a;

for (i=0; i<m*n; i++) cin >> *(p+i); // nh p nh dãy mxn ph n t ậ ư ầ ử

*(p+2*n+3) = 100; *(p+4*n) = 100; // gán a[2,3] = a[4][0] = 100

for (i=0; i<m; i++) // in l i d i d ng ma tr nạ ướ ạ ậ

{

for (j=0; j<n; j++) cout << *(p+i*n+j);

cout << endl;

Page 94: Giao Trinh C++ Toan Tap

}

getch();

}Chú ý: vi c l y đ a ch ph n t a[i][j] c a m ng th c a là không chính xác. T c: vi t p = &a[i]ệ ấ ị ỉ ầ ử ủ ả ự ứ ế[j] có th d n đ n k t qu sai.ể ẫ ế ế ả

M ng con tr ả ỏ

Khái ni m chungệTh c ch t m t con tr cũng là m t bi n thông th ng có tên g i (ví d p, q, …), do đó cũngự ấ ộ ỏ ộ ế ườ ọ ụ gi ng nh bi n, nhi u bi n cùng ki u có th t ch c thành m t m ng v i tên g i chung, ố ư ế ề ế ể ể ổ ứ ộ ả ớ ọ ở đây cũng v y nhi u con tr cùng ki u cũng đ c t ch c thành m ng. Nh v y m i ph n tậ ề ỏ ể ượ ổ ứ ả ư ậ ỗ ầ ử c a m ng con tr là m t con tr tr đ n m t m ng nào đó. Nói cách khác m t m ng con trủ ả ỏ ộ ỏ ỏ ế ộ ả ộ ả ỏ cho phép qu n lý nhi u m ng d li u cùng ki u. Cách khai báo:ả ề ả ữ ệ ể

<ki u> *a[size];ể

Ví d : ụ

int *a[10];

khai báo m t m ng ch a 10 con tr . M i con tr a[i] ch a đ a ch c a m t m ng nguyên nàoộ ả ứ ỏ ỗ ỏ ứ ị ỉ ủ ộ ả đó.

M ng xâu kí tả ựLà tr ng h p riêng c a m ng con tr nói chung, trong đó ki u c th là char. M i thànhườ ợ ủ ả ỏ ể ụ ể ỗ ph n m ng là m t con tr tr đ n m t xâu kí t , có nghĩa các thao tác ti n hành trên *a[i] nhầ ả ộ ỏ ỏ ế ộ ự ế ư đ i v i m t xâu kí t . ố ớ ộ ự

: Nh p vào và in ra m t bài th . ậ ộ ơ

main()

{

clrscr();

char *dong[100]; // khai báo 100 con tr kí t (100 dòng)ỏ ự

int i, n;

cout << "so dong = "; cin >> n ; // nh p s dòng th c sậ ố ự ự

cin.ignore(); // lo i d u ¿ trong l nh cin trênạ ấ ệ ở

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

{

dong[i] = new char[80]; // c p b nh cho dòng iấ ộ ớ

Page 95: Giao Trinh C++ Toan Tap

cin.getline(dong[i],80); // nh p dòng iậ

}

for (i=0; i<n; i++) cout << dong[i] << endl; // in k t quế ả

getch();

}

HÀM

Hàm là m t ch ng trình con trong ch ng trình l n. Hàm nh n (ho c không) các đ i s vàộ ươ ươ ớ ậ ặ ố ố tr l i (ho c không) m t giá tr cho ch ng trình g i nó. Trong tr ng h p không tr l i giáả ạ ặ ộ ị ươ ọ ườ ợ ả ạ tr , hàm ho t đ ng nh m t th t c trong các NNLT khác. M t ch ng trình là t p các hàm,ị ạ ộ ư ộ ủ ụ ộ ươ ậ trong đó có m t hàm chính v i tên g i main(), khi ch y ch ng trình, hàm main() s đ cộ ớ ọ ạ ươ ẽ ượ ch y đ u tiên và g i đ n hàm khác. K t thúc hàm main() cũng là k t thúc ch ng trình. ạ ầ ọ ế ế ế ươ

Hàm giúp cho vi c phân đo n ch ng trình thành nh ng môđun riêng r , ho t đ ng đ c l pệ ạ ươ ữ ẽ ạ ộ ộ ậ v i ng nghĩa c a ch ng trình l n, có nghĩa m t hàm có th đ c s d ng trong ch ngớ ữ ủ ươ ớ ộ ể ượ ử ụ ươ trình này mà cũng có th đ c s d ng trong ch ng trình khác, d cho vi c ki m tra và b oể ượ ử ụ ươ ễ ệ ể ả trì ch ng trình. Hàm có m t s đ c tr ng:ươ ộ ố ặ ư

N m trong ho c ngoài văn b n có ch ng trình g i đ n hàm. Trong m t văn b n có thằ ặ ả ươ ọ ế ộ ả ể ch a nhi u hàm,ứ ề

Đ c g i t ch ng trình chính (main), t hàm khác ho c t chính nó (đ quy),ượ ọ ừ ươ ừ ặ ừ ệ

Không l ng nhau.ồ

Có 3 cách truy n giá tr : Truy n theo tham tr , tham bi n và tham tr .ề ị ề ị ế ỏ

Khai báo và đ nh nghĩa hàm ị

Khai báoM t hàm th ng làm ch c năng: tính toán trên các tham đ i và cho l i giá tr k t qu , ho cộ ườ ứ ố ạ ị ế ả ặ ch đ n thu n th c hi n m t ch c năng nào đó, không tr l i k t qu tính toán. Thông th ngỉ ơ ầ ự ệ ộ ứ ả ạ ế ả ườ ki u c a giá tr tr l i đ c g i là ki u c a hàm. Các hàm th ng đ c khai báo đ uể ủ ị ả ạ ượ ọ ể ủ ườ ượ ở ầ ch ng trình. Các hàm vi t s n đ c khai báo trong các file nguyên m u *.h. Do đó, đ sươ ế ẵ ượ ẫ ể ử d ng đ c các hàm này, c n có ch th #include <*.h> ngay đ u ch ng trình, trong đó *.h làụ ượ ầ ỉ ị ở ầ ươ tên file c th có ch a khai báo c a các hàm đ c s d ng (ví d đ s d ng các hàm toánụ ể ứ ủ ượ ử ụ ụ ể ử ụ h c ta c n khai báo file nguyên m u math.h). Đ i v i các hàm do NSD t vi t, cũng c n ph iọ ầ ẫ ố ớ ự ế ầ ả khai báo. Khai báo m t hàm nh sau:ộ ư

<ki u giá tr tr l i> <tên hàm>(d/s ki u đ i) ;ể ị ả ạ ể ốtrong đó, ki u giá tr tr l i còn g i là ki u hàm và có th nh n ki u b t kỳ chu n c a C++ vàể ị ả ạ ọ ể ể ậ ể ấ ẩ ủ c ki u c a NSD t t o. Đ c bi t n u hàm không tr l i giá tr thì ki u c a giá tr tr l iả ể ủ ự ạ ặ ệ ế ả ạ ị ể ủ ị ả ạ đ c khai báo là ượ void. N u ki u giá tr tr l i đ c b qua thì ch ng trình ng m đ nh hàmế ể ị ả ạ ượ ỏ ươ ầ ị có ki u là ể int (phân bi t v i void !).ệ ớ

Page 96: Giao Trinh C++ Toan Tap

:

int bp(int); // Khai báo hàm bp, có đ i ki u int và ki u hàm là intố ể ể

int rand100(); // Không đ i, ki u hàm (giá tr tr l i) là intố ể ị ả ạ

void alltrim(char[]) ; // đ i là xâu kí t , hàm không tr l i giá tr (không ki u).ố ự ả ạ ị ể

cong(int, int); // Hai đ i ki u int, ki u hàm là int (ng m ố ể ể ầ đ nh).ịThông th ng đ ch ng trình đ c rõ ràng chúng ta nên tránh l m d ng các ng m đ nh. Víườ ể ươ ượ ạ ụ ầ ị d trong khai báo cong(int, int); nên khai báo rõ c ki u hàm (trong tr ng h p này ki u hàmụ ả ể ườ ợ ể ng m đ nh là int) nh sau : int cong(int, int);ầ ị ư

Đ nh nghĩa hàmịC u trúc m t hàm b t kỳ đ c b trí cũng gi ng nh hàm main() trong các ph n tr c. Cấ ộ ấ ượ ố ố ư ầ ướ ụ th :ể

Hàm có tr v giá trả ề ị<ki u hàm> <tên hàm>(danh sách tham ể đ i hình th c) ố ứ

{

khai báo c c b c a hàm ;ụ ộ ủ // ch dùng riêng cho hàm nàyỉ

dãy l nh c a hàm ;ệ ủ

return (bi u th c tr v );ể ứ ả ề // có th n m ể ằ đâu đó trong dãy l nh.ệ

}

Danh sách tham đ i hình th c còn đ c g i ng n g n là danh sách đ i g m dãy các đ iố ứ ượ ọ ắ ọ ố ồ ố cách nhau b i d u ph y, đ i có th là m t bi n th ng, bi n tham chi u ho c bi nở ấ ẩ ố ể ộ ế ườ ế ế ặ ế con tr , hai lo i bi n sau ta s trình bày trong các ph n t i. M i đ i đ c khai báoỏ ạ ế ẽ ầ ớ ỗ ố ượ gi ng nh khai báo bi n, t c là c p g m <ki u đ i> <tên đ i>.ố ư ế ứ ặ ồ ể ố ố

V i hàm có tr l i giá tr c n có câu l nh ớ ả ạ ị ầ ệ return kèm theo sau là m t bi u th c. Ki uộ ể ứ ể c a giá tr bi u th c này chính là ki u c a hàm đã đ c khai báo ph n tên hàm.ủ ị ể ứ ể ủ ượ ở ầ Câu lênh return có th n m v trí b t kỳ trong ph n câu l nh, tuỳ thu c m c đíchể ằ ở ị ấ ầ ệ ộ ụ c a hàm. Khi g p câu l nh return ch ng trình t c kh c thoát kh i hàm và tr l iủ ặ ệ ươ ứ ắ ỏ ả ạ giá tr c a bi u th c sau return nh giá tr c a hàm. ị ủ ể ứ ư ị ủ

: Ví d sau đ nh nghĩa hàm tính lu th a n (v i n nguyên) c a m t s th c b t kỳ. Hàm này cóụ ị ỹ ừ ớ ủ ộ ố ự ấ hai đ u vào (đ i th c x và s mũ nguyên n) và đ u ra (giá tr tr l i) ki u th c v i đ chínhầ ố ự ố ầ ị ả ạ ể ự ớ ộ xác g p đôi là xấ n.

double luythua(float x, int n)

{

int i ; // bi n ch sế ỉ ố

double kq = 1 ; // đ l u k t qu ể ư ế ả

Page 97: Giao Trinh C++ Toan Tap

for (i=1; i<=n; i++) k t qu *= x ;ế ả

return kq;

}

Hàm không tr v giá trả ề ịN u hàm không tr l i giá tr (t c ki u hàm là void), khi đó có th có ho c không có câu l nhế ả ạ ị ứ ể ể ặ ệ return, n u có thì đ ng sau return s không có bi u th c giá tr tr l i.ế ằ ẽ ể ứ ị ả ạ

: Hàm xoá màn hình 100 l n, hàm ch làm công vi c c n th n xoá màn hình nhi u l n đ mànầ ỉ ệ ẩ ậ ề ầ ể hình th t s ch, nên không có giá tr gì đ tr l i.ậ ạ ị ể ả ạ

void xmh()

{

int i;

for (i=1; i<=100; i++) clrscr();

return ;

}Hàm main() thông th ng có ho c không có giá tr tr v cho h đi u hành khi ch ng trìnhườ ặ ị ả ề ệ ề ươ ch y xong, vì v y ta th ng khai báo ki u hàm là int main() ho c void main() và câu l nh cu iạ ậ ườ ể ặ ệ ố cùng trong hàm th ng là return 1 ho c return. Tr ng h p b qua t khoá void nh ng trongườ ặ ườ ợ ỏ ừ ư thân hàm không có câu l nh return (gi ng ph n l n ví d trong giáo trình này) ch ng trình sệ ố ầ ớ ụ ươ ẽ ng m hi u hàm main() tr l i m t giá tr nguyên nh ng vì không có nên khi d ch ch ng trìnhầ ể ả ạ ộ ị ư ị ươ ta s g p l i c nh báo "C n có giá tr tr l i cho hàm" (m t l i c nh báo không ph i là l i,ẽ ặ ờ ả ầ ị ả ạ ộ ờ ả ả ỗ ch ng trình v n ch y bình th ng). Đ tránh b qu y r y v nh ng l i c nh báo "khôngươ ẫ ạ ườ ể ị ấ ầ ề ữ ờ ả m i" này chúng ta có th đ t thêm câu l nh return 0; (n u không khai báo void main()) ho cờ ể ặ ệ ế ặ khai báo ki u hàm là void main() và đ t câu l nh return vào cu i hàm. ể ặ ệ ố

Chú ý v khai báo và đ nh nghĩa hàmề ị

Danh sách đ i trong khai báo hàm có th ch a ho c không ch a tên đ i, thông th ng taố ể ứ ặ ứ ố ườ ch khai báo ki u đ i ch không c n khai báo tên đ i, trong khi dòng đ u tiên c aỉ ể ố ứ ầ ố ở ầ ủ đ nh nghĩa hàm ph i có tên đ i đ y đ .ị ả ố ầ ủ

Cu i khai báo hàm ph i có d u ch m ph y (;), trong khi cu i dòng đ u tiên c a đ nhố ả ấ ấ ẩ ố ầ ủ ị nghĩa hàm không có d u ch m ph y.ấ ấ ẩ

Hàm có th không có đ i (danh sách đ i r ng), tuy nhiên c p d u ngo c sau tên hàmể ố ố ỗ ặ ấ ặ v n ph i đ c vi t. Ví d clrscr(), lamtho(), vietgiaotrinh(), …ẫ ả ượ ế ụ

M t hàm có th không c n ph i khai báo n u nó đ c đ nh nghĩa tr c khi có hàm nàoộ ể ầ ả ế ượ ị ướ đó g i đ n nó. Ví d có th vi t hàm main() tr c (trong văn b n ch ng trình), r iọ ế ụ ể ế ướ ả ươ ồ sau đó m i vi t đ n các hàm "con". Do trong hàm main() ch c ch n s g i đ n hàmớ ế ế ắ ắ ẽ ọ ế con này nên danh sách c a chúng ph i đ c khai báo tr c hàm main(). Tr ng h pủ ả ượ ướ ườ ợ ng c l i n u các hàm con đ c vi t (đ nh nghĩa) tr c thì không c n ph i khai báoượ ạ ế ượ ế ị ướ ầ ả chúng n a (vì trong đ nh nghĩa đã hàm ý khai báo). Nguyên t c này áp d ng cho haiữ ị ắ ụ hàm A, B b t kỳ ch không riêng cho hàm main(), nghĩa là n u B g i đ n A thì tr cấ ứ ế ọ ế ướ

Page 98: Giao Trinh C++ Toan Tap

đó A ph i đ c đ nh nghĩa ho c ít nh t cũng có dòng khai báo v A.ả ượ ị ặ ấ ề

L i g i và s d ng hàmờ ọ ử ụL i g i hàm đ c phép xu t hi n trong b t kỳ bi u th c, câu l nh c a hàm khác … N u l iờ ọ ượ ấ ệ ấ ể ứ ệ ủ ế ờ g i hàm l i n m trong chính b n thân hàm đó thì ta g i là đ quy. Đ g i hàm ta ch c n vi tọ ạ ằ ả ọ ệ ể ọ ỉ ầ ế tên hàm và danh sách các giá tr c th truy n cho các đ i đ t trong c p d u ngo c tròn (). ị ụ ể ề ố ặ ặ ấ ặ

tên hàm(danh sách tham đ i th c s ) ;ố ự ự

Danh sách tham đ i th c s còn g i là danh sách giá tr g m các giá tr c th đ gán l nố ự ự ọ ị ồ ị ụ ể ể ầ l t cho các đ i hình th c c a hàm. Khi hàm đ c g i th c hi n thì t t c nh ng vượ ố ứ ủ ượ ọ ự ệ ấ ả ữ ị trí xu t hi n c a đ i hình th c s đ c gán cho giá tr c th c a đ i th c s t ngấ ệ ủ ố ứ ẽ ượ ị ụ ể ủ ố ự ự ươ

ng trong danh sách, sau đó hàm ti n hành th c hi n các câu l nh c a hàm (đ tínhứ ế ự ệ ệ ủ ể k t qu ).ế ả

Danh sách tham đ i th c s truy n cho tham đ i hình th c có s l ng b ng v i số ự ự ề ố ứ ố ượ ằ ớ ố l ng đ i trong hàm và đ c truy n cho đ i theo th t t ng ng. Các tham đ iượ ố ượ ề ố ứ ự ươ ứ ố th c s có th là các h ng, các bi n ho c bi u th c. Bi n trong giá tr có th trùngự ự ể ằ ế ặ ể ứ ế ị ể v i tên đ i. Ví d ta có hàm in n l n kí t c v i tên hàm inkitu(int n, char c); và l iớ ố ụ ầ ự ớ ờ g i hàm inkitu(12, 'A'); thì n và c là các đ i hình th c, 12 và 'A' là các đ i th c sọ ố ứ ố ự ự ho c giá tr . Các đ i hình th c n và c s l n l t đ c gán b ng các giá tr t ngặ ị ố ứ ẽ ầ ượ ượ ằ ị ươ

ng là 12 và 'A' tr c khi ti n hành các câu l nh trong ph n thân hàm. Gi s hàm inứ ướ ế ệ ầ ả ử kí t đ c khai báo l i thành inkitu(char c, int n); thì l i g i hàm cũng ph i đ cự ượ ạ ờ ọ ả ượ thay l i thành inkitu('A', 12). ạ

Các giá tr t ng ng đ c truy n cho đ i ph i có ki u cùng v i ki u đ i (ho c C++ cóị ươ ứ ượ ề ố ả ể ớ ể ố ặ th t đ ng chuy n ki u đ c v ki u c a đ i).ể ự ộ ể ể ượ ề ể ủ ố

Khi m t hàm đ c g i, n i g i t m th i chuy n đi u khi n đ n th c hi n dòng l nhộ ượ ọ ơ ọ ạ ờ ể ề ể ế ự ệ ệ đ u tiên trong hàm đ c g i. Sau khi k t thúc th c hi n hàm, đi u khi n l i đ cầ ượ ọ ế ự ệ ề ể ạ ượ tr v th c hi n ti p câu l nh sau l nh g i hàm c a n i g i. ả ề ự ệ ế ệ ệ ọ ủ ơ ọ

: Gi s ta c n tính giá tr c a bi u th c 2xả ử ầ ị ủ ể ứ 3 - 5x2 - 4x + 1, thay cho vi c tính tr c ti p xệ ự ế 3 và x2, ta có th g i hàm luythua() trong ví d trên đ tính các giá tr này b ng cách g i nó trong hàmể ọ ụ ể ị ằ ọ main() nh sau:ư

#include <iostream.h>

#include <iomanip.h>

double luythua(float x, int n) // tr l i giá tr xả ạ ị n

{

int i ; // bi n ch sế ỉ ố

double kq = 1 ; // đ l u k t qu ể ư ế ả

for (i=1; i<=n; i++) k t qu *= x ;ế ả

return kq;

}

Page 99: Giao Trinh C++ Toan Tap

void xmh(int n) // xoá màn hình n l nầ

{

int i;

for (i=1; i<=n; i++) clrscr();

return ;

}

main() // tính giá tr 2xị 3 - 5x2 - 4x + 1

{

float x ; // tên bi n có th trùng v i đ i c a hàmế ể ớ ố ủ

double f ; // đ l u k t qu ể ư ế ả

cout << "x = " ; cin >> x

f = 2*luythua(x,3) - 5*luythua(x,2) - 4*x + 1;

xmh(100); // xoá th t s ch màn hình 100 l nậ ạ ầ

cout << setprecision(2) << f << endl ;

}Qua ví d này ta th y l i ích c a l p trình c u trúc, ch ng trình tr nên g n h n, ch ng h nụ ấ ợ ủ ậ ấ ươ ở ọ ơ ẳ ạ hàm luythua() ch đ c vi t m t l n nh ng có th s d ng nó nhi u l n (2 l n trong ví dỉ ượ ế ộ ầ ư ể ử ụ ề ầ ầ ụ này) ch b ng m t câu l nh g i đ n gi n cho m i l n s d ng thay vì ph i vi t l i nhi u l nỉ ằ ộ ệ ọ ơ ả ỗ ầ ử ụ ả ế ạ ề ầ đo n l nh tính lu th a.ạ ệ ỹ ừ

Hàm v i đ i m c đ nhớ ố ặ ịM c này và m c sau chúng ta bàn đ n m t vài m r ng thi t th c c a C++ đ i v i C có liênụ ụ ế ộ ở ộ ế ự ủ ố ớ quan đ n hàm, đó là hàm v i đ i m c đ nh và cách t o, s d ng các hàm có chung tên g i.ế ớ ố ặ ị ạ ử ụ ọ M t m r ng quan tr ng khác là cách truy n đ i theo tham chi u s đ c bàn chung trongộ ở ộ ọ ề ố ế ẽ ượ m c truy n tham đ i th c s cho hàm. ụ ề ố ự ự

Trong ph n tr c chúng ta đã kh ng đ nh s l ng tham đ i th c s ph i b ng s l ngầ ướ ẳ ị ố ượ ố ự ự ả ằ ố ượ tham đ i hình th c khi g i hàm. Tuy nhiên, trong th c t r t nhi u l n hàm đ c g i v i cácố ứ ọ ự ế ấ ề ầ ượ ọ ớ giá tr c a m t s tham đ i hình th c đ c l p đi l p l i. Trong tr ng h p nh v y lúc nàoị ủ ộ ố ố ứ ượ ặ ặ ạ ườ ợ ư ậ cũng ph i vi t m t danh sách dài các tham đ i th c s gi ng nhau cho m i l n g i là m tả ế ộ ố ự ự ố ỗ ầ ọ ộ công vi c không m y thú v . T th c t đó C++ đ a ra m t cú pháp m i v hàm sao cho m tệ ấ ị ừ ự ế ư ộ ớ ề ộ danh sách tham đ i th c s trong l i g i không nh t thi t ph i vi t đ y đ n u m t s trongố ự ự ờ ọ ấ ế ả ế ầ ủ ế ộ ố chúng đã có s n nh ng giá tr đ nh tr c. Cú pháp này đ c g i là hàm v i tham đ i m c đ nhẵ ữ ị ị ướ ượ ọ ớ ố ặ ị và đ c khai báo v i cú pháp nh sau:ượ ớ ư

<ki u hàm> <tên hàm>(đ1, …, đn, đmđ1 = gt1, …, đmđm = gtm) ;ể

Page 100: Giao Trinh C++ Toan Tap

Các đ i đ1, …, đn và đ i m c đ nh đmđ1, …, đmđm đ u đ c khai báo nh cũ nghĩa làố ố ặ ị ề ượ ư g m có ki u đ i và tên đ i.ồ ể ố ố

Riêng các đ i m c đ nh đmđ1, …, đmđm có gán thêm các giá tr m c đ nh gt1, …, gtm.ố ặ ị ị ặ ị M t l i g i b t kỳ khi g i đ n hàm này đ u ph i có đ y đ các tham đ i th c sộ ờ ọ ấ ọ ế ề ả ầ ủ ố ự ự

ng v i các đ1, …, đm nh ng có th có ho c không các tham đ i th c s ng v iứ ớ ư ể ặ ố ự ự ứ ớ các đ i m c đ nh đmđ1, …, đmđm. N u tham đ i nào không có tham đ i th c s thìố ặ ị ế ố ố ự ự nó s đ c t đ ng gán giá tr m c đ nh đã khai báo.ẽ ượ ự ộ ị ặ ị

:

Xét hàm xmh(int n = 100), trong đó n m c đ nh là 100, nghĩa là n u g i xmh(99) thì mànặ ị ế ọ hình đ c xoá 99 l n, còn n u g i xmh(100) ho c g n h n xmh() thì ch ng trìnhượ ầ ế ọ ặ ọ ơ ươ s xoá màn hình 100 l n.ẽ ầ

T ng t , xét hàm int luythua(float x, int n = 2); Hàm này có m t tham đ i m c đ nh làươ ự ộ ố ặ ị s mũ n, n u l i g i hàm b qua s mũ này thì ch ng trình hi u là tính bìnhố ế ờ ọ ỏ ố ươ ể ph ng c a x (n = 2). Ví d l i g i luythua(4, 3) đ c hi u là 4ươ ủ ụ ờ ọ ượ ể 3 còn luythua(4) đ c hi u là 4ượ ể 2.

Hàm tính t ng 4 s nguyên: int tong(int m, int n, int i = 0; int j = 0); khi đó có th tínhổ ố ể t ng c a 5, 2, 3, 7 b ng l i g i hàm ổ ủ ằ ờ ọ tong(5,2,3,7) ho c có th ch tính t ng 3 s 4, 2,ặ ể ỉ ổ ố 1 b ng l i g i ằ ờ ọ tong(4,2,1) ho c cũng có th g i ặ ể ọ tong(6,4) ch đ tính t ng c a 2 s 6ỉ ể ổ ủ ố và 4.

Chú ý: Các đ i ng m đ nh ph i đ c khai báo liên t c và xu t hi n cu i cùng trong danh sáchố ầ ị ả ượ ụ ấ ệ ố đ i. Ví d : ố ụ

int tong(int x, int y=2, int z, int t=1); // sai vì các đ i m c đ nh không liên t cố ặ ị ụ

void xoa(int x=0, int y) // sai vì đ i m c đ nh không cu iố ặ ị ở ố

Khai báo hàm trùng tênHàm trùng tên hay còn g i là hàm ch ng (đè). Đây là m t k thu t cho phép s d ng cùng m tọ ồ ộ ỹ ậ ử ụ ộ tên g i cho các hàm "gi ng nhau" (cùng m c đích) nh ng x lý trên các ki u d li u khácọ ố ụ ư ử ể ữ ệ nhau ho c trên s l ng d li u khác nhau. Ví d hàm sau tìm s l n nh t trong 2 s nguyên:ặ ố ượ ữ ệ ụ ố ớ ấ ố

int max(int a, int b) { return (a > b) ? a: b ; }

N u đ t c = max(3, 5) ta s có c = 5. Tuy nhiên cũng t ng t nh v y n u đ t c = max(3.0,ế ặ ẽ ươ ự ư ậ ế ặ 5.0) ch ng trình s b l i vì các giá tr (float) không phù h p v ki u (int) c a đ i trong hàmươ ẽ ị ỗ ị ợ ề ể ủ ố max. Trong tr ng h p nh v y chúng ta ph i vi t hàm m i đ tính max c a 2 s th c. M cườ ợ ư ậ ả ế ớ ể ủ ố ự ụ đích, cách làm vi c c a hàm này hoàn toàn gi ng hàm tr c, tuy nhiên trong C và các NNLTệ ủ ố ướ c đi n khác chúng ta bu c ph i s d ng m t tên m i cho hàm "m i" này. ổ ể ộ ả ử ụ ộ ớ ớ Ví d :ụ

float fmax(float a, float b) { return (a > b) ? a: b ; }

T ng t đ tu n ti n ta s vi t thêm các hàm ươ ự ể ậ ệ ẽ ế

char cmax(char a, char b) { return (a > b) ? a: b ; }

Page 101: Giao Trinh C++ Toan Tap

long lmax(long a, long b) { return (a > b) ? a: b ; }

double dmax(double a, double b) { return (a > b) ? a: b ; }

Tóm l i ta s có 5 hàm: max, cmax, fmax, lmax, dmax, vi c s d ng tên nh v y s gâyạ ẽ ệ ử ụ ư ậ ẽ b t l i khi c n g i hàm. C++ cho phép ta có th khai báo và đ nh nghĩa c 5 hàm trên v i cùngấ ợ ầ ọ ể ị ả ớ 1 tên g i ví d là max ch ng h n. Khi đó ta có 5 hàm:ọ ụ ẳ ạ

1: int max(int a, int b) { return (a > b) ? a: b ; }

2: float max(float a, float b) { return (a > b) ? a: b ; }

3: char max(char a, char b) { return (a > b) ? a: b ; }

4: long max(long a, long b) { return (a > b) ? a: b ; }

5: double max(double a, double b) { return (a > b) ? a: b ; }Và l i g i hàm b t kỳ d ng nào nh max(3,5), max(3.0,5), max('O', 'K') đ u đ c đáp ng.ờ ọ ấ ạ ư ề ượ ứ Chúng ta có th đ t ra v n đ : v i c 5 hàm cùng tên nh v y, ch ng trình g i đ n hàm nào.ể ặ ấ ề ớ ả ư ậ ươ ọ ế V n đ đ c gi i quy t d dàng vì ch ng trình s d a vào ki u c a các đ i khi g i đấ ề ượ ả ế ễ ươ ẽ ự ể ủ ố ọ ể quy t đ nh ch y hàm nào. Ví d l i g i max(3,5) có 2 đ i đ u là ki u nguyên nên ch ngế ị ạ ụ ờ ọ ố ề ể ươ trình s g i hàm 1, l i g i max(3.0,5) h ng đ n hàm s 2 và t ng t ch ng trình s ch yẽ ọ ờ ọ ướ ế ố ươ ự ươ ẽ ạ hàm s 3 khi g p l i g i max('O','K'). Nh v y m t đ c đi m c a các hàm trùng tên đó làố ặ ờ ọ ư ậ ộ ặ ể ủ trong danh sách đ i c a chúng ph i có ít nh t m t c p đ i nào đó khác ki u nhau. M t đ cố ủ ả ấ ộ ặ ố ể ộ ặ tr ng khác đ phân bi t thông qua các đ i đó là s l ng đ i trong các hàm ph i khác nhauư ể ệ ố ố ượ ố ả (n u ki u c a chúng là gi ng nhau).ế ể ủ ố

Ví d vi c v các hình: th ng, tam giác, vuông, ch nh t trên màn hình là gi ng nhau, chúngụ ệ ẽ ẳ ữ ậ ố ch ph thu c vào s l ng các đi m n i và to đ c a chúng. Do v y ta có th khai báo vàỉ ụ ộ ố ượ ể ố ạ ộ ủ ậ ể đ nh nghĩa 4 hàm v nói trên v i cùng chung tên g i. Ch ng h n:ị ẽ ớ ọ ẳ ạ

void ve(Diem A, Diem B) ; // v đ ng th ng ABẽ ườ ẳ

void ve(Diem A, Diem B, Diem C) ; // v tam giác ABCẽ

void ve(Diem A, Diem B, Diem C, Diem D) ; // v t giác ABCDẽ ứtrong ví d trên ta gi thi t Diem là m t ki u d li u l u to đ c a các đi m trên màn hình.ụ ả ế ộ ể ữ ệ ư ạ ộ ủ ể Hàm ve(Diem A, Diem B, Diem C, Diem D) s v hình vuông, ch nh t, thoi, bình hành hayẽ ẽ ữ ậ hình thang ph thu c vào to đ c a 4 đi m ABCD, nói chung nó đ c s d ng đ v m tụ ộ ạ ộ ủ ể ượ ử ụ ể ẽ ộ t giác b t kỳ.ứ ấ

Tóm l i nhi u hàm có th đ c đ nh nghĩa ch ng (v i cùng tên g i gi ng nhau) n u chúngạ ề ể ượ ị ồ ớ ọ ố ế tho các đi u ki n sau:ả ề ệ

S l ng các tham đ i trong hàm là khác nhau, ho c ố ượ ố ặ

Ki u c a tham đ i trong hàm là khác nhau.ể ủ ố

Page 102: Giao Trinh C++ Toan Tap

K thu t ch ng tên này còn áp d ng c cho các toán t . Trong ph n l p trình h ng đ iỹ ậ ồ ụ ả ử ầ ậ ướ ố t ng, ta s th y NSD đ c phép đ nh nghĩa các toán t m i nh ng v n l y tên cũ nh +, -, *,ượ ẽ ấ ượ ị ử ớ ư ẫ ấ ư / …

Bi n, đ i tham chi uế ố ếM t bi n có th đ c gán cho m t bí danh m i, và khi đó ch nào xu t hi n bi n thì cũngộ ế ể ượ ộ ớ ỗ ấ ệ ế t ng đ ng nh dùng bí danh và ng c l i. M t bí danh nh v y đ c g i là m t bi nươ ươ ư ượ ạ ộ ư ậ ượ ọ ộ ế tham chi u, ý nghĩa th c t c a nó là cho phép "tham chi u" t i m t bi n khác cùng ki u c aế ự ế ủ ế ớ ộ ế ể ủ nó, t c s d ng bi n khác nh ng b ng tên c a bi n tham chi u.ứ ử ụ ế ư ằ ủ ế ế

Gi ng khai báo bi n bình th ng, tuy nhiên tr c tên bi n ta thêm d u và (&). Có th t mố ế ườ ướ ế ấ ể ạ phân bi n thành 3 lo i: bi n th ng v i tên th ng, bi n con tr v i d u * tr c tên và bi nế ạ ế ườ ớ ườ ế ỏ ớ ấ ướ ế tham chi u v i d u &.ế ớ ấ

<ki u bi n> &<tên bi n tham chi u> = <tên bi n đ c tham chi u>;ể ế ế ế ế ượ ế

Cú pháp khai báo này cho phép ta t o ra m t bi n tham chi u m i và cho nó tham chi u đ nạ ộ ế ế ớ ế ế bi n đ c tham chi u (cùng ki u và ph i đ c khai báo t tr c). Khi đó bi n tham chi uế ượ ế ể ả ượ ừ ướ ế ế còn đ c g i là bí danh c a bi n đ c tham chi u. Chú ý không có cú pháp khai báo ch tênượ ọ ủ ế ượ ế ỉ bi n tham chi u mà không kèm theo kh i t o.ế ế ở ạ

Ví d :ụ

int hung, dung ; // khai báo các bi n nguyên hung, dungế

int &ti = hung; // khai báo bi n tham chi u ti, teo tham chieu đ nế ế ế

int &teo = dung; // hung dung. ti, teo là bí danh c a hung, dungủT v trí này tr đi vi c s d ng các tên hung, ti ho c dung, teo là nh nhau.ừ ị ở ệ ử ụ ặ ư

Ví d :ụ

hung = 2 ;

ti ++; // tương đương hung ++;

cout << hung << ti ; // 3 3

teo = ti + hung ; // t ng đ ng dung = hung + hungươ ươ

dung ++ ; // t ng đ ng teo ++ươ ươ

cout << dung << teo ; // 7 7V y s d ng thêm bi n tham chi u đ làm gì ?ậ ử ụ ế ế ể

Cách t ch c bên trong c a m t bi n tham chi u khác v i bi n th ng ch n i dung c a nóổ ứ ủ ộ ế ế ớ ế ườ ở ỗ ộ ủ là đ a ch c a bi n mà nó đ i di n (gi ng bi n con tr ), ví d câu l nhị ỉ ủ ế ạ ệ ố ế ỏ ụ ệ

cout << teo ; // 7

Page 103: Giao Trinh C++ Toan Tap

in ra giá tr 7 nh ng th c ch t đây không ph i là n i dung c a bi n teo, n i dung c a teo là đ aị ư ự ấ ả ộ ủ ế ộ ủ ị ch c a dung, khi c n in teo, ch ng trình s tham chi u đ n dung và in ra n i dung c a dungỉ ủ ầ ươ ẽ ế ế ộ ủ (7). Các ho t đ ng khác trên teo cũng v y (ví d teo++), th c ch t là tăng m t đ n v n i dungạ ộ ậ ụ ự ấ ộ ơ ị ộ c a dung (ch không ph i c a teo). T cách t ch c c a bi n tham chi u ta th y chúng gi ngủ ứ ả ủ ừ ổ ứ ủ ế ế ấ ố con tr nh ng thu n l i h n ch khi truy c p đên giá tr c a bi n đ c tham chi u (dung) taỏ ư ậ ợ ơ ở ỗ ậ ị ủ ế ượ ế ch c n ghi tên bi n tham chi u (teo) ch không c n thêm toán t (*) tr c nh tr ng h pỉ ầ ế ế ứ ầ ử ở ướ ư ườ ợ dùng con tr . Đi m khác bi t này có ích khi đ c s d ng đ truy n đ i cho các hàm v iỏ ể ệ ượ ử ụ ể ề ố ớ m c đích làm thay đ i n i dung c a bi n ngoài. T t ng này đ c trình bày rõ ràng h nụ ổ ộ ủ ế ư ưở ượ ơ trong m c 6 c a ch ng.ụ ủ ươ

Chú ý:

Bi n tham chi u ph i đ c kh i t o khi khai báo. ế ế ả ượ ở ạ

Tuy gi ng con tr nh ng không dùng đ c các phép toán con tr cho bi n tham chi u.ố ỏ ư ượ ỏ ế ế Nói chung ch nên dùng trong truy n đ i cho hàm.ỉ ề ố

Các cách truy n tham đ i ề ốCó 3 cách truy n tham đ i th c s cho các tham đ i hình th c trong l i g i hàm. Trong đóề ố ự ự ố ứ ờ ọ cách ta đã dùng cho đ n th i đi m hi n nay đ c g i là truy n theo tham tr , t c các đ i hìnhế ờ ể ệ ượ ọ ề ị ứ ố th c s nh n các giá tr c th t l i g i hàm và ti n hành tính toán r i tr l i giá tr . Đ dứ ẽ ậ ị ụ ể ừ ờ ọ ế ồ ả ạ ị ể ễ hi u các cách truy n đ i chúng ta s xem qua cách th c ch ng trình th c hi n v i các đ iể ề ố ẽ ứ ươ ự ệ ớ ố khi th c hi n hàm.ự ệ

Truy n theo tham trề ịTa xét l i ví d hàm luythua(float x, int n) tính xạ ụ n. Gi s trong ch ng trình chính ta có cácả ử ươ bi n a, b, f đang ch a các giá tr a = 2, b = 3, và f ch a có giá tr . Đ tính aế ứ ị ư ị ể b và gán giá tr tínhị đ c cho f, ta có th g i f = luythua(a,b). Khi g p l i g i này, ch ng trình s t ch c nhượ ể ọ ặ ờ ọ ươ ẽ ổ ứ ư sau:

T o 2 bi n m i (t c 2 ô nh trong b nh ) có tên x và n. Gán n i dung các ô nh nàyạ ế ớ ứ ớ ộ ớ ộ ớ b ng các giá tr trong l i g i, t c gán 2 (a) cho x và 3 (b) cho n.ằ ị ờ ọ ứ

T i ph n khai báo (c a hàm), ch ng trình t o thêm các ô nh mang tên kq và i.ớ ầ ủ ươ ạ ớ

Ti n hành tính toán (gán l i k t qu cho kq). ế ạ ế ả

Cu i cùng l y k t qu trong kq gán cho ô nh f (là ô nh có s n đã đ c khai báo tr c,ố ấ ế ả ớ ớ ẵ ượ ướ n m bên ngoài hàm).ằ

K t thúc hàm quay v ch ng trình g i. Do hàm luythua đã hoàn thành xong vi c tínhế ề ươ ọ ệ toán nên các ô nh đ c t o ra trong khi th c hi n hàm (x, n, kq, i) s đ c xoá kh iớ ượ ạ ự ệ ẽ ượ ỏ b nh . K t qu tính toán đ c l u gi trong ô nh f (không b xoá vì không liênộ ớ ế ả ượ ư ữ ớ ị quan gì đ n hàm).ế

Trên đây là truy n đ i theo cách thông th ng. V n đ đ t ra là gi s ngoài vi c tính f, taề ố ườ ấ ề ặ ả ử ệ còn mu n thay đ i các giá tr c a các ô nh a, b (khi truy n nó cho hàm) thì có th th c hi nố ố ị ủ ớ ề ể ự ệ

Page 104: Giao Trinh C++ Toan Tap

đ c không ? Đ gi i quy t bài toán này ta c n theo m t k thu t khác, nh vào vai trò c aượ ể ả ế ầ ộ ỹ ậ ờ ủ bi n con tr và tham chi u.ế ỏ ế

Truy n theo d n trề ẫ ỏXét ví d tráo đ i giá tr c a 2 bi n. Đây là m t yêu c u nh nh ng đ c g p nhi u l n trongụ ổ ị ủ ế ộ ầ ỏ ư ượ ặ ề ầ ch ng trình, ví d đ s p x p m t danh sách. Do v y c n vi t m t hàm đ th c hi n yêuươ ụ ể ắ ế ộ ậ ầ ế ộ ể ự ệ c u trên. Hàm không tr k t qu . Do các bi n c n trao đ i là ch a đ c bi t tr c t i th iầ ả ế ả ế ầ ổ ư ượ ế ướ ạ ờ đi m vi t hàm, nên ta ph i đ a chúng vào hàm nh các tham đ i, t c hàm có hai tham đ i x, yể ế ả ư ư ố ứ ố đ i di n cho các bi n s thay đ i giá tr sau này.ạ ệ ế ẽ ổ ị

T m t vài nh n xét trên, theo thông th ng hàm tráo đ i s đ c vi t nh sau:ừ ộ ậ ườ ổ ẽ ượ ế ư

void swap(int x, int y)

{

int t ; t = x ; x = y ; y = t ;

}Gi s trong ch ng trình chính ta có 2 bi n x, y ch a các giá tr l n l t là 2, 5. Ta c n đ iả ử ươ ế ứ ị ầ ượ ầ ổ n i dung 2 bi n này sao cho x = 5 còn y = 2 b ng cách g i đ n hàm swap(x, y).ộ ế ằ ọ ế

main()

{

int x = 2; int y = 5;

swap(x, y) ;

cout << x << y ; // 2, 5 (x, y v n không đ i)ẫ ổ

}Th c s sau khi ch y xong ch ng trình ta th y giá tr c a x và y v n không thay đ i !?.ự ự ạ ươ ấ ị ủ ẫ ổ

Nh đã gi i thích trong m c trên (g i hàm luythua), vi c đ u tiên khi ch ng trình th c hi nư ả ụ ọ ệ ầ ươ ự ệ m t hàm là t o ra các bi n m i (các ô nh m i, đ c l p v i các ô nh x, y đã có s n) t ngộ ạ ế ớ ớ ớ ộ ậ ớ ớ ẵ ươ

ng v i các tham đ i, trong tr ng h p này cũng có tên là x, y và gán n i dung c a x, y (ngoàiứ ớ ố ườ ợ ộ ủ hàm) cho x, y (m i). Và vi c cu i cùng c a ch ng trình sau khi th c hi n xong hàm là xoáớ ệ ố ủ ươ ự ệ các bi n m i này. Do v y n i dung c a các bi n m i th c s là có thay đ i, nh ng không nhế ớ ậ ộ ủ ế ớ ự ự ổ ư ả h ng gì đ n các bi n x, y cũ. Hình v d i đây minh ho cách làm vi c c a hàm swap,ưở ế ế ẽ ướ ạ ệ ủ tr c, trong và sau khi g i hàm.ướ ọ

Tr cướ Trong Sau

x y x y x y

2 5 2 5 2 5

Page 105: Giao Trinh C++ Toan Tap

t x' y'

2 2 5 Các bi n t m bế ạ ị xoá khi ch y xongạ

hàm2 5 5

2 5 2

Nh v y hàm swap c n đ c vi t l i sao cho vi c thay đ i giá tr không th c hi n trên cácư ậ ầ ượ ế ạ ệ ố ị ự ệ bi n t m mà ph i th c s th c hi n trên các bi n ngoài. Mu n v y thay vì truy n giá tr c aế ạ ả ự ự ự ệ ế ố ậ ề ị ủ các bi n ngoài cho đ i, bây gi ta s truy n đ a ch c a nó cho đ i, và các thay đ i s ph iế ố ờ ẽ ề ị ỉ ủ ố ổ ẽ ả th c hi n trên n i dung c a các đ a ch này. Đó chính là lý do ta ph i s d ng con tr đ làmự ệ ộ ủ ị ỉ ả ử ụ ỏ ể tham đ i thay cho bi n th ng. C th hàm swap đ c vi t l i nh ố ế ườ ụ ể ượ ế ạ ư sau:

void swap(int *p, int *q)

{

int t; // khai báo bi n t m tế ạ

t = *p ; // đ t giá tr c a t b ng n i dung n i p tr t iặ ị ủ ằ ộ ơ ỏ ớ

*p = *q ; // thay n i dung n i p tr b ng n i dung n i q tr ộ ơ ỏ ằ ộ ơ ỏ

*q = t ; // thay n i dung n i q tr t i b ng n i dung c a tộ ơ ỏ ớ ằ ộ ủ

}V i cách t ch c hàm nh v y rõ ràng n u ta cho p tr t i bi n x và q tr t i bi n y thì hàmớ ổ ứ ư ậ ế ỏ ớ ế ỏ ớ ế swap s th c s làm thay đ i n i dung c a x, y ch không ph i c a p, q.ẽ ự ự ổ ộ ủ ứ ả ủ

T đó l i g i hàm s là swap(&x, &y) (t c truy n đ a ch c a x cho p, p tr t i x và t ng từ ờ ọ ẽ ứ ề ị ỉ ủ ỏ ớ ươ ự q tr t i y).ỏ ớ

Nh v y có th tóm t t 3 đ c tr ng đ vi t m t hàm làm thay đ i giá tr bi n ngoài nh sau:ư ậ ể ắ ặ ư ể ế ộ ổ ị ế ư

Đ i c a hàm ph i là con tr (ví d int *p)ố ủ ả ỏ ụ

Các thao tác liên quan đ n đ i này (trong thân hàm) ph i th c hi n t i n i nó tr đ n (víế ố ả ự ệ ạ ơ ỏ ế d *p = …)ụ

L i g i hàm ph i chuy n đ a ch cho p (ví d &x).ờ ọ ả ể ị ỉ ụNgoài hàm swap đã trình bày, đây ta đ a thêm ví d đ th y s c n thi t ph i có hàm choở ư ụ ể ấ ự ầ ế ả phép thay đ i bi n ngoài. Ví d hàm gi i ph ng trình b c 2 r t hay g p trong các bài toánổ ế ụ ả ươ ậ ấ ặ khoa h c k thu t. T c cho tr c 3 s a, b, c nh 3 h s c a ph ng trình, c n tìm 2ọ ỹ ậ ứ ướ ố ư ệ ố ủ ươ ầ nghi m x1, x2 c a nó. Không th l y giá tr tr l i c a hàm đ làm nghi m vì giá tr tr l iệ ủ ể ấ ị ả ạ ủ ể ệ ị ả ạ ch có 1 trong khi ta c n đ n 2 nghi m. Do v y ta c n khai báo 2 bi n "ngoài" trong ch ngỉ ầ ế ệ ậ ầ ế ươ trình đ ch a các nghi m, và hàm ph i làm thay đ i 2 bi n này (t c ch a giá tr nghi m gi iể ứ ệ ả ổ ế ứ ứ ị ệ ả đ c). Nh v y hàm đ c vi t c n ph i có 5 đ i, trong đó 3 đ i a, b, c đ i di n cho các hượ ư ậ ượ ế ầ ả ố ố ạ ệ ệ s , không thay đ i và 2 bi n x1, x2 đ i di n cho nghi m, 2 đ i này ph i đ c khai báo d ngố ổ ế ạ ệ ệ ố ả ượ ạ con tr . Ngoài ra, ph ng trình có th vô nghi m, 1 nghi m ho c 2 nghi m do v y hàm s trỏ ươ ể ệ ệ ặ ệ ậ ẽ ả

Page 106: Giao Trinh C++ Toan Tap

l i giá tr là s nghi m c a ph ng trình, trong tr ng h p 1 nghi m (nghi m kép), giá trạ ị ố ệ ủ ươ ườ ợ ệ ệ ị nghi m s đ c cho vào x1. ệ ẽ ượ

: D i đây là m t d ng đ n gi n c a hàm gi i ph ng trình b c 2.ướ ộ ạ ơ ả ủ ả ươ ậ

int gptb2(float a, float b, float c, float *p, float *q)

{

float d ; // đ ch a Dể ứ

d = (b*b) - 4*a*c ;

if (d < 0) return 0 ;

else if (d == 0) { *p = -b/(2*a) ; return 1 ; }

else {

*p = (-b + sqrt(d))/(2*a) ;

*q = (-b - sqrt(d))/(2*a) ;

return 2 ;

}

}M t ví d c a l i g i hàm trong ch ng trình chính nh sau:ộ ụ ủ ờ ọ ươ ư

main()

{

float a, b, c ; // các h s ệ ố

float x1, x2 ; // các nghi mệ

cout << "Nh p h s : " ;ậ ệ ố

cin >> a >> b >> c;

switch (gptb2(a, b, c, &x1, &x2))

{

case 0: cout << "Ph ng trình vô nghi m" ; break;ươ ệ

case 1: cout << "Ph ng trình có nghi m kép x = " << x1 ; break ;ươ ệ

case 2: cout << "Ph ng trình có 2 nghi m phân bi t:" << endl ;ươ ệ ệ

cout << "x1 = " << x1 << " và x2 = " << x2 << endl ; break;

}

}Trên đây chúng ta đã trình bày cách xây d ng các hàm cho phép thay đ i giá tr c a bi n ngoài.ự ổ ị ủ ế M t đ c tr ng d nh n th y là cách vi t hàm t ng đ i ph c t p. Do v y C++ đã phát tri nộ ặ ư ễ ậ ấ ế ươ ố ứ ạ ậ ể

Page 107: Giao Trinh C++ Toan Tap

m t cách vi t khác d a trên đ i tham chi u và vi c truy n đ i cho hàm đ c g i là truy nộ ế ự ố ế ệ ề ố ượ ọ ề theo tham chi u.ế

Truy n theo tham chi uề ếM t hàm vi t d i d ng đ i tham chi u s đ n gi n h n r t nhi u so v i đ i con tr vàộ ế ướ ạ ố ế ẽ ơ ả ơ ấ ề ớ ố ỏ gi ng v i cách vi t bình th ng (truy n theo tham tr ), trong đó ch có m t khác bi t đó là cácố ớ ế ườ ề ị ỉ ộ ệ đ i khai báo d i d ng tham chi u.ố ướ ạ ế

Đ so sánh 2 cách s d ng ta nh c l i các đi m khi vi t hàm theo con tr ph i chú ý đ n, đóể ử ụ ắ ạ ể ế ỏ ả ế là:

Đ i c a hàm ph i là con tr (ví d int *p)ố ủ ả ỏ ụ

Các thao tác liên quan đ n đ i này trong thân hàm ph i th c hi n t i n i nó tr đ n (víế ố ả ự ệ ạ ơ ỏ ế d *p = …)ụ

L i g i hàm ph i chuy n đ a ch cho p (ví d &x).ờ ọ ả ể ị ỉ ụHãy so sánh v i đ i tham chi u, c th :ớ ố ế ụ ể

Đ i c a hàm ph i là tham chi u (ví d int &p)ố ủ ả ế ụ

Các thao tác liên quan đ n đ i này ph i th c hi n t i n i nó tr đ n, t c đ a ch c nế ố ả ự ệ ạ ơ ỏ ế ứ ị ỉ ầ thao tác. Vì m t thao tác trên bi n tham chi u th c ch t là thao tác trên bi n đ c nóộ ế ế ự ấ ế ượ tham chi u nên trong hàm ch c n vi t p trong m i thao tác (thay vì *p nh trong conế ỉ ầ ế ọ ư tr )ỏ

L i g i hàm ph i chuy n đ a ch cho p. Vì b n thân p khi tham chi u đ n bi n nào thìờ ọ ả ể ị ỉ ả ế ế ế s ch a đ a ch c a bi n đó, do đó l i g i hàm ch c n ghi tên bi n, ví d x (thay vìẽ ứ ị ỉ ủ ế ờ ọ ỉ ầ ế ụ &x nh đ i v i d n tr ).ư ố ớ ẫ ỏ

Tóm l i, đ i v i hàm vi t theo tham chi u ch thay đ i đ i (là các tham chi u) còn l i m iạ ố ớ ế ế ỉ ổ ở ố ế ạ ọ n i khác đ u vi t đ n gi n nh cách vi t truy n theo tham tr .ơ ề ế ơ ả ư ế ề ị

: Đ i giá tr 2 bi nổ ị ế

void swap(int &x, int &y)

{

int t = x; x = y; y = t;

}và l i g i hàm cũng đ n gi n nh trong truy n đ i theo tham tr . ờ ọ ơ ả ư ề ố ị Ví d :ụ

int a = 5, b = 3;

swap(a, b);

cout << a << b;B ng d i đây minh ho tóm t t 3 cách vi t hàm thông qua ví d đ i bi n trên.ả ướ ạ ắ ế ụ ổ ế ở

Page 108: Giao Trinh C++ Toan Tap

Tham trị Tham chi uế D n trẫ ỏ

Khai báo đ iố

void swap(int x, int y) void swap(int &x, int &y) void swap(int *x, int *y)

Câu l nh ệ t = x; x = y; y = t; t = x; x = y; y = t; t = *x; *x = *y; *y = t;

L i g iờ ọ swap(a, b); swap(a, b); swap(&a, &b);

Tác d ngụ a, b không thay đ i ổ a, b có thay đ i ổ a, b có thay đ i ổ

Hàm và m ng d li u ả ữ ệ

Truy n m ng 1 chi u cho hàmề ả ềThông th ng chúng ta hay xây d ng các hàm làm vi c trên m ng nh vect hay ma tr n cácườ ự ệ ả ư ơ ậ ph n t . Khi đó tham đ i th c s c a hàm s là các m ng d li u này. Trong tr ng h p nàyầ ử ố ự ự ủ ẽ ả ữ ệ ườ ợ ta có 2 cách khai báo đ i. Cách th nh t đ i đ c khai báo bình th ng nh khai báo bi nố ứ ấ ố ượ ườ ư ế m ng nh ng không c n có s ph n t kèm theo, ví d :ả ư ầ ố ầ ử ụ

int x[];

float x[]; Cách th hai khai báo đ i nh m t con tr ki u ph n t m ng, ví d :ứ ố ư ộ ỏ ể ầ ử ả ụ

int *p;

float *pTrong l i g i hàm tên m ng a s đ c vi t vào danh sách tham đ i th c s , vì a là đ a ch c aờ ọ ả ẽ ượ ế ố ự ự ị ỉ ủ ph n t đ u tiên c a m ng a, nên khi hàm đ c g i đ a ch này s gán cho con tr p. Vì v yầ ử ầ ủ ả ượ ọ ị ỉ ẽ ỏ ậ giá tr c a ph n t th i c a a có th đ c truy c p b i x[i] (theo khai báo 1) ho c *(p+i)ị ủ ầ ử ứ ủ ể ượ ậ ở ặ (theo khai báo 2) và nó cũng có th đ c thay đ i th c s (do đây cũng là cách truy n theoể ượ ổ ự ự ề d n tr ).ẫ ỏ

Sau đây là ví d đ n gi n, nh p và in vect , minh ho cho c 2 ki u khai báo đ i.ụ ơ ả ậ ơ ạ ả ể ố

: Hàm nh p và in giá tr 1 vectậ ị ơ

void nhap(int x[], int n) // n: s ph n t ố ầ ử

{

int i;

for (i=0; i<n; i++) cin >> x[i]; // ho c cin >> *(x+i)ặ

}

void in(int *p, int n)

{

int i;

Page 109: Giao Trinh C++ Toan Tap

for (i=0; i<n; i++) cout << *(p+i);

}

main()

{

int a[10] ; // m ng a ch a t i đa 10 ph n t ả ứ ố ầ ử

nhap(a,7); // vào 7 ph n t đ u tiên cho aầ ử ầ

in(a,3); // ra 3 ph n t đ u tiên c a aầ ử ầ ủ

}

Truy n m ng 2 chi u cho hàmề ả ềĐ i v i m ng 2 chi u khai báo đ i cũng nh l i g i là ph c t p h n nhi u so v i m ng 1ố ớ ả ề ố ư ờ ọ ứ ạ ơ ề ớ ả chi u. Ta có hai cách khai báo đ i nh sau:ề ố ư

Khai báo theo đúng b n ch t c a m ng 2 chi u float x[m][n] do C++ qui đ nh, t c x làả ấ ủ ả ề ị ứ m ng 1 chi u m ph n t , m i ph n t c a nó có ki u float[n]. T đó, đ i đ c khaiả ề ầ ử ỗ ầ ử ủ ể ừ ố ượ báo nh m t m ng hình th c 1 chi u (kh ng c n s ph n t - đây là s dòng) c aư ộ ả ứ ề ồ ầ ố ầ ử ở ố ủ ki u float[n]. T c có th khai báo nh sau:ể ứ ể ư

float x[][n] ; // m ng v i s ph n t không đ nh tr c, m i ph n t là n s ả ớ ố ầ ử ị ướ ỗ ầ ử ố

float (*x)[n] ; // m t con tr , có ki u là m ng n s (float[n])ộ ỏ ể ả ốĐ truy nh p đ n đ n ph n t th i, j ta v n s d ng cú pháp x[i][j]. Tên c a m ng a đ cể ậ ế ế ầ ử ứ ẫ ử ụ ủ ả ượ vi t bình th ng trong l i g i hàm. Nói chung theo cách khai báo này vi c truy nh p là đ nế ườ ờ ọ ệ ậ ơ gi n nh ng ph ng pháp cũng có h n ch đó là s c t c a m ng truy n cho hàm ph i cả ư ươ ạ ế ố ộ ủ ả ề ả ố đ nh b ng n.ị ằ

Xem m ng float x[m][n] th c s là m ng m t chi u float x[m*n] và s d ng cách khaiả ự ự ả ộ ề ử ụ báo nh trong m ng m t chi u, đó là s d ng con tr float *p đ truy c p đ c đ nư ả ộ ề ử ụ ỏ ể ậ ượ ế t ng ph n t c a m ng. Cách này có h n ch trong l i g i: đ a ch truy n cho hàmừ ầ ử ủ ả ạ ế ờ ọ ị ỉ ề không ph i là m ng a mà c n ph i ép ki u v (float*) (đ phù h p v i p). V i cáchả ả ầ ả ể ề ể ợ ớ ớ này g i k là th t c a ph n t a[i][j] trong m ng m t chi u (m*n), ta có quan họ ứ ự ủ ầ ử ả ộ ề ệ gi a k, i, j nh sau: ữ ư

k = *(p + i*n + j)

i = k/n

j = k%ntrong đó n là s c t c a m ng truy n cho hàm. Đi u này có nghĩa đ truy c p đ n a[i][j] ta cóố ộ ủ ả ề ề ể ậ ế th vi t *(p+i*n+j), ng c l i bi t ch s k có th tính đ c dòng i, c t j c a ph n t này. uể ế ượ ạ ế ỉ ố ể ượ ộ ủ ầ ử Ư đi m c a cách khai báo này là ta có th truy n m ng v i kích th c b t kỳ (s c t không c nể ủ ể ề ả ớ ướ ấ ố ộ ầ đ nh tr c) cho hàm. ị ướ

Sau đây là các ví d minh ho cho 2 cách khai báo trên.ụ ạ

: Tính t ng các s h ng trong ma tr nổ ố ạ ậ

Page 110: Giao Trinh C++ Toan Tap

float tong(float x[][10], int m, int n) // ho c float tong(float (*x)[10], int m, int n)ặ

{ // m: s dòng, n: s c tố ố ộ

float t = 0;

int i, j ;

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

for (j=0; j<n; j++) t += x[i][j] ;

return t;

}

main()

{

float a[8][10], b[5][7] ;

int i, j, ma, na, mb, nb;

cout << "nh p s dòng, s c t ma tr n a: " ; cin >> ma >> na;ậ ố ố ộ ậ

for (i=0; i<ma; i++) // nh p ma tr n aậ ậ

for (j=0; j<na; j++)

{ cout << "a[" << i << "," << j << "] = " ; cin >> a[i][j] ; }

cout << "nh p s dòng, s c t ma tr n b: " ; cin >> mb >> nb;ậ ố ố ộ ậ

for (i=0; i<mb; i++) // nh p ma tr n bậ ậ

for (j=0; j<nb; j++)

{ cout << "b[" << i << "," << j << "] = " ; cin >> b[i][j] ; }

cout << tong(a, ma, na); // in t ng các s trong ma tr nổ ố ậ

cout << tong(b, mb, nb); // sai vì s c t c a b khác 10ố ộ ủ

}

: Tìm ph n t bé nh t c a ma tr nầ ử ấ ủ ậ

void minmt(float *x, int m, int n) // m: s dòng, n: s c tố ố ộ

{

float min = *x; // gán ph n t đ u tiên cho minầ ử ầ

int k, kmin;

for (k=1; k<m*n; k++)

if (min > *(x+k)) { min = *(x+k) ; kmin = k; }

cout << "Giá tr min la: " << min << " t i dòng " << k/n << " c t " << k%n;ị ạ ộ

}

Page 111: Giao Trinh C++ Toan Tap

main()

{

float a[8][10], b[5][7] ;

int i, j ;

for (i=0; i<8; i++) // nh p ma tr n aậ ậ

for (j=0; j<10; j++)

{ cout << "a[" << i << "," << j << "] = " ; cin >> a[i][j] ; }

for (i=0; i<5; i++) // nh p ma tr n bậ ậ

for (j=0; j<7; j++)

{ cout << "b[" << i << "," << j << "] = " ; cin >> b[i][j] ; }

minmt((float*)a, 8, 10) ; // in giá tr và v trí s bé nh t trong aị ị ố ấ

minmt((float*)b, 5, 7) ; // in giá tr và v trí s bé nh t trong bị ị ố ấ

}

: C ng 2 ma tr n và in k t qu .ộ ậ ế ả

void inmt(float *x, int m, int n)

{

int i, j;

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

{

for (j=0; j<n; j++) cout << *(x+i*n+j);

cout << endl;

}

}

void cong(float *x, float *y, int m, int n)

{

float *t = new float[m*n]; // t là ma tr n k t qu (xem nh dãy s )ậ ế ả ư ố

int k, i, j ;

for (k = 0; k < m*n; k++) *(t+k) = *(x+k) + *(y+k) ;

inmt((float*)t, m, n);

}

Page 112: Giao Trinh C++ Toan Tap

main()

{

float a[8][10], b[5][7] ;

int i, j, m, n;

cout << "nh p s dòng, s c t ma tr n: " ; cin >> m >> n;ậ ố ố ộ ậ

for (i=0; i<m; i++) // nh p ma tr n a, bậ ậ

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

{

cout << "a[" << i << "," << j << "] = " ; cin >> a[i][j] ;

cout << "b[" << i << "," << j << "] = " ; cin >> b[i][j] ;

}

cong((float*)a, (float*)b, m, n); // c ng và in k t qu a+bộ ế ả

}Xu h ng chung là chúng ta xem m ng (1 ho c 2 chi u) nh là m t dãy liên ti p các s trongướ ả ặ ề ư ộ ế ố b nh , t c m t ma tr n là m t đ i con tr tr đ n thành ph n c a m ng. Đ i v i m ng 2ộ ớ ứ ộ ậ ộ ố ỏ ỏ ế ầ ủ ả ố ớ ả chi u m*n khi truy n đ i đ a ch c a ma tr n c n ph i ép ki u v ki u con tr . Ngoài raề ề ố ị ỉ ủ ậ ầ ả ể ề ể ỏ b c ch y k c a con tr (t 0 đ n m*n-1) t ng ng v i các to đ c a ph n t a[i][j] trongướ ạ ủ ỏ ừ ế ươ ứ ớ ạ ộ ủ ầ ử m ng nh sau: ả ư

k = *(p + i*n + j)

i = k/n

j = k%nt đó, chúng ta có th vi t các hàm mà không c n ph i băn khoăn gì v kích th c c aừ ể ế ầ ả ề ướ ủ

ma tr n s truy n cho hàm. ậ ẽ ề

Giá tr tr l i c a hàm là m t m ngị ả ạ ủ ộ ảKhông có cách nào đ giá tr tr l i c a m t hàm là m ng. Tuy nhiên th c s m i m ng cũngể ị ả ạ ủ ộ ả ự ự ỗ ả chính là m t con tr , vì v y vi c hàm tr l i m t con tr tr đ n dãy d li u k t qu làộ ỏ ậ ệ ả ạ ộ ỏ ỏ ế ữ ệ ế ả t ng đ ng v i vi c tr l i m ng. Ngoài ra còn m t cách d dùng h n đ i v i m ng 2ươ ươ ớ ệ ả ạ ả ộ ễ ơ ố ớ ả chi u là m ng k t qu đ c tr l i vào trong tham đ i c a hàm (gi ng nh nghi m c aề ả ế ả ượ ả ạ ố ủ ố ư ệ ủ ph ng trình b c 2 đ c tr l i vào trong các tham đ i). đây chúng ta s l n l t xét 2ươ ậ ượ ả ạ ố Ở ẽ ầ ượ cách làm vi c này.ệ

Giá tr tr l i là con tr tr đ n m ng k t qu . Tr c h t chúng ta xét ví d nh sauị ả ạ ỏ ỏ ế ả ế ả ướ ế ụ ỏ đây:

int* tragiatri1() // giá tr tr l i là con tr tr đ n dãy s nguyênị ả ạ ỏ ỏ ế ố

{

int kq[3] = { 1, 2, 3 }; // t o m ng k t qu v i 3 giá tr 1, 2, 3ạ ả ế ả ớ ị

Page 113: Giao Trinh C++ Toan Tap

return kq ; // tr l i đ a ch cho con tr k t qu hàmả ạ ị ỉ ỏ ế ả

}

int* tragiatri2() // giá tr tr l i là con tr tr đ n dãy s nguyênị ả ạ ỏ ỏ ế ố

{

int *kq = new int[4]; // c p phát 3 ô nh nguyênấ ớ

*kq = *(kq+1) = *(kq+2) = 0 ; // t o m ng k t qu v i 3 giá tr 1, 2, 3ạ ả ế ả ớ ị

return kq ; // tr l i đ a ch cho con tr k t qu hàmả ạ ị ỉ ỏ ế ả

}

main()

{

int *a, i;

a = tragiatri1();

for (i=0; i<3; i++) cout *(a+i); // không ph i là 1, 2, 3ả

a = tragiatri2();

for (i=0; i<3; i++) cout *(a+i); // 1, 2, 3

}Qua ví d trên ta th y hai hàm tr giá tr đ u t o bên trong nó m t m ng 3 s nguyên và trụ ấ ả ị ề ạ ộ ả ố ả l i đ a ch m ng này cho con tr k t qu hàm. Tuy nhiên, ch có tragiatri2() là cho l i k t quạ ị ỉ ả ỏ ế ả ỉ ạ ế ả đúng. T i sao ? Xét m ng kq đ c khai báo và kh i t o trong tragiatri1(), đây là m t m ngạ ả ượ ở ạ ộ ả c c b (đ c t o bên trong hàm) nh sau này chúng ta s th y, các lo i bi n "t m th i" nàyụ ộ ượ ạ ư ẽ ấ ạ ế ạ ờ (và c các tham đ i) ch t n t i trong quá trình hàm ho t đ ng. Khi hàm k t thúc các bi n nàyả ố ỉ ồ ạ ạ ộ ế ế s m t đi. Do v y tuy hàm đã tr l i đ a ch c a kq tr c khi nó k t thúc, th nh ng sau khiẽ ấ ậ ả ạ ị ỉ ủ ướ ế ế ư hàm th c hi n xong, toàn b kq s đ c xoá kh i b nh và vì v y con tr k t qu hàm đãự ệ ộ ẽ ượ ỏ ộ ớ ậ ỏ ế ả tr đ n vùng nh không còn các giá tr nh kq đã có. T đi u này vi c s d ng hàm tr l iỏ ế ớ ị ư ừ ề ệ ử ụ ả ạ con tr là ph i h t s c c n th n. Mu n tr l i con tr cho hàm thì con tr này ph i tr đ nỏ ả ế ứ ẩ ậ ố ả ạ ỏ ỏ ả ỏ ế dãy d li u nào sao cho nó không m t đi sau khi hàm k t thúc, hay nói khác h n đó ph i làữ ệ ấ ế ơ ả nh ng dãy d li u đ c kh i t o bên ngoài hàm ho c có th s d ng theo ph ng pháp trongữ ữ ệ ượ ở ạ ặ ể ử ụ ươ hàm tragiatri2(). Trong tragiatri2() m t m ng k t qu 3 s cũng đ c t o ra nh ng b ng cáchộ ả ế ả ố ượ ạ ư ằ xin c p phát vùng nh . Vùng nh đ c c p phát này s v n còn t n t i sau khi hàm k t thúcấ ớ ớ ượ ấ ẽ ẫ ồ ạ ế (nó ch b xoá đi khi s d ng toán t delete). Do v y ho t đ ng c a tragiatri2() là chính xác.ỉ ị ử ụ ử ậ ạ ộ ủ

Tóm l i, ví d trên cho th y n u mu n tr l i giá tr con tr thì vùng d li u mà nó tr đ nạ ụ ấ ế ố ả ạ ị ỏ ữ ệ ỏ ế ph i đ c c p phát m t cách t ng minh (b ng toán t new), ch không đ ch ng trình tả ượ ấ ộ ườ ằ ử ứ ể ươ ự đ ng c p phát và t đ ng thu h i. Ví d sau minh ho hàm c ng 2 vect và tr l i vect k tộ ấ ự ộ ồ ụ ạ ộ ơ ả ạ ơ ế qu (th c ch t là con tr tr đ n vùng nh đ t k t qu )ả ự ấ ỏ ỏ ế ớ ặ ế ả

Page 114: Giao Trinh C++ Toan Tap

int* congvt(int *x, int *y, int n) // n s ph n t c a vectố ầ ử ủ ơ

{

int* z = new int[n]; // xin c p phát b nhấ ộ ớ

for (int i=0; i<n; i++) z[i] = x[i] + y[i];

return c;

}

main()

{

int i, n, a[10], b[10], c[10] ;

cout << "n = " ; cin >> n; // nh p s ph n t ậ ố ầ ử

for (i=0; i<n; i++) cin >> a[i] ; // nh p vect aậ ơ

for (i=0; i<n; i++) cin >> b[i] ; // nh p vect bậ ơ

c = congvt(a, b, n);

for (i=0; i<n; i++) cout << c[i] ; // in k t quế ả

}Chú ý: a[i], b[i], c[i] còn đ c vi t d i d ng t ng đ ng *(a+i), *(b+i), *(c+i).ượ ế ướ ạ ươ ươ

Trong cách này, m ng c n tr l i đ c khai báo nh m t tham đ i trong danh sách đ iả ầ ả ạ ượ ư ộ ố ố c a hàm. Tham đ i này là m t con tr nên hi n nhiên khi truy n m ng đã khai báoủ ố ộ ỏ ể ề ả s n (đ ch a k t qu ) t ngoài vào cho hàm thì m ng s th c s nh n đ c n iẵ ể ứ ế ả ừ ả ẽ ự ự ậ ượ ộ dung k t qu (t c có thay đ i tr c và sau khi g i hàm - xem m c truy n tham đ iế ả ứ ổ ướ ọ ụ ề ố th c s theo d n tr ). đây ta xét 2 ví d : bài toán c ng 2 vect trong ví d tr cự ự ẫ ỏ Ở ụ ộ ơ ụ ướ và nhân 2 ma tr n. ậ

: C ng 2 vect , vect k t qu tr l i trong tham đ i c a hàm. So v i ví d tr c giá tr tr l iộ ơ ơ ế ả ả ạ ố ủ ớ ụ ướ ị ả ạ là void (không tr l i giá tr ) còn danh sách đ i có thêm con tr z đ ch a k t qu .ả ạ ị ố ỏ ể ứ ế ả

void congvt(int *x, int *y, int *z, int n) // z l u k t quư ế ả

{

for (int i=0; i<n; i++) z[i] = x[i] + y[i];

}

main()

{

int i, n, a[10], b[10], c[10] ;

cout << "n = " ; cin >> n; // nh p s ph n t ậ ố ầ ử

for (i=0; i<n; i++) cin >> a[i] ; // nh p vect aậ ơ

Page 115: Giao Trinh C++ Toan Tap

for (i=0; i<n; i++) cin >> b[i] ; // nh p vect bậ ơ

congvt(a, b, c, n);

for (i=0; i<n; i++) cout << c[i] ; // in k t quế ả

}

: Nhân 2 ma tr n kích th c m*n và n*p. Hai ma tr n đ u vào và ma tr n k t qu (kích th cậ ướ ậ ầ ậ ế ả ướ m*p) đ u đ c khai báo d i d ng con tr và là đ i c a hàm nhanmt(). Nh c l i, trong l iề ượ ướ ạ ỏ ố ủ ắ ạ ờ g i hàm đ a ch c a 3 m ng c n đ c ép ki u v (int*) đ phù h p v i các con tr tham đ i.ọ ị ỉ ủ ả ầ ượ ể ề ể ợ ớ ỏ ố

void nhanmt(int *x, int *y, int *z, int m, int n, int p) // z l u k t quư ế ả

{

int i, j, k ;

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

for (j=0; j<p; j++)

{

*(z+i*p+j) = 0; // t c z[i][j] = 0ứ

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

*(z+i*p+j) += *(x+i*n+k)**(y+k*p+j) ; // t c z[i][j] += x[i][k]*y[k][j]ứ

}

}

main()

{

int a[10][10], b[10][10], c[10][10] ; // khai báo 3 m ng a, b, cả

int m, n, p ; // kích th c các m ngướ ả

cout << "m, n, p = " ; cin >> m >> n >> p ; // nh p s ph n t ậ ố ầ ử

for (i=0; i<m; i++) // nh p ma tr n aậ ậ

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

cout << "a[" << i << "," << j << "] = " ; cin >> a[i][j] ;

for (i=0; i<n; i++) // nh p ma tr n bậ ậ

for (j=0; j<p; j++)

cout << "b[" << i << "," << j << "] = " ; cin >> b[i][j] ;

nhanmt((int*)a, (int*)b, (int*)c, m, n, p); // g i hàmọ

for (i=0; i<m; i++) // in k t quế ả

{

Page 116: Giao Trinh C++ Toan Tap

for (j=0; j<p; j++) cout << c[i][j] ;

cout << endl;

}

}

Đ i và giá tr tr l i là xâu kí tố ị ả ạ ựGi ng các tr ng h p đã xét v i m ng 1 chi u, đ i c a các hàm xâu kí t có th khai báoố ườ ợ ớ ả ề ố ủ ự ể d i 2 d ng: m ng kí t ho c con tr kí t . Giá tr tr l i luôn luôn là con tr kí t . Ngoài raướ ạ ả ự ặ ỏ ự ị ả ạ ỏ ự hàm cũng có th tr l i giá tr vào trong các đ i con tr trong danh sách đ i.ể ả ạ ị ố ỏ ố

Ví d sau đây dùng đ tách h , tên c a m t xâu h và tên. Ví d g m 3 hàm. Hàm h tr l iụ ể ọ ủ ộ ọ ụ ồ ọ ả ạ xâu h (con tr kí t ) v i đ i là xâu h và tên đ c khai báo d ng m ng. Hàm tên tr l i xâuọ ỏ ự ớ ố ọ ượ ạ ả ả ạ tên (con tr kí t ) v i đ i là xâu h và tên đ c khai báo d ng con tr kí t . Th c ch t đ i hỏ ự ớ ố ọ ượ ạ ỏ ự ự ấ ố ọ và tên trong hai hàm h , tên có th đ c khai báo theo cùng cách th c, đây ch ng trìnhọ ể ượ ứ ở ươ mu n minh ho các cách khai báo đ i khác nhau (đã đ c p đ n trong ph n đ i m ng 1ố ạ ố ề ậ ế ầ ố ả chi u). Hàm th ba cũng tr l i h , tên nh ng cho vào trong danh sách tham đ i, do v y hàmề ứ ả ạ ọ ư ố ậ không tr l i giá tr (void). Đ đ n gi n ta qui c xâu h và tên không ch a các d u cáchả ạ ị ể ơ ả ướ ọ ứ ấ đ u và cu i xâu, trong đó h là dãy kí t t đ u cho đ n khi g p d u cách đ u tiên và tên làầ ố ọ ự ừ ầ ế ặ ấ ầ dãy kí t t sau d u cách cu i cùng đ n kí t cu i xâu.ự ừ ấ ố ế ự ố

char* ho(char hoten[]) // hàm tr l i hả ạ ọ

{

char* kq = new char[10]; // c p b nh đ ch a hấ ộ ớ ể ứ ọ

int i=0;

while (hoten[i] != '\40') i++; // i d ng t i d u cách đ u tiênừ ạ ấ ầ

strncpy(kq, hoten, i) ; // copy i kí t c a hoten vào kqự ủ

return kq;

}

char* ten(char* hoten) // hàm tr l i tênả ạ

{

char* kq = new char[10]; // c p b nh đ ch a tênấ ộ ớ ể ứ

int i=strlen(hoten);

while (hoten[i] != '\40') i--; // i d ng t i d u cách cu i cùngừ ạ ấ ố

strncpy(kq, hoten+i+1, strlen(hoten)-i-1) ; // copy tên vào kq

return kq;

}

Page 117: Giao Trinh C++ Toan Tap

void tachht(char* hoten, char* ho, char* ten)

{

int i=0;

while (hoten[i] != '\40') i++; // i d ng t i d u cách đ u tiênừ ạ ấ ầ

strncpy(ho, hoten, i) ; // copy i kí t c a hoten vào hoự ủ

i=strlen(hoten);

while (hoten[i] != '\40') i--; // i d ng t i d u cách cu i cùngừ ạ ấ ố

strncpy(ten, hoten+i+1, strlen(hoten)-i-1) ; // copy tên vào ten

}

main()

{

char ht[30], *h, *t ; // các bi n h tên, h , tênế ọ ọ

cout << "H và tên = " ; cin.getline(ht,30) ;ọ // nh p h tênậ ọ

h = ho(ht); t = ten(ht);

cout << "H = " << h << ", tên = " << t << endl;ọ

tachht(ht, h, t);

cout << "H = " << h << ", tên = " << t << endl;ọ

}

Đ i là h ng con trố ằ ỏTheo ph n truy n đ i cho hàm ta đã bi t đ thay đ i bi n ngoài đ i t ng ng ph i đ cầ ề ố ế ể ổ ế ố ươ ứ ả ượ khai báo d i d ng con tr . Tuy nhiên, trong nhi u tr ng h p các bi n ngoài không có nhuướ ạ ỏ ề ườ ợ ế c u thay đ i nh ng đ i t ng ng v i nó v n ph i khai báo d i d ng con tr (ví d đ i làầ ổ ư ố ươ ứ ớ ẫ ả ướ ạ ỏ ụ ố m ng ho c xâu kí t ). Đi u này có kh năng do nh m l n, các bi n ngoài này s b thay đ iả ặ ự ề ả ầ ẫ ế ẽ ị ổ ngoài ý mu n. Trong tr ng h p nh v y đ c n th n, các đ i con tr n u không mu n thayố ườ ợ ư ậ ể ẩ ậ ố ỏ ế ố đ i (ch l y giá tr ) c n đ c khai báo nh là m t h ng con tr b ng cách thêm tr c khai báoổ ỉ ấ ị ầ ượ ư ộ ằ ỏ ằ ướ ki u c a chúng t khoá const. T khoá này kh ng đ nh bi n tuy là con tr nh ng nó là m tể ủ ừ ừ ẳ ị ế ỏ ư ộ h ng không thay đ i đ c giá tr . N u trong thân hàm ta c tình thay đ i chúng thì ch ngằ ổ ượ ị ế ố ổ ươ trình s báo l i. Ví d đ i hoten trong c 3 hàm trên có th đ c khai báo d ng const char*ẽ ỗ ụ ố ả ở ể ượ ạ hoten.

: Đ i là h ng con tr . ố ằ ỏ In hoa m t xâu kí tộ ự

void inhoa(const char* s)

{

char *t;

Page 118: Giao Trinh C++ Toan Tap

strcpy(t, s);

cout << s << strupr(t); // không dùng đ c strupr(s)ượ

}

main()

{

char *s = "abcde" ;

inhoa(s); // abcdeABCDE

}

Con tr hàmỏM t hàm (t p h p các l nh) cũng gi ng nh d li u: có tên g i , có đ a ch l u trong b nhộ ậ ợ ệ ố ư ữ ệ ọ ị ỉ ư ộ ớ và có th truy nh p đ n hàm thông qua tên g i ho c đ a ch c a nó. Đ truy nh p (g i hàm)ể ậ ế ọ ặ ị ỉ ủ ể ậ ọ thông qua đ a ch chúng ta ph i khai báo m t con tr ch a đ a ch này và sau đó g i hàm b ngị ỉ ả ộ ỏ ứ ị ỉ ọ ằ cách g i tên con tr . ọ ỏ

Khai báo<ki u giá tr > (*tên bi n hàm)(d/s tham ể ị ế đ i);ố

<ki u giá tr > (*tên bi n hàm)(d/s tham ể ị ế đ i) = <tên hàm>;ố

Ta th y cách khai báo con tr hàm cũng t ng t khai báo con tr bi n (ch c n đ t d u *ấ ỏ ươ ự ỏ ế ỉ ầ ặ ấ tr c tên), ngoài ra còn ph i bao *tên hàm gi a c p d u ngo c (). Ví d :ướ ả ữ ặ ấ ặ ụ

- float (*f)(int); // khai báo con tr hàm có tên là f tr đ n hàm ỏ ỏ ế

// có m t tham đ i ki u int và cho giá tr ki u float.ộ ố ể ị ể

- void (*f)(float, int); // con tr tr đ n hàm v i c p đ i (float, int).ỏ ỏ ế ớ ặ ốho c ph c t p h n:ặ ứ ạ ơ

- char* (*m[10])(int, char) // khai báo m t m ng 10 con tr hàm tr đ n ộ ả ỏ ỏ ế// các hàm có c p tham đ i (int, char), giá tr tr ặ ố ị ả

// l i c a các hàm này là xâu kí t . ạ ủ ự

Chú ý: phân bi t gi a 2 khai báo: float (*f)(int) và float *f(int). Cách khai báo tr c là khai báoệ ữ ướ con tr hàm có tên là f. Cách khai báo sau có th vi t l i thành float* f(int) là khai báo hàm fỏ ể ế ạ v i giá tr tr l i là m t con tr float. ớ ị ả ạ ộ ỏ

Kh i t o ở ạM t con tr hàm cũng gi ng nh các con tr , đ c phép kh i t o trong khi khai báo ho c gánộ ỏ ố ư ỏ ượ ở ạ ặ v i m t đ a ch hàm c th sau khi khai báo. Cũng gi ng nh ki u d li u m ng, tên hàmớ ộ ị ỉ ụ ể ố ư ể ữ ệ ả chính là m t h ng đ a ch tr đ n b n thân nó. Do v y cú pháp c a kh i t o cũng nh phépộ ằ ị ỉ ỏ ế ả ậ ủ ở ạ ư gán là nh sau: ư

Page 119: Giao Trinh C++ Toan Tap

bi n con tr hàm = tên hàm;ế ỏ

trong đó f và tên hàm đ c tr ph i gi ng nhau v ki u tr l i và danh sách đ i. Nói cáchượ ỏ ả ố ề ể ả ạ ố khác v i m c đích s d ng con tr f tr đ n hàm (l p hàm) nào đó thì f ph i đ c khai báoớ ụ ử ụ ỏ ỏ ế ớ ả ượ v i ki u tr l i và danh sách đ i gi ng nh hàm đó. Ví d :ớ ể ả ạ ố ố ư ụ

float luythua(float, int); // khai báo hàm lu th a ỹ ừ

float (*f)(float, int); // khai báo con tr f t ng thích v i hàm luythuaỏ ươ ớ

f = luythua; // cho f tr đ n hàm lu th aỏ ế ỹ ừ

S d ng con tr hàmử ụ ỏĐ s d ng con tr hàm ta ph i gán nó v i tên hàm c th và sau đó b t kỳ n i nào đ cể ử ụ ỏ ả ớ ụ ể ấ ơ ượ phép xu t hi n tên hàm thì ta đ u có th thay nó b ng tên con tr . Ví d nh các thao tác g iấ ệ ề ể ằ ỏ ụ ư ọ hàm, đ a hàm vào làm tham đ i hình th c cho m t hàm khác … Sau đây là các ví d minhư ố ứ ộ ụ ho .ạ

: Dùng tên con tr đ g i hàmỏ ể ọ

float bphuong(float x) // hàm tr l i xả ạ 2

{

return x*x;

}

void main()

{

float (*f)(float);

f = bphuong;

cout << "Bình ph ng c a 3.5 là " << f(3.5) ;ươ ủ

}

: Dùng hàm làm tham đ i. Tham đ i c a hàm ngoài các ki u d li u đã bi t còn có th là m tố ố ủ ể ữ ệ ế ể ộ hàm. Đi u này có tác d ng r t l n trong các bài toán tính toán trên nh ng đ i t ng là hàmề ụ ấ ớ ữ ố ượ toán h c nh tìm nghi m, tính tích phân c a hàm trên m t đo n ... Hàm đóng vai trò tham đ iọ ư ệ ủ ộ ạ ố s đ c khai báo d i d ng con tr hàm. Ví d sau đây trình bày hàm tìm nghi m x p x c aẽ ượ ướ ạ ỏ ụ ệ ấ ỉ ủ m t hàm liên t c và đ i d u trên đo n [a, b]. Đ hàm tìm nghi m này s d ng đ c trênộ ụ ổ ấ ạ ể ệ ử ụ ượ nhi u hàm toán h c khác nhau, trong hàm s ch a m t bi n con tr hàm và hai c n a, b, cề ọ ẽ ứ ộ ế ỏ ậ ụ th b ng khai báo ể ằ float timnghiem(float (*f)(float), float a, float b). Trong l i g i hàm f sờ ọ ẽ đ c thay th b ng tên hàm c th c n tìm nghi m.ượ ế ằ ụ ể ầ ệ

#define EPS 1.0e-6

float timnghiem(float (*f)(float), float a, float b);

float emu(float);

float loga(float);

Page 120: Giao Trinh C++ Toan Tap

void main()

{

clrscr();

cout << "Nghi m c a e mũ x - 2 trên đo n [0,1] = ";ệ ủ ạ

cout << timnghiem(emu,0,1));

cout << "Nghi m c a loga(x) - 1 trên đo n [2,3] = ";ệ ủ ạ

cout << timnghiem(loga,2,3));

getch();

}

float timnghiem(float (*f)(float), float a, float b)

{

float c = (a+b)/2;

while (fabs(a-b)>EPS && f(c)!=0)

{

if (f(a)*f(c)>0) a = c ; else b = c;

c = (a+b)/2;

}

return c;

}

float emux(float x) { return (exp(x)-2); }

float logx(float x) { return (log(x)-1); }

M ng con tr hàmả ỏT ng t nh bi n bình th ng các con tr hàm gi ng nhau có th đ c g p l i vào trongươ ự ư ế ườ ỏ ố ể ượ ộ ạ m t m ng, trong khai báo ta ch c n thêm [n] vào sau tên m ng v i n là s l ng t i đa cácộ ả ỉ ầ ả ớ ố ượ ố con tr . Ví d sau minh ho cách s d ng này. Trong ví d chúng ta xây d ng 4 hàm c ng,ỏ ụ ạ ử ụ ụ ự ộ tr , nhân, chia 2 s th c. Các hàm này gi ng nhau v ki u, s l ng đ i, … Chúng ta có thừ ố ự ố ề ể ố ượ ố ể s d ng 4 con tr hàm riêng bi t đ tr đ n các hàm này ho c cũng có th dùng m ng 4 conử ụ ỏ ệ ể ỏ ế ặ ể ả tr đ tr đ n các hàm này. Ch ng trình s in ra k t qu c ng, tr , nhân, chia c a 2 s nh pỏ ể ỏ ế ươ ẽ ế ả ộ ừ ủ ố ậ vào t bàn phím. ừ

:

void cong(int a, int b) { cout << a << " + " << b << " = " << a+b ; }

void tru(int a, int b) { cout << a << " - " << b << " = " << a-b ; }

Page 121: Giao Trinh C++ Toan Tap

void nhan(int a, int b) { cout << a << " x " << b << " = " << a*b ; }

void chia(int a, int b) { cout << a << ": " << b << " = " << a/b ; }

main()

{

clrscr();

void (*f[4])(int, int) = {cong, tru, nhan, chia}; // khai báo, kh i t o 4 con tr ở ạ ỏ

int m, n;

cout "Nh p m, n " ; cin >> m >> n ;ậ

for (int i=0; i<4; i++) f[i](m,n);

getch();

}

Đ QUIỆ

Khái ni m đ quiệ ệM t hàm g i đ n hàm khác là bình th ng, nh ng n u hàm l i g i đ n chính nó thì ta g iộ ọ ế ườ ư ế ạ ọ ế ọ hàm là đ qui. Khi th c hi n m t hàm đ qui, hàm s ph i ch y r t nhi u l n, trong m i l nệ ự ệ ộ ệ ẽ ả ạ ấ ề ầ ỗ ầ ch y ch ng trình s t o nên m t t p bi n c c b m i trên ngăn x p (các đ i, các bi n riêngạ ươ ẽ ạ ộ ậ ế ụ ộ ớ ế ố ế khai báo trong hàm) đ c l p v i l n ch y tr c đó, t đó d gây tràn ngăn x p. Vì v y đ iộ ậ ớ ầ ạ ướ ừ ễ ế ậ ố v i nh ng bài toán có th gi i đ c b ng ph ng pháp l p thì không nên dùng đ qui. ớ ữ ể ả ượ ằ ươ ặ ệ

Đ minh ho ta hãy xét hàm tính n giai th a. Đ tính n! ta có th dùng ph ng pháp l p nhể ạ ừ ể ể ươ ặ ư sau:

main()

{

int n; doule kq = 1;

cout << "n = " ; cin >> n;

for (int i=1; i<=n; i++) kq *= i;

cout << n << "! = " << kq;

}M t khác, n! giai th a cũng đ c tính thông qua (n-1)! b i công th c truy h iặ ừ ượ ở ứ ồ

n! = 1 n u n = 0ế

n! = (n-1)!n n u n > 0ếdo đó ta có th xây d ng hàm đ qui tính n! nh sau:ể ự ệ ư

double gt(int n)

Page 122: Giao Trinh C++ Toan Tap

{

if (n==0) return 1;

else return gt(n-1)*n;

}

main()

{

int n;

cout << "n = " ; cin >> n;

cout << gt(n);

}Trong hàm main() gi s ta nh p 3 cho n, khi đó đ th c hi n câu l nh cout << gt(3) đ in 3!ả ử ậ ể ự ệ ệ ể đ u tiên ch ng trình s g i ch y hàm gt(3). Do 3 ầ ươ ẽ ọ ạ ¹ 0 nên hàm gt(3) s tr l i giá tr gt(2)*3,ẽ ả ạ ị t c l i g i hàm gt v i tham đ i th c s b c này là n = 2. T ng t gt(2) = gt(1)*2 và gt(1)ứ ạ ọ ớ ố ự ự ở ướ ươ ự = gt(0)*1. Khi th c hi n gt(0) ta có đ i n = 0 nên hàm tr l i giá tr 1, t đó gt(1) = 1*1 = 1 vàự ệ ố ả ạ ị ừ suy ng c tr l i ta có gt(2) = gt(1)*2 = 1*2 = 2, gt(3) = gt(2)*3 = 2*3 = 6, ch ng trình in raượ ở ạ ươ k t qu 6.ế ả

T ví d trên ta th y hàm đ qui có đ c đi m:ừ ụ ấ ệ ặ ể

Ch ng trình vi t r t g n,ươ ế ấ ọ

Vi c th c hi n g i đi g i l i hàm r t nhi u l n ph thu c vào đ l n c a đ u vào.ệ ự ệ ọ ọ ạ ấ ề ầ ụ ộ ộ ớ ủ ầ Ch ng h n trong ví d trên hàm đ c g i n l n, m i l n nh v y ch ng trình sẳ ạ ụ ượ ọ ầ ỗ ầ ư ậ ươ ẽ m t th i gian đ l u gi các thông tin c a hàm g i tr c khi chuy n đi u khi n đ nấ ờ ể ư ữ ủ ọ ướ ể ề ể ế th c hi n hàm đ c g i. M t khác các thông tin này đ c l u tr nhi u l n trongự ệ ượ ọ ặ ượ ư ữ ề ầ ngăn x p s d n đ n tràn ngăn x p n u n l n.ế ẽ ẫ ế ế ế ớ

Tuy nhiên, đ qui là cách vi t r t g n, d vi t và đ c ch ng trình, m t khác có nhi u bàiệ ế ấ ọ ễ ế ọ ươ ặ ề toán h u nh tìm m t thu t toán l p cho nó là r t khó trong khi vi t theo thu t toán đ qui thìầ ư ộ ậ ặ ấ ế ậ ệ l i r t d dàng.ạ ấ ễ

L p các bài toán gi i đ c b ng đ quiớ ả ượ ằ ệPh ng pháp đ qui th ng đ c dùng đ gi i các bài toán có đ c đi m:ươ ệ ườ ượ ể ả ặ ể

Gi i quy t đ c d dàng trong các tr ng h p riêng g i là tr ng h p ả ế ượ ễ ườ ợ ọ ườ ợ suy bi nế hay cơ sở, trong tr ng h p này hàm đ c tính bình th ng mà không c n g i l i chính nó,ườ ợ ượ ườ ầ ọ ạ

Đ i v i tr ng h p ố ớ ườ ợ t ng quátổ , bài toán có th gi i đ c b ng bài toán cùng d ng nh ngể ả ượ ằ ạ ư v i tham đ i khác có kích th c nh h n tham đ i ban đ u. Và sau m t s b cớ ố ướ ỏ ơ ố ầ ộ ố ướ h u h n bi n đ i cùng d ng, bài toán đ a đ c v tr ng h p suy bi n.ữ ạ ế ổ ạ ư ượ ề ườ ợ ế

Page 123: Giao Trinh C++ Toan Tap

Nh v y trong tr ng h p tính n! n u n = 0 hàm cho ngay giá tr 1 mà không c n ph i g i l iư ậ ườ ợ ế ị ầ ả ọ ạ chính nó, đây chính là tr ng h p suy bi n. Tr ng h p n > 0 hàm s g i l i chính nó nh ngườ ợ ế ườ ợ ẽ ọ ạ ư v i n gi m 1 đ n v . Vi c g i này đ c l p l i cho đ n khi n = 0.ớ ả ơ ị ệ ọ ượ ặ ạ ế

M t l p r t r ng c a bài toán d ng này là các bài toán có th đ nh nghĩa đ c d i d ng độ ớ ấ ộ ủ ạ ể ị ượ ướ ạ ệ qui nh các bài toán l p v i s b c h u h n bi t tr c, các bài toán UCLN, tháp Hà N i, ...ư ặ ớ ố ướ ữ ạ ế ướ ộ

C u trúc chung c a hàm đ quiấ ủ ệD ng th c chung c a m t ch ng trình đ qui th ng nh sau:ạ ứ ủ ộ ươ ệ ườ ư

if (trư ng h p suy bi n)ờ ợ ế

{

trình bày cách gi i ả // gi ả đ nh ị đã có cách gi iả

}

else // trư ng h p t ng quátờ ợ ổ

{

g i l i hàm v i tham đ i "bé" h nọ ạ ớ ố ơ

}

Các ví dụ

: Tìm UCLN c a 2 s a, b. Bài toán có th đ c đ nh nghĩa d i d ng đ qui nh sau:ủ ố ể ượ ị ướ ạ ệ ư

n u a = b thì UCLN = aế

n u a > b thì UCLN(a, b) = UCLN(a-b, b)ế

n u a < b thì UCLN(a, b) = UCLN(a, b-a)ếT đó ta có ch ng trình đ qui đ tính UCLN c a a và b nh sau.ừ ươ ệ ể ủ ư

int UCLN(int a, int b) // qui uoc a, b > 0

{

if (a < b) UCLN(a, b-a);

if (a == b) return a;

if (a > b) UCLN(a-b, b);

}

: Tính s h ng th n c a dãy Fibonaci là dãy f(n) đ c đ nh nghĩa:ố ạ ứ ủ ượ ị

f(0) = f(1) = 1

f(n) = f(n-1) + f(n-2) v i "n ³ 2.ớ

long Fib(int n)

Page 124: Giao Trinh C++ Toan Tap

{

long kq;

if (n==0 || n==1) kq = 1; else kq = Fib(n-1) + Fib(n-2);

return kq;

}

: Chuy n tháp là bài toán c n i ti ng, n i dung nh sau: Cho m t tháp n t ng, đang x p t i vể ổ ổ ế ộ ư ộ ầ ế ạ ị trí 1. Yêu c u bài toán là hãy chuy n toàn b tháp sang v trí 2 (cho phép s d ng v trí trungầ ể ộ ị ử ụ ị gian 3) theo các đi u ki n sau đâyề ệ

m i l n ch đ c chuy n m t t ng trên cùng c a tháp,ỗ ầ ỉ ượ ể ộ ầ ủ

t i b t kỳ th i đi m t i c 3 v trí các t ng tháp l n h n ph i n m d i các t ng thápạ ấ ờ ể ạ ả ị ầ ớ ơ ả ằ ướ ầ nh h n.ỏ ơ

Bài toán chuy n tháp đ c minh ho b i hình v d i đây.ể ượ ạ ở ẽ ướ

tr c khi chuy nướ ể sau khi chuy nể

1 2 3 1 2 3

Bài toán có th đ c đ t ra t ng quát h n nh sau: chuy n tháp t v trí di đ n v trí den, trongể ượ ặ ổ ơ ư ể ừ ị ế ị đó di, den là các tham s có th l y giá tr là 1, 2, 3 th hi n cho 3 v trí. Đ i v i 2 v trí di vàố ể ấ ị ể ệ ị ố ớ ị den, d th y v trí trung gian (v trí còn l i) s là v trí 6-di-den (vì di+den+tg = 1+2+3 = 6). Tễ ấ ị ị ạ ẽ ị ừ đó đ chuy n tháp t v trí di đ n v trí den, ta có th xây d ng m t cách chuy n đ qui nhể ể ừ ị ế ị ể ự ộ ể ệ ư sau:

chuy n 1 t ng t di sang tg, ể ầ ừ

chuy n n-1 t ng còn l i t di sang den,ể ầ ạ ừ

chuy n tr t ng t i v trí tg v l i v trí denể ả ầ ạ ị ề ạ ịhi n nhiên n u s t ng là 1 thì ta ch ph i th c hi n m t phép chuy n t di sang den.ể ế ố ầ ỉ ả ự ệ ộ ể ừ

M i l n chuy n 1 t ng t v trí i đ n j ta kí hi u i ® j. Ch ng trình s nh p vào input là sỗ ầ ể ầ ừ ị ế ệ ươ ẽ ậ ố t ng và in ra các b c chuy n theo kí hi u trên.ầ ướ ể ệ

T đó ta có th xây d ng hàm đ qui sau đây ;ừ ể ự ệ

void chuyen(int n, int di, int den) // n: s t ng, di, den: v trí đi, đ n ố ầ ị ế

{

Page 125: Giao Trinh C++ Toan Tap

if (n==1) cout << di << " ® " << den << endl;

else {

cout << di << "®" << 6-di-den << endl; // 1 t ng t di qua trung gianầ ừ

chuyen(n-1, di, den) ; // n-1 t ng t di qua denầ ừ

cout << 6-di-den << "®" den << endl; // 1 t ng t tg v l i denầ ừ ề ạ

}

}

main()

{

int sotang ;

cout << "S t ng = " ; cin >> sotang;ố ầ

chuyen(sotang, 1, 2);

}Ví d n u s t ng b ng 3 thì ch ng trình in ra k t qu là dãy các phép chuy n sau đây:ụ ế ố ầ ằ ươ ế ả ể

1 ® 2 , 1 ® 3 , 2 ® 3 , 1 ® 2 , 3 ® 1 , 3 ® 2 , 1 ® 2.

có th tính đ c s l n chuy n là 2ể ượ ố ầ ể n - 1 v i n là s t ng.ớ ố ầ

T CH C CH NG TRÌNHỔ Ứ ƯƠ

Các lo i bi n và ph m viạ ế ạ

Bi n c c bế ụ ộLà các bi n đ c khai báo trong thân c a hàm và ch có tác d ng trong hàm này, k c cácế ượ ủ ỉ ụ ể ả bi n khai báo trong hàm main() cũng ch có tác d ng riêng trong hàm main(). T đó, tên bi nế ỉ ụ ừ ế trong các hàm là đ c phép trùng nhau. Các bi n c a hàm nào s ch t n t i trong th i gianượ ế ủ ẽ ỉ ồ ạ ờ hàm đó ho t đ ng. Khi b t đ u ho t đ ng các bi n này đ c t đ ng sinh ra và đ n khi hàmạ ộ ắ ầ ạ ộ ế ượ ự ộ ế k t thúc các bi n này s m t đi. Tóm l i, m t hàm đ c xem nh m t đ n v đ c l p, khépế ế ẽ ấ ạ ộ ượ ư ộ ơ ị ộ ậ kín.

Tham đ i c a các hàm cũng đ c xem nh bi n c c b .ố ủ ượ ư ế ụ ộ

: D i đây ta nh c l i m t ch ng trình nh g m 3 hàm: lu th a, xoá màn hình và main().ướ ắ ạ ộ ươ ỏ ồ ỹ ừ M c đích đ minh ho bi n c c b .ụ ể ạ ế ụ ộ

float luythua(float x, int n) // hàm tr giá tr xả ị n

{

int i ;

Page 126: Giao Trinh C++ Toan Tap

float kq = 1;

for (i=1; i<=n; i++) kq *= x;

return kq;

}

void xmh(int n) // xoá màn hình n l nầ

{

int i;

for (i=1; i<=n; i++) clrscr();

}

main()

{

float x; int n;

cout << "Nh p x và n: "; cin >> x >> n;ậ

xmh(5); // xoá màn hình 5 l nầ

cout << luythua(x, n); // in xn

}

Qua ví d trên ta th y các bi n i, đ i n đ c khai báo trong hai hàm: luythua() và xmh(). kqụ ấ ế ố ượ đ c khai báo trong luythua và main(), ngoài ra các bi n x và n trùng v i đ i c a hàmượ ế ớ ố ủ luythua(). Tuy nhiên, t t c khai báo trên đ u h p l và đ u đ c xem nh khác nhau. ấ ả ề ợ ệ ề ượ ư Có thể gi i thích nh sau:ả ư

T t c các bi n trên đ u c c b trong hàm nó đ c khai báo.ấ ả ế ề ụ ộ ượ

x và n trong main() có th i gian ho t đ ng dài nh t: trong su t quá trình ch y ch ngờ ạ ộ ấ ố ạ ươ trình. Chúng ch m t đi khi ch ng trình ch m d t. Đ i x và n trong luythua() chỉ ấ ươ ấ ứ ố ỉ t m th i đ c t o ra khi hàm luythua() đ c g i đ n và đ c l p v i x, n trongạ ờ ượ ạ ượ ọ ế ộ ậ ớ main(), nói cách khác t i th i đi m đó trong b nh có hai bi n x và hai bi n n. Khiạ ờ ể ộ ớ ế ế hàm luythua chay xong bi n x và n c a nó t đ ng bi n m t. ế ủ ự ộ ế ấ

T ng t 2 đ i n, 2 bi n i trong luythua() và xoá màn hình cũng đ c l p v i nhau, chúngươ ự ố ế ộ ậ ớ ch đ c t o và t n t i trong th i gian hàm c a chúng đ c g i và ho t đ ng.ỉ ượ ạ ồ ạ ờ ủ ượ ọ ạ ộ

Bi n ngoàiếLà các bi n đ c khai báo bên ngoài c a t t c các hàm. V trí khai báo c a chúng có th tế ượ ủ ấ ả ị ủ ể ừ đ u văn b n ch ng trình ho c t i m t m t v trí b t kỳ nào đó gi a văn b n ch ng trình.ầ ả ươ ặ ạ ộ ộ ị ấ ữ ả ươ Th i gian t n t i c a chúng là t lúc ch ng trình b t đ u ch y đ n khi k t thúc ch ngờ ồ ạ ủ ừ ươ ắ ầ ạ ế ế ươ trình gi ng nh các bi n trong hàm main(). Tuy nhiên v ph m vi tác d ng c a chúng là b tố ư ế ề ạ ụ ủ ắ

Page 127: Giao Trinh C++ Toan Tap

đ u t đi m khai báo chúng đ n h t ch ng trình, t c t t c các hàm khai báo sau này đ u cóầ ừ ể ế ế ươ ứ ấ ả ề th s d ng và thay đ i giá tr c a chúng. Nh v y các bi n ngoài đ c khai báo t đ uể ử ụ ổ ị ủ ư ậ ế ượ ừ ầ ch ng trình s có tác d ng lên toàn b ch ng trình. T t c các hàm đ u s d ng đ c cácươ ẽ ụ ộ ươ ấ ả ề ử ụ ượ bi n này n u trong hàm đó không có bi n khai báo trùng tên. M t hàm n u có bi n trùng tênế ế ế ộ ế ế v i bi n ngoài thì bi n ngoài b che đ i v i hàm này. Có nghĩa n u i đ c khai báo nh m tớ ế ế ị ố ớ ế ượ ư ộ bi n ngoài và ngoài ra trong m t hàm nào đó cũng có bi n i thì nh v y có 2 bi n i đ c l pế ộ ế ư ậ ế ộ ậ v i nhau và khi hàm truy nh p đ n i thì có nghĩa là i c a hàm ch không ph i i c a bi n ngoài.ớ ậ ế ủ ứ ả ủ ế

D i đây là ví d minh ho cho các gi i thích trên.ướ ụ ạ ả

: Chúng ta xét l i các hàm luythua() và xmh(). Chú ý r ng trong c hai hàm này đ u có bi n i,ạ ằ ả ề ế vì v y chúng ta có th khai báo i nh m t bi n ngoài (đ dùng chung cho luythua() và xmh()),ậ ể ư ộ ế ể ngoài ra x, n cũng có th đ c khai báo nh bi n ngoài. C th :ể ượ ư ế ụ ể

#include <iostream.h>

#include <iomanip.h>

float x; int n; int i ;

float luythua(float x, int n)

{

float kq = 1;

for (i=1; i<=n; i++) kq *= x;

}

void xmh()

{

for (i=1; i<=n; i++) clrscr();

}

main()

{

cout << "Nh p x và n: "; cin >> x >> n;ậ

xmh(5); // xoá màn hình 5 l nầ

cout << luythua(x, n); // in xn

}Trong ví d này ta th y các bi n x, n, i đ u là các bi n ngoài. Khi ta mu n s d ng bi n ngoàiụ ấ ế ề ế ố ử ụ ế ví d i, thì bi n i s không đ c khai báo trong hàm s d ng nó. Ch ng h n, luythua() vàụ ế ẽ ượ ử ụ ẳ ạ xmh() đ u s d ng i cho vòng l p for c a mình và nó không đ c khai báo l i trong 2 hàmề ử ụ ặ ủ ượ ạ này. Các đ i x và n trong luythua() là đ c l p v i bi n ngoài x và n. Trong luythua() khi số ộ ậ ớ ế ử

Page 128: Giao Trinh C++ Toan Tap

d ng đ n x và n (ví d câu l nh kq *= x) thì đây là x c a hàm ch không ph i bi n ngoài,ụ ế ụ ệ ủ ứ ả ế trong khi trong main() không có khai báo v x và n nên ví d câu l nh cout << luythua(x, n); làề ụ ệ s d ng x, n c a bi n ngoài.ử ụ ủ ế

Nói chung trong 2 ví d trên ch ng trình đ u ch y t t và nh nhau. Tuy nhiên, vi c khai báoụ ươ ề ạ ố ư ệ khác nhau nh v y có nh h ng ho c gây nh m l n gì cho ng i l p trình ? Li u chúng taư ậ ả ưở ặ ầ ẫ ườ ậ ệ có nên t đ t ra m t nguyên t c nào đó trong khai báo bi n ngoài và bi n c c b đ tránhự ặ ộ ắ ế ế ụ ộ ể nh ng nh m l n có th x y ra. Chúng ta hãy xét ti p cũng ví d trên nh ng thay đ i m t sữ ầ ẫ ể ả ế ụ ư ổ ộ ố khai báo và tính 23 (có th b b t bi n n) nh sau: ể ỏ ớ ế ư

#include <iostream.h>

#include <iomanip.h>

float x; int i ; // không dùng n

float luythua(float x, int n)

{

float kq = 1;

for (i=1; i<=n; i++) kq *= x;

}

void xmh()

{

for (i=1; i<=n; i++) clrscr();

}

main()

{

x = 2;

i = 3;

xmh(5); // xoá màn hình 5 l nầ

cout << luythua(x, i); // in xi, k t qu x = 2ế ả 3 = 8 ?

}Nhìn vào hàm main() ta th y giá tr 2ấ ị 3 đ c tính b ng cách đ t x = 2, i = 3 và g i hàmượ ằ ặ ọ luythua(x,i). K t qu ta mong mu n s là giá tr 8 hi n ra màn hình, tuy nhiên không đúng nhế ả ố ẽ ị ệ ư v y. Tr c khi in k t qu này ra màn hình hàm xmh() đã đ c g i đ n đ xoá màn hình. Hàmậ ướ ế ả ượ ọ ế ể này s d ng m t bi n ngoài i đ làm bi n đ m cho mình trong vòng l p for và sau khi ra kh iử ụ ộ ế ể ế ế ặ ỏ for (cũng là k t thúc xmh()) i nh n giá tr 6. Bi n i ngoài này l i đ c s d ng trong l i g iế ậ ị ế ạ ượ ử ụ ờ ọ

Page 129: Giao Trinh C++ Toan Tap

luythua(x,i) c a hàm main(), t c t i th i đi m này x = 2 và i = 6, k t qu in ra màn hình s làủ ứ ạ ờ ể ế ả ẽ 26 = 64 thay vì 8 nh mong mu n. ư ố

Tóm l i "đi m y u" d n đ n sai sót c a ch ng trình trên là ch l p trình viên đã "tranhạ ể ế ẫ ế ủ ươ ở ỗ ậ th " s d ng bi n i cho 2 hàm xmh() và main() (b ng cách khai báo nó nh bi n ngoài) nh ngủ ử ụ ế ằ ư ế ư l i v i m c đích khác nhau. Do v y sau khi ch y xong hàm xmh() i b thay đ i khác v i giá trạ ớ ụ ậ ạ ị ổ ớ ị i đ c kh i t o lúc ban đ u. Đ kh c ph c l i trong ch ng trình trên ta c n khai báo l iượ ở ạ ầ ể ắ ụ ỗ ươ ầ ạ bi n i: ho c trong main() khai báo thêm i (nó s che bi n i ngoài), ho c trong c hai xmh() vàế ặ ẽ ế ặ ả main() đ u có bi n i (c c b trong t ng hàm). ề ế ụ ộ ừ

T đó, ta nên đ ra m t vài nguyên t c l p trình sao cho nó có th tránh đ c nh ng l i khôngừ ề ộ ắ ậ ể ượ ữ ỗ đáng có nh v y:ư ậ

n u m t bi n ch s d ng vì m c đích riêng c a m t hàm thì nênế ộ ế ỉ ử ụ ụ ủ ộ khai báo bi n đóế nh bi n c c b trong hàmư ế ụ ộ . Ví d các bi n đ m c a vòng l p, thông th ngụ ế ế ủ ặ ườ chúng ch đ c s d ng th m chí ch riêng trong vòng l p ch cũng ch a ph i choỉ ượ ử ụ ậ ỉ ặ ứ ư ả toàn b c hàm, vì v y không nên khai báo chúng nh bi n ngoài. Nh ng bi n c cộ ả ậ ư ế ữ ế ụ b này sau khi hàm k t thúc chúng cũng s k t thúc, không gây nh h ng đ n b tộ ế ẽ ế ả ưở ế ấ kỳ hàm nào khác. M t đ c đi m có l i n a cho khai báo c c b là chúng t o choộ ặ ể ợ ữ ụ ộ ạ hàm tính cách hoàn ch nh, đ c l p v i m i hàm khác, ch ng trình khác. Ví d hàmỉ ộ ậ ớ ọ ươ ụ xmh() có th mang qua ch y ch ng trình khác mà không ph i s a ch a gì n u iể ạ ở ươ ả ử ữ ế đã đ c khai báo bên trong hàm. Trong khi ví d này hàm xmh() v n ho t đ ngượ ở ụ ẫ ạ ộ đ c nh ng trong ch ng trình khác n u không có i nh m t bi n ngoài (đ xmh()ượ ư ươ ế ư ộ ế ể s d ng) thì hàm s gây l i.ử ụ ẽ ỗ

v i các bi n mang tính ch t ớ ế ấ s d ng chungử ụ rõ nét (đ c bi t v i nh ng bi n kích th cặ ệ ớ ữ ế ướ l n) mà nhi u hàm cùng s d ng chúng v i m c đích gi ng nhau thì nên khai báoớ ề ử ụ ớ ụ ố chúng nh bi n ngoài. Đi u này ti t ki m đ c th i gian cho ng i l p trình vìư ế ề ế ệ ượ ờ ườ ậ không ph i khai báo chúng nhi u l n trong nhi u hàm, ti t ki m b nh vì khôngả ề ầ ề ế ệ ộ ớ ph i t o chúng t m th i m i khi ch y các hàm, ti t ki m đ c th i gian ch yả ạ ạ ờ ỗ ạ ế ệ ượ ờ ạ ch ng trình vì không ph i t ch c b nh đ l u tr và gi i phóng chúng. Ví dươ ả ổ ứ ộ ớ ể ư ữ ả ụ trong ch ng trình qu n lý sinh viên (ch ng 6), bi n sinh viên đ c dùng chung vàươ ả ươ ế ượ th ng nh t trong h u h t các hàm (xem, xoá, s a, b sung, th ng kê …) nên có thố ấ ầ ế ử ổ ố ể khai báo chúng nh bi n ngoài, đi u này cũng tăng tính th ng nh t c a ch ng trìnhư ế ề ố ấ ủ ươ (m i bi n sinh viên là nh nhau cho m i hàm con c a ch ng trình).ọ ế ư ọ ủ ươ

Tóm l i, nguyên t c t ng quát nh t là c g ng t o hàm m t cách đ c l p, khép kín, khôngạ ắ ổ ấ ố ắ ạ ộ ộ ậ ch u nh h ng c a các hàm khác và không gây nh h ng đ n ho t đ ng c a các hàm khácị ả ưở ủ ả ưở ế ạ ộ ủ đ n m c có th .ế ứ ể

Bi n v i m c đích đ c bi tế ớ ụ ặ ệ

Bi n h ng và t khoá const ế ằ ừĐ s d ng h ng có th khai báo thêm t khoá const tr c khai báo bi n. Ph m vi và mi nể ử ụ ằ ể ừ ướ ế ạ ề tác d ng cũng nh bi n, có nghĩa bi n h ng cũng có th d ng c c b ho c toàn th . Bi nụ ư ế ế ằ ể ở ạ ụ ộ ặ ể ế h ng luôn luôn đ c kh i t o tr c. ằ ượ ở ạ ướ

Page 130: Giao Trinh C++ Toan Tap

Có th khai báo t khoá const tr c các tham đ i hình th c đ không cho phép thay đ i giá trể ừ ướ ố ứ ể ổ ị c a các bi n ngoài (đ c bi t đ i v i v i m ng và xâu kí t , vì b n thân các bi n này đ củ ế ặ ệ ố ớ ớ ả ự ả ế ượ xem nh con tr do đó hàm có th thay đ i đ c giá tr c a các bi n ngoài truy n cho hàmư ỏ ể ổ ượ ị ủ ế ề này).

Ví d sau th hi n h ng cũng có th đ c khai báo các ph m vi khác nhau.ụ ể ệ ằ ể ượ ở ạ

const int MAX = 30; // toàn thể

void vidu(const int *p) // c c b ụ ộ

{

const MAX = 10; // c c bụ ộ

}

void main()

{

const MAX = 5; // c c bụ ộ

}

…Trong Turbo C, BorlandC và các ch ng trình d ch khác có nhi u h ng s khai báo s n trongươ ị ề ằ ố ẵ t p values.h nh MAXINT, M_PI ho c các h ng đ ho trong graphics.h nh WHITE, RED,ệ ư ặ ằ ồ ạ ư …

Bi n tĩnh và t khoá staticế ừĐ c khai báo b ng t khoá static. Là bi n c c b nh ng v n gi giá tr sau khi ra kh i hàm.ượ ằ ừ ế ụ ộ ư ẫ ữ ị ỏ Ph m vi tác d ng nh bi n c c b , nghĩa là nó ch đ c s d ng trong hàm khai báo nó. Tuyạ ụ ư ế ụ ộ ỉ ượ ử ụ nhiên th i gian tác d ng đ c xem nh bi n toàn th , t c sau khi hàm th c hi n xong bi nờ ụ ượ ư ế ể ứ ự ệ ế v n còn t n t i và v n l u l i giá tr sau khi ra kh i hàm. Giá tr này này đ c ti p t c sẫ ồ ạ ẫ ư ạ ị ỏ ị ượ ế ụ ử d ng khi hàm đ c g i l i, t c bi n static ch đ c kh i đ u m t l n trong l n ch y hàmụ ượ ọ ạ ứ ế ỉ ượ ở ầ ộ ầ ầ ạ đ u tiên. N u không kh i t o, C++ t đ ng gán giá tr 0 (ng m đ nh = 0). Ví d :ầ ế ở ạ ự ộ ị ầ ị ụ

int i = 1;

void bp()

{

static int lanthu = 0;

lanthu++;

i = 2 * i;

cout << "Hàm ch y l n th " << lanthu << ", i = " << i ; ạ ầ ứ

Page 131: Giao Trinh C++ Toan Tap

}

main()

{

ham(); // Hàm ch y l n th 1, i = 1ạ ầ ứ

ham(); // Hàm ch y l n th 2, i = 2ạ ầ ứ

ham(); // Hàm ch y l n th 3, i = 4ạ ầ ứ

}

Bi n thanh ghi và t khoá register ế ừĐ tăng t c đ tính toán C++ cho phép m t s bi n đ c đ t tr c ti p vào thanh ghi thay vì ể ố ộ ộ ố ế ượ ặ ự ế ở b nh . Khai báo b ng t khoá ộ ớ ằ ừ register đ ng tr c khai báo bi n. Tuy nhiên khai báo này chứ ướ ế ỉ có tác d ng đ i v i các bi n có kích th c nh nh bi n char, int.ụ ố ớ ế ướ ỏ ư ế

Ví d : register char c; register int dem; ụ

Bi n ngoài và t khoá externế ừNh đã bi t m t ch ng trình có th đ c đ t trên nhi u file văn b n khác nhau. M t bi nư ế ộ ươ ể ượ ặ ề ả ộ ế không th đ c khai báo nhi u l n v i cùng ph m vi ho t đ ng. Do v y n u m t hàm sể ượ ề ầ ớ ạ ạ ộ ậ ế ộ ử d ng bi n đ c khai báo trong file văn b n khác thì bi n này ph i đ c khai báo v i t khoáụ ế ượ ả ế ả ượ ớ ừ extern. T khoá này cho phép ch ng trình d ch tìm và liên k t bi n này t bên ngoài file đangừ ươ ị ế ế ừ ch a bi n. Chúng ta hãy xét ví d gây l i sau đây và tìm ph ng án kh c ph c chúng.ứ ế ụ ỗ ươ ắ ụ

void in();

void main()

{

int i = 1;

in();

}

void in()

{

cout << i ;

}

L i (cú pháp) vì i là bi n c c b trong main(), trong in() không nh n bi t i, n u trongỗ ế ụ ộ ậ ế ế ho c tr c in() khai báo thêm i thì l i ng nghĩa (t c ch ng trình in giá tr i khácặ ướ ỗ ữ ứ ươ ị

Page 132: Giao Trinh C++ Toan Tap

không theo ý mu n c a l p trình viên).ố ủ ậ

Gi thi t khai báo l i nh sau:ả ế ạ ư

void in();

void main() { ... } // B khai báo i trong main()ỏ

int i; // Đ a khai báo i ra tr c in() và sau main() ư ướ

void in() { ... }cách khai báo này cũng gây l i vì main() không nh n bi t i. Cu i cùng đ main() có th nh nỗ ậ ế ố ể ể ậ bi t i thì i ph i đ c khai báo d i d ng bi n extern. Thông th ng trong tr ng h p nàyế ả ượ ướ ạ ế ườ ườ ợ cách kh c ph c hay nh t là khai báo tr c main() đ b các extern (không c n thi t).ắ ụ ấ ướ ể ỏ ầ ế

Gi thi t 2 ch ng trình trên n m trong 2 t p khác nhau. Đ liên k t (link) bi n i gi a 2ả ế ươ ằ ệ ể ế ế ữ ch ng trình c n đ nh nghĩa t ng th i trong m t và khai báo extern trong ch ng trình kia.ươ ầ ị ổ ể ộ ươ

/* program1.cpp*/

void in();

int i;

void main()

{

i = 1;

in();

}

/* program2.cpp */

void in()

{

extern i;

cout << i ;

}Hàm in() n m trong t p văn b n program2.cpp, đ c dùng đ in giá tr c a bi n i khai báoằ ệ ả ượ ể ị ủ ế trong program1.cpp, t m g i là t p g c (hai t p này khi d ch s đ c liên k t v i nhau). Tạ ọ ệ ố ệ ị ẽ ượ ế ớ ừ đó trong t p g c, i ph i đ c khai báo là bi n ngoài, và b t kỳ hàm t p khác mu n s d ngệ ố ả ượ ế ấ ở ệ ố ử ụ bi n i này đ u ph i có câu l nh khai báo extern int i (n u không có t khoá extern thì bi n i l iế ề ả ệ ế ừ ế ạ đ c xem là bi n c c b , khác v i bi n i trong t p g c). ượ ế ụ ộ ớ ế ệ ố

Đ liên k t các t p ngu n có th t o m t d án (project) thông qua menu PROJECT (Alt-P).ể ế ệ ồ ể ạ ộ ự Các phím nóng cho phép m d án, thêm b t t p vào danh sách t p c a d án … đ c h ngở ự ớ ệ ệ ủ ự ượ ướ d n dòng cu i c a c a s d án.ẫ ở ố ủ ử ổ ự

Page 133: Giao Trinh C++ Toan Tap

Các ch th ti n x lýỉ ị ề ửNh đã bi t tr c khi ch y ch ng trình (b t đ u t văn b n ch ng trình t c ch ng trìnhư ế ướ ạ ươ ắ ầ ừ ả ươ ứ ươ ngu n) C++ s d ch ch ng trình ra t p mã máy còn g i là ch ng trình đích. Thao tác d chồ ẽ ị ươ ệ ọ ươ ị ch ng trình nói chung g m có 2 ph n: x lý s b ch ng trình và d ch. Ph n x lý s bươ ồ ầ ử ơ ộ ươ ị ầ ử ơ ộ đ c g i là ti n x lý, trong đó có các công vi c liên quan đ n các ch th đ c đ t đ u t pượ ọ ề ử ệ ế ỉ ị ượ ặ ở ầ ệ ch ng trình ngu n nh #include, #define … ươ ồ ư

Ch th bao hàm t p #includeỉ ị ệCho phép ghép n i dung các t p đã có khác vào ch ng trình tr c khi d ch. Các t p c n ghépộ ệ ươ ướ ị ệ ầ thêm vào ch ng trình th ng là các t p ch a khai báo nguyên m u c a các h ng, bi n, hàmươ ườ ệ ứ ẫ ủ ằ ế … có s n trong C ho c các hàm do l p trình viên t vi t. Có hai d ng vi t ch th này.ẵ ặ ậ ự ế ạ ế ỉ ị

1: #include <t p>ệ

2: #include “đ ng d n\t p”ườ ẫ ệ

D ng khai báo 1 cho phép C++ ng m đ nh tìm t p t i th m c đ nh s n (khai báo thôngạ ầ ị ệ ạ ư ụ ị ẵ qua menu Options\Directories) th ng là th m c TC\INCLUDE và t p là các t p nguyên m uườ ư ụ ệ ệ ẫ c a th vi n C++.ủ ư ệD ng khai báo 2 cho phép tìm t p theo đ ng d n, n u không có đ ng d n s tìm trong thạ ệ ườ ẫ ế ườ ẫ ẽ ư m c hi n t i. T p th ng là các t p (th vi n) đ c t o b i l p trình viên và đ c đ t trongụ ệ ạ ệ ườ ệ ư ệ ượ ạ ở ậ ượ ặ cùng th m c ch a ch ng trình. Cú pháp này cho phép l p trình viên chia m t ch ng trìnhư ụ ứ ươ ậ ộ ươ thành nhi u môđun đ t trên m t s t p khác nhau đ d qu n lý. Nó đ c bi t h u ích khi l pề ặ ộ ố ệ ể ễ ả ặ ệ ữ ậ trình viên mu n t o các th vi n riêng cho mình. ố ạ ư ệ

Ch th macro #defineỉ ị

#define tên_macro xaukituTr c khi d ch b ti n x lý s tìm trong ch ng trình và thay th b t kỳ v trí xu t hi n nàoướ ị ộ ề ử ẽ ươ ế ấ ị ấ ệ c a tên_macro b i xâu kí t . Ta th ng s d ng macro đ đ nh nghĩa các h ng ho c thay c mủ ở ự ườ ử ụ ể ị ằ ặ ụ t này b ng c m t khác d nh h n, ví d :ừ ằ ụ ừ ễ ớ ơ ụ

#define then // thay then b ng d u cáchằ ấ

#define begin { // thay begin b ng d u {ằ ấ

#define end } // thay end b ng d u }ằ ấ

#define MAX 100 // thay MAX b ng 100ằ

#define TRUE 1 // thay TRUE b ng 1ằt đó trong ch ng trình ta có th vi t nh ng đo n l nh nh :ừ ươ ể ế ữ ạ ệ ư

if (i < MAX) then

begin

Ok = TRUE;

cout << i ;

Page 134: Giao Trinh C++ Toan Tap

endtr c khi d ch b ti n x lý s chuy n đo n ch ng trình trên thànhướ ị ộ ề ử ẽ ể ạ ươ

if (i < 100)

{

Ok = 1;

cout << i ;

}theo đúng cú pháp c a C++ và r i m i ti n hành d ch.ủ ồ ớ ế ị

Ngoài vi c ch th #define cho phép thay tên_macro b i m t xâu kí t b t kỳ, nó còn cũngệ ỉ ị ở ộ ự ấ đ c phép vi t d i d ng có đ i. Ví d , đ tìm s l n nh t c a 2 s , thay vì ta ph i vi tượ ế ướ ạ ố ụ ể ố ớ ấ ủ ố ả ế nhi u hàm max (m i hàm ng v i m t ki u s khác nhau), bây gi ta ch c n thay chúng b iề ỗ ứ ớ ộ ể ố ờ ỉ ầ ở m t macro có đ i đ n gi n nh sau:ộ ố ơ ả ư

#define max(A,B) ((A) > (B) ? (A): (B))khi đó trong ch ng trình n u có dòng x = max(a, b) thì nó s đ c thay b i: x = ((a) > (b) ?ươ ế ẽ ượ ở (a): (b))

Chú ý:

Tên macro ph i đ c vi t li n v i d u ngo c c a danh sách đ i. Ví d không vi t maxả ượ ế ề ớ ấ ặ ủ ố ụ ế (A,B).

#define bp(x) (x*x) vi t sai vì bp(5) đúng nh ng bp(a+b) s thành (a+b*a+b) (t cế ư ẽ ứ a+b+ab).

Cũng t ng t vi t #define max(A,B) (A > B ? A: B) là sai (?) vì v y luôn luôn bao cácươ ự ế ậ đ i b i d u ngo c.ố ở ấ ặ

#define bp(x) ((x)*(x)) vi t đúng nh ng n u gi s l p trình viên mu n tính bìnhế ư ế ả ử ậ ố ph ng c a 2 b ng đo n l nh sau:ươ ủ ằ ạ ệ

int i = 1;

cout << bp(++i); // 6thì k t qu in ra s là 6 thay vì k t qu đúng là 4. Lí do là ch ch ng trình d ch sế ả ẽ ế ả ở ỗ ươ ị ẽ

thay bp(++i) b i ((++i)*(++i)), và v i i = 1 ch ng trình s th c hi n nh 2*3 = 6. Do v yở ớ ươ ẽ ự ệ ư ậ c n c n th n khi s d ng các phép toán t tăng gi m trong các macro có đ i. Nói chung, nênầ ẩ ậ ử ụ ự ả ố h n ch vi c s d ng các macro ph c t p, vì nó có th gây nên nh ng hi u ng ph khóạ ế ệ ử ụ ứ ạ ể ữ ệ ứ ụ ki m soát.ể

Các ch th biên d ch có đi u ki n #if, #ifdef, #ifndefỉ ị ị ề ệ

Ch th :ỉ ị#if dãy l nh … #endifệ

#if dãy l nh … #else dãy l nh … #endif, ệ ệ

Page 135: Giao Trinh C++ Toan Tap

Các ch th này gi ng nh câu l nh if, m c đích c a nó là báo cho ch ng trình d ch bi tỉ ị ố ư ệ ụ ủ ươ ị ế đo n l nh gi a #if (đi u ki n ) và #endif ch đ c d ch n u đi u ki n đúng. Ví d : ạ ệ ữ ề ệ ỉ ượ ị ế ề ệ ụ

const int M = 1;

void main() {

int i = 5;

#if M==1

cout << i ;

#endif

}ho c:ặ

const int M = 10;

void main() {

int i = 5;

#if M > 8

cout << i+i ;

#else

cout << i*i ;

#endif

}

Ch th #ifdef và #ifndefỉ ịCh th này báo cho ch ng trình d ch bi t đo n l nh có đ c d ch hay không khi m t tên g iỉ ị ươ ị ế ạ ệ ượ ị ộ ọ đã đ c đ nh nghĩa hay ch a. #ifdef đ c hi u là n u tên đã đ c đ nh nghĩa thì d ch, cònượ ị ư ượ ể ế ượ ị ị #ifndef đ c hi u là n u tên ch a đ c đ nh nghĩa thì d ch. Đ đ nh nghĩa m t tên g i ta dùngượ ể ế ư ượ ị ị ể ị ộ ọ ch th #define tên.ỉ ị

Ch th này đ c bi t có ích khi chèn các t p th vi n vào đ s d ng. M t t p th vi n có thỉ ị ặ ệ ệ ư ệ ể ử ụ ộ ệ ư ệ ể đ c chèn nhi u l n trong văn b n do v y nó có th s đ c d ch nhi u l n, đi u này s gâyượ ề ầ ả ậ ể ẽ ượ ị ề ầ ề ẽ ra l i vì các bi n đ c khai báo nhi u l n. Đ tránh vi c này, ta c n s d ng ch th trên nhỗ ế ượ ề ầ ể ệ ầ ử ụ ỉ ị ư ví d minh ho sau: Gi s ta đã vi t s n 2 t p th vi n là mylib.h và mathfunc.h, trong đóụ ạ ả ử ế ẵ ệ ư ệ mylib.h ch a hàm max(a,b) tìm s l n nh t gi a 2 s , mathfunc.h ch a hàm max(a,b,c) tìm sứ ố ớ ấ ữ ố ứ ố l n nh t gi a 3 s thông qua s d ng hàm max(a,b). Do v y mathfunc.h ph i có ch thớ ấ ữ ố ử ụ ậ ả ỉ ị #include mylib.h đ s d ng đ c hàm max(a,b). ể ử ụ ượ

Th vi n 1. tên t p: MYLIB.Hư ệ ệ

int max(int a, int b)

{

Page 136: Giao Trinh C++ Toan Tap

return (a>b? a: b);

}

Th vi n 2. tên t p: MATHFUNC.Hư ệ ệ

#include "mylib.h"

int max(int a, int b)

{

return (a>b? a: b);

}Hàm main c a chúng ta nh p 3 s , in ra max c a t ng c p s và max c a c 3 s .ủ ậ ố ủ ừ ặ ố ủ ả ố

Ch ng trình c n ph i s d ng c 2 th vi n.ươ ầ ả ử ụ ả ư ệ

#include "mylib.h"

#include "mathfunc.h"

main()

{

int a, b, c;

cout << "a, b, c = " ; cin >> a >> b >> c;

cout << max(a,b) << max(b,c) << max(a,c) << max(a,b,c) ;

}Tr c khi d ch ch ng trình, b ti n x lý s chèn các th vi n vào trong t p chính (ch aướ ị ươ ộ ề ử ẽ ư ệ ệ ứ main()) trong đó mylib.h đ c chèn vào 2 l n (m t l n c a t p chính và m t l n c aượ ầ ộ ầ ủ ệ ộ ầ ủ mathfunc.h), do v y khi d ch ch ng trình, C++ s báo l i (do hàm int max(inta, int b) đ cậ ị ươ ẽ ỗ ượ khai báo hai l n). Đ kh c ph c tình tr ng này trong mylib.h ta thêm ch th m i nh sau: ầ ể ắ ụ ạ ỉ ị ớ ư

// t p mylib.hệ

#ifndef _MYLIB_ // n u ch a đ nh nghĩa tên g iế ư ị ọ _MYLIB_

#define _MYLIB_ // thì đ nh nghĩa nóị

int max(int a, int b) // và các hàm khác

{

return (a>b? a: b);

}

#endifNh v y khi ch ng trình d ch x lý mylib.h l n đ u do _MYLIB_ ch a đ nh nghĩa nên máyư ậ ươ ị ử ầ ầ ư ị s đ nh nghĩa t này, và d ch đo n ch ng trình ti p theo cho đ n #endif. L n th hai khi g pẽ ị ừ ị ạ ươ ế ế ầ ứ ặ l i đo n l nh này do _MYLIB_ đã đ c đ nh nghĩa nên ch ng trình b qua đo n l nh nàyạ ạ ệ ượ ị ươ ỏ ạ ệ không d ch.ị

Page 137: Giao Trinh C++ Toan Tap

Đ c n th n trong c mathfunc.h ta cũng s d ng cú pháp này, vì có th trong m t ch ngể ẩ ậ ả ử ụ ể ộ ươ trình khác mathfunc.h l i đ c s d ng nhi u l n.ạ ượ ử ụ ề ầ

BÀI T PẬ

Con trỏ

Hãy khai báo bi n kí t ch và con tr ki u kí t pc tr vào bi n ch. Vi t ra các cách gán giá trế ự ỏ ể ự ỏ ế ế ị ‘A’ cho bi n ch. ế

Cho m ng nguyên cost. Vi t ra các cách gán giá tr 100 cho ph n t th 3 c a m ng.ả ế ị ầ ử ứ ủ ả

Cho p, q là các con tr cùng tr ỏ ỏ đ n kí t c. ế ự Đ t *p = *q + 1. Có th kh ng ặ ể ẳ đ nh: *q = *p - 1 ?ị

Cho p, q là các con tr tr ỏ ỏ đ n bi n nguyên x = 5. ế ế Đ t *p = *q + 1; H i *q ?ặ ỏ

Cho p, q, r, s là các con tr tr ỏ ỏ đ n bi n nguyên x = 10. ế ế Đ t *q = *p + 1; *r = *q + 1; *s = *r +ặ 1. H i giá tr c a bi n x ?ỏ ị ủ ế

Ch n câu ọ đúng nh t trong các câu sau: ấA: Đ a ch c a m t bi n là s th t c a byte đ u tiên máy dành cho bi n đó. ị ỉ ủ ộ ế ố ứ ự ủ ầ ế

B: Đ a ch c a m t bi n là m t s nguyên.ị ỉ ủ ộ ế ộ ố

C: S h c đ a ch là các phép toán làm vi c trên các s nguyên bi u di n đ a ch c a bi n ố ọ ị ỉ ệ ố ể ễ ị ỉ ủ ế

D: a và b đúng

Ch n câu sai trong các câu sau: ọA: Các con tr có th phân bi t nhau b i ki u c a bi n mà nó tr đ n. ỏ ể ệ ở ể ủ ế ỏ ế

B: Hai con tr tr đ n các ki u khác nhau s có kích th c khác nhau.ỏ ỏ ế ể ẽ ướ

C: M t con tr ki u void có th đ c gán b i con tr có ki u b t kỳ (c n ép ki u).ộ ỏ ể ể ượ ở ỏ ể ấ ầ ể

D: Hai con tr cùng tr đ n ki u c u trúc có th gán cho nhau.ỏ ỏ ế ể ấ ể

Cho con tr p tr ỏ ỏ đ n bi n x ki u float. ế ế ể Có th kh ng ể ẳ đ nh ? ịA: p là m t bi n và *p cũng là m t bi nộ ế ộ ế

B: p là m t bi n và *p là m t giá tr h ngộ ế ộ ị ằ

C: Đ s d ng đ c p c n ph i khai báo float *p; và gán *p = x;ể ử ụ ượ ầ ả

D: Cũng có th khai báo void *p; và gán (float)p = &x;ể

Cho khai báo float x, y, z, *px, *py; và các l nh px = &x; py = &y; Có th kh ng ệ ể ẳ đ nh ?ịA: N u x = *px thì y = *pyế B: N u x = y + z thì *px = y + zế

Page 138: Giao Trinh C++ Toan Tap

C: N u *px = y + z thì *px = *py + zế D: a, b, c đúng

Cho khai báo float x, y, z, *px, *py; và các l nh px = &x; py = &y; Có th kh ng ệ ể ẳ đ nh ? ịA: N u *px = x thì *py = yế B: N u *px = *py - z thì *px = y - zế

C: N u *px = y - z thì x = y - zế D: a, b, c đúng

Không dùng m ng, hãy nh p m t dãy s nguyên và in ngả ậ ộ ố ư c dãy ra màn hình.ợ

Không dùng m ng, hãy nh p m t dãy s nguyên và ch ra v trí c a s bé nh t, l n nh t.ả ậ ộ ố ỉ ị ủ ố ấ ớ ấ

Không dùng m ng, hãy nh p m t dãy s nguyên và in ra dãy ả ậ ộ ố đã đư c s p x p.ợ ắ ế

Không dùng m ng, hãy nh p m t dãy kí t . Thay m i kí t ‘a’ trong dãy thành kí t ‘b’ và inả ậ ộ ự ỗ ự ự k t qu ra màn hình.ế ả

Con tr và xâu kí t ỏ ự

Gi s p là m t con tr ki u kí t tr ả ử ộ ỏ ể ự ỏ đ n xâu "Tin h c". Ch n câu ế ọ ọ đúng nh t trong các câuấ sau:

A: cout << p s in ra dòng "Tin h c"ẽ ọ B: cout << p s in ra dòng "Tin h c"ẽ ọ

C: cout << p s in ra ch cái 'T'ẽ ữ D: b và c đúng

Xét chương trình (không k các khai báo file nguyên m u): ể ẫ

char st[] = "tin h c"; ọ

main() {

char *p; p = new char[10];

for (int i=0; st[i] != '\0'; i++) p[i] = st[i];

} Ch ng trình trên ch a hoàn ch nh vì: ươ ư ỉ

A: S d ng sai cú pháp toán t new ử ụ ử

B: S d ng sai cú pháp p[i] (đúng ra là *(p+i))ử ụ

C: Xâu p ch a có k t thúcư ế

D: C a, b, c, đ u saiả ề

Đ tính ể đ dài xâu m t sinh viên vi t ộ ộ ế đo n chạ ương trình sau:

char *st;

main()

{

int len = 0; gets(st); while (st++ != '\0') len++; printf("%d",len);

Page 139: Giao Trinh C++ Toan Tap

}Hãy ch n câu đúng nh t:ọ ấ

A: Ch ng trình trên là hoàn ch nhươ ỉ B: C n thay len++ b i ++lenầ ở

C: C n thay st++ b i *st++ầ ở D: C n thay st++ != '\0' b i st++ == '\0'ầ ở

Cho xâu kí t (d ng con tr ) s. Hãy in ngự ạ ỏ ư c xâu ra màn hình.ợ

Cho xâu kí t (d ng con tr ) s. Hãy copy t s sang xâu t m t ự ạ ỏ ừ ộ đo n b t ạ ắ đ u t i v trí m v i ầ ạ ị ớ độ dài n.

Cho xâu kí t (d ng con tr ) s. Hãy th ng kê t n xu t xu t hi n c a các kí t có trong s. In raự ạ ỏ ố ầ ấ ấ ệ ủ ự màn hình theo th t gi m d n c a các t n xu t (t n xu t là t l % s l n xu t hi nứ ự ả ầ ủ ầ ấ ầ ấ ỉ ệ ố ầ ấ ệ c a x trên t ng s kí t trong s).ủ ổ ố ự

Hàm

Ch n câu sai trong các câu sau ọ đây: A: Hàm không tr l i giá tr thì không c n khai báo ki u giá tr c a hàm.ả ạ ị ầ ể ị ủ

B: Các bi n đ c khai báo trong hàm là c c b , t xoá khi hàm th c hi n xongế ượ ụ ộ ự ự ệ

C: Hàm không tr l i giá tr s có ki u giá tr ng m đ nh là void.ả ạ ị ẽ ể ị ầ ị

D: Hàm là đ n v đ c l p, không đ c khai báo hàm l ng nhau.ơ ị ộ ậ ượ ồ

Ch n câu ọ đúng nh t trong các câu sau ấ đây: A: Hàm ph i đ c k t thúc v i 1 câu l nh returnả ượ ế ớ ệ

B: Ph i có ít nh t 1 câu l nh return cho hàmả ấ ệ

C: Các câu l nh return đ c phép n m v trí b t kỳ trong thân hàm ệ ượ ằ ở ị ấ

D: Không c n khai báo ki u giá tr tr l i c a hàm n u hàm không có l nh returnầ ể ị ả ạ ủ ế ệ

Ch n câu sai trong các câu sau ọ đây: A: S tham s th c s ph i b ng s tham s hình th c trong l i g i hàmố ố ự ự ả ằ ố ố ứ ờ ọ

B: Các bi n c c b trong thân hàm đ c ch ng trình d ch c p phát b nhế ụ ộ ượ ươ ị ấ ộ ớ

C: Các tham s hình th c s đ c c p phát b nh t m th i khi hàm đ c g iố ứ ẽ ượ ấ ộ ớ ạ ờ ượ ọ

D: Ki u c a tham s th c s ph i b ng ki u c a tham s hình th c t ng ng v i nó trongể ủ ố ự ự ả ằ ể ủ ố ứ ươ ứ ớ l i g i hàmờ ọ

Đ thay ể đ i giá tr c a tham bi n, các ổ ị ủ ế đ i c a hàm c n khai báo dố ủ ầ ư i d ng: ớ ạA: bi n bình th ng và tham đ i đ c truy n theo giá trế ườ ố ượ ề ị

B: bi n con tr và tham đ i đ c truy n theo giá tr ế ỏ ố ượ ề ị

Page 140: Giao Trinh C++ Toan Tap

C: bi n bình th ng và tham đ i đ c truy n theo đ a chế ườ ố ượ ề ị ỉ

D: bi n tham chi u và tham đ i đ c truy n theo giá tr ế ế ố ượ ề ị

Vi t hàm tìm UCLN c a 2 s . áp d ng hàm này (AD: ) ế ủ ố ụ đ tìm UCLN c a 4 s nh p t bànể ủ ố ậ ừ phím.

Vi t hàm ki m tra m t s nguyên n có là s nguyên t . AD: In ra các s nguyên t bé hế ể ộ ố ố ố ố ố ơn 1000.

Vi t hàm ki m tra m t s nguyên n có là s nguyên t . AD: In các c p s sinh ế ể ộ ố ố ố ặ ố đôi < 1000. (Các s "sinh ố đôi" là các s nguyên t mà kho ng cách gi a chúng là 2).ố ố ả ữ

Vi t hàm ki m tra m t nế ể ộ ăm có là năm nhu n. AD: In ra các nậ ăm nhu n t nậ ừ ăm 1000 đ n 2000.ế

Vi t hàm xoá d u cách ế ấ đ u tiên trong m t xâu. AD: Xoá t t c d u cách trong xâu.ầ ộ ấ ả ấ

Vi t hàm thay 2 d u cách b i 1 d u cách. AD: C t các d u cách gi a 2 t c a m t xâu v cònế ấ ở ấ ắ ấ ữ ừ ủ ộ ề 1 d u cách.ấ

Vi t hàm tráo ế đ i giá tr c a 2 s . AD: s p x p dãy s .ổ ị ủ ố ắ ế ố

Vi t hàm gi i phế ả ương trình b c 2. Dùng chậ ương trình con này tìm nghi m c a m t phệ ủ ộ ương trình chính phương b c 4.ậ

S hoàn ch nh là s b ng t ng m i ố ỉ ố ằ ổ ọ ư c c a nó (Ví d 6 = 1 + 2 + 3). Hãy in ra m i s hoànớ ủ ụ ọ ố ch nh t 1 ỉ ừ đ n 100.ế

Tính t ng c a dãy phân s . In ra màn hình k t qu dổ ủ ố ế ả ư i d ng phân s t i gi n.ớ ạ ố ố ả

Nh p s t nhiên ch n n > 2. Hãy ki m tra s này có th bi u di n ậ ố ự ẵ ể ố ể ể ễ đư c dợ ư i d ng t ng c aớ ạ ổ ủ 2 s nguyên t hay không ?.ố ố

In t ng c a n s nguyên t ổ ủ ố ố đ u tiên.ầ

Tính ph n di n tích gi i h n b i hình tròn bán kính R và hình vuông ngo i ti p c a nó.ầ ệ ớ ạ ở ạ ế ủ

Chu n hoá m t xâu (c t kí t tr ng 2 ẩ ộ ắ ự ắ đ u, c t b t các d u tr ng (ch ầ ắ ớ ấ ắ ỉ đ l i 1) gi a các t ,ể ạ ữ ừ vi t hoa ế đ u t ).ầ ừ

Vi t chế ương trình nh p s nguyên l n (không quá m t t ), hãy ậ ố ớ ộ ỷ đ c giá tr c a nó b ng cách inọ ị ủ ằ ra xâu kí t tự ương ng v i giá tr c a nó. Ví d 1094507 là “M t tri u, (không trứ ớ ị ủ ụ ộ ệ ăm) chín tư nghìn, năm trăm linh b y ả đơn v ”.ị

Vi t chế ương trình s p x p theo tên m t m ng h tên nào ắ ế ộ ả ọ đó.

Tìm t t c s t nhiên có 4 ch s mà trong m i s không có 2 ch s nào gi ng nhau.ấ ả ố ự ữ ố ỗ ố ữ ố ố

Nh p s t nhiên n. Hãy bi u di n n dậ ố ự ể ễ ư i d ng tích c a các th a s nguyên t .ớ ạ ủ ừ ố ố

Đ quiệ

Nh p s nguyên dậ ố ương N. Vi t hàm ế đ qui tính:ệ

N

N...S

++++= 3211

Page 141: Giao Trinh C++ Toan Tap

22222 321 N...S ++++=

1. Nh p s nguyên dậ ố ương n. Vi t hàm ế đ qui tính:ệ

33331 ++++= ...S n d u cănấ

2

12

12

12

12

...

S

++

+=

n d u chiaấ

Vi t hàm ế đ qui tính n!. áp d ng chệ ụ ương trình con này tính t h p ch p k theo công th c truyổ ợ ậ ứ h i: C(n, k) = n!/(k! (n-k)!)ồ

Vi t hàm ế đ qui tính s fibonaci th n. Dùng chệ ố ứ ương trình con này tính f(2) + f(4) + f(6) + f(8).

Vi t d i d ng đ qui các hàm ế ướ ạ ệ

daoxau b. UCLN c. Fibonaci d. Tháp Hà N iộ

Vi t macro tráo đ i n i dung 2 bi n. AD: S p x p dãy s .ế ổ ộ ế ắ ế ố

CH NG 5ƯƠ

D LI U KI U C U TRÚC VÀ H PỮ Ệ Ể Ấ Ợ

Ki u c u trúcể ấC u trúc t tr và danh sách liên k t ấ ự ỏ ếKi u h pể ợKi u li t kêể ệ

Đ l u tr các giá tr g m nhi u thành ph n d li u gi ng nhau ta có ki u bi n m ng. Th cể ư ữ ị ồ ề ầ ữ ệ ố ể ế ả ự t r t nhi u d li u là t p các ki u d li u khác nhau t p h p l i, đ qu n lý d li u ki uế ấ ề ữ ệ ậ ể ữ ệ ậ ợ ạ ể ả ữ ệ ể này C++ đ a ra ki u d li u c u trúc. M t ví d c a d li u ki u c u trúc là m t b ng lý l chư ể ữ ệ ấ ộ ụ ủ ữ ệ ể ấ ộ ả ị trong đó m i nhân s đ c l u trong m t b ng g m nhi u ki u d li u khác nhau nh hỗ ự ượ ư ộ ả ồ ề ể ữ ệ ư ọ tên, tu i, gi i tính, m c l ng … ổ ớ ứ ươ

KI U C U TRÚCỂ Ấ

Khai báo, kh i t oở ạĐ t o ra m t ki u c u trúc NSD c n ph i khai báo tên c a ki u (là m t tên g i do NSD tể ạ ộ ể ấ ầ ả ủ ể ộ ọ ự đ t), tên cùng v i các thành ph n d li u có trong ki u c u trúc này. M t ki u c u trúc đ cặ ớ ầ ữ ệ ể ấ ộ ể ấ ượ khai báo theo m u sau: ẫ

Page 142: Giao Trinh C++ Toan Tap

struct <tên ki u> ể

{

các thành ph n ;ầ

} <danh sách bi n>;ế

M i thành ph n gi ng nh m t bi n riêng c a ki u, nó g m ki u và tên thành ph n.ỗ ầ ố ư ộ ế ủ ể ồ ể ầ M t thành ph n cũng còn đ c g i là tr ng. ộ ầ ượ ọ ườ

Ph n tên c a ki u c u trúc và ph n danh sách bi n có th có ho c không. Tuy nhiênầ ủ ể ấ ầ ế ể ặ trong khai báo kí t k t thúc cu i cùng ph i là d u ch m ph y (;).ự ế ố ả ấ ấ ẩ

Các ki u c u trúc đ c phép khai báo l ng nhau, nghĩa là m t thành ph n c a ki u c uể ấ ượ ồ ộ ầ ủ ể ấ trúc có th l i là m t tr ng có ki u c u trúc.ể ạ ộ ườ ể ấ

M t bi n có ki u c u trúc s đ c phân b b nh sao cho các th c hi n c a nó đ cộ ế ể ấ ẽ ượ ố ộ ớ ự ệ ủ ượ s p liên t c theo th t xu t hi n trong khai báo.ắ ụ ứ ự ấ ệ

Khai báo bi n ki u c u trúc cũng gi ng nh khai báo các bi n ki u c s dế ể ấ ố ư ế ể ơ ở ư i d ng: ớ ạstruct <tên c u trúc> <danh sách bi n> ;ấ ế // ki u cũ trong C ể

ho c ặ

<tên c u trúc> <danh sách bi n> ;ấ ế // trong C++

Các bi n đ c khai báo cũng có th đi kèm kh i t o:ế ượ ể ở ạ

<tên c u trúc> bi n = { giá tr kh i t o } ;ấ ế ị ở ạ

Ví d :ụ

Khai báo ki u c u trúc ch a phân s g m 2 thành ph n nguyên ch a t s và m u s .ể ấ ứ ố ồ ầ ứ ử ố ẫ ố

struct Phanso

{

int tu ;

int mau ;

} ;ho c: ặ

struct Phanso { int tu, mau ; }

Ki u ngày tháng g m 3 thành ph n nguyên ch a ngày, tháng, năm.ể ồ ầ ứ

struct Ngaythang {

int ng ;

int th ;

Page 143: Giao Trinh C++ Toan Tap

int nam ;

} holiday = { 1,5,2000 } ;m t bi n holiday cũng đ c khai báo kèm cùng ki u này và đ c kh i t o b i b s 1.ộ ế ượ ể ượ ở ạ ở ộ ố

5. 2000. Các giá tr kh i t o này l n l t gán cho các thành ph n theo đúng th t trong khaiị ở ạ ầ ượ ầ ứ ự báo, t c ng = 1, th = 5 và nam = 2000.ứ

Ki u Lop dùng ch a thông tin v m t l p h c g m tên l p và sĩ s sinh viên. Các bi nể ứ ề ộ ớ ọ ồ ớ ố ế ki u Lop đ c khai báo là daihoc và caodang, trong đó daihoc đ c kh i t o b i bể ượ ượ ở ạ ở ộ giá tr {"K41T", 60} v i ý nghĩa tên l p đ i h c là K41T và sĩ s là 60 sinh viên. ị ớ ớ ạ ọ ố

struct Lop {

char tenlop[10],

int soluong;

} ;

struct Lop daihoc = {"K41T", 60}, caodang ;ho c:ặ

Lop daihoc = {"K41T", 60}, caodang ;

Ki u Sinhvien g m có các tr ng hoten đ l u tr h và tên sinh viên, ns l u tr ngàyể ồ ườ ể ư ữ ọ ư ữ sinh, gt l u tr gi i tính d i d ng s (qui c 1: nam, 2: n ) và cu i cùng tr ngư ữ ớ ướ ạ ố ướ ữ ố ườ diem l u tr đi m thi c a sinh viên. Các tr ng trên đ u có ki u khác nhau. ư ữ ể ủ ườ ề ể

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} x, *p, K41T[60];

Sinhvien y = {"NVA", {1,1,1980}, 1} ;

Khai báo cùng v i c u trúc Sinhvien có các bi n x, con tr p và m ng K41T v i 60 ph n tớ ấ ế ỏ ả ớ ầ ử ki u Sinhvien. M t bi n y đ c khai báo thêm và kèm theo kh i t o giá tr {"NVA",ể ộ ế ượ ở ạ ị {1,1,1980}, 1}, t c h tên c a sinh viên y là "NVA", ngày sinh là 1/1/1980, gi i tính nam vàứ ọ ủ ớ đi m thi đ tr ng. Đây là ki u kh i t o thi u giá tr , gi ng nh kh i t o m ng, các giá tr để ể ố ể ở ạ ế ị ố ư ở ạ ả ị ể tr ng ph i n m cu i b giá tr kh i t o (t c các thành ph n b kh i t o không đ c n mố ả ằ ở ố ộ ị ở ạ ứ ầ ỏ ở ạ ượ ằ xen k gi a nh ng thành ph n đ c kh i t o).Ví d này còn minh ho cho các c u trúc l ngẽ ữ ữ ầ ượ ở ạ ụ ạ ấ ồ nhau, c th trong ki u c u trúc Sinhvien có m t thành ph n cũng ki u c u trúc là thành ph nụ ể ể ấ ộ ầ ể ấ ầ ns.

Truy nh p các thành ph n ki u c u trúc ậ ầ ể ấ

Page 144: Giao Trinh C++ Toan Tap

Đ truy nh p vào các thành ph n ki u c u trúc ta s d ng cú pháp: tên bi n.tên thành ph nể ậ ầ ể ấ ử ụ ế ầ ho c tên bi n ® tên thành ph n đ i v i bi n con tr c u trúc. C th : ặ ế ầ ố ớ ế ỏ ấ ụ ể

Đ i v i bi n thố ớ ế ư ng: ờ tên bi n.tên thành ph n ế ầVí d :ụ

struct Lop {

char tenlop[10];

int siso;

} ;

Lop daihoc = "K41T", caodang ;

caodang.tenlop = daihoc.tenlop ; // gán tên l p cđ ng b i tên l p đh cớ ẳ ở ớ ọ

caodang.siso++; // tăng sĩ s l p caodang lên 1ố ớ

Đ i v i bi n con tr : ố ớ ế ỏ tên bi n ® tên thành ph n ế ầVí d : ụ

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} x, *p, K41T[60];

Sinhvien y = {"NVA", {1,1,1980}, 1} ;

y.diem = 5.5 ; // gán đi m thi cho sinh viên yể

p = new Sinhvien ; // c p b nh ch a 1 sinh viênấ ộ ớ ứ

strcpy(p®hoten, y.hoten) ; // gán h tên c a y cho sv tr b i pọ ủ ỏ ở

cout << p®hoten << y.hoten; // in hoten c a y và con tr pủ ỏ

Đ i v i bi n m ng: truy nh p thành ph n m ng r i đ n thành ph n c u trúc.ố ớ ế ả ậ ầ ả ồ ế ầ ấVí d :ụ

strcpy(K41T[1].hoten, p®hoten) ; // gán h tên cho sv đ u tiên c a l pọ ầ ủ ớ

K41T[1].diem = 7.0 ; // gán đi m cho sv đ u tiênể ầ

Đ i v i c u trúc l ng nhau. Truy nh p thành ph n ngoài r i đ n thành ph n c a c uố ớ ấ ồ ậ ầ ồ ế ầ ủ ấ trúc bên trong, s d ng các phép toán . ho c ® (các phép toán l y thành ph n) m tử ụ ặ ấ ầ ộ cách thích h p.ợ

x.ngaysinh.ng = y.ngaysinh.ng ; // gán ngày,

x.ngaysinh.th = y.ngaysinh.th ; // tháng,

x.ngaysinh.nam = y.ngaysinh.nam ; // năm sinh c a y cho x.ủ

Page 145: Giao Trinh C++ Toan Tap

Phép toán gán c u trúcấCũng gi ng các bi n m ng, đ làm vi c v i m t bi n c u trúc chúng ta ph i th c hi n thaoố ế ả ể ệ ớ ộ ế ấ ả ự ệ tác trên t ng thành ph n c a chúng. Ví d vào/ra m t bi n c u trúc ph i vi t câu l nh vào/raừ ầ ủ ụ ộ ế ấ ả ế ệ t ng cho t ng thành ph n. Nh n xét này đ c minh h a trong ví d sau:ừ ừ ầ ậ ượ ọ ụ

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} x, y;

cout << " Nh p d li u cho sinh viên x:" << endl ;ậ ữ ệ

cin.getline(x.hoten, 25);

cin >> x.ns.ng >> x.ns.th >> x.ns.nam;

cin >> x.gt;

cin >> x.diem

cout << "Thông tin v sinh viên x là:" << endl ;ề

cout << "H và tên: " << x.hoten << endl;ọ

cout << "Sinh ngày: " << x.ns.ng << "/" << x.ns.th << "/" << x.ns.nam ;

cout << "Gi i tính: " << (x.gt == 1) ? "Nam": "N ;ớ ữ

cout << x.diem

Tuy nhiên, khác v i bi n m ng, ớ ế ả đ i v i c u trúc chúng ta có th gán giá tr c a 2 bi n choố ớ ấ ể ị ủ ế nhau. Phép gán này cũng t ng đ ng v i vi c gán t ng thành ph n c a c u trúc. Ví d :ươ ươ ớ ệ ừ ầ ủ ấ ụ

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} x, y, *p ;

cout << " Nh p d li u cho sinh viên x:" << endl ;ậ ữ ệ

cin.getline(x.hoten, 25);

cin >> x.ns.ng >> x.ns.th >> x.ns.nam;

cin >> x.gt;

Page 146: Giao Trinh C++ Toan Tap

cin >> x.diem

y = x ; // Đ i v i bi n m ng, phép gán này là không th c hi n đ cố ớ ế ả ự ệ ượ

p = new Sinhvien[1] ; *p = x ;

cout << "Thông tin v sinh viên y là:" << endl ;ề

cout << "H và tên: " << y.hoten << endl;ọ

cout << "Sinh ngày: " << y.ns.ng << "/" << y.ns.th << "/" << y.ns.nam ;

cout << "Gi i tính: " << (y.gt = 1) ? "Nam": "N ;ớ ữ

cout << y.diem

Chú ý: không gán b giá tr c th cho bi n c u trúc. Cách gán này ch th c hi n đ c khiộ ị ụ ể ế ấ ỉ ự ệ ượ kh i t o. Ví d :ở ạ ụ

Sinhvien x = { "NVA", {1,1,1980}, 1, 7.0}, y ; // đ cượ

y = { "NVA", {1,1,1980}, 1, 7.0}; // không đ c ượ

y = x; // đ cượ

Các ví d minh ho ụ ạD i đây chúng ta đ a ra m t vài ví d minh ho cho vi c s d ng ki u c u trúc.ướ ư ộ ụ ạ ệ ử ụ ể ấ

: C ng, tr , nhân chia hai phân s đ c cho d i d ng c u trúc.ộ ừ ố ượ ướ ạ ấ

#include <iostream.h>

#include <conio.h>

struct Phanso {

int tu ;

int mau ;

} a, b, c ;

void main()

{

clrscr();

cout << "Nh p phân s a:" << endl ;ậ ố // nh p aậ

cout << "T :"; cin >> a.tu;ử

cout << "M u:"; cin >> a.mau;ẫ

cout << "Nh p phân s b:" << endl ;ậ ố // nh p bậ

Page 147: Giao Trinh C++ Toan Tap

cout << "T :"; cin >> b.tu;ử

cout << "M u:"; cin >> b.mau;ẫ

c.tu = a.tu*b.mau + a.mau*b.tu; // tính và in a+b

c.mau = a.mau*b.mau;

cout << "a + b = " << c.tu << "/" << c.mau;

c.tu = a.tu*b.mau - a.mau*b.tu; // tính và in a-b

c.mau = a.mau*b.mau;

cout << "a - b = " << c.tu << "/" << c.mau;

c.tu = a.tu*b.tu; // tính và in axb

c.mau = a.mau*b.mau;

cout << "a + b = " << c.tu << "/" << c.mau;

c.tu = a.tu*b.mau; // tính và in a/b

c.mau = a.mau*b.tu;

cout << "a + b = " << c.tu << "/" << c.mau;

getch();

}

: Nh p m ng K41T. Tính tu i trung bình c a sinh viên nam, n . Hi n danh sách c a sinh viênậ ả ổ ủ ữ ệ ủ có đi m thi cao nh t.ể ấ

#include <iostream.h>

#include <conio.h>

void main()

{

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} x, K41T[60];

int i, n;

// nh p d li u ậ ữ ệ

Page 148: Giao Trinh C++ Toan Tap

cout << "Cho bi t s sinh viên: "; cin >> n;ế ố

for (i=1, i<=n, i++)

{

cout << "Nhap sinh vien thu " << i);

cout << "Ho ten: " ; cin.getline(x.hoten);

cout << "Ngày sinh: " ; cin >> x.ns.ng >> x.ns.th >>x.ns.nam ;

cout << "Gi i tính: " ; cin >> x.gt ;ớ

cout << "Đi m: " ; cin >> x.diem ;ể

cin.ignore();

K41T[i] = x ;

}

}

// Tính đi m trung bìnhể

float tbnam = 0, tbnu = 0;

int sonam = 0, sonu = 0 ;

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

if (K41T[i].gt == 1) { sonam++ ; tbnam += K41T[1].diem ; }

else { sonu++ ; tbnu += K41T[1].diem ; }

cout << "Đi m trung bình c a sinh viên nam là " << tbnam/sonam ;ể ủ

cout << "Đi m trung bình c a sinh viên n là " << tbnu/sonu ;ể ủ ữ

// In danh sách sinh viên có đi m cao nh tể ấ

float diemmax = 0;

for (i=1; i<=n; i++) // Tìm đi m cao nh tể ấ

if (diemmax < K41T[i].diem) diemmax = K41T[i].diem ;

for (i=1; i<=n; i++) // In danh sách

{

Page 149: Giao Trinh C++ Toan Tap

if (K41T[i].diem < diemmax) continue ;

x = K41T[1] ;

cout << x.hoten << '\t' ;

cout << x.ns.ng << "/" << x.ns.th << "/" << x.ns.nam << '\t' ;

cout << (x.gt == 1) ? "Nam": "N " << '\t' ;ữ

cout << x.diem << endl;

}

}

Hàm v i c u trúcớ ấ

Con tr và đ a ch c u trúcỏ ị ỉ ấM t con tr c u trúc cũng gi ng nh con tr tr đ n các ki u d li u khác, có nghĩa nó ch aộ ỏ ấ ố ư ỏ ỏ ế ể ữ ệ ứ đ a ch c a m t bi n c u trúc ho c m t vùng nh có ki u c u trúc nào đó. M t con tr c uị ỉ ủ ộ ế ấ ặ ộ ớ ể ấ ộ ỏ ấ trúc đ c kh i t o b i:ượ ở ạ ở

Gán đ a ch c a m t bi n c u trúc, m t thành ph n c a m ng, t ng t n u đ a ch c aị ỉ ủ ộ ế ấ ộ ầ ủ ả ươ ự ế ị ỉ ủ m ng (cũng là đ a ch c a ph n t đ u tiên c a m ng) gán cho con tr thì ta cũng g iả ị ỉ ủ ầ ử ầ ủ ả ỏ ọ là con tr m ng c u trúc. Ví d :ỏ ả ấ ụ

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} x, y, *p, lop[60];

p = &x ; // cho con tr p tr t i bi n c u trúc xỏ ỏ ớ ế ấ

p®diem = 5.0; // gán giá tr 5.0 cho đi m c a bi n xị ể ủ ế

p = &lop[10] ; // cho p tr t i sinh viên th 10 c a l p ỏ ớ ứ ủ ớ

cout << p®hoten; // hi n h tên c a sinh viên nàyệ ọ ủ

*p = y ; // gán l i sinh viên th 10 là yạ ứ

(*p).gt = 2; // s a l i gi i tính c a sinh viên th 10 là nử ạ ớ ủ ứ ữ

Page 150: Giao Trinh C++ Toan Tap

Chú ý: thông qua ví d này ta còn th y m t cách khác n a đ truy nh p các thành ph n c a xụ ấ ộ ữ ể ậ ầ ủ đ c tr b i con tr p. Khi đó *p là t ng đ ng v i x, do v y ta dùng l i cú pháp s d ngượ ỏ ở ỏ ươ ươ ớ ậ ạ ử ụ toán t . sau *p đ l y thành ph n nh (*p).hoten, (*p).diem, …ử ể ấ ầ ư

Con tr đ c kh i t o do xin c p phát b nh . Ví d :ỏ ượ ở ạ ấ ộ ớ ụ

Sinhvien *p, *q ;

p = new Sinhvien[1];

q = new Sinhvien[60];

trong ví d này *p có th thay cho m t bi n ki u sinh viên (t ng đ ng bi n x trên)ụ ể ộ ế ể ươ ươ ế ở còn q có th đ c dùng đ qu n lý m t danh sách có t i đa là 60 sinh viên (t ng đ ng bi nể ượ ể ả ộ ố ươ ươ ế lop[60], ví d khi đó *(p+10) là sinh viên th 10 trong danh sách). ụ ứ

Đ i v i con tr p tr đ n m ng a, chúng ta có th s d ng m t s cách sau đ truyố ớ ỏ ỏ ế ả ể ử ụ ộ ố ể nh p đ n các tr ng c a các thành ph n trong m ng, ví d đ truy c p hoten c aậ ế ườ ủ ầ ả ụ ể ậ ủ thành ph n th i c a m ng a ta có th vi t:ầ ứ ủ ả ể ế

p[i].hoten

(p+i)®hoten

*(p+i).hotenNói chung các cách vi t trên đ u d nh do suy t ki u m ng và con tr m ng. C thế ề ễ ớ ừ ể ả ỏ ả ụ ể

trong đó p[i] là thành ph n th i c a m ng a, t c a[i]. (p+i) là con tr tr đ n thành ph n th iầ ứ ủ ả ứ ỏ ỏ ế ầ ứ và *(p+i) chính là a[i]. Ví d sau gán giá tr cho thành ph n th 10 c a m ng sinh viên lop, sauụ ị ầ ứ ủ ả đó in ra màn hình các thông tin này. Ví d dùng đ minh ho các cách truy nh p tr ng dụ ể ạ ậ ườ ữ li u c a thành ph n trong m ng lop. ệ ủ ầ ả

:

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} lop[60] ;

strcpy(lop[10].hoten, "NVA");

lop[10].gt = 1; lop[10].diem = 9.0 ;

Sinhvien *p ; // khai báo thêm bi n con tr Sinh viên ế ỏ

p = &lop ; // cho con tr p tr t i m ng lopỏ ỏ ớ ả

cout << p[10].hoten ; // in h tên sinh viên th 10ọ ứ

Page 151: Giao Trinh C++ Toan Tap

cout << (p+10) ® gt ; // in gi i tính c a sinh viên th 10 ớ ủ ứ

cout << (*(p+10)).diem ; // in đi m c a sinh viên th 10ể ủ ứ

Chú ý: Đ u tiên c a toán t l y thành ph n (d u ch m) là cao h n các toán t l y đ a chộ ư ủ ử ấ ầ ấ ấ ơ ử ấ ị ỉ (&) và l y giá tr (*) nên c n ph i vi t các d u ngo c đúng cách.ấ ị ầ ả ế ấ ặ

Đ a ch c a các thành ph n c a c u trúc ị ỉ ủ ầ ủ ấCác thành ph n c a m t c u trúc cũng gi ng nh các bi n, do v y cách l y đ a ch c a cácầ ủ ộ ấ ố ư ế ậ ấ ị ỉ ủ thành ph n này cũng t ng t nh đ i v i bi n bình th ng. Ch ng h n đ a ch c a thànhầ ươ ự ư ố ớ ế ườ ẳ ạ ị ỉ ủ ph n gi i tính c a bi n c u trúc x là &x.gt (l u ý đ u tiên c a . cao h n &, nên &x.gt làầ ớ ủ ế ấ ư ộ ư ủ ơ cũng t ng đ ng v i &(x.gt)), đ a ch c a tr ng hoten c a thành ph n th 10 trong m ngươ ươ ớ ị ỉ ủ ườ ủ ầ ứ ả l p là lop[10].hoten (hoten là xâu kí t ), t ng t đ a ch c a thành ph n diem c a bi n đ cớ ự ươ ự ị ỉ ủ ầ ủ ế ượ tr b i p là &(p®diem).ỏ ở

Ví d :ụ

struct Sinhvien {

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} lop[60], *p, x = { "NVA", {1,1,1980}, 1, 9.0) };

lop[10] = x; p = &lop[10] ; // p tr đ n sinh viên th 10 trong lopỏ ế ứ

char *ht; int *gt; float *d; // các con tr ki u thành ph nỏ ể ầ

ht = x.ht ; // cho ht tr đ n thành ph n hoten c a xỏ ế ầ ủ

gt = &(lop[10].gt) ; // gt tr đ n gt c a sinh viên th 10ỏ ế ủ ứ

d = &(p®diem) ; // p tr đ n diem c a sv p đang tr ỏ ế ủ ỏ

cout << ht ; // in h tên sinh viên xọ

cout << *gt ; // in gi i tính c a sinh viên th 10ớ ủ ứ

cout << *d ; // in đi m c a sinh viên p đang tr .ể ủ ỏ

Đ i c a hàm là c u trúcố ủ ấM t c u trúc có th đ c s d ng đ làm đ i c a hàm d i các d ng sau đây:ộ ấ ể ượ ử ụ ể ố ủ ướ ạ

Là m t bi n c u trúc, khi đó tham đ i th c s là m t c u trúc.ộ ế ấ ố ự ự ộ ấ

Là m t con tr c u trúc, tham đ i th c s là đ a ch c a m t c u trúc. ộ ỏ ấ ố ự ự ị ỉ ủ ộ ấ

Là m t tham chi u c u trúc, tham đ i th c s là m t c u trúc.ộ ế ấ ố ự ự ộ ấ

Là m t m ng c u trúc hình th c ho c con tr m ng, tham đ i th c s là tên m ng c uộ ả ấ ứ ặ ỏ ả ố ự ự ả ấ trúc.

Page 152: Giao Trinh C++ Toan Tap

: Ví d sau đây cho phép tính chính xác kho ng cách c a 2 ngày tháng b t kỳ, t đó có th suyụ ả ủ ấ ừ ể ra th c a m t ngày tháng b t kỳ. Đ i c a các hàm là m t bi n c u trúc.ứ ủ ộ ấ ố ủ ộ ế ấ

Khai báo

struct DATE { // Ki u ngàyể tháng

int ngay ;

int thang;

int nam ;

};

// S ngày c a m i thángố ủ ỗ

int n[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

Hàm tính năm nhu n hay không nhu n, tr l i 1 n u năm nhu n, ng c l i tr 0.ậ ậ ả ạ ế ậ ượ ạ ả

int Nhuan(int nm)

{

return (nam%4==0 && nam%100!=0 || nam%400==0)? 1: 0;

}

Hàm tr l i s ngày c a m t tháng b t kỳ. N u năm nhu n và là tháng hai s ngày c aả ạ ố ủ ộ ấ ế ậ ố ủ tháng hai (28) đ c c ng thêm 1.ượ ộ

int Ngayct(int thang, int nam)

{

return n[thang] + ((thang==2) ? Nhuan(nam): 0);

}

Hàm tr l i s ngày tính t ngày 1 tháng 1 năm 1 b ng cách c ng d n s ngày c a t ngả ạ ố ừ ằ ộ ồ ố ủ ừ năm t năm 1 đ n năm hi n t i, ti p theo c ng d n s ngày t ng tháng c a nămừ ế ệ ạ ế ộ ồ ố ừ ủ hi n t i cho đ n tháng hi n t i và cu i cùng c ng thêm s ngày hi n t i. ệ ạ ế ệ ạ ố ộ ố ệ ạ

long Tongngay(DATE d)

{

long i, kq = 0;

for (i=1; i<d.nam; i++) kq += 365 + Nhuan(i);

Page 153: Giao Trinh C++ Toan Tap

for (i=1; i<d.thang; i++) kq += Ngayct(i,d.nam);

kq += d.ngay;

return kq;

}

Hàm tr l i kho ng cách gi a 2 ngày b t kỳ.ả ạ ả ữ ấ

long Khoangcach(DATE d1, DATE d2)

{

return Tongngay(d1)-Tongngay(d2);

}

Hàm tr l i th c a m t ngày b t kỳ. Qui c 1 là ch nh t, 2 là th hai, … Đ tính thả ạ ứ ủ ộ ấ ướ ủ ậ ứ ể ứ hàm d a trên m t ngày chu n nào đó ( đây là ngày 1/1/2000, đ c bi t là th b y).ự ộ ẩ ở ượ ế ứ ả T ngày chu n này n u c ng ho c tr 7 s cho ra ngày m i cũng là th b y. T đó,ừ ẩ ế ộ ặ ừ ẽ ớ ứ ả ừ tính kho ng cách gi a ngày c n tính th và ngày chu n. Tìm ph n d c a phép chiaả ữ ầ ứ ẩ ầ ư ủ kho ng cách này v i 7, n u ph n d là 0 thì th là b y, ph n d là 1 thì th là chả ớ ế ầ ư ứ ả ầ ư ứ ủ nh t … ậ

int Thu(DATE d)

{

DATE curdate = {1,1,2000}; // ngày 1/1/2000 là th b yứ ả

long kc = Khoangcach(d, curdate);

int du = kc % 7; if (du < 0) du += 7;

return du;

}

Hàm d ch m t s d sang thị ộ ố ư ứ

char* Dich(int t)

{

char* kq = new char[10];

switch (t) {

case 0: strcpy(kq, "th b y"); break;ứ ả

case 1: strcpy(kq, "ch nh t"); break;ủ ậ

case 2: strcpy(kq, "th hai"); break;ứ

case 3: strcpy(kq, "th ba"); break;ứ

Page 154: Giao Trinh C++ Toan Tap

case 4: strcpy(kq, "th t "); break;ứ ư

case 5: strcpy(kq, "th năm"); break;ứ

case 6: strcpy(kq, "th sáu"); break;ứ

}

return kq;

}

Hàm main()

void main()

{

DATE d;

cout << "Nhap ngay thang nam: " ;

cin >> d.ngay >> d.thang >> d.nam ;

cout << "Ngày " << d.ngay << "/" << d.thang << "/" << d.nam ;

cout << " là " << Dich(Thu(d));

}

: Ch ng trình đ n gi n v qu n lý sinh viên.ươ ơ ả ề ả

Khai báo.

struct Sinhvien { // c u trúc sinh viên ấ

char hoten[25] ;

Ngaythang ns;

int gt;

float diem ;

} ;

Sinhvien lop[3]; // l p ch a t i đa 3 sinh viên ớ ứ ố

Hàm in thông tin v sinh viên s d ng bi n c u trúc làm đ i. Trong l i g i s d ngề ử ụ ế ấ ố ờ ọ ử ụ bi n c u trúc đ truy n cho hàm.ế ấ ể ề

void in(Sinhvien x)

{

cout << x.hoten << "\t" ;

cout << x.ns.ng << "/" << x.ns.th << "/" << x.ns.nam << "\t" ;

cout << x.gt << "\t";

cout << x.diem << endl;

Page 155: Giao Trinh C++ Toan Tap

}

Hàm nh p thông tin v sinh viên s d ng con tr sinh viên làm đ i. Trong l i g i sậ ề ử ụ ỏ ố ờ ọ ử d ng đ a ch c a m t c u trúc đ truy n cho hàm.ụ ị ỉ ủ ộ ấ ể ề

void nhap(Sinhvien *p)

{

cin.ignore();

cout << "H tên: "; cin.getline(p®hoten, 25) ;ọ

cout << "Ngày sinh: ";

cin >> (p®ns).ng >> (p®ns).th >> (p®ns).nam ;

cout << "Gi i tính: "; cin >> (p®gt) ; ớ

cout << "Đi m: "; cin >> (p®diem) ; ể

}

Hàm s a thông tin v sinh viên s d ng tham chi u c u trúc làm đ i. Trong l i g i sử ề ử ụ ế ấ ố ờ ọ ử d ng bi n c u trúc đ truy n cho hàm.ụ ế ấ ể ề

void sua(Sinhvien &r)

{

int chon;

do {

cout << "1: S a h tên" << endl ;ử ọ

cout << "2: S a ngày sinh" << endl ;ử

cout << "3: S a gi i tính" << endl ;ử ớ

cout << "4: S a đi m" << endl ;ử ể

cout << "0: Thôi" << endl ;

cout << "S a (0/1/2/3/4) ? ; cin >> chon ; cin.ignore();ử

switch (chon) {

case 1: cin.getline(r.hoten, 25) ; break;

case 2: cin >> r.ns.ng >> r.ns.th >> r.ns.nam ; break;

case 3: cin >> r.gt ; break;

case 4: cin >> r.diem ; break;

}

} while (chon) ;

}

Hàm nhapds nh p thông tin c a m i sinh viên trong m ng, s d ng con tr m ngậ ủ ọ ả ử ụ ỏ ả

Page 156: Giao Trinh C++ Toan Tap

Sinhvien làm tham đ i hình th c. Trong l i g i s d ng tên m ng đ truy n choố ứ ờ ọ ử ụ ả ể ề hàm.

void nhapds(Sinhvien *a)

{

int sosv = sizeof(lop) / sizeof(Sinhvien) -1; // b ph n t 0ỏ ầ ử

for (int i=1; i<=sosv; i++) nhap(&a[i]) ;

}

Hàm suads cho phép s a thông tin c a sinh viên trong m ng, s d ng con tr m ngử ủ ả ử ụ ỏ ả Sinhvien làm tham đ i hình th c. Trong l i g i s d ng tên m ng đ truy n choố ứ ờ ọ ử ụ ả ể ề hàm.

void suads(Sinhvien *a)

{

int chon;

cout << "Ch n sinh viên c n s a: " ; cin >> chon ; cin.ignore();ọ ầ ử

sua(a[chon]) ;

}

Hàm inds hi n thông tin c a m i sinh viên trong m ng, s d ng h ng con tr m ngệ ủ ọ ả ử ụ ằ ỏ ả Sinhvien làm tham đ i hình th c. Trong l i g i s d ng tên m ng đ truy n choố ứ ờ ọ ử ụ ả ể ề hàm.

void hien(const Sinhvien *a)

{

int sosv = sizeof(lop) / sizeof(Sinhvien) -1; // b ph n t 0ỏ ầ ử

for (int i=1; i<=sosv; i++) in(a[i]) ;

}

Hàm main() g i ch y các hàm trên đ nh p, in, s a danh sách sinh viên.ọ ạ ể ậ ử

void main()

{

nhapds(lop) ;

inds(lop);

suads(lop);

inds(lop);

}

Giá tr hàm là c u trúcị ấ

Page 157: Giao Trinh C++ Toan Tap

Cũng t ng t nh các ki u d li u c b n, giá tr tr l i c a m t hàm cũng có th là các c uươ ự ư ể ữ ệ ơ ả ị ả ạ ủ ộ ể ấ trúc d i các d ng sau:ướ ạ

là m t bi n c u trúc.ộ ế ấ

là m t con tr c u trúc. ộ ỏ ấ

là m t tham chi u c u trúc.ộ ế ấSau đây là các ví d minh ho giá tr c u trúc c a hàm.ụ ạ ị ấ ủ

: Đ i và giá tr c a hàm là c u trúc: C ng, tr hai s ph c.ố ị ủ ấ ộ ừ ố ứ

Khai báo ki u s ph cể ố ứ

struct Sophuc // Khai báo ki u s ph c dùng chungể ố ứ

{

float thuc;

float ao;

};

Hàm c ng 2 s ph c, tr l i m t s ph cộ ố ứ ả ạ ộ ố ứSophuc Cong(Sophuc x, Sophuc y)

{

Sophuc kq;

kq.thuc = x.thuc + y.thuc ;

kq.ao = x.ao + y.ao ;

return kq;

}

Hàm tr 2 s ph c, tr l i m t s ph cừ ố ứ ả ạ ộ ố ứSophuc Tru(Sophuc x, Sophuc y)

{

Sophuc kq;

kq.thuc = x.thuc + y.thuc ;

kq.ao = x.ao + y.ao ;

return kq;

}

Hàm in m t s ph c d ng (r + im)ộ ố ứ ạ

void In(Sophuc x)

Page 158: Giao Trinh C++ Toan Tap

{

cout << "(" << x.thuc << "," << x.ao << ")" << endl ;

}

Hàm chính

void main()

{

Sophuc x, y, z ;

cout << "x = " ; cin >> x.thuc >> x.ao ;

cout << "y = " ; cin >> y.thuc >> y.ao ;

cout << "x + y = " ; In(Cong(x,y)) ;

cout << "x - y = " ; In(Tru(x,y)) ;

}

: Ch ng trình nh p và in thông tin v m t l p cùng sinh viên có đi m cao nh t l p. ươ ậ ề ộ ớ ể ấ ớ

Khai báo ki u d li u Sinh viên và bi n m ng lop.ể ữ ệ ế ả

struct Sinhvien {

char *hoten ;

float diem ;

} lop[4] ;

Hàm nh p sinh viên, giá tr tr l i là m t con tr tr đ n d li u v a nh p.ậ ị ả ạ ộ ỏ ỏ ế ữ ệ ừ ậ

Sinhvien* nhap()

{

Sinhvien* kq = new Sinhvien[1]; // nh c p phát vùng nhớ ấ ớ

kq->hoten = new char[15]; // cho c con tr hotenả ỏ

cout << "H tên: "; cin.getline(kq->hoten,30);ọ

cout << "Đi m: "; cin >> kq->diem; cin.ignore(); ể

return kq; // tr l i con tr kqả ạ ỏ

}

Hàm tìm sinh viên có đi m cao nh t, giá tr tr l i là m t tham chi u đ n sinh viên tìmể ấ ị ả ạ ộ ế ế

Page 159: Giao Trinh C++ Toan Tap

đ c.ượ

Sinhvien& svmax()

{

int sosv = sizeof(lop)/sizeof(Sinhvien)-1; // b thành ph n th 0ỏ ầ ứ

float maxdiem = 0;

int kmax; // ch s sv có đi mỉ ố ể max

for (int i=1; i<sosv; i++)

if (maxdiem < lop[i].diem)

{

maxdiem = lop[i].diem ;

kmax = i;

}

return lop[kmax]; // tr l i sv có đi m maxả ạ ể

}

Hàm in thông tin c a m t sinh viên xủ ộ

void in(Sinhvien x)

{

cout << x.hoten << "\t";

cout << x.diem << endl;

}

Hàm chính

void main()

{

clrscr();

int i;

int sosv = sizeof(lop)/sizeof(Sinhvien)-1; // b thành ph n th 0ỏ ầ ứ

for (i=1; i<=sosv; i++) lop[i] = *nhap(); // nh p danh sách l pậ ớ

for (i=1; i<=sosv; i++) in(lop[i]); // in danh sách l pớ

Page 160: Giao Trinh C++ Toan Tap

Sinhvien &b = svmax(); // khai báo tham chi u b và cho ế

// tham chi u đ n sv có đi m max ế ế ể

in(b); // in sinh viên có đi m max ể

getch();

}

C u trúc v i thành ph n ki u bitấ ớ ầ ể

Trư ng bitờThông th ng các trườ ư ng trong m t c u trúc thờ ộ ấ ư ng s d ng ít nh t là 2 byte t c 16 bit.ờ ử ụ ấ ứ Trong nhi u tr ng h p m t s tr ng có th ch c n đ n s bit ít hề ườ ợ ộ ố ườ ể ỉ ầ ế ố ơn, ví d tr ng gioitinhụ ườ thông th ng ch c n đ n 1 bit đ l u tr . Nh ng tr ng h p nh v y ta có th khai báo ki uườ ỉ ầ ế ể ư ữ ữ ườ ợ ư ậ ể ể bit cho các tr ng này đ ti t ki m b nh . Tuy nhiên, cách khai báo này ít đ c s d ng trườ ể ế ệ ộ ớ ượ ử ụ ừ khi c n thi t ph i truy nh p ầ ế ả ậ đ n m c bit c a d li u trong các ch ng trình liên quan đ n hế ứ ủ ữ ệ ươ ế ệ th ng.ố

M t tr ng bit là m t khai báo tr ng int và thêm d u: cùng s bit n theo sau, trong đó 0 £ n <ộ ườ ộ ườ ấ ố 15. Ví d do đ l n c a ngày không v t quá 31, tháng không vu t quá 12 nên 2 tr ng nàyụ ộ ớ ủ ượ ợ ườ trong c u trúc ngày tháng có th khai báo ti t ki m h n b ng 5 và 4 bit nh sau:ấ ể ế ệ ơ ằ ư

struct Date {

int ng: 5;

int th: 4;

int nam;

} ;

Đ c đi mặ ểC n chú ý các đ c đi m sau c a m t c u trúc có ch a tr ng bit:ầ ặ ể ủ ộ ấ ứ ườ

Các bit đư c b trí liên t c trên dãy các byte.ợ ố ụ

Ki u tr ng bit ph i là int (signed ho c unsigned).ể ườ ả ặ

Đ dài m i tr ng bit không quá 16 bit.ộ ỗ ườ

Có th b qua m t s bit n u b tr ng tên trể ỏ ộ ố ế ỏ ố ư ng, ví d : ờ ụ

struct tu {

int: 8;

int x:8;

}m i m t bi n c u trúc theo khai báo trên g m 2 byte, b qua không s d ng byte th pỗ ộ ế ấ ồ ỏ ử ụ ấ

Page 161: Giao Trinh C++ Toan Tap

và tr ng x chi m byte (8 bit) cao.ườ ế

Không cho phép l y đ a ch c a thành ph n ki u bit.ấ ị ỉ ủ ầ ể

Không th xây d ng đ c m ng ki u bit.ể ự ượ ả ể

Không đ c tr v t hàm m t thành ph n ki u bit. Ví d n u b là m t thành ph n c aượ ả ề ừ ộ ầ ể ụ ế ộ ầ ủ bi n c u trúc x có ki u bit thì câu l nh sau là sai:ế ấ ể ệ

return x.b ; // saituy nhiên có th thông qua bi n ph nh sau:ể ế ụ ư

int tam = x.b ; return tam ;

Ti t ki m b nhế ệ ộ ớ

Dùng trong ki u union ể đ l y các bit c a m t t (xem ví d trong ph n ki u h p).ể ấ ủ ộ ừ ụ ầ ể ợ

Câu l nh typedefệĐ thu n ti n trong s d ng, thông th ng các ki u đ c NSD t o m i s đ c gán cho m tể ậ ệ ử ụ ườ ể ượ ạ ớ ẽ ượ ộ tên ki u b ng câu l nh typedef nh sau:ể ằ ệ ư

typedef <ki u> <tên_ki u> ;ể ể

Ví d : Đ t o ki u m i có tên Bool và ch ch a giá tr nguyên (th c ch t ch c n 2 giá tr 0,ụ ể ạ ể ớ ỉ ứ ị ự ấ ỉ ầ ị 1), ta có th khai báo:ể

typedef int Bool;

khai báo này cho phép xem Bool nh ki u s nguyên.ư ể ố

ho c có th đ t tên cho ki u ngày tháng là Date v i khai báo sau:ặ ể ặ ể ớ

typedef struct Date {

int ng;

int th;

int nam;

};khi đó ta có th s d ng các tên ki u này trong các khai báo (ví d tên ki u c a đ i, c aể ử ụ ể ụ ể ủ ố ủ

giá tr hàm tr l i …).ị ả ạ

Hàm sizeof()Hàm tr l i kích th c c a m t bi n ho c ki u. Ví d :ả ạ ướ ủ ộ ế ặ ể ụ

Bool a, b;

Date x, y, z[50];

cout << sizeof(a) << sizeof(b) << sizeof(Bool) ; // in 2 2 2

Page 162: Giao Trinh C++ Toan Tap

cout << "S ph n t c a z = " << sizeof(z) / sizeof(Date)ố ầ ử ủ // in 50

C U TRÚC T TR VÀ DANH SÁCH LIÊN K TẤ Ự Ỏ Ế

Thông th ng khi thi t k ch ng trình chúng ta ch a bi t đ c s l ng d li u c n dùngườ ế ế ươ ư ế ượ ố ượ ữ ệ ầ là bao nhiêu đ khai báo s bi n cho phù h p. Đ c bi t là bi n d li u ki u m ng. S l ngể ố ế ợ ặ ệ ế ữ ệ ể ả ố ượ các thành ph n c a bi n m ng c n ph i khai báo tr c và ch ng trình d ch s b trí vùngầ ủ ế ả ầ ả ướ ươ ị ẽ ố nh c đ nh cho các bi n này. Do bu c ph i khai báo tr c s l ng thành ph n nên ki uớ ố ị ế ộ ả ướ ố ượ ầ ể m ng th ng d n đ n ho c là lãng phí b nh (khi ch ng trình không dùng h t) ho c làả ườ ẫ ế ặ ộ ớ ươ ế ặ không đ đ ch a d li u (khi ch ng trình c n ch a d li u v i s l ng thành ph n l nủ ể ứ ữ ệ ươ ầ ứ ữ ệ ớ ố ượ ầ ớ h n).ơ

Đ kh c ph c tình tr ng này C++ cho phép c p phát b nh đ ng, nghĩa là s l ng cácể ắ ụ ạ ấ ộ ớ ộ ố ượ thành ph n không c n ph i khai báo tr c. B ng toán t new chúng ta có th xin c p phátầ ầ ả ướ ằ ử ể ấ vùng nh theo nhu c u m i khi ch y ch ng trình. Tuy nhiên, cách làm này d n đ n vi c dớ ầ ỗ ạ ươ ẫ ế ệ ữ li u c a m t danh sách s không còn n m liên t c trong b nh nh đ i v i bi n m ng. M iệ ủ ộ ẽ ằ ụ ộ ớ ư ố ớ ế ả ỗ l n xin c p phát b i toán t new, ch ng trình s tìm m t vùng nh đang r i b t kỳ đ c pầ ấ ở ử ươ ẽ ộ ớ ỗ ấ ể ấ phát cho bi n và nh v y d li u s n m r i rác trong b nh . T đó, đ d dàng qu n lýế ư ậ ữ ệ ẽ ằ ả ộ ớ ừ ể ễ ả tr t t c a m t danh sách các d li u, m i thành ph n c a danh sách c n ph i ch a đ a chậ ự ủ ộ ữ ệ ỗ ầ ủ ầ ả ứ ị ỉ c a thành ph n ti p theo ho c tr c nó (đi u này là không c n thi t đ i v i bi n m ng vì cácủ ầ ế ặ ướ ề ầ ế ố ớ ế ả thành ph n c a chúng s p x p liên t c, k nhau). T đó, m i thành ph n c a danh sách s làầ ủ ắ ế ụ ề ừ ỗ ầ ủ ẽ m t c u trúc, ngoài các thành ph n ch a thông tin c a b n thân, chúng còn ph i có thêm m tộ ấ ầ ứ ủ ả ả ộ ho c nhi u con tr đ tr đ n các thành ph n ti p theo hay đ ng tr c. Các c u trúc nh v yặ ề ỏ ể ỏ ế ầ ế ứ ướ ấ ư ậ đ c g i là c u trúc t tr vì các thành ph n con tr trong c u trúc này s tr đ n các vùngượ ọ ấ ự ỏ ầ ỏ ấ ẽ ỏ ế d li u có ki u chính là ki u c a chúng. ữ ệ ể ể ủ

C u trúc t trấ ự ỏM t c u trúc có ch a ít nh t m t thành ph n con tr có ki u c a chính c u trúc đang đ nhộ ấ ứ ấ ộ ầ ỏ ể ủ ấ ị nghĩa đ c g i là c u trúc t tr . Có th khai báo c u trúc t tr b i m t trong nh ng cáchượ ọ ấ ự ỏ ể ấ ự ỏ ở ộ ữ sau:

Cách 1:

typedef struct <tên c u trúc> <tên ki u> ; ấ ể // đ nh nghĩa tên c u trúc ị ấ

struct <tên c u trúc> ấ

{

các thành ph n ch a thông tin … ;ầ ứ

<tên ki u> *con tr ;ể ỏ

} ;Ví d :ụ

typedef struct Sv Sinhvien ; // l u ý ph i có t khoá structư ả ừ

Page 163: Giao Trinh C++ Toan Tap

struct Sv

{

char hoten[30] ; // thành ph n ch a thông tinầ ứ

float diem ; // thành ph n ch a thông tinầ ứ

Sinhvien *tiep ; // thành ph n con tr ch a đ a ch ti p theoầ ỏ ứ ị ỉ ế

} ;

Cách 2:

struct <tên c u trúc> ấ

{

các thành ph n ch a thông tin … ;ầ ứ

<tên c u trúc> *con tr ;ấ ỏ

} ;

typedef <tên c u trúc> <tên ki u> ; ấ ể // đ nh nghĩa tên c u trúc t trị ấ ự ỏVí d :ụ

struct Sv

{

char hoten[30] ; // thành ph n ch a thông tinầ ứ

float diem ; // thành ph n ch a thông tinầ ứ

Sv *tiep ; // thành ph n con tr ch a đ a ch ti p theoầ ỏ ứ ị ỉ ế

} ;

typedef Sv Sinhvien ;

Cách 3:

typedef struct <tên ki u> ể // đ nh nghĩa tên c u trúc t trị ấ ự ỏ

{

các thành ph n ch a thông tin … ;ầ ứ

<tên ki u> *con tr ;ể ỏ

} ;Ví d :ụ

typedef struct Sinhvien

{

char hoten[30] ; // thành ph n ch a thông tinầ ứ

Page 164: Giao Trinh C++ Toan Tap

float diem ; // thành ph n ch a thông tinầ ứ

Sinhvien *tiep ; // con tr ch a đ a ch thành ph n ti p theoỏ ứ ị ỉ ầ ế

} ;

Cách 4:

struct <tên ki u>ể

{

các thành ph n ch a thông tin … ;ầ ứ

<tên ki u> *con tr ;ể ỏ

} ;Ví d :ụ

struct Sinhvien

{

char hoten[30] ; // thành ph n ch a thông tinầ ứ

float diem ; // thành ph n ch a thông tinầ ứ

Sinhvien *tiep ; // con tr ch a đ a ch c a ph n t ti p.ỏ ứ ị ỉ ủ ầ ử ế

} ;Trong các cách trên ta th y 2 cách khai báo cu i cùng là đ n gi n nh t. C++ quan ni mấ ố ơ ả ấ ệ

các tên g i đ ng sau các t khoá struct, union, enum là các tên ki u (dù không có t khoáọ ứ ừ ể ừ typedef), do v y có th s d ng các tên này đ khai báo.ậ ể ử ụ ể

Khái ni m danh sách liên k tệ ếDanh sách liên k t là m t c u trúc d li u cho phép th hi n và qu n lý danh sách b ng cácế ộ ấ ữ ệ ể ệ ả ằ c u trúc liên k t v i nhau thông qua các con tr trong c u trúc. Có nhi u d ng danh sách liênấ ế ớ ỏ ấ ề ạ k t ph thu c vào các k t n i, ví d :ế ụ ộ ế ố ụ

Danh sách liên k t đ n, m i c u trúc ch a m t con tr tr đ n c u trúc ti p theo ho cế ơ ỗ ấ ứ ộ ỏ ỏ ế ấ ế ặ tr c đó. Đ i v i danh sách con tr tr v tr c, c u trúc đ u tiên c a danh sách sướ ố ớ ỏ ỏ ề ướ ấ ầ ủ ẽ tr v h ng con tr NULL, c u trúc cu i cùng đ c đánh d u b i con tr last là conỏ ề ằ ỏ ấ ố ượ ấ ở ỏ tr tr vào c u trúc này. Đ i v i danh sách con tr tr v c u trúc ti p theo, c u trúcỏ ỏ ấ ố ớ ỏ ỏ ề ấ ế ấ đ u s đ c đánh d u b ng con tr head và c u trúc cu i cùng ch a con tr NULL.ầ ẽ ượ ấ ằ ỏ ấ ố ư ỏ

Danh sách liên k t kép g m 2 con tr , m t tr đ n c u trúc tr c và m t tr đ n c uế ồ ỏ ộ ỏ ế ấ ướ ộ ỏ ế ấ trúc sau, 2 đ u c a danh sách đ c đánh d u b i các con tr head, last.ầ ủ ượ ấ ở ỏ

Danh sách liên k t vòng g m 1 con tr tr v sau (ho c tr c), hai đ u c a danh sáchế ồ ỏ ỏ ề ặ ướ ầ ủ đ c n i v i nhau t o thành vòng tròn. Ch c n m t con tr head đ đánh d u đ uượ ố ớ ạ ỉ ầ ộ ỏ ể ấ ầ danh sách.

Do trong c u trúc có ch a các con tr tr đ n c u trúc ti p theo và/ho c c u trúc đ ng tr cấ ứ ỏ ỏ ế ấ ế ặ ấ ứ ướ nên t m t c u trúc này chúng ta có th truy c p đ n m t c u trúc khác (tr c và/ho c sauừ ộ ấ ể ậ ế ộ ấ ướ ặ

Page 165: Giao Trinh C++ Toan Tap

nó). K t h p v i các con tr đánh d u 2 đ u danh sách (head, last) chúng ta s d dàng làmế ợ ớ ỏ ấ ầ ẽ ễ vi c v i b t kỳ ph n t nào c a danh sách. Có th k m t s công vi c th ng th c hi nệ ớ ấ ầ ử ủ ể ể ộ ố ệ ườ ự ệ trên m t danh sách nh : b sung ph n t vào cu i danh sách, chèn thêm m t ph n t m i, xoáộ ư ổ ầ ử ố ộ ầ ử ớ m t ph n t c a danh sách, tìm ki m, s p x p danh sách, in danh sách … ộ ầ ử ủ ế ắ ế

Hình v bên d i minh ho m t danh sách liên k t đ n qu n lý sinh viên, thông tin ch a trongẽ ướ ạ ộ ế ơ ả ứ m i ph n t c a danh sách g m có h tên sinh viên, đi m. Ngoài ra m i ph n t còn ch a conỗ ầ ử ủ ồ ọ ể ỗ ầ ử ứ tr tiep đ n i v i ph n t ti p theo c a nó. Ph n t cu i cùng n i v i c u trúc r ngỏ ể ố ớ ầ ử ế ủ ầ ử ố ố ớ ấ ỗ (NULL).

NVA9.0

TTB7.5

PHT4.0

Các phép toán trên danh sách liên k tếD i đây chúng ta mô t tóm t t cách th c th c hi n m t s thao tác trên danh sách liên k tướ ả ắ ứ ự ệ ộ ố ế đ n.ơ

T o ph n t m iạ ầ ử ớĐ t o ph n t m i thông th ng chúng ta th c hi n theo các b c sau đây:ể ạ ầ ử ớ ườ ự ệ ướ

dùng toán t new xin c p phát m t vùng nh đ ch a m t ph n t c a danh sách.ử ấ ộ ớ ủ ứ ộ ầ ử ủ

nh p thông tin c n l u tr vào ph n t m i. Con tr tiep đ c đ t b ng NULL.ậ ầ ư ữ ầ ử ớ ỏ ượ ặ ằ

g n ph n t v a t o đ c vào danh sách. Có hai cách:ắ ầ ử ừ ạ ượ

ho c g n vào đ u danh sách, khi đó v trí c a con tr head (ch vào đ u danh sách)ặ ắ ầ ị ủ ỏ ỉ ầ đ c đi u ch nh l i đ ch vào ph n t m i.ượ ề ỉ ạ ể ỉ ầ ử ớ

ho c g n vào cu i danh sách b ng cách cho con tr tiep c a ph n t cu i danh sáchặ ắ ố ằ ỏ ủ ầ ử ố (đang tr vào NULL) tr vào ph n t m i. N u danh sách có con tr last đ chỏ ỏ ầ ử ớ ế ỏ ể ỉ vào cu i danh sách thì last đ c đi u ch nh đ tr vào ph n t m i. N u danhố ượ ề ỉ ể ỏ ầ ử ớ ế sách không có con tr last thì đ tìm đ c ph n t cu i ch ng trình ph i duy tỏ ể ượ ầ ử ố ươ ả ệ t đ u, b t đ u t con tr head cho đ n khi g p ph n t tr vào NULL, đó làừ ầ ắ ầ ừ ỏ ế ặ ầ ử ỏ ph n t cu i c a danh sách.ầ ử ố ủ

NULL

head

head

Page 166: Giao Trinh C++ Toan Tap

MOI0.0

NVA9.0

TTB7.5

PHT4.0

G n ph n t m i vào đ u danh sách ắ ầ ử ớ ầ

Chèn ph n t m i vào gi aầ ử ớ ữGi s ph n t m i đ c chèn vào gi a ph n t th i và i+1. Đ chèn ta n i ph n t th iả ử ầ ử ớ ượ ữ ầ ử ứ ể ố ầ ử ứ vào ph n t m i và ph n t m i n i vào ph n t th i+1. Thu t toán s nh sau:ầ ử ớ ầ ử ớ ố ầ ử ứ ậ ẽ ư

Cho con tr p ch y đ n ph n t th i.ỏ ạ ế ầ ử ứ

Cho con tr tiep c a ph n t m i tr vào ph n t th i+1 (tuc p->tiep).ỏ ủ ầ ử ớ ỏ ầ ử ứ

Cho con tr tiep c a ph n t th i (hi n đ c tr b i p) thay vì tr vào ph n t th i+1ỏ ủ ầ ử ứ ệ ượ ỏ ở ỏ ầ ử ứ bây gi s tr vào ph n t m i. ờ ẽ ỏ ầ ử ớ

MOI

đ uầ0.0

i9.0

i+17.5

cu iố4.0

Chèn ph n t m i vào gi a ph n t i và i+1 ầ ử ớ ữ ầ ử

a. Xoá ph n t th i kh i danh sách ầ ử ứ ỏVi c xoá m t ph n t ra kh i danh sách r t đ n gi n b i ch vi c thay đ i các con tr . Cệ ộ ầ ử ỏ ấ ơ ả ở ỉ ệ ổ ỏ ụ th gi s c n xoá ph n t th i ta ch c n cho con tr tiep c a ph n t th i-1 tr ("vòngể ả ử ầ ầ ử ứ ỉ ầ ỏ ủ ầ ử ứ ỏ qua" ph n t th i) vào ph n t th i+1. Nh v y bây gi khi ch y trên danh sách đ n ph nầ ử ứ ầ ử ứ ư ậ ờ ạ ế ầ t th i-1, ph n t ti p theo là ph n t th i+1 ch không còn là ph n t th i. Nói cách khácử ứ ầ ử ế ầ ử ứ ứ ầ ử ư ph n t th i không đ c n i b i b t kỳ ph n t nào nên nó s không thu c danh sách. Cóầ ử ứ ượ ố ở ấ ầ ử ẽ ộ th th c hi n các b c nh sau:ể ự ệ ướ ư

Cho con tr p ch y đ n ph n t th i-1.ỏ ạ ế ầ ử ứ

Đ t ph n t th i vào bi n x.ặ ầ ử ứ ế

Cho con tr tiep c a ph n t th i-1 tr vào ph n t th i+1 b ng cách đ t tiep = x.tiep.ỏ ủ ầ ử ứ ỏ ầ ử ứ ằ ặ

Gi i phóng b nh đ c tr b i x b ng câu l nh delete x.ả ộ ớ ượ ỏ ở ằ ệ

NULL

NULL

Page 167: Giao Trinh C++ Toan Tap

i-10.0

i9.0

i+17.5

cu iố4.0

Xóa ph n t th i ầ ử ứ

Duy t danh sáchệDuy t là thao tác đi qua t ng ph n t c a danh sách, t i m i ph n t ch ng trình th c hi nệ ừ ầ ử ủ ạ ỗ ầ ử ươ ự ệ m t công vi c gì đó trên ph n t mà ta g i là thăm ph n t đó. M t phép thăm có th đ nộ ệ ầ ử ọ ầ ử ộ ể ơ gi n là hi n n i dung thông tin c a ph n t đó ra màn hình ch ng h n. Đ duy t danh sách taả ệ ộ ủ ầ ử ẳ ạ ể ệ ch c n cho m t con tr p ch y t đ u đ n cu i danh sách đ n khi ph n t cu i có con trỉ ầ ộ ỏ ạ ừ ầ ế ố ế ầ ử ố ỏ tiep = NULL thì d ng. Câu l nh cho con tr p chuy n đ n ph n t ti p theo c a nó là:ừ ệ ỏ ể ế ầ ử ế ủ

p = p ® tiep ;

Tìm ki mếCho m t danh sách trong đó m i ph n t c a danh sách đ u ch a m t tr ng g i là tr ngộ ỗ ầ ử ủ ề ứ ộ ườ ọ ườ khoá, th ng là các tr ng có ki u c s ho c k t h p c a m t s tr ng nh v y. Bài toánườ ườ ể ơ ở ặ ế ợ ủ ộ ố ườ ư ậ đ t ra là tìm trên danh sách ph n t có giá tr c a tr ng khoá b ng v i m t giá tr cho tr c.ặ ầ ử ị ủ ườ ằ ớ ộ ị ướ Ti n trình th c hi n nhi m v th cch t cũng là bài toán duy t, trong đó thao tác "thăm" chínhế ự ệ ệ ụ ự ấ ệ là so sánh tr ng khoá c a ph n t v i giá tr cho tr c, n u trùng nhau ta in k t qu vàườ ủ ầ ử ớ ị ướ ế ế ả d ng, N u đã duy t h t mà không có ph n t nào có tr ng khoá trùng v i giá tr cho tr cừ ế ệ ế ầ ử ườ ớ ị ướ thì xem danh sách không ch a giá tr này.ứ ị

Ngoài các thao tác trên, nói chung còn nhi u các thao tác quen thu c khác tuy nhiên chúng taề ộ không trình bày đây vì nó không thu c ph m vi c a giáo trình này.ở ộ ạ ủ

D i đây là m t ví d minh ho cho c c c u trúc t tr , danh sách liên k t và m t vài thao tácướ ộ ụ ạ ấ ấ ự ỏ ế ộ trên danh sách liên k t thông qua bài toán qu n lý sinh viên.ế ả

Khai báo

struct DATE

{

int day, month, year; // ngày, tháng, năm

};

struct Sinhvien { // c u trúc t trấ ự ỏ

char hoten[31];

DATE ns;

float diem;

NULL

Page 168: Giao Trinh C++ Toan Tap

Sinhvien *tiep ;

};

Sinhvien *dau = NULL, *cuoi = NULL;// Các con tr t i đ u và cu i dsỏ ớ ầ ố

Sinhvien *cur = NULL; // Con tr t i sv hi n t iỏ ớ ệ ạ

int sosv = 0; // S sv c a danh sáchố ủ

T o sinh viên m i và nh p thông tin, tr l i con tr tr đ n sinh viên m i. ạ ớ ậ ả ạ ỏ ỏ ế ớ

Sinhvien* Nhap1sv() // T o 1 kh i d li u cho svạ ố ữ ệ m iớ

{

Sinhvien *kq = new Sinhvien[1] ; // C p phát b nh cho kqấ ộ ớ

cout << "\nSinh vien thu ", sosv+1 ;

cout << "Ho ten = " ; cin.getline(kq->hoten);

cout << "Ns = " ; cin >> kq->ns.day >> kq->ns.month >> kq->ns.year;

cout << "Diem = " ; cin >> kq->diem ; cin.ignore() ;

kq->tiep = NULL;

return kq ;

}

B sung sinh viên m i vào cu i danh sách. ổ ớ ố

void Bosung() // B sung sv m i vào cu iổ ớ ố ds

{

cur = Nhap1sv();

if (sosv == 0) {dau = cuoi = cur;}

else { cuoi->tiep = cur; cuoi = cur; }

sosv++;

}

Chèn sv m i vào tr c sinh viên th n.ớ ướ ứ

void Chentruoc(int n) // Chèn sv m i vào tr c sv th nớ ướ ứ

{

cur = Nhap1sv();

Page 169: Giao Trinh C++ Toan Tap

if (sosv==0) { dau = cuoi = cur; sosv++; return; }

if (sosv==1 || n==1) {cur->tiep = dau; dau = cur; sosv++; return;}

Sinhvien *truoc, *sau;

truoc = dau;

sau = dau -> tiep;

for (int i=1; i<n-1; i++) truoc = truoc->tiep;

sau = truoc->tiep;

truoc->tiep = cur;

cur -> tiep = sau;

sosv ++;

}

Chèn sv m i vào sau sinh viên th n.ớ ứ

void Chensau(int n) // Chèn sv m i vào sau svớ th nứ

{

cur = Nhap1sv();

if (sosv==0 || sosv<n) { dau = cuoi = cur; sosv++; return; }

Sinhvien *truoc, *sau;

truoc = dau; sau = dau -> tiep;

for (int i=1; i<n; i++) truoc = truoc->tiep;

sau = truoc->tiep;

truoc->tiep = cur;

cur -> tiep = sau;

sosv ++;

}

Xoá sinh viên th n.ứ

void Xoa(int n) // Xoá sinh viên th nứ

{

if (sosv==1&&n==1) { delete dau ; dau = cuoi = NULL; sosv--; return; }

if (n==1) { cur = dau; dau = cur->tiep; delete cur; sosv--; return; }

Sinhvien *truoc, *sau;

Page 170: Giao Trinh C++ Toan Tap

truoc = dau;

sau = dau -> tiep;

for (int i=1; i<n-1; i++) truoc = truoc->tiep;

cur = truoc->tiep; sau = cur->tiep; truoc->tiep = sau;

delete cur ;

sosv --;

}

T o danh sách sinh viên.ạ

void Taods() // T o danh sáchạ

{

int tiep = 1;

while (tiep) {

Bosung();

cout << "Tiep (0/1) ? " ; cin >> tiep ;

}

}

In danh sách sinh viên.

void Inds() // In danh sách

{

cur = dau; int i=1;

while (cur != NULL) {

cout << "\nSinh vien thu " << i << " ----------------------------\n") ;

cout << "Hoten:" << cur->hoten ;

cout << "Ngay sinh: "

cout << cur -> ns.day << "/" ;

cout << cur -> ns.month << "/" ;

cout << cur -> ns.year ;

cout << "Diem: " << cur->diem ;

cur = cur->tiep; i++;

}

}

Page 171: Giao Trinh C++ Toan Tap

Hàm chính.

void main()

{

clrscr();

Taods();

Inds();

getch();

}

KI U H PỂ Ợ

Khai báoGi ng nh c u trúc, ki u h p cũng có nhi u thành ph n nh ng các thành ph n c a chúng số ư ấ ể ợ ề ầ ư ầ ủ ử d ng chung nhau m t vùng nh . Do v y kích th c c a m t ki u h p là đ dài c a tr ngụ ộ ớ ậ ướ ủ ộ ể ợ ộ ủ ườ l n nh t và vi c thay đ i m t thành ph n s nh h ng đ n t t c các thành ph n còn l i. ớ ấ ệ ổ ộ ầ ẽ ả ưở ế ấ ả ầ ạ

union <tên ki u> { ể

Danh sách các thành ph n; ầ

};

Truy c p ậCú pháp truy c p đ n các thành ph n c a h p cũng t ng t nhậ ế ầ ủ ợ ươ ự ư ki u c u trúc, t c cũng sể ấ ứ ử d ng toán t l y thành ph n (d u ch m . ho c ® cho bi n con tr ki u h p). ụ ử ấ ầ ấ ấ ặ ế ỏ ể ợ

D i đây là m t ví d minh ho vi c s d ng khai báo ki u h p đ tách byte th p, byte caoướ ộ ụ ạ ệ ử ụ ể ợ ể ấ c a m t s nguyên.ủ ộ ố

:

void main()

{

union songuyen {

int n;

unsigned char c[2];

} x;

Page 172: Giao Trinh C++ Toan Tap

cout << "Nh p s nguyên: " ; cin >> x.n ;ậ ố

cout << "Byte th p c a x = " << x.c[0] << endl ;ấ ủ

cout << "Byte cao c a x = " << x.c[1] << endl;ủ

}

: K t h p cùng ki u nhóm bit trong c u trúc, chúng ta có th tìm đ c các bit c a m t s nhế ợ ể ấ ể ượ ủ ộ ố ư ch ng trình sau. Trong ch ng trình ta s d ng m t bi n u có ki u h p. Trong ki u h p nàyươ ươ ử ụ ộ ế ể ợ ể ợ có 2 thành ph n là 2 c u trúc l n l t có tên s và f.ầ ấ ầ ượ

union {

struct { unsigned a, b ; } s;

struct {

unsigned n1: 1;

unsigned: 15;

unsigned n2: 1;

unsigned: 7;

unsigned n3: 8;

} t ;

} u;

v i khai báo trên đây khi nh p u.s thì nó cũng nh h ng đ n u.t, c thớ ậ ả ưở ế ụ ể

u.t.n1 là bit đ u tiên (0) c a thành ph n u.s.aầ ủ ầ

u.t.n2 là bit 0 c a thành ph n u.s.bủ ầ

u.t.n3 là byte cao c a u.s.bủ

KI U LI T KÊỂ Ệ

Có th gán các giá tr nguyên liên ti p (tính t 0) cho các tên g i c th b ng ki u li t kê theoể ị ế ừ ọ ụ ể ằ ể ệ khai báo sau đây:

enum tên_ki u { d/s tên các giá tr };ể ị

Ví d : ụ

enum Bool {false, true};

khai báo ki u m i đ t tên Bool ch nh n 1 trong 2 giá tr đ t tên false và true, trong đó falseể ớ ặ ỉ ậ ị ặ ng v i giá tr 0 và true ng v i giá tr 1. Cách khai báo ki u enum trên cũng t ng đ ng v iứ ớ ị ứ ớ ị ể ươ ươ ớ

dãy các macro sau:

Page 173: Giao Trinh C++ Toan Tap

#define false 0

#define true 1

V i ki u Bool ta có th khai báo m t s bi n nh sau:ớ ể ể ộ ố ế ưBool Ok, found;

hai bi n Ok và found s ch nh n 1 trong 2 giá tr false (thay cho 0) ho c true (thay cho 1). Cóế ẽ ỉ ậ ị ặ nghĩa có th gán:ể

Ok = true;

ho c:ặ found = false;

Tuy nhiên không th gán các giá tr nguyên tr c ti p cho các bi n enum mà ph i thôngể ị ự ế ế ả qua ép ki u. Ví d :ể ụ

Ok = 0; // sai

Ok = Bool(0) ; // đúng

ho c Ok = false ;ặ // đúng

BÀI T PẬ

Có th truy nh p thành ph n c a c u trúc thông qua con tr nhể ậ ầ ủ ấ ỏ ư sau (v i p là con tr c u trúcớ ỏ ấ và a là thành ph n c a c u trúc):ầ ủ ấ

A: (*p).a B: *p®a C: a và b sai D: a và b đúng

Cho khai báo struct T {int x; float y;} t, *p, a[10]; Câu l nh nào trong các câu sau là không h pệ ợ l :ệ

(1) p = &t; (2) p = &t.x; (3) p = a;

(4) p = &a (5) p = &a[5]; (6) p = &a[5].y;

A: 1, 2 và 3 B: 4, 5 và 6 C: 1, 3 và 5 D: 2, 4 và 6

Cho các khai báo sau: struct ngay {int ng, th, nam;} vaotruong, ratruong;

typedef struct {char hoten[25]; ngay ngaysinh;} sinhvien;

Hãy ch n câu ọ đúng nh t ấ

Page 174: Giao Trinh C++ Toan Tap

A: Không đư c phép gán: ratruong = vaotruong;ợ

B: sinhvien là tên c u trúc, vaotruong, ratruong là bi n c u trúcấ ế ấ

C: Có th vi t: vaotruong.ng, ratruong.th, sinhvien.vaotruong.nam ể ế đ truy nh p ể ậ đ n cácế thành ph n tầ ương ng.ứ

D: a, b, c đúng

Trong các kh i t o giá tr cho các c u trúc sau, kh i t o nào ở ạ ị ấ ở ạ đúng:

struct S1 {

int ngay, thang, nam;

} s1 = {2,3};

struct S2 {

char hoten[10];

struct S1 ngaysinh;

} s2 = {"Ly Ly",1,2,3};

struct S3 {

struct S2 sinhvien;

float diem;

} s3 = {{{"C c c c", {4,5,6}}, 7}; ố ốA: S1 và S2 đúng B: S2 và S3 đúng C: S3 và S1 đúng D: C 3 cùng ả đúng

Đ i v i ki u c u trúc, cách gán nào dố ớ ể ấ ư i ớ đây là không đư c phép: ợA: Gán hai bi n cho nhau.ế

B: Gán hai ph n t m ng (ki u c u trúc) cho nhau ầ ử ả ể ấ

C: Gán m t ph n t m ng (ki u c u trúc) cho m t bi n và ngộ ầ ử ả ể ấ ộ ế ư c l iợ ạ

D: Gán hai m ng c u trúc cùng s ph n t cho nhau ả ấ ố ầ ử

Cho đo n chạ ương trình sau:

struct {

int to ;

float soluong;

} x[10];

for (int i = 0; i < 10; i++) cin >> x[i].to >> x[i].soluong ; Ch n câu ọ đúng nh t trong các câu sau: ấ

A: Đo n chạ ương trình trên có l i cú phápỗ

Page 175: Giao Trinh C++ Toan Tap

B: Không đư c phép s d ng toán t l y ợ ử ụ ử ấ đ a ch ị ỉ đ i v i các thành ph n to và soluongố ớ ầ

C: L y ấ đ a ch thành ph n soluong d n ị ỉ ầ ẫ đ n chế ương trình ho t ạ đ ng không ộ đúng đ n ắ

D: C a, b, c ả đ u saiề

Ch n câu ọ đúng nh t trong các câu sau: ấA: Các thành ph n c a ki u h p (union) ầ ủ ể ợ đư c c p phát m t vùng nh chungợ ấ ộ ớ

B: Kích thư c c a ki u h p b ng kích thớ ủ ể ợ ằ ư c c a thành ph n l n nh tớ ủ ầ ớ ấ

C: M t bi n ki u h p có th ộ ế ể ợ ể đư c t ch c ợ ổ ứ đ cho phép thay ể đ i ổ đư c ki u d li u c aợ ể ữ ệ ủ bi n trong qua trình ch y chế ạ ương trình

D: a, b, c đúng

Cho khai báo:

union {

unsigned x;

unsigned char y[2];

} z = {0xabcd}; Ch n câu ọ đúng nh t trong các câu sau: ấ

A: Khai báo trên là sai vì thi u tên ki uế ể

B: Kh i t o bi n z là sai vì ch có m t giá tr (0xabcd)ở ạ ế ỉ ộ ị

C: z.y[0] = 0xab

D: z.y[1] = 0xab

Cho ki u h p: ể ợ

union U {

char x[1];

int y[2]; float z[3];

} u; Ch n câu ọ đúng nh t trong các câu sau: ấ

A: sizeof(U) = 1+2+3 = 6

B: sizeof(U) = max(sizeof(char), sizeof(int), sizeof(float))

C: sizeof(u) = max(sizeof(u.x), sizeof(u.y), sizeof(u.z))

D: b và c đúng

Page 176: Giao Trinh C++ Toan Tap

Cho khai báo:

union {

unsigned x;

struct {

unsigned char a, b;

} y;

} z = {0xabcd}; Giá tr c a z.y.a và z.y.b tị ủ ương ng: ứ

A: 0xab, 0xcd B: 0xcd, 0xab C: 0xabcd, 0 D: 0, 0xabcd

Cho khai báo:

union {

struct {

unsigned char a, b;

} y;

unsigned x;

} z = {{1,2}}; Giá tr c a z.x b ng: ị ủ ằ

A: 513 B: 258

C: Không xác đ nh vì kh i t o saiị ở ạ D: Kh i t o ở ạ đúng nhưng z.x chưa có giá trị

Xét đo n l nh: ạ ệ

union U {

int x; char y;

} u;

u.x = 0; u.y = 200; Tìm giá tr c a u.x + u.y ? ị ủ

A: 122 B: 144 C: 200 D: 400

Cho s ph c dố ứ ư i d ng c u trúc g m 2 thành ph n là th c và o. Vi t chớ ạ ấ ồ ầ ự ả ế ương trình nh p 2ậ s ph c và in ra t ng, tích, hi u, thố ứ ổ ệ ương c a chúng. ủ

Cho phân s dố ư i d ng c u trúc g m 2 thành ph n là t và m u. Vi t chớ ạ ấ ồ ầ ử ẫ ế ương trình nh p 2ậ phân s , in ra t ng, tích, hi u, thố ổ ệ ương c a chúng dủ ư i d ng t i gi n.ớ ạ ố ả

Tính s ngày ố đã qua k t ể ừ đ u nầ ăm cho đ n ngày hi n t i. Qui ế ệ ạ ư c ngày ớ đư c khai báo dợ ư iớ d ng c u trúc và ạ ấ đ ể đơn gi n m t nả ộ ăm b t kỳ ấ đư c tính 365 ngày và tháng b t kỳ có 30ợ ấ ngày.

Page 177: Giao Trinh C++ Toan Tap

Nh p m t ngày tháng nậ ộ ăm dư i d ng c u trúc. Tính chính xác (k c nớ ạ ấ ể ả ăm nhu n) s ngày ậ ố đã qua k t ngày 1/1/1 cho ể ừ đ n ngày ế đó.

Tính kho ng cách gi a 2 ngày tháng b t kỳ.ả ữ ấ

Hi n th c a m t ngày b t kỳ nào ệ ứ ủ ộ ấ đó, bi t r ng ngày 1/1/1 là th hai.ế ằ ứ

Hi n th c a m t ngày b t kỳ nào ệ ứ ủ ộ ấ đó, l y ngày th hi n t i ấ ứ ệ ạ đ làm chu n.ể ẩ

Vi t chế ương trình nh p m t m ng sinh viên, thông tin v m i sinh viên g m h tên và ngàyậ ộ ả ề ỗ ồ ọ sinh (ki u c u trúc). S p x p m ng theo tu i và in ra màn hìnhể ấ ắ ế ả ổ

Đ bi u di n s ph c có th s d ng ể ể ễ ố ứ ể ử ụ đ nh nghĩa sau:ịtypedef struct { float re, im; } sophuc;

C n b sung thêm trầ ổ ư ng nào vào c u trúc ờ ấ đ có th l p ể ể ậ đư c m t danh sách liên k t các sợ ộ ế ố ph c.ứ

Đ t o danh sách liên k t, theo b n sinh viên nào dể ạ ế ạ ư i ớ đây khai báo đúng c u trúc t tr sấ ự ỏ ẽ đư c dùng: ợ

Sinh viên 1: struct SV {char ht[25]; int tuoi; struct SV *tiep;};

Sinh viên 2: typedef struct SV node; struct SV {char ht[25]; int tuoi; node *tiep;};

Sinh viên 3: typedef struct SV {char ht[25]; int tuoi; struct SV *tiep;} node;

A: Sinh viên 1 B: Sinh viên 2 C: Sinh viên 2 và 3 D: Sinh viên 1, 2 và 3

L p danh sách liên k t ch a b ng ch cái A, B, C … Hãy ậ ế ứ ả ữ đ o ph n ả ầ đ u t A .. M xu ng cu iầ ừ ố ố thành N, O, … Z, A, …M.

Vi t chế ương trình tìm ngư i cu i cùng trong trò chờ ố ơi: 30 ngư i x p vòng tròn. ờ ế Đ m vòng trònế (b t ắ đ u t ngầ ừ ư i s 1) c ờ ố ứ đ n ngế ư i th 7 thì ngờ ứ ư i này b lo i ra kh i vòng. H iờ ị ạ ỏ ỏ ngư i còn l i cu i cùng ?ờ ạ ố

Gi s có danh sách liên k t mà m i n t c a nó lả ử ế ỗ ố ủ ưu m t giá tr nguyên. Vi t chộ ị ế ương trình s pắ x p danh sách theo th t gi m d n.ế ứ ự ả ầ

Gi s có danh sách liên k t mà m i n t c a nó lả ử ế ỗ ố ủ ưu m t giá tr nguyên ộ ị đư c s p gi m d n.ợ ắ ả ầ Vi t chế ương trình cho phép chèn thêm m t ph n t vào danh sách sao cho danh sách v nộ ầ ử ẫ đư c s p gi m d n. ợ ắ ả ầ

T o danh sách liên k t các s th c xạ ế ố ự 1, x2, ..., xn. G i m là trung bình c ng:ọ ộ

n

x...xxm n+++

= 21

. Hãy in l n lầ ư t ra màn hình các giá tr : m, xợ ị 1 - m, x2 - m, ..., xn - m.

S d ng ki u union ử ụ ể đ in ra byte th p, byte cao c a m t s nguyên.ể ấ ủ ộ ố

Page 178: Giao Trinh C++ Toan Tap

CH NG 6 ƯƠ

Đ HO VÀ ÂM THANHỒ Ạ

Đ hoồ ạÂm thanh

Đ HOỒ Ạ

Khái ni m ệ đ hoồ ạ

Đi m nh và ể ả đ phân gi iộ ảMàn hình ch ở ế đ ộ đ ho là t p h p các ồ ạ ậ ợ đi m (pixel-picture elements) nh. S ể ả ố đi m nh vàể ả cách b trí theo chi u ngang, d c c a màn hình ố ề ọ ủ đư c g i là ợ ọ đ phân gi i (resolution). Vì v yộ ả ậ đ phân gi i thộ ả ư ng ờ đư c ợ đ c trặ ưng b i m t c p s ch ở ộ ặ ố ỉ đ nh s ị ố đi m nh theo chi u ngangể ả ề và chi u d c c a màn hình. Ví d màn hình VGA mode 2 có ề ọ ủ ụ ở đ phân gi i là 640x480, t cộ ả ứ trên m i dòng ngang c a màn hình có th v ỗ ủ ể ẽ đư c 640 ợ đi m nh và trên m i c t d c v ể ả ỗ ộ ọ ẽ đư cợ 480 đi m nh. Các c t và dòng ể ả ộ đư c ợ đánh s t 0, theo chi u t trái sang ph i (ố ừ ề ừ ả đ i v i c t)ố ớ ộ và t trên xu ng dừ ố ư i (ớ đ i v i dòng). M t ố ớ ộ đi m nh hay còn g i là pixel là giao ể ả ọ đi m c aể ủ m t c t và m t dòng nào ộ ộ ộ đó trên màn hình và v trí c a nó ị ủ đư c th hi n b i c p to ợ ể ệ ở ặ ạ đ (x,y)ộ v i x bi u di n cho c t và y bi u di n cho dòng. Ví d v i màn hình trên ớ ể ễ ộ ể ễ ụ ớ đi m nh “ể ả đ u tiên”ầ n m góc trên bên trái c a màn hình có to ằ ở ủ ạ đ (0,0) và ộ đi m “cu i cùng” góc dể ố ở ư i bênớ ph i có to ả ạ đ (639,479). ộ Đi m có to ể ạ đ (150,200) là giao ộ đi m c a c t th 150 và dòngể ủ ộ ứ 200.

Trình đi u khi n ề ể đ hoồ ạMàn hình đ ho có nhi u lo i khác nhau. M i lo i màn hình c n có trình ồ ạ ề ạ ỗ ạ ầ đi u khi n tề ể ương

ng. C cung c p các trình ứ ấ đi u khi n màn hình trong thề ể ư m c BGI ụ đ t dặ ư i thớ ư m c g c c aụ ố ủ C (TC ho c BC) g m có:ặ ồ

Tên trình đi u khi nề ể Ki u màn hình ể đ hoồ ạ

ATT.BGI ATT & T6300 (400 dòng)

CGA.BGI IBMCGA, MCGA và các máy tương thích

EGAVGA.BGI IBM EGA, VGA và các máy tương thích

HERC.BGI Hercules mono và các máy tương thích

IBM8514.BGI IBM 8514 và các máy tương thích

PC3270.BGI IBM 3270 PCNgoài các trình đi u khi n trong thề ể ư m c BGI còn ch a các file font ch có ụ ứ ữ đuôi CHR g m:ồ

Page 179: Giao Trinh C++ Toan Tap

GOTH.CHR

LITT.CHR

SANS.CHR

TRIP.CHR

M t (mode) ố đ hoồ ạM i màn hình ỗ đ ho có th ho t ồ ạ ể ạ đ ng dộ ư i nhi u m t khác nhau. Đ phân gi i c a mànớ ề ố ộ ả ủ hình ph thu c vào t ng m t. Ví d màn hình VGA có th ho t ụ ộ ừ ố ụ ể ạ đ ng dộ ư i các m t 0ớ ố (VGALO: đ phân gi i th p 640x200), 1 (VGAMED: ộ ả ấ đ phân gi i trung bình 640x350), 2ộ ả (VGAHI: đ phân gi i cao 640x480).ộ ả

Vào/ra ch ế đ ộ đ ho ồ ạ

Trong C++ các hàm liên quan đ n ế đ ho ồ ạ đư c khai báo trong t p <graphics.h>ợ ệ

Kh i ở đ ng ch ộ ế đ ộ đ hoồ ạvoid initgraph(int *graphdriver, int *graphmode, char *drivepath)

drivepath: đư ng d n c a thờ ẫ ủ ư m c ch a các trình ụ ứ đi u khi n ề ể đ ho . N u r ng s tìmồ ạ ế ỗ ẽ trong thư m c hi n t i.ụ ệ ạ

graphdriver, graphmode: Ch ỉ đ nh trình qu n lý và m t màn hình c n s d ng. Trong ị ả ố ầ ử ụ đó graphdriver có th nh n 1 trong các giá tr sau:ể ậ ị

DETECT 0

CGA 1

EGA 3

EGA64 4

EGAMONO 5

VGA 9

..................... ..

Hi n nhiên vi c ch n giá tr c a graphdriver ph i tể ệ ọ ị ủ ả ương ng v i màn hình th c t . Trongứ ớ ự ế trư ng h p ta không bi t ch ng lo i th c t c a màn hình có th s d ng giá tr DETECTờ ợ ế ủ ạ ự ế ủ ể ử ụ ị (ho c 0) là giá tr ch ặ ị ỉ đ nh cho chị ương trình t tìm hi u v màn hình và g i trình ự ể ề ọ đi u khi nề ể tương ng. Trong trứ ư ng h p này graphmode s ờ ợ ẽ đư c gán giá tr t ợ ị ự đ ng v i mode có ộ ớ độ phân gi i cao nh t có th . V graphmode có th nh n các giá tr sau:ả ấ ể ề ể ậ ị

Page 180: Giao Trinh C++ Toan Tap

CGAC0 0 320 x 200

CGAC1 1 320 x 200

CGAC2 2 320 x 200

CGAC3 3 320 x 200

CGAHI 4 640 x 200 2 color

EGALO 0 640 x 200 16 color

EGAHI 1 640 x 350 16 color

EGA64LO 0 640 x 200 16 color

EGA64HI 1 640 x 350 4 color

VGALO 0 640 x 200 16 color

VGAMED 0 640 x 350 16 color

VGAHI 0 640 x 480 16 color

Trong quá trình s d ng ử ụ đ xoá màn hình ể đ ho ta dùng hàm ồ ạ cleardevice();

K t thúc ch ế ế đ ộ đ hoồ ạĐ k t thúc ch ể ế ế đ ộ đ ho v l i ch ồ ạ ề ạ ế đ vộ ăn b n ta s d ng hàm ả ử ụ closegraph();

L i ỗ đ hoồ ạ- Sau m i thao tác ỗ đ ho , hàm ồ ạ graphresult() s cho giá tr 0 n u không có l i, ho c các giáẽ ị ế ỗ ặ tr âm (-1 .. -18) tị ương ng v i l i. Hàm ứ ớ ỗ grapherrormsg(n) tr l i n i dung l i và mã l i. ả ạ ộ ỗ ỗ

Mã l iỗ H ng l i (graphresult())ằ ỗ N i dung l i (grapherrormsg())ộ ỗ

0 grOk No error

-1 grNoInitGraph (BGI) Không có BGI

-2 grNotDetected Graphics hardware not detected

-3 grFileNotFound Device driver file not found

........................................................................................................

:Ví d sau ụ đây kh i t o ch ở ạ ế đ ộ đ ho v i graphdriver = 0 (DETECT) và thông báo l i n uồ ạ ớ ỗ ế không thành công ho c thông báo ch ặ ế đ ộ đ ho cũng nhồ ạ ư mode màn hình. Đ bi t đ phânể ế ộ gi i c a màn hình có th dùng các hàm ả ủ ể getmaxx() (s c t) và ố ộ getmaxy() (s dòng)ố

void main()

Page 181: Giao Trinh C++ Toan Tap

{

int gd = DETECT, gm, maloi;

initgraph(&gd, &gm, "C:\\BC\\BGI");

maloi = graphresult();

if (maloi != grOk)

{

cout << "L i: " << grapherrormsg(maloi)) << endl;ỗ

cout << "An phím b t kỳ ấ đ d ng "; getch();ể ừ

exit(1);

} else {

cout << "Ch ế đ màn hình = " << gd << endl;ộ

cout << "Mode màn hình = " << gm << endl;

cout << "Đ phân gi i: " << getmaxx() << "," << getmaxy() << endl;ộ ả

getch();

}

closegraph();

}

Các ph n ti p theo sau đây s cung c p các câu l nh đ v trong ch đ đ h a.ầ ế ẽ ấ ệ ể ẽ ế ộ ồ ọ

V ẽ đi m, ể đư ng, kh i, màu s c ờ ố ắ

Màu s cắ

getmaxcolor(): Tr l i s hi u (h ng) t ng ng v i màu t i ả ạ ố ệ ằ ươ ứ ớ ố đa c a màn hình hi n t i.ủ ệ ạ Do các h ng màu đ c tính t 0 nên s màu s b ng h ng tr l i c ng thêm 1.ằ ượ ừ ố ẽ ằ ằ ả ạ ộ

setbkcolor(màu): Đ t màu n n. Có tác d ng v i vặ ề ụ ớ ăn b n và các nét v .ả ẽ

setcolor(màu): Đ t màu v . Có tác d ng v i vặ ẽ ụ ớ ăn b n và các nét v .ả ẽ

getbkcolor(): Tr l i màu n n hi n t i.ả ạ ề ệ ạ

getcolor(): Tr l i màu v hi n t i (t 0 ả ạ ẽ ệ ạ ừ đ n getmaxcolor()).ếVí d : In to ụ ạ đ t i v trí hi n t i c a con tr màn hình. Trong ví d này chúng ta s d ng câuộ ạ ị ệ ạ ủ ỏ ụ ử ụ l nh sprintf(xâu s, "dòng đk", các bi u th c c n in), câu l nh này s thay vi c in các bi u th cệ ể ứ ầ ệ ẽ ệ ể ứ ra màn hình thành in ra xâu s (t c t o xâu s t các bi u th c). Ngoài ra hàm outtextxy(x, y, s)ứ ạ ừ ể ứ s in xâu s t i v trí (x,y). ẽ ạ ị

void intoado(dx, dy, color)

{

Page 182: Giao Trinh C++ Toan Tap

int oldcolor;

oldcolor = getcolor();

setcolor(color);

char td[10];

sprintf(td, "(%d, %d)", getx(), gety());

outtextxy(getx()+dx, gety()+dy, td);

setcolor(oldcolor);

}

V đi mẽ ể

putpixel(x, y, c): V đi m (x, y) v i màu c.ẽ ể ớ

getpixel (x, y): Tr l i màu t i ả ạ ạ đi m (x, y).ể

: V b u tr i saoẽ ầ ờ

void sky()

{

int maxx, maxy, maxc;

int i, xarr[3001], yarr[3001];

maxx = getmaxx();

maxy = getmaxy();

maxc = getmaxcolor();

randomize();

for (i=1;i<3001;i++) {xarr[i]=random(maxx);yarr[i]=random(maxy);}

while (!kbhit()) {

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

{

putpixel(xarr[i], yarr[i], random(maxc));delay(1);

}

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

if (getpitxel(xarr[i], yarr[i]) == random(maxc))

putpitxel(xarr[i], yarr[i], 0);

}

}

V đẽ ư ng th ng và g p khúcờ ẳ ấ

Page 183: Giao Trinh C++ Toan Tap

line(x1, y1, x2, y2): V đ ng th ng t (x1, y1) ẽ ườ ẳ ừ đ n (x2, y2). Con tr màn hình v nế ỏ ẫ đ ng t i v trí cũ.ứ ạ ị

lineto(x, y): V đ ng th ng t v trí hi n t i c a con tr ẽ ườ ẳ ừ ị ệ ạ ủ ỏ đ n v trí (x, y). con trế ị ỏ chuy n v (x, y).ể ề

linerel(dx, dy): G i (x, y) là v trí hi n t i c a con tr , l nh này s v đ ng th ng n iọ ị ệ ạ ủ ỏ ệ ẽ ẽ ườ ẳ ố (x, y) v i đi m m i có t a đ (x+dx, y+dy). T c l nh này cũng t ng đ ng v iớ ể ớ ọ ộ ứ ệ ươ ươ ớ l nh lineto(getx()+dx, gety()+dy), trong đó getx() và gety() là hai hàm tr l i v trí x, yệ ả ạ ị hi n t i c a con tr . L nh linerel sau khi th c hi n xong s đ t con tr t i v trí cu iệ ạ ủ ỏ ệ ự ệ ẽ ặ ỏ ạ ị ố c a đ ng th ng v a v .ủ ườ ẳ ừ ẽ

: V hình bao thẽ ư b ng 1 nét.ằ

void baothu()

{

setbkcolor(1);

setcolor(YELLOW);

moveto(100, 100);

lineto(300, 100); lineto(300, 200); lineto(100, 200); lineto(100, 100);

lineto(200, 50); lineto(300, 100);

}

rectangle(x1, y1, x2, y2): V hình khung ch nh t v i góc trên bên trái có t a đ (x1,ẽ ữ ậ ớ ọ ộ y1) và góc d i bên ph i có t a đ (x2, y2).ướ ả ọ ộ

bar(x1, y1, x2, y2): V hình ch nh t ẽ ữ ậ đ c. Màu khung đ c đ t b i ặ ượ ặ ở setcolor và màu n n l n m u tô n n đ c đ t b i l nh ề ẫ ẫ ề ượ ặ ở ệ setlinestyle. M u n n ng m đ nh là ẫ ề ầ ị đ c vàặ màu là getmaxcolor.

bar3d(x1, y1, x2, y2, c, top): V hình tr ch nh t v i đáy là (x1, y1, x2, y2) và ẽ ụ ữ ậ ớ đ caoộ c, n u top = 1 hình s có n p và n u top = 0 hình không có n p.ế ẽ ắ ế ắ

Ví d : V các hình kh i ch nh t v i m u n n và m u tô khác nhau.ụ ẽ ố ữ ậ ớ ầ ề ẫ

void main()

{

int gdriver = DETECT, gmode;

initgraph(&gdriver, &gmode, "c:\\borlandc\\bgi");

int midx = getmaxx() / 2;

int midy = getmaxy() / 2;

for (int i=SOLID_FILL; i<USER_FILL; i++)

{

setfillstyle(i, i);

bar3d(midx-50, midy-50, midx+50, midy+50, 100, 0);

Page 184: Giao Trinh C++ Toan Tap

getch();

}

closegraph();

}

Ghi chú: đ xoá ể đi m ho c ể ặ đư ng ta v l i ờ ẽ ạ đi m ho c ể ặ đư ng ờ đó b ng màu n n hi n t i. ằ ề ệ ạ Để bi t màu n n hi n t i ta s d ng hàm getbkcolor().ế ề ệ ạ ử ụ

Các thu c tính v ộ ề đư ng (ki u ờ ể đư ng, ờ đ r ng)ộ ộ

setlinestyle(style, pattern, width): đ t các thu c tính v ặ ộ ề đư ng v , trong đó style là ki uờ ẽ ể đ ng, pattern là m u tô và width là đ đ m c a đ ng v . Các thu c tính này đ cườ ẫ ộ ậ ủ ườ ẽ ộ ượ gi i thích bên d i.ả ướ

getlinesettings(struct linesettingstype *info): L y các thu c tính v ấ ộ ề đư ng v hi n t iờ ẽ ệ ạ cho vào bi n đ c tr b i info. ế ượ ỏ ở

Ki u c a bi n ch a các thu c tính đ ng v :ể ủ ế ứ ộ ườ ẽ

struct linesettingstype {

int linetsyle;

int upattern;

int thickness;

}

Các h ng s qui đ nh các ki u đ ng (style):ằ ố ị ể ườstyle: SOLID_LINE = 0

DOTTED_LINE = 1

CENTER_LINE = 2

DASHED_LINE = 3

USERBIT_LINE = 4, // Ki u đ ng do NSD đ nh nghĩa ể ườ ị

pattern: Do NSD đ nh nghĩa theo 2 byte cho m t ị ộ đư ng. Ch có tác d ng khi style = 4.ờ ỉ ụ

Các h ng s qui đ nh đ đ m (đ dày) c a đ ng (width):ằ ố ị ộ ậ ộ ủ ườNORM_WIDTH = 1

THICK_WIDTH = 3

:

void netve()

Page 185: Giao Trinh C++ Toan Tap

{

char *lname[] = {"Duong lien net", "Duong cham cham",

"Duong trung tam", "Duong dut net", "Duong do NSD dinh nghia" };

int style, midx, midy, mauNSD;

midx = getmaxx() / 2; midy = getmaxy() / 2;

// M u đ ng đ c đ nh nghĩa b i NSD "0000000000000001" ẫ ườ ượ ị ở

mauNSD = 1;

for (style=SOLID_LINE; style<=USERBIT_LINE; style++) {

setlinestyle(style, mauNSD, 1);

line(0, 0, midx-10, midy);

rectangle(0, 0, getmaxx(), getmaxy());

outtextxy(midx, midy, lname[style]);

line(midx, midy+10, midx+8*strlen(lname[style]), midy+10);

getch();

cleardevice();

}

}

Các thu c tính v hình (m u tô, màu tô)ộ ề ẫ

setfillstyle(m u tô, màu tô): ẫ Đ t m u tô, màu tôặ ẫ

setfillpattern(m u tô, màu tô): ẫ Đ nh nghĩa m u tô.ị ẫ

getfillsettings(struct fillsettingstype *info): L y m u tô hi n t iấ ẫ ệ ạstruct fillsettingstype {

int pattern;

int color;

};

getfillpattern(m u tô)ẫ : Tr l i m u tô hi n do NSD ả ạ ẫ ệ đ nh nghĩa. Là m t con tr tr ị ộ ỏ ỏ đ nế m ng 8 kí t . ả ự Sau đây là m t s m u tô và các h ng t ng ng ộ ố ẫ ằ ươ ứ

EMPTY_FILL 0

SOLID_FILL 1

LINE_FILL 2

LTSLASH_FILL 3

Page 186: Giao Trinh C++ Toan Tap

SLASH_FILL 4

BKSLASH_FILL 5

LTBKSLASH_FILL 6

HATCH_FILL 7

XHATCH_FILL 8

INTERLEAVE_FILL 9

WIDE_DOT_FILL 10

CLOSE_DOT_FILL 11

USER_FILL 12

: Đ t m u tô.ặ ẫ

char caro[8] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};

maxx = getmaxx();

maxy = getmaxy();

setfillpattern(caro, getmaxcolor());

// Tô màn hình theo m uẫ

bar(0, 0, maxx, maxy);

getch();

V đa giác ẽ

drawpoly(s ố đ nh, v trí ỉ ị đ nh)ỉ : V ẽ đư ng ờ đa giác theo setlinestyle;

fillpoly(s ố đ nh, v trí ỉ ị đ nh)ỉ : V hình ẽ đa giác đ c theo setfillstyle;ặV trí ị đ nh là con tr tr ỉ ỏ ỏ đ n dãy các to ế ạ đ , thông thộ ư ng dùng m ng.ờ ả

Đ v ể ẽ đa giác đóng ph i ả đưa ra n+1 to ạ đ trong ộ đó to ạ đ n = to ộ ạ đ 0.ộ

:

int poly[10];

poly[0] = 20; poly[1] = maxy / 2; // đ nh th nh tỉ ứ ấ

poly[2] = maxx - 20; poly[3] = 20; // đ nh th haiỉ ứ

poly[4] = maxx - 50; poly[5] = maxy - 20; // đ nh th baỉ ứ

poly[6] = maxx / 2; poly[7] = maxy / 2; // đ nh th tỉ ứ ư

poly[8] = poly[0]; poly[9] = poly[1];

Page 187: Giao Trinh C++ Toan Tap

// v đa giácẽ

drawpoly(5, poly);

V đẽ ư ng congờ

arc(x, y, góc đ u, góc cu i, bán kính):ầ ố V cung tròn có tâm (x, y) v i các góc và bánẽ ớ kính t ng ng.ươ ứ

circle(x, y, bán kính): V ẽ đư ng tròn có tâm t i (x, y).ờ ạ

pieslice(x, y, góc đ u, góc cu i, bán kính):ầ ố V hình qu t tròn ẽ ạ đ c v i m u hi n t i;ặ ớ ẫ ệ ạ

ellipse(x, y, góc đ u, góc cu i, bkx, bky):ầ ố V cung elip v i tâm, các góc và các bán kínhẽ ớ theo hoàng đ và tung đ t ng ng. ộ ộ ươ ứ

fillellipse(x, y, bkx, bky): V hình elip đ c.ẽ ặ

sector(x, y, góc đ u, góc cu i, bkx, bky): V hình qu t elip.ầ ố ẽ ạChú ý: N u góc ế đ u = 0 và góc cu i = 360 cung, l nh trên s v ầ ố ệ ẽ ẽ đư ng tròn ho c elip.ờ ặ

: V ẽ đư ng tròn và elip.ờarc(200, 200, 45, 135, 100) ; // cung tròn

arc(200, 200, 0, 360, 100) ; // đư ng trònờ

circle(200, 200, 100) ; // đư ng trònờ

ellipse(200, 200, 45, 135, 100, 80) ; // cung elip

ellipse(200, 200, 0, 360, 100, 80) ; // đư ng elip;ờ

setfillstyle(EMPTY_FILL, getmaxcolor());

pieslice(200, 200, 45, 135, 100) ; // đư ng qu t trònờ ạ

fillellipse(200, 200, 0, 360, 100, 80) ; // đư ng elipờ

setfillstyle(SOLID_FILL, getmaxcolor());

pieslice(200, 200, 45, 135, 100); // hình qu t tròn;ạ

circle(200, 200, 100); // hình tròn;

fillellipse(200, 200, 0, 360, 100, 80); // hình elip;

sector(200, 200, 45, 135, 100, 80); // hình qu t elipạ

Tô m u ầ

floodfill(x, y, c): Tô màu m t hình kín ch a ộ ứ đi m x, y và màu vi n c. M u dùng đ tôể ề ầ ể đ c đ t b i hàm setfillstyle(ki u tô, màu tô). Ví d : ượ ặ ở ể ụ

Page 188: Giao Trinh C++ Toan Tap

void fill()

{

rectangle(100, 100, 180, 140); // V hình ch nh tẽ ữ ậ

setfillstyle(1, BLUE); // M u tô đ c, màu xanhẫ ặ

floodfill(120, 120, 15); // Tô hình ch nh t đã vữ ậ ẽ

int tg[8] = {150, 120, 180, 280, 350, 180, 150, 120};

drawpoly(4, tg);

setfillstyle(2, RED);

floodfill(180, 200, 15);

circle(380, 210, 100);

setfillstyle(3, GREEN);

floodfill(380, 210, 15);

}

void fill2() // V và tô màu dãy ẽ đư ng tròn liênờ ti pế

{

int i, x = 0, y = 0, r = 0;

for (i=1;i<10;i++) {

r = 10*i;

y = x += r;

circle(x, y, r);

setfillstyle(i, i);

floodfill(x, y, 15);

}

}

Vi t văn b n trong màn hình đ h aế ả ồ ọ

Vi t văn b nế ảouttext(s) ;

outtextxy(x, y, s) ;

Câu l nh trên cho phép vi t xâu kí t t i v trí con tr trên màn hình đ h a. Câu l nh ti pệ ế ự ạ ị ỏ ồ ọ ệ ế theo cho phép vi t s ra t i v trí (x, y). V trí con tr sau khi th c hi n outtext(s) s đ t t i v tríế ạ ị ị ỏ ự ệ ẽ ặ ạ ị cu i c a xâu đ c in trong khi v trí con tr sau khi th c hi n l nh outtextxy(x, y, s) là khôngố ủ ượ ị ỏ ự ệ ệ

Page 189: Giao Trinh C++ Toan Tap

thay đ i. Ví d sau in ra màn hình đ h a dòng ch "Đây là ch ng trình minh h a l nhổ ụ ồ ọ ữ ươ ọ ệ outtext(s)" t i v trí (100, 20): ạ ị

moveto(100, 20) ; // chuyen con tro den cot 100, dong 20

outtext("Đây là ch ng trình minh h a l nh outtext(s)") ; ho c ươ ọ ệ ặ

outtext("Đây là ch ng trình ") ;ươ

outtext("minh h a l nh ") ;ọ ệ

outtext("outtext(s)") ;ho c dòng văn b n trên cũng có th đ c in b i l nh outtextxy(x, y, s); ặ ả ể ượ ở ệ

outtextxy(100, 20, "Đây là ch ng trình minh h a l nh outtextxy(x, y, s)"); ươ ọ ệ

Đi u ch nh font, h ng và c chề ỉ ướ ỡ ữsettextstyle(Font, H ng, C ch );ướ ỡ ữ

Font : G m các lo i font t ng ng v i các h ng sau đây:ồ ạ ươ ứ ớ ằ

DEFAULT_FONT 0

SMALL_FONT 1

TRIPLEX_FONT 2

SANS_SERIF_FONT 3

GOTHIC_FONT 4

H ng : h ng vi t theo ki u n m ngang hay th ng đ ng, t ng ng v i các h ng:ướ ướ ế ể ằ ẳ ứ ươ ứ ớ ằHOIRIZ_DIR 0

VERT_DIR 1

C ch : G m các c ch đánh s tăng d n t 1. C ch ng m đ nh là 1. ỡ ữ ồ ỡ ữ ố ầ ừ ỡ ữ ầ ịVí d sau l n l t in t i tâm màn hình tên c a các font v i các c ch l n d n, theoụ ầ ượ ạ ủ ớ ỡ ữ ớ ầ

h ng n m ngang.ướ ằ#include <graphics.h>

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

void main()

{

char *fname[] = {"ng m đ nh", "Triplex", "Small", "Sans Serif", "Gothic" };ầ ị

int gdriver = DETECT, gmode;

Page 190: Giao Trinh C++ Toan Tap

int font, midx, midy;

int size = 1;

initgraph(&gdriver, &gmode, "C:\\Borlandc\\BGI");

midx = getmaxx() / 2; midy = getmaxy() / 2;

for (font = DEFAULT_FONT; font <= GOTHIC_FONT; font++)

{

cleardevice();

size = font;

settextstyle(font, HORIZ_DIR, size);

outtextxy(midx, midy, fname[font]);

getch();

}

closegraph();

}

Đi u ch nh cách vi tề ỉ ếTheo m i h ng (n m ngang hay th ng đ ng) có 3 cách vi t t ng ng v i các h ng s sau:ỗ ướ ằ ẳ ứ ế ươ ứ ớ ằ ố

Theo h ng n m ngang:ướ ằLEFT_TEXT = 0 : Vi t t trái sang ph i. ế ừ ả

CENTER_TEXT = 1 : Vi t t v trí con tr sang hai bên.ế ừ ị ỏ

RIGHT_TEXE = 2 : Vi t t ph i sang trái.ế ừ ả

Theo h ng th ng đ ng:ướ ẳ ứBOTTOM_TEXT = 0 : Vi t t d i lên.ế ừ ướ

CENTER_TEXT = 1 : Vi t t v trí con tr lên trên và xu ng d i.ế ừ ị ỏ ố ướ

TOP_TEXT = 2. Vi t t trên xu ng.ế ừ ố

Đ ch đ nh m t trong các cách vi t trên ta dùng l nhể ỉ ị ộ ế ệ

settextjustify(Theo h ng ngang, Theo h ng d c);ướ ướ ọ

Page 191: Giao Trinh C++ Toan Tap

Chuy n ể đ ng ộ

Nguyên t c: xóa hình v trí cũ r i v l i hình đó t i v trí m i theo h ng chuy n đ ng. Đắ ở ị ồ ẽ ạ ạ ị ớ ướ ể ộ ể xoá, ta v l i hình ngay t i v trí cũ nh ng v i m u v trùng v i màu n n (do đó hình v bẽ ạ ạ ị ư ớ ầ ẽ ớ ề ẽ ị chìm vào n n gi ng nh đã b xóa). Đ bi t màu n n hi n t i có th dùng hàmề ố ư ị ể ế ề ệ ạ ể setcolor(getbkcolor()). Tóm l i có th đ a ra s đ nh sau:ạ ể ư ơ ồ ư

- v l i hình v i màu n n t i v trí cũ ẽ ạ ớ ề ạ ị // xóa hình

- delay // t m d ngạ ừ

- v l i hình (v i màu c a hình) t i v trí m i // hình chuy n đ n v trí khácẽ ạ ớ ủ ạ ị ớ ể ế ị

Các b c trên n u đ c l p đi l p l i ta s th y hình chuy n đ ng t v trí này đ n v tríướ ế ượ ặ ặ ạ ẽ ấ ể ộ ừ ị ế ị khác.

Đ i v i các hình v ph c t p, đ xóa nhanh ta có th v l i hình trong ch ố ớ ẽ ứ ạ ể ể ẽ ạ ế đ XOR_PUT nhộ ư đ c trình bày trong ph n sau.ượ ầ

Chúng ta hãy xem qua m t s hàm ph c t p h n đ v hình.ộ ố ứ ạ ơ ể ẽ

setviewport(x1, y1, x2, y2, clip): T o m t c a s m i trong ch ạ ộ ử ổ ớ ế đ ộ đ ho . Khi đó t aồ ạ ọ đ c a các đi m s đ c tính l i theo c a s m i này. C th đi m (x1, y1) c aộ ủ ể ẽ ượ ạ ử ổ ớ ụ ể ể ủ màn hình bây gi s l i đ c tính v i t a đ m i là (0,0). N u clip = 0 s cho phépờ ẽ ạ ượ ớ ọ ộ ớ ế ẽ các hình v đ c m r ng kh i khung c a s , n u clip = 1 các ph n c a hình vẽ ượ ở ộ ỏ ử ổ ế ầ ủ ẽ n m ngoài khung c a s s b c t.ằ ử ổ ẽ ị ắ

getviewsettings(struct viewporttype *vp): L y to ấ ạ đ c a s hi n t i vào bi n con trộ ử ổ ệ ạ ế ỏ vp. Ki u c a cu s là m t c u trúc nh sau:ể ủ ẳ ổ ộ ấ ư

struct viewporttype {int left, top, right, bottom, clip;};

imagesize(x1, y1, x2, y2): Cho l i kích thạ ư c (byte) c a m t nh bitmap trong khungớ ủ ộ ả ch nh t đ c xác đ nh b i các t a đ (x1, y1, x2, y2).ữ ậ ượ ị ở ọ ộ

getimage(x1, y1, x2, y2, *pict): Lưu nh t màn hình vào vùng b nh ả ừ ộ ớ đư c tr b i conợ ỏ ở tr pict. ỏ

putimage(x1, y1, *pict, op): Ghi ra màn hình nh ả đã đư c lợ ưu t i v trí con tr pict. op làạ ị ỏ ch đ qui ế ộ đ nh vi c hi n nh lên màn hình, màu c a các ị ệ ệ ả ủ đi m s ể ẽ đư c qui ợ đ nhị thông qua màu c a nh ủ ả đư c lợ ưu trong pict và màu hi n t i c a ệ ạ ủ đi m trên màn hình.ể Hai màu này s "tr n" theo các phép toán qui đ nh b i op d i đây đ cho ra màu vẽ ộ ị ở ướ ể ẽ c a nh:ủ ả

COPY_PUT = 0 Săn c u thầ ủ

XOR_PUT = 1 Ho c lo i tr (gi ng nhau thì b ng 0). Đ xóa nh ta có thặ ạ ừ ố ằ ể ả ể v l i chúng v i ch đ này.ẽ ạ ớ ế ộ

OR_PUT = 2 Ho cặ

Page 192: Giao Trinh C++ Toan Tap

AND_PUT = 3 Và

NOT_PUT = 4 Not

Ví d 8 ụ : V bánh xe xoayẽ

void bx(int x, int y, int r, float phi, int xoa) // xoá nh n u xoa = 1 ả ế

{

int i, x1, x2, y1, y2;

if (xoa) setcolor(BLACK); // đ t màu v b ng màu n nặ ẽ ằ ề

circle(x, y, r); // v vành bánh xeẽ

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

x1 = x+int(r*cos(phi)); y1 = y-int(r*sin(phi));

x2 = x-int(r*cos(phi)); y2 = y+int(r*sin(phi));

line(x1, y1, x2, y2); // v các nan hoaẽ

phi = phi + pi/3; // l ch nhau 60ệ 0

}

setcolor(WHITE);

}

void xoay()

{

int i, x, y, r;

static float phi = 0;

x = midx; y = midy; r = 100;

while (!kbhit()) {

bx(x, y, r, phi, 0); // v bánh xe ẽ

delay(100); // t m d ngạ ừ

bx(x, y, r, phi, 1); // xóa bánh xe

phi = phi-pi/72; // xoay đi m t góc phiộ

}

}

: V bánh xe lăn trên đ ng n m ngangẽ ườ ằ

Page 193: Giao Trinh C++ Toan Tap

void lan()

{

int i, x, y, r;

float phi=0;

x = 0; y = maxy-110; r = 60;

setlinestyle(SOLID_LINE, 1, 3);

line(0, maxy-50, maxx, maxy-50);

setlinestyle(SOLID_LINE, 1, 1);

while (x-r<=maxx) {

bx(x, y, r, phi, 0);

delay(20); bx(x, y, r, phi, 1); x += 1; phi = phi-pi/72;

}

}

V đ th c a các hàm toán h cẽ ồ ị ủ ọ

Đ v đ th c a m t hàm toán h c, ta v t ng đi m m t c a đ th . M i đi m đ c xácể ẽ ồ ị ủ ộ ọ ẽ ừ ể ộ ủ ồ ị ỗ ể ượ đ nh b i c p t a đ (x, y) trên màn hình. Do v y c n tính các đi m này theo t a đ trên mànị ở ặ ọ ộ ậ ầ ể ọ ộ hình. Các b c c n làm g m có:ướ ầ ồ

Xác đ nh h tr c t a đ . Thông th ng ta s l y tâm màn hình làm tâm h tr c b ngị ệ ụ ọ ộ ườ ẽ ấ ệ ụ ằ vi c xác đ nh l i c a s màn hình b i câu l nh:ệ ị ạ ử ổ ở ệ

viewport(midx, midy, maxx, maxy, 0);

trong đó midx, midy là t a đ tâm màn hình, maxx, maxy là t a đ góc d i bên ph i c a mànọ ộ ọ ộ ướ ả ủ hình. Câu l nh trên t o m t c a s là ph n t bên ph i, phía d i c a màn hình. Tham trệ ạ ộ ử ổ ầ ư ả ướ ủ ị cu i (1) cho phép các hình v s đ c v ra ngoài khung c a s này. Nh v y tâm màn hìnhố ẽ ẽ ượ ẽ ử ổ ư ậ s bi n thành tâm c a h tr c t a đ . T a đ c a tâm màn hình bây gi đ c tính là (0,0). ẽ ế ủ ệ ụ ọ ộ ọ ộ ủ ờ ượ

Xác đ nh t l : C n xác đ nh m t đ n v c a x và y c a hàm c n v s t ng ng v iị ỉ ệ ầ ị ộ ơ ị ủ ủ ầ ẽ ẽ ươ ứ ớ bao nhiêu đi m trên tr c x và y c a màn hình. Do s đi m theo chi u r ng và chi uể ụ ủ ố ể ề ộ ề cao c a màn hình khác nhau và do giá tr c a hàm (y) có th r t l n so v i giá tr c aủ ị ủ ể ấ ớ ớ ị ủ đ i (x) (ví d hàm y = xố ụ 4) ho c r t bé (ví d hàm y = sinx) nên các t l này theo x vàặ ấ ụ ỉ ệ y có th khác nhau đ hình v trên màn hình đ c cân đ i. Vi c xác đ nh các t lể ể ẽ ượ ố ệ ị ỉ ệ này ph thu c vào kinh nghi m và th ng đ c đi u ch nh sau khi ch y th ch ngụ ộ ệ ườ ượ ề ỉ ạ ử ươ trình.

V h tr c : Có th v h tr c t a đ hay không. Hàm sau cho phép v các tr c t a đẽ ệ ụ ể ẽ ệ ụ ọ ộ ẽ ụ ọ ộ v i tâm n m gi a màn hình.ớ ằ ữ

void vetruc() // Ve truc toa do

{

Page 194: Giao Trinh C++ Toan Tap

line(0, midy, maxx, midy); // truc hoanh

line(maxx-7, midy-3, maxx, midy); // mui ten

line(maxx-7, midy+3, maxx, midy);

line(midx, 0, midx, maxy); // truc tung

line(midx-3, 7, midx, 0); // mui ten

line(midx+3, 7, midx, 0);

outtextxy(midx+6, midy+6, "(0, 0)"); // in toa do (0,0)

}

Các ví d sau s v đ th c a m t s hàm quen thu c.ụ ẽ ẽ ồ ị ủ ộ ố ộ

void Sinx() // Do thi ham Sinx

{

int tileX = 20, tileY = 60; // T l theo X và Yỉ ệ

int x, y, i;

setviewport(midx, midy, maxx, maxy, 0);

for (i = -400; i<=400; i++) {

x = 2*pi*i*tileX/200;

y = sin(2*pi*i/200)*tileY;

putpixel(x, y, 1);

}

setviewport(0, 0, maxx, maxy, 0);

}

void Sinoverx() // Ham Sinx/x

{

float t;

float tileX = 50/pi;

float tileY = 80;

int x, y;

for (x = 30; x < maxx-30; x++) {

t = ((x==midx)? 1 : (x-midx))/tileX;

y = midy - int(sin(t)/t*tileY);

Page 195: Giao Trinh C++ Toan Tap

putpixel(x, y, 2);

}

}

Ve do thi theo tham so (x = x(t), y = y(t))

void Hypocycloide() // Ham x = cos3t, y = sin3t

{ // t Î [0, 2p]

float t;

int i, x, y;

for (i = 0; i<1000; i++) {

t = (pi/500)*i;

x = int(120*pow(cos(t), 3)) + midx;

y = int(120*pow(sin(t), 3)) + midy;

putpixel(x, y, 3);

}

}

void Trocoide() // Ham (2t-3sint, 2-3cost)

{ // t Î [-9, 9]

float t;

int i, x, y;

for (i = -1000; i<=1000; i++) {

t = 0.01*i;

x = int(15*(2*t-3*sin(t))) + midx;

y = -int(10*(2-3*cos(t))) + midy;

putpixel(x, y, 4);

}

}

void So3() // x = sintcos2t + sint

{ // y = sin2tcost, t Î [0, 2p]

float t;

int i, x, y;

for (i = 0; i<=1000; i++) {

t = (pi/500)*i;

Page 196: Giao Trinh C++ Toan Tap

x = int(150*(sin(t)*(1+cos(t)*cos(t)))) + midx;

y = int(200*sin(t)*sin(t)*cos(t)) + midy;

putpixel(x, y, 5);

}

}

Ve do thi theo toa do cuc r = j(q)

void Archimede() // Ham r = q, q Î [0, 40]

{

int i, x, y;

float r, t;

for (i = 0;i<=2500;i++) {

t = 0.02*i;

x = int(3*t*cos(t))+midx;

y = -int(3*t*sin(t))+midy;

putpixel(x, y, 6);

}

}

void Hoahong() // Ham r = sin2q, q Î [0, 2p]

{

int i, x, y;

float r, t;

for (i = 0;i<=2000;i++) {

t = (pi/500)*i;

x = int(150*(sin(2*t)*cos(t)))+midx;

y = int(150*sin(2*t)*sin(t))+midy;

putpixel(x, y, 7);

}

}

Page 197: Giao Trinh C++ Toan Tap

Ch ng trình d i đây cho phép v hai m t trong không gian 3 chi u đ c cho b i hai hàm fươ ướ ẽ ặ ề ượ ở

= sinx.siny và g = 22

22

yx

)yxsin(

+

+

typedef struct TOADO {

int OX, OY, UX, UY, UZ; // truc hoanh, tung va don vi cac truc

double Xx, Xy; // goc (OX, ox), (OY, oy)

};

TOADO gr3 = { 320, 20, 20, 20, 20, 0.8*pi, 0.2*pi };

void Vetruc() // Ve truc Ox, Oy

{

setviewport(0, 0, maxx, maxy, 0);

settextstyle(DEFAULT_FONT, HORIZ_HUONG, 0);

setcolor(WHITE);

line(0, midy, maxx, midy);

line(maxx-7, midy-3, maxx, midy); line(maxx-7, midy+3, maxx, midy);

line(midx, 0, midx, maxy);

line(midx-3, 7, midx, 0); line(midx+3, 7, midx, 0);

outtextxy(midx+6, midy+6, "(0, 0)");

outtextxy(maxx-18, midy+6, "x"); outtextxy(midx+8, 6, "y");

setbkcolor(CYAN); setcolor(RED);

settextstyle(TRIPLEX_FONT, HORIZ_HUONG, 2);

outtextxy(10, 0, "DO THI KHONG GIAN 3 CHIEU");

}

int X(double x, double y, double z) // doi toa do xyz sang truc X

{

return gr3.OX + x*gr3.UX*cos(gr3.Xx) + y*gr3.UY*cos(gr3.Xy);

}

int Y(double x, double y, double z) // doi toa do xyz sang truc Y

{

Page 198: Giao Trinh C++ Toan Tap

return gr3.OY + x*gr3.UX*sin(gr3.Xx) + y*gr3.UY*sin(gr3.Xy) - z*gr3.UZ;

}

double f(double x, double y) // Ham f(x, y) can ve

{

return 4*sin(x)*sin(y);

}

double g(double x, double y) // Ham g(x, y) can ve

{

return 5*sin(sqrt(x*x+y*y))/sqrt(x*x+y*y);

}

void Vehamf()

{

double x, y, z;

double xa = -6.28, xb = 6.28;

double ya = -6.28, yb = 6.28;

double xp = 0.2, yp = 0.2;

int mat[8];

settextstyle(TRIPLEX_FONT, HORIZ_HUONG, 1);

outtextxy(10, 20, "Ham z = sinx.siny");

setviewport(0, midy, maxx, maxy, 0);

for (x = xa; x <= xb; x+=xp) // ve mat an

for (y = ya; y <= yb; y+=yp)

{

if (kbhit()) return;

z = f(x, y); // diem A

mat[0] = X(x, y, z); mat[1] = Y(x, y, z);

z = f(x, y+yp); // diem B

mat[2] = X(x, y+yp, z); mat[3] = Y(x, y+yp, z);

z = f(x+xp, y+yp); // diem C

mat[4] = X(x+xp, y+yp, z); mat[5] = Y(x+xp, y+yp, z);

z = f(x+xp, y); // diem D

mat[6] = X(x+xp, y, z); mat[7] = Y(x+xp, y, z);

if ((mat[3]-mat[1]) * (mat[6]-mat[0]) -

Page 199: Giao Trinh C++ Toan Tap

(mat[7]-mat[1]) * (mat[2]-mat[0]) < 0)

setfillstyle(1, YELLOW); else setfillstyle(1, GREEN);

fillpoly(4, mat);

delay(10);

}

getch();

}

void Vehamg()

{

double x, y, z;

double xa = -10, xb = 10;

double ya = -10, yb = 10;

double xp = 0.1, yp = 0.1;

settextstyle(TRIPLEX_FONT, HORIZ_DIR, 1);

outtextxy(10, 20, "Ham z = sin(sqrt(x*x+y*y))");

outtextxy(100, 30, "------------");

outtextxy(115, 40, "sqrt(x*x+y*y)");

setviewport(0, midy, maxx, maxy, 0);

setcolor(BLUE);

for (x = xa; x <= xb; x+=xp)

for (y = ya; y <= yb; y+=yp)

{

if (kbhit()) return;

z = g(x, y); lineto(X(x, y, z), Y(x, y, z));

delay(10);

}

getch();

}

void main()

{

Initgraph(); Vetruc(); Vehamf();

Page 200: Giao Trinh C++ Toan Tap

cleardevice(); Vetruc(); Vehamg();

closegraph();

}

ÂM THANH

Âm thanh đư c ợ đ c trặ ưng b i cao ở đ (t n s ) và trộ ầ ố ư ng ờ đ (đ dài). Vi c t o ra m t chu iộ ộ ệ ạ ộ ỗ âm (bài hát ch ng h n), là s k t h p l p đi l p l i c a các hàm sau v i các tham s n và tẳ ạ ự ế ợ ặ ặ ạ ủ ớ ố đ c ch n thích h p. ượ ọ ợ

- sound(n): phát âm ra loa máy tính v i t n s n. ớ ầ ố

- delay(t): kéo dài trong t miligiây.

- nosound(): t t âm thanh đã phát.ắ

: Ti ng còi báo ế đ ngộ

void coi(int cao; int thap)

{

do {

sound(cao); delay(400); sound(thap); delay(400);

} while (!kbhit())

nosound();

}

: Ti ng bóng n yế ả

void bong(int cao; int thap)

{

int sodem = 20;

while (sodem > 1) {

sound(thap-2*sodem); delay(sodem*500/20);

nosound(); delay(100);

sound(cao); delay(sodem*500/15); nosound(); delay(150);

sodem --;

}

Page 201: Giao Trinh C++ Toan Tap

}

: Ti ng bomế

void bong(int cao; int thap; int t)

{

int sodem = thap;

while (sodem <= cao) {

sound(sodem); delay(t/sodem*75);

sodem += 10;

}

for (sodem =1 to 3) {

nosound();

sound(40); delay(500); nosound(); delay(100);

}

sound(40); delay(3000); nosound();

}

Đ t o âm phát c a m t n t nh c có t n s (cao ể ạ ủ ộ ố ạ ầ ố đ ) n và dài trong t miligiây c n vi t hàm :ộ ầ ế

void not(unsigned n, float t);

{

sound(n);

delay(t);

nosound();

}

: Ch i bài hát Ti n quân ca trên n n c đ sao vàng.ơ ế ề ờ ỏ

#include <stdio.h>

#include <stdlib.h>

#include <graphics.h>

#include <dos.h>

// cao đ c a các n t nh c ộ ủ ố ạ

#define do1 66 #define dod1 70 #define re1 73

#define red1 78 #define mi1 82 #define fa1 86

Page 202: Giao Trinh C++ Toan Tap

#define fad1 91 #define sol1 96 #define sold1 102

#define la1 108 #define lad1 115 #define si1 122

#define do2 130 #define dod2 139 #define re2 148

#define re2 148 #define red2 156 #define mi2 164

#define fa2 176 #define fad2 188 #define sol2 196

#define sold2 209 #define la2 230 #define lad2 233

#define si2 247 #define do3 264 #define dod3 281

#define re3 297 #define red3 313 #define mi3 330

#define fa3 352 #define fad3 374 #define sol3 396

#define sold3 415 #define la3 440 #define lad3 468

#define si3 495 #define do4 528 #define dod4 565

#define re4 594 #define red4 625 #define mi4 660

#define fa4 704 #define fad4 748 #define sol4 792

#define sold4 836 #define la4 880 #define lad4 935

#define si4 990 #define lang 30000

void not(unsigned caodo, float truongdo)

{ sound(caodo); delay(truongdo); nosound(); }

void main()

{

int gdriver = DETECT, gmode;

initgraph(&gdriver, &gmode, "c:\\borlandc\\bgi");

int star[20] = {320, 150, 285, 225, 200, 225, 270, 270, 240, 350,

320, 300, 390, 350, 360, 270, 430, 225, 345, 225};

setbkcolor(RED); setcolor(YELLOW); // V lá c đ sao vàngẽ ờ ỏ

setfillstyle(SOLID_FILL, YELLOW);

fillpoly(10, star);

// Trư ng ờ đ các n t nh c ộ ố ạ

float d = 300; // đen

float tr = 2*d; // tr ngắ

float tro = 4*d; // tròn

float md = d/2; // móc đen

Page 203: Giao Trinh C++ Toan Tap

float mk = d/4; // móc kép

float m3 = d/8; // móc 3

float m4 = d/16; // móc 4

float dc = 3*d/2; // đen ch m ấ

float trc = 3*d; // tr ng ch m ắ ấ

float troc = 6*d; // tròn ch m ấ

// Choi bai TQC

not(re2, d); not(mi2, d); not(re2, d); not(sol2, tr); not(sol2, tro);

not(la2, d); not(sol2, d); not(si2, tr); not(si2, tro); not(la2, d);

not(sol2, d); not(mi2, tr); not(sol2, tr); not(sol2, d); not(mi2, tro);

not(re2, d); not(si2, d); not(re2, tro); not(sol2, d); not(la2, d);

not(si2, tr); not(si2, tr); not(si2, tr); not(la2, d); not(sol2, d);

not(re3, tro); not(si2, d); not(sol2, d); not(la2, tr); not(la2, tr);

not(si2, tr); not(fad2, d); not(re2, d); not(sol2, tro); not(si2, d);

not(do3, d); not(re3, tr); not(re3, tr); not(mi3, tro); not(re3, d);

not(si2, tro); not(si2, tr); not(la2, d); not(sol2, tr); not(re2, tr);

not(fad2, tr); not(fad2, d); not(la2, d); not(sol2, tr); not(si2, d);

not(do3, d); not(re3, tr); not(re3, tr); not(mi3, tro); not(re3, d);

not(si2, tro); not(si2, tr); not(la2, d); not(sol2, tr); not(sol2, tr);

not(re2, tro); not(re3, tro); not(si2, tr); not(sol2, tr); not(mi3, tro);

not(re3, tr); not(si2, d); not(la2, d); not(re2, d); not(la2, tr);

not(la2, tro); not(si2, tr); not(sol2, tro);

closegraph();

}

BÀI T PẬ

Page 204: Giao Trinh C++ Toan Tap

V hai hình ch nh t, l n l t cho m t t ng hình, r i hi n l i c hai.ẽ ữ ậ ầ ượ ấ ừ ồ ệ ạ ả

Bi u di n dãy 5 giá tr (đ c nh p t bàn phím) b ng bi u đ bar.ể ễ ị ượ ậ ừ ằ ể ồ

Bi u di n dãy 5 giá tr (đ c nh p t bàn phím) b ng bi u đ hình qu t.ể ễ ị ượ ậ ừ ằ ể ồ ạ

V m t bàn c qu c t v i các ô đen tr ng.ẽ ộ ờ ố ế ớ ắ

Vi t ch ng trình v đ th hàm s y = 100*sin(x/4.8) trong kho ng x ế ươ ẽ ồ ị ố ả ∈ [0, 60] v i giá tr m iớ ị ỗ b c ướ ∆x = 0,1. Yêu c u :ầ

n n màn hình m u đen.ề ầ

tr c t a đ màu xanh lá câyụ ọ ộ

đ th màu tr ng.ồ ị ắ

Vi t ch ng trình v tam giác v i các t a đ đ nh l n l t là A(300, 20), B(100, 220), C(500,ế ươ ẽ ớ ọ ộ ỉ ầ ượ 220) và đ ng tròn ngo i ti p c a nó. Yêu c u : ườ ạ ế ủ ầ

n n màn hình m u đen.ề ầ

các c nh tam giác màu xanh lá câyạ

đ ng tròn ngo i ti p màu đ t i.ườ ạ ế ỏ ươ

Vi t ch ng trình v hình ch nh t có t a đ đ nh góc trên bên trái là (100,150), chi u ngangế ươ ẽ ữ ậ ọ ộ ỉ ề 120, chi u d c 90 và đ ng tròn ngo i ti p nó. Yêu c u : ề ọ ườ ạ ế ầ

n n màn hình m u đen.ề ầ

các c nh hình ch nh t màu xanh da tr i.ạ ữ ậ ờ

đ ng tròn ngo i ti p màu đ t i.ườ ạ ế ỏ ươ

V tam giác n i ti p trong hình tròn, hình tròn n i ti p trong elip. Tô các màu khác nhau choẽ ộ ế ộ ế các mi n t o b i các đ ng trên.ề ạ ở ườ

V m t đài phát sóng. Các vòng sóng phát t đ nh c a tháp tâm màn hình lan t a ra chungẽ ộ ừ ỉ ủ ở ỏ quanh. Quá trình l p đ n khi n phím b t kỳ thì d ng.ặ ế ấ ấ ừ

V hai hình ng i đi vào t 2 phía màn hình v i t c đ khác nhau. G p nhau hai hình ng iẽ ườ ừ ớ ố ộ ặ ườ xoay l i và đi ng c v 2 phía màn hình. Ch ng trình d ng khi c hai đã đi khu t vàoạ ượ ề ươ ừ ả ấ hai phía c a màn hình.ủ

CH NG 7ƯƠ

L P VÀ Đ I T NGỚ Ố ƯỢ

L p trình có c u trúc và l p trình h ng đ i t ngậ ấ ậ ướ ố ượL p và đ i t ng ớ ố ượĐ i c a ph ng th c - Con tr thisố ủ ươ ứ ỏHàm t o (contructor)ạHàm h y (destructor)ủ

Page 205: Giao Trinh C++ Toan Tap

Các hàm tr c tuy n (inline)ự ế

L P TRÌNH CÓ C U TRÚC VÀ L P TRÌNH H NG Đ I T NGẬ Ấ Ậ ƯỚ Ố ƯỢ

Ph ng pháp l p trình c u trúcươ ậ ấ

L p trình c u trúc là t ch c ch ng trình thành các ch ng trình con. Trong m t sậ ấ ổ ứ ươ ươ ộ ố ngôn ng nh PASCAL có 2 ki u ch ng trình con là th t c và hàm, còn trong C++ữ ư ể ươ ủ ụ ch có m t lo i ch ng trình con là hàm.ỉ ộ ạ ươ

Hàm là m t đ n v ch ng trình đ c l p dùng đ th c hi n m t ph n vi c nào đó nh :ộ ơ ị ươ ộ ậ ể ự ệ ộ ầ ệ ư Nh p s li u, in k t qu hay th c hi n m t s công vi c tính toán. Hàm c n có đ iậ ố ệ ế ả ự ệ ộ ố ệ ầ ố và các bi n, m ng c c b dùng riêng cho hàm.ế ả ụ ộ

Vi c trao đ i d li u gi a các hàm th c hi n thông qua các đ i và các bi n toàn c c.ệ ổ ữ ệ ữ ự ệ ố ế ụ

M t ch ng trình c u trúc g m các c u trúc d li u (nh bi n, m ng, b n ghi) và cácộ ươ ấ ồ ấ ữ ệ ư ế ả ả hàm, th t c.ủ ụ

Nhi m v chính c a vi c t ch c thi t k ch ng trình c u trúc là t ch c ch ngệ ụ ủ ệ ổ ứ ế ế ươ ấ ổ ứ ươ trình thành các hàm, th t c.ủ ụ

Ví d , ta xét yêu c u sau: Vi t ch ng trình nh p to đ (x,y) c a m t dãy đi m, sau đó tìmụ ầ ế ươ ậ ạ ộ ủ ộ ể m t c p đi m cách xa nhau nh t.ộ ặ ể ấ

Trên t t ng c a l p trình c u trúc có th t ch c ch ng trình nh sau:ư ưở ủ ậ ấ ể ổ ứ ươ ư

S d ng 2 m ng th c toàn b x và y đ ch a to đ dãy đi m.ử ụ ả ự ộ ể ứ ạ ộ ể

Xây d ng 2 hàm:ựHàm nhapsl dùng đ nh p to đ n đi m, hàm này có m t đ i là bi n nguyên n và đ c khaiể ậ ạ ộ ể ộ ố ế ượ báo nh sau:ư

void nhapsl(int n); Hàm do_dai dùng đ tính đ dài đo n th ng đi qua 2 đi m có ch s là i và j, nó đ c khai báoể ộ ạ ẳ ể ỉ ố ượ nh sau:ư

float do_dai(int i, int j); Ch ng trình C c a ví d trên đ c vi t nh sau:ươ ủ ụ ượ ế ư

#include <stdio.h>

#include <conio.h>

#include <math.h>

float x[100],y[100];

float do_dai(int i, int j)

{

return sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2));

}

Page 206: Giao Trinh C++ Toan Tap

void nhapsl(int n)

{

int i;

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

{

printf("\n Nhap toa do x, y cua diem thu %d : ",i);

scanf(''%f%f",&x[i],&y[i]);

}

}

void main()

{

int n, i, j, imax,jmax;

float d, dmax;

printf(''\n So diem N= '');

scanf(''%d'', &n);

nhapsl(n);

dmax=do_dai(1,2);imax=1; jmax=2;

for(i=1; i<=n-1; ++i)

for (j=i+1; j<=n; ++j)

{

d=do_dai(i,j);

if (d>dmax)

{

dmax=d;

imax=i; jmax=j;

}

}

printf(''\nDoan thang lon nhat co do dai bang: %0.2f",dmax);

printf(''\n Di qua 2 diem co chi so la %d va %d'',imax,jmax);

getch();

}

Ph ng pháp l p trình h ng đ i t ngươ ậ ướ ố ượ

Page 207: Giao Trinh C++ Toan Tap

Là l p trình có c u trúc + tr u t ng hóa d li u. Có nghĩa ch ng trình t ch c d i d ngậ ấ ừ ượ ữ ệ ươ ổ ứ ướ ạ c u trúc. Tuy nhiên vi c thi t k ch ng trình s xoay quanh d li u, l y d li u làm trungấ ệ ế ế ươ ẽ ữ ệ ấ ữ ệ tâm. Nghĩa là tr l i câu h i: Ch ng trình làm vi c v i nh ng đ i t ng d li u nào, trênả ờ ỏ ươ ệ ớ ữ ố ượ ữ ệ các đ i t ng d li u này c n thao tác, th c hi n nh ng gì. T đó g n v i m i đ i t ng dố ượ ữ ệ ầ ự ệ ữ ừ ắ ớ ỗ ố ượ ữ li u m t s thao tác th c hiên c đ nh riêng c a đ i t ng d li u đó, đi u này s qui đ nhệ ộ ố ự ố ị ủ ố ượ ữ ệ ề ẽ ị ch t ch h n nh ng thao tác nào đ c th c hi n trên đ i t ng d li u nào. Khác v i l pặ ẽ ơ ữ ượ ự ệ ố ượ ữ ệ ớ ậ trình c u trúc thu n túy, trong đó d li u đ c khai báo riêng r , tách r i v i thao tác x lý,ấ ầ ữ ệ ượ ẽ ờ ớ ử do đó vi c x lý d li u th ng không th ng nh t khi ch ng trình đ c xây d ng t nhi uệ ử ữ ệ ườ ố ấ ươ ượ ự ừ ề l p trình viên khác nhau. ậ

T đó l p trình h ng đ i t ng đ c xây d ng d a trên đ c tr ng chính là khái ni m đóngừ ậ ướ ố ượ ượ ự ự ặ ư ệ gói. Đóng gói là khái ni m trung tâm c a ph ng pháp l p trình h ng đ i t ng, trong đóệ ủ ươ ậ ướ ố ượ d li u và các thao tác x lý nó s đ c qui đ nh tr c và "đóng" thành m t "gói" th ng nh t,ữ ệ ử ẽ ượ ị ướ ộ ố ấ riêng bi t v i các d li u khác t o thành ki u d li u v i tên g i là các l p. Nh v y m t l pệ ớ ữ ệ ạ ể ữ ệ ớ ọ ớ ư ậ ộ ớ không ch ch a d li u bình th ng nh các ki u d li u khác mà còn ch a các thao tác đỉ ứ ữ ệ ườ ư ể ữ ệ ứ ể x lý d li u này. Các thao tác đ c khai báo trong gói d li u nào ch x lý d li u trong góiử ữ ệ ượ ữ ệ ỉ ử ữ ệ đó và ng c l i d li u trong m t gói ch b tác đ ng, x lý b i thao tác đã khai báo trong góiượ ạ ữ ệ ộ ỉ ị ộ ử ở đó. Đi u này t o tính t p trung cao khi l p trình, m i đ i t ng trong m t l p s ch a cùngề ạ ậ ậ ọ ố ượ ộ ớ ẽ ứ lo i d li u đ c ch đ nh và cùng đ c x lý b i các thao tác nh nhau. M i l p trình viênạ ữ ệ ượ ỉ ị ượ ử ở ư ọ ậ khi làm vi c v i d li u trong m t gói đ u s d ng các thao tác nh nhau đ x lý d li uệ ớ ữ ệ ộ ề ử ụ ư ể ử ữ ệ trong gói đó. C++ cung c p cách th c đ t o m t c u trúc d li u m i th hi n các gói nóiấ ứ ể ạ ộ ấ ữ ệ ớ ể ệ trên, c u trúc d li u này đ c g i là ấ ữ ệ ượ ọ l pớ .

Đ minh ho các khái ni m v a nêu v kiêu d li u l p ta tr l i xét bài toán tìm đ dài l nể ạ ệ ừ ề ữ ệ ớ ở ạ ộ ớ nh t đi qua 2 đi m. Trong bài toán này ta g p m t th c th là dãy đi m. Các thành ph n dấ ể ặ ộ ự ể ể ầ ữ li u c a l p dãy đi m g m: ệ ủ ớ ể ồ

Bi n nguyên n là s đi m c a dãy ế ố ể ủ

Con tr x ki u th c tr đ n vùng nh ch a dãy hoành đỏ ể ự ỏ ế ớ ứ ộ

Con tr y ki u th c tr đ n vùng nh ch a dãy tung đ ỏ ể ự ỏ ế ớ ứ ộCác ph ng th c c n đ a vào theo yêu c u bài toán g m:ươ ứ ầ ư ầ ồ

Nh p to đ m t đi mậ ạ ộ ộ ể

Tính đ dài đo n th ng đi qua 2 đi mộ ạ ẳ ểD i đây là ch ng trình vi t theo thi t k h ng đ i t ng. ướ ươ ế ế ế ướ ố ượ

#include <stdio.h>

#include <conio.h>

#include <math.h>

#include <alloc.h>

class daydiem

Page 208: Giao Trinh C++ Toan Tap

{

int n;

float *x,*y;

public:

float do_dai(int i, int j)

{

return sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2));

}

void nhapsl(void);

};

void daydiem::nhapsl(void)

{

int i;

printf(''\n So diem N= '');

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

x = (float*)malloc((n+1)*sizeof(float));

y = (float*)malloc((n+1)*sizeof(float));

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

{

printf(''\n Nhap toa do x, y cua diem thu %d : '',i);

scanf(''%f%f'',&x[i],&y[i]);

}

}

void main()

{

clrscr();

daydiem p;

p.nhapsl();

int n,i,j,imax,jmax;

float d,dmax;

n = p.n;

dmax=p.do_dai(1,2);imax=1; jmax=2;

for (i=1;i<=n-1;++i)

Page 209: Giao Trinh C++ Toan Tap

for (j=i+1;j<=n;++j)

{

d=p.do_dai(i,j);

if (d>dmax)

{

dmax=d;

imax=i; jmax=j;

}

}

printf(''\n Doan thang lon nhat co do dai bang: %0.2f",dmax);

printf(''\n Di qua 2 diem co chi so la %d va %d" , imax,jmax);

getch();

}

L P VÀ Đ I T NG Ớ Ố ƯỢ

Trong l p trình h ng đ i t ng, l p (class) là m t khái ni m r t quan tr ng, nó cho phépậ ướ ố ượ ớ ộ ệ ấ ọ gi i quy t các v n đ ph c t p c a vi c l p trình. M t l p đ n (đ c đ nh nghĩa nh struct,ả ế ấ ề ứ ạ ủ ệ ậ ộ ớ ơ ượ ị ư union, ho c class) bao g m các hàm và d li u có liên quan. Các hàm này là các hàm thànhặ ồ ữ ệ ph n (member functon) hay còn là ph ng th c (method), th hi n tác đ ng c a l p có thầ ươ ứ ể ệ ộ ủ ớ ể đ c th c hi n trên d li u c a chính l p đó (data member).ượ ự ệ ữ ệ ủ ớ

Cũng gi ng nh c u trúc, l p có th xem nh m t ki u d li u. Vì v y l p còn g i là ki uố ư ấ ớ ể ư ộ ể ữ ệ ậ ớ ọ ể đ i t ng và l p đ c dùng đ khai báo các bi n, m ng đ i t ng (nh th dùng ki u int đố ượ ớ ượ ể ế ả ố ượ ư ể ể ể khai báo các bi n m ng nguyên).ế ả

Nh v y t m t l p có th t o ra (b ng cách khai báo) nhi u đ i t ng (bi n, m ng) khácư ậ ừ ộ ớ ể ạ ằ ề ố ượ ế ả nhau. M i đ i t ng có vùng nh riêng c a mình và vì v y ta cũng có th quan ni m l pỗ ố ượ ớ ủ ậ ể ệ ớ chính là t p h p các đ i t ng cùng ki u.ậ ợ ố ượ ể

Khai báo l pớĐ khai báo m t l p, ta s d ng t khoá class nh sau:ể ộ ớ ử ụ ừ ư

class tên_l pớ

{

// Khai báo các thành ph n d li u (thu c tính)ầ ữ ệ ộ

// Khai báo các ph ng th c (hàm)ươ ứ

};

Page 210: Giao Trinh C++ Toan Tap

Chú ý: Vi c khai báo m t l p không chi m gi b nh , ch các đ i t ng c a l p m i th c sệ ộ ớ ế ữ ộ ớ ỉ ố ượ ủ ớ ớ ự ự chi m gi b nh .ế ữ ộ ớ

Thu c tính c a l p có th là các bi n, m ng, con tr có ki u chu n (int, float, char, char*,ộ ủ ớ ể ế ả ỏ ể ẩ long,...) ho c ki u ngoài chu n đã đ nh nghĩa tr c (c u trúc, h p, l p,...). Thu c tính c a l pặ ể ẩ ị ướ ấ ợ ớ ộ ủ ớ không th có ki u c a chính l p đó, nh ng có th là con tr c a l p này, ví d :ể ể ủ ớ ư ể ỏ ủ ớ ụ

class A

{

A x; //Không cho phép, vì x có ki u l p Aể ớ

A* p ; //Cho phép , vì p là con tr ki u l p Aỏ ể ớ

} ;

Khai báo các thành ph n c a l p (thu c tính và ph ng th c)ầ ủ ớ ộ ươ ứ

Các t khóa private và publicừKhi khai báo các thành ph n d li u và ph ng th c có th dùng các t khoá private và publicầ ữ ệ ươ ứ ể ừ đ quy đ nh ph m vi s d ng c a các thành ph n này. Trong đó t khóa private qui đ nh cácể ị ạ ử ụ ủ ầ ừ ị thành ph n (đ c khai báo v i t khóa này) ch đ c s d ng bên trong l p (trong thân cácầ ượ ớ ừ ỉ ượ ử ụ ớ ph ng th c c a l p). Các hàm bên ngoài l p (không ph i là ph ng th c c a l p) khôngươ ứ ủ ớ ớ ả ươ ứ ủ ớ đ c phép s d ng các thành ph n này. Đ c tr ng này th hi n tính che gi u thông tin trongượ ử ụ ầ ặ ư ể ệ ấ n i b c a l p, đ đ n đ c các thông tin này c n ph i thông qua chính các thành ph n hàmộ ộ ủ ớ ể ế ượ ầ ả ầ c a l p đó. Do v y thông tin có tính toàn v n cao và vi c x lý thông tin (d li u) này mangủ ớ ậ ẹ ệ ử ữ ệ tính th ng nh t h n và h u nh d li u trong các l p đ u đ c khai báo v i t khóa này.ố ấ ơ ầ ư ữ ệ ớ ề ượ ớ ừ Ng c l i v i private, các thành ph n đ c khai báo v i t khóa public đ c phép s d ng ượ ạ ớ ầ ượ ớ ừ ượ ử ụ ở c bên trong và bên ngoài l p, đi u này cho phép trong ch ng trình có th s d ng các hàmả ớ ề ươ ể ử ụ này đ truy nh p đ n d li u c a l p. Hi n nhiên n u các thành ph n d li u đã khai báo làể ậ ế ữ ệ ủ ớ ể ế ầ ữ ệ privte thì các thành ph n hàm ph i có ít nh t m t vài hàm đ c khai báo d ng public đầ ả ấ ộ ượ ạ ể ch ng trình có th truy c p đ c, n u không toàn b l p s b đóng kín và đi u này khôngươ ể ậ ượ ế ộ ớ ẽ ị ề giúp gì cho ch ng trình. Do v y cách khai báo l p t ng đ i ph bi n là các thành ph n dươ ậ ớ ươ ố ổ ế ầ ữ li u đ c d ng private và thành ph n hàm d i d ng public. N u không quy đ nh c thệ ượ ở ạ ầ ướ ạ ế ị ụ ể (không dùng các t khoá private và public) thì C++ hi u đó là private.ừ ể

Các thành ph n d li u (thu c tính)ầ ữ ệ ộĐ c khai báo nh khai báo các thành ph n trong ki u c u trúc hay h p. Bình th ng cácượ ư ầ ể ấ ợ ườ thành ph n này đ c khai báo là private đ b o đ m tính gi u kín, b o v an toàn d li u c aầ ượ ể ả ả ấ ả ệ ữ ệ ủ l p không cho phép các hàm bên ngoài xâm nh p vào các d li u này.ớ ậ ữ ệ

Các ph ng th c (hàm thành viên)ươ ứTh ng khai báo là public đ chúng có th đ c g i t i (s d ng) t các hàm khác trongườ ể ể ượ ọ ớ ử ụ ừ ch ng trình.ươ

Page 211: Giao Trinh C++ Toan Tap

Các ph ng th c có th đ c khai báo và đ nh nghĩa bên trong l p ho c ch khai báo bên trongươ ứ ể ượ ị ớ ặ ỉ còn đ nh nghĩa c th c a ph ng th c có th đ c vi t bên ngoài. Thông th ng, cácị ụ ể ủ ươ ứ ể ượ ế ườ ph ng th c ng n đ c vi t (đ nh nghĩa) bên trong l p, còn các ph ng th c dài thì vi t bênươ ứ ắ ượ ế ị ớ ươ ứ ế ngoài l p.ớ

M t ph ng th c b t kỳ c a m t l p, có th s d ng b t kỳ thành ph n (thu c tính vàộ ươ ứ ấ ủ ộ ớ ể ử ụ ấ ầ ộ ph ng th c) nào c a l p đó và b t kỳ hàm nào khác trong ch ng trình (vì ph m vi s d ngươ ứ ủ ớ ấ ươ ạ ử ụ c a hàm là toàn ch ng trình).ủ ươ

Giá tr tr v c a ph ng th c có th có ki u b t kỳ (chu n và ngoài chu n)ị ả ề ủ ươ ứ ể ể ấ ẩ ẩ

Ví d sau s minh ho các đi u nói trên. Chúng ta s đ nh nghĩa l p đ mô t và x lý cácụ ẽ ạ ề ẽ ị ớ ể ả ử đi m trên màn hình đ ho . L p đ c đ t tên là DIEM.ể ồ ạ ớ ượ ặ

Các thu c tính c a l p g m:ộ ủ ớ ồ

int x ; // Hoành đ (c t)ộ ộ

int y ; // Tung đ (hàng)ộ

int m ; // M uầ

Các ph ng th c:ươ ứNh p d li u m t đi mậ ữ ệ ộ ể

Hi n th m t đi mể ị ộ ể

n m t đi mẨ ộ ể

L p đi m đ c xây d ng nh sau:ớ ể ượ ự ư

#include <iostream.h>

#include <graphics.h>

class DIEM

{

private:

int x, y, m ;

public:

void nhapsl() ;

void hien() ;

void an() { putpixel(x, y, getbkcolor());}

};

void DIEM::nhapsl()

Page 212: Giao Trinh C++ Toan Tap

{

cout <<"\n Nhap hoanh do (cot) va tung do (hang) cua diem: '';

cin >> x >> y ;

cout << ''\n Nhap ma mau cua diem: '';

cin >> m ;

}

void DIEM::hien()

{

int mau_ht ;

mau_ht = getcolor();

putpixel(x, y, m);

setcolor(mau_ht);

}Qua ví d trên có th rút ra m t s chú ý sau:ụ ể ộ ố

Trong c 3 ph ng th c (dù vi t trong hay vi t ngoài đ nh nghĩa l p) đ u đ c phépả ươ ứ ế ế ị ớ ề ượ truy nh p đ n các thu c tính x, y và m c a l p.ậ ế ộ ủ ớ

Các ph ng th c vi t bên trong đ nh nghĩa l p (nh ph ng th c an() ) đ c vi t nhươ ứ ế ị ớ ư ươ ứ ượ ế ư m t hàm thông th ng.ộ ườ

Khi xây d ng các ph ng th c bên ngoài l p, c n dùng thêm tên l p và toán t ph mự ươ ứ ớ ầ ớ ử ạ vi :: đ t ngay tr c tên ph ng ph c đ quy đ nh rõ đây là ph ng th c c a l p nào.ặ ướ ươ ứ ể ị ươ ứ ủ ớ

Bi n, m ng và con tr đ i t ng ế ả ỏ ố ượNh đã nói trên, m t l p (sau khi đ nh nghĩa) có th xem nh m t ki u đ i t ng và có thư ở ộ ớ ị ể ư ộ ể ố ượ ể dùng đ khai báo các bi n, m ng đ i t ng. Cách khai báo bi n, m ng đ i t ng cũng gi ngể ế ả ố ượ ế ả ố ượ ố nh khai báo bi n, m ng các ki u khác (nh int, float, c u trúc, h p,...), theo m u sau: ư ế ả ể ư ấ ợ ẫ

Tên_l p danh sách đ i ; ớ ố

Tên_l p danh sách m ng ; ớ ảVí d s d ng DIEM trên, ta có th khai báo các bi n, m ng DIEM nh sau:ụ ử ụ ở ể ế ả ư

DIEM d1, d2, d3 ; // Khai báo 3 bi n đ i t ng d1, d2, d3ế ố ượ

DIEM d[20] ; // Khai báo m ng đ i t ng d g m 20 ph n tả ố ượ ồ ầ ửM i đ i t ng sau khi khai báo s đ c c p phát m t vùng nh riêng đ ch a các thu cỗ ố ượ ẽ ượ ấ ộ ớ ể ứ ộ

tính c a nó. Chú ý r ng s không có vùng nh riêng đ ch a các ph ng th c cho m i đ iủ ằ ẽ ớ ể ứ ươ ứ ỗ ố t ng, các ph ng th c s đ c s d ng chung cho t t c các đ i t ng cùng l p. Nh v yượ ươ ứ ẽ ượ ử ụ ấ ả ố ượ ớ ư ậ v b nh đ c c p phát thì đ i t ng gi ng c u trúc. ề ộ ớ ượ ấ ố ượ ố ấTrong tr ng h p này:ườ ợ

Page 213: Giao Trinh C++ Toan Tap

sizeof(d1) = sizeof(d2) = sizeof(d3) = 3*sizeof(int) = 6

sizeof(d) = 20*6 = 120

Thu c tính c a đ i t ngộ ủ ố ượTrong ví d trên, m i đ i t ng d1, d2, d3 và m i ph n t d[i] đ u có 3 thu c tính là x, y, m.ụ ỗ ố ượ ỗ ầ ử ề ộ Chú ý là m i thu c tính đ u thu c v m t đ i t ng, vì v y không th vi t tên thu c tínhỗ ộ ề ộ ề ộ ố ượ ậ ể ế ộ m t cách riêng r mà bao gi cũng ph i có tên đ i t ng đi kèm, gi ng nh cách vi t trongộ ẽ ờ ả ố ượ ố ư ế c u trúc c aấ ủ C. Nói cách khác, cách vi t thu c tính c a đ i t ng nh sau: ế ộ ủ ố ượ ư

tên_đ i_t ng.Tên_thu c_tínhố ượ ộV i cácớ đ i t ng d1, d2, d3 và m ng d, có th vi t nh sau:ố ượ ả ể ế ư

d1.x; // Thu c tính x c a đ i t ng d1ộ ủ ố ượ

d2.x; // Thu c tính x c a đ i t ng d2ộ ủ ố ượ

d3.y; // Thu c tính y c a đ i t ng d3ộ ủ ố ượ

d[2].m; // Thu c tính m c a ph n t d[2]ộ ủ ầ ử

d1.x = 100; // Gán 100 cho d1.x

d2.y =d1.x; // Gán d1.x cho d2.y

S d ng các ph ng th cử ụ ươ ứCũng gi ng nh hàm, m t ph ng th c đ c s d ng thông qua l i g i. Tuy nhiên trongố ư ộ ươ ứ ượ ử ụ ờ ọ

l i g i ph ng th c bao gi cũng ph i có tên đ i t ng đ ch rõ ph ng th c th c hi n trênờ ọ ươ ứ ờ ả ố ượ ể ỉ ươ ứ ự ệ các thu c tính c a đ i t ng nào. ộ ủ ố ượ

Ví d l i g i sau s th c hi n nh p s li u vào các thành ph n d1.x, d1.y và d1.m:ụ ờ ọ ẽ ự ệ ậ ố ệ ầ d1.nhapsl(); Câu l nh sau s th c hi n nh p s li u vào các thành ph n d[3].x, d[3].y vàệ ẽ ự ệ ậ ố ệ ầ d[3].m: d[3].nhapsl() ;

Chúng ta s minh h a các đi u nói trên b ng m t ch ng trình đ n gi n s d ng l p DIEMẽ ọ ề ằ ộ ươ ơ ả ử ụ ớ đ nh p 3 đi m, hi n r i n các đi m v a nh p. Trong ch ng trình đ a vào hàmể ậ ể ệ ồ ẩ ể ừ ậ ươ ư kd_do_hoa() dùng đ kh i đ ng h đ ho .ể ở ộ ệ ồ ạ

#include <conio.h>

#include <iostream.h>

#include <graphics.h>

class DIEM

{

private:

int x, y, m ;

Page 214: Giao Trinh C++ Toan Tap

public:

void nhapsl();

void an() { putpixel(x,y,getbkcolor());}

void hien();

};

void DIEM::nhapsl()

{

cout << "\n Nhap hoanh do (cot) va tung do (hang) cua DIEM: '' ;

cin>> x >> y ;

cout << " \n Nhap ma tran cua diem: " ;

cin >> m ;

}

void DIEM::hien()

{

int mau_ht;

mau_ht = getcolor() ;

putpixel(x,y,m);

setcolor(mau_ht);

}

void kd_do_hoa()

{

int mh, mode ;

mh=mode=0;

initgraph(&mh, &mode, "C:\\TC\BGI");

}

void main()

{

DIEMd1, d2, d3 ;

d1.nhapsl(); d2.nhapsl(); d3.nhapsl();

kd_do_hoa();

Page 215: Giao Trinh C++ Toan Tap

setbkcolor(BLACK);

d1.hien(); d2.hien(); d3.hien();

getch();

d1.an(); d2.an(); d3.an();

getch();

closegraph();

}

Con tr đ i t ngỏ ố ượCon tr đ i t ng dùng đ ch a đ a ch c a bi n, m ng đ i t ng. Nó đ c khai báo nhỏ ố ượ ể ứ ị ỉ ủ ế ả ố ượ ượ ư sau:

Tên_l p *con tr ; ớ ỏVí d dùng l p DIEM có th khai báo:ụ ớ ể

DIEM *p1, *p2, *p3 ; // Khai báo 3 con tr p1, p2, p3ỏ

DIEM d1, d2 ; // Khai báo 2 đ i t ng d1, d2ố ượ

DIEM d[20] ; // Khai báo m ng đ i t ng ả ố ượvà có th th c hi n các câu l nh:ể ự ệ ệ

p1= &d2 ; // p1 ch a đ a ch c a d2 , hay p1 tr t i d2ứ ị ỉ ủ ỏ ớ

p2 = d ; // p2 tr t i đ u m ng dỏ ớ ầ ả

p3 = new DIEM // T o m t đt và ch a đ a ch c a nó vào p3ạ ộ ứ ị ỉ ủĐ s d ng thu c tính c a đ i t ng thông qua con tr , ta vi t nh sau:ể ử ụ ộ ủ ố ượ ỏ ế ư

Tên_con_tr ỏ→ Tên_thu c_tínhộChú ý: N u con tr ch a đ a ch đ u c a m ng, có th dùng con tr nh tên m ng.ế ỏ ứ ị ỉ ầ ủ ả ể ỏ ư ả

Nh v y sau khi th c hi n các câu l nh trên thì:ư ậ ự ệ ệ

p1 → x và d2.x là nh nhauư

p2[i].y và d[i].y là nh nhauư

T đó ta có quy t c s d ng thu c tính: Đ s d ng m t thu c tính c a đ i t ng ta ph iừ ắ ử ụ ộ ể ử ụ ộ ộ ủ ố ượ ả

dùng phép . ho c phép ặ →. Trong ch ng trình, không cho phép vi t tên thu c tính m t cáchươ ế ộ ộ đ n đ c mà ph i đi kèm tên đ i t ng ho c tên con tr theo các m u sau:ơ ộ ả ố ượ ặ ỏ ẫ

Tên_đ i_t ng.Tên_thu c_tínhố ượ ộ

Tên_con_tr ỏ → Tên_thu c_tínhộ

Tên_m ng_đ i_ t ng[ch _s ].Tên_thu c_tínhả ố ượ ỉ ố ộ

Page 216: Giao Trinh C++ Toan Tap

Tên_con_tr [ch _s ].Tên_thu c_tínhỏ ỉ ố ộCh ng trình d i đây cũng s d ng l p DIEM đ nh p m t dãy đi m, hi n th và n cácươ ướ ử ụ ớ ể ậ ộ ể ể ị ẩ đi m v a nh p. Ch ng trình dùng m t con tr ki u DIEM và dùng toán t new đ t o taể ừ ậ ươ ộ ỏ ể ử ể ạ m t dãy đ i t ngộ ố ượ

#include <conio.h>

#include <iostream.h>

#include <graphics.h>

class DIEM

{

private:

int x, y, m ;

public:

void nhapsl();

void an() { putpixel(x,y,getbkcolor());}

void hien();

};

void DIEM::nhapsl()

{

cout <<"\n Nhap hoanh do (cot) va tung do (hang) cua diem:'' ;

cin >> x >> y ;

cout << " \n Nhap ma mau cua DIEM: '' ;

cin >> m ;

}

void DIEM::hien()

{

int mau_ht;

mau_ht = getcolor() ;

putpixel(x,y,m);

setcolor(mau_ht);

}

void kd_do_hoa()

Page 217: Giao Trinh C++ Toan Tap

{

int mh, mode ;

mh=mode=0;

initgraph(&mh, &mode, ''C:\\TC\BGI'');

}

void main()

{

DIEM *p;

int i, n;

cout << ''So diem: '' ;

cin >> n;

p = new DIEM[n+1];

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

p[i].nhapsl();

kd_do_hoa();

for (i=1;i<=n;++i) p[i].hien();

getch();

for (i=1;i<=n;++i) p[i].an();

getch();

closegraph();

}

Đ I C A PH NG TH C, CON TR thisỐ Ủ ƯƠ Ứ Ỏ

Con tr this là đ i th nh t c a ph ng th cỏ ố ứ ấ ủ ươ ứChúng ta hãy xem l i ph ng th c nhapsl c a l p DIEMạ ươ ứ ủ ớ

void DIEM::nhapsl()

{

cout <<"\n Nhap hoanh do (cot) va tung do (hang) cua diem:" ;

cin >> x >> y ;

cout <<'' \n Nhap ma mau cua diem: " ;

cin >> m ;

}

Page 218: Giao Trinh C++ Toan Tap

Trong ph ng th c này chúng ta s d ng tên các thu c tính x, y và mươ ứ ử ụ ộ m t cách đ n đ c. Đi uộ ơ ộ ề này có v nh mâu thu n v i quy t c s d ng thu c tính nêu trong m c tr c. Th c t C++ẻ ư ẫ ớ ắ ử ụ ộ ụ ướ ự ế đã ng m đ nh s d ng m t con tr đ c bi t v i tên g i this trong các ph ng th c trên. Cácầ ị ử ụ ộ ỏ ặ ệ ớ ọ ươ ứ thu c tính vi t trong ph ng th c đ c hi u là thu c m t đ i t ng do con tr this tr t i.ộ ế ươ ứ ượ ể ộ ộ ố ượ ỏ ỏ ớ Do đó, n u t ng minh h n, ph ng th c nhapsl() có th đ c vi t d i d ng t ng đ ngế ườ ơ ươ ứ ể ượ ế ướ ạ ươ ươ nh sau:ư

void DIEM::nhapsl()

{

cout << ''\n Nhap hoanh do (cot) va tung do (hang) cua diem:'' ;

cin >> this → x >> this → y ;

cout << "\n Nhap ma mau cua diem: '' ;

cin >>this → m;

}Nh v y có th k t lu n r ng: Ph ng th c bao gi cũng có ít nh t m t đ i là con tr this vàư ậ ể ế ậ ằ ươ ứ ờ ấ ộ ố ỏ nó luôn luôn là đ i đ u tiên c a ph ng th c.ố ầ ủ ươ ứ

Tham s ng v i đ i con tr thisố ứ ớ ố ỏXét m t l i g i t i ph ng th c nhapsl() :ộ ờ ọ ớ ươ ứ

DIEM d1;

d1.nhapsl() ;Trong tr ng h p này tham s truy n cho con tr this chính là đ a ch c a d1:ườ ợ ố ề ỏ ị ỉ ủ

this = &d1Do đó:

this → x chính là d1.x

this → y chính là d1.y

this → m chính là d1.mNh v y câu l nh:ư ậ ệ d1.nhapsl() ;s nh p d li u cho các thu c tính c a đ i t ng d1. T đóẽ ậ ữ ệ ộ ủ ố ượ ừ có th rút ra k t lu n sau:ể ế ậ

Tham s truy n cho đ i con tr this chính là đ a ch c a đ i t ng đi kèm v i ph ng th cố ề ố ỏ ị ỉ ủ ố ượ ớ ươ ứ trong l i g i ph ng th c.ờ ọ ươ ứ

Các đ i khác c a ph ng th cố ủ ươ ứNgoài đ i đ c bi t this (đ i này không xu t hi n m t cách t ng minh), ph ng th c còn cóố ặ ệ ố ấ ệ ộ ườ ươ ứ các đ i khác đ c khai báo th trong các hàm. Đ i c a ph ng th c có th cóki u b t kỳố ượ ư ố ủ ươ ứ ể ể ấ (chu n và ngoài chu n).ẩ ẩ

Page 219: Giao Trinh C++ Toan Tap

Ví d đ xây d ng ph ng th c v đ ng th ng qua 2 đi m ta c n đ a vào 3 đ i: Hai đ i làụ ể ự ươ ứ ẽ ườ ẳ ể ầ ư ố ố 2 bi n ki u DIEM, đ i th ba ki u nguyên xác đ nh mã m u. Vì đã có đ i ng m đ nh this làế ể ố ứ ể ị ầ ố ầ ị đ i th nh t, nên ch c n khai báo thêm 2 đ i. Ph ng th c có th vi t nh sau:ố ứ ấ ỉ ầ ố ươ ứ ể ế ư

void DIEM::doan_thang(DIEM d2, int mau)

{

int mau_ht;

mau_ht = getcolor();

setcolor(mau);

line(this → x, this → y,d2.x,d2.y);

setcolor(mau_ht);

}Ch ng trình sau minh ho các ph ng th c có nhi u đ i. Ta v n dùng l p DIEM nh ng cóươ ạ ươ ứ ề ố ẫ ớ ư m t s thay đ i:ộ ố ổ

B thu c tính m (m u)ỏ ộ ầ

B các ph ng th c ỏ ươ ứ hien và an

Đ a vào 4 ph ng th c m i:ư ươ ứ ớ

ve_doan_thang (V đo n th ng qua 2 đi m)ẽ ạ ẳ ể

ve_tam_giac (V tam giác qua 3 đi m)ẽ ể

do_dai (Tính đ dài c a đo n th ng qua 2 đi m)ộ ủ ạ ẳ ể

chu_vi (Tính chu vi tam giác qua 3 đi m)ểCh ng trình còn minh ho :ươ ạ

Vi c ph ng th c này s d ng ph ng th c khác (ph ng th c ve_tam_giac s d ngệ ươ ứ ử ụ ươ ứ ươ ứ ử ụ ph ng th c ve_doan_thang, ph ng th c chu_vi s d ng ph ng th c do_dai)ươ ứ ươ ứ ử ụ ươ ứ

S d ng con tr this trong thân các ph ng th c ve_tam_giac và chu_viử ụ ỏ ươ ứN i dung ch ng trình là nh p 3 đi m, v tam giác có đ nh là 3 đi m v a nh p sau đó tínhộ ươ ậ ể ẽ ỉ ể ừ ậ chu vi tam giác.

#include <conio.h>

#include <iostream.h>

#include <graphics.h>

#include <math.h>

#include <stdio.h>

class DIEM

{

Page 220: Giao Trinh C++ Toan Tap

private:

int x, y ;

public:

void nhapsl();

void ve_doan_thang(DIEM d2, int mau) ;

void ve_tam_giac(DIEM d2, DIEM d3,int mau) ;

double do_dai(DIEM d2)

{

DIEM d1 = *this ;

return sqrt(pow(d1.x - d2.x,2) + pow(d1.y - d2.y,2) ) ;

}

double chu_vi(DIEM d2, DIEM d3);

};

void DIEM::nhapsl()

{

cout <<'' \n Nhap hoanh do (cot) va tung do (hang) cua diem:'' ;

cin >> x >> y;

}

void kd_do_hoa()

{

int mh, mode ;

mh=mode=0;

initgraph(&mh, &mode, '''');

}

void DIEM::ve_doan_thang(DIEM d2, int mau)

{

setcolor(mau);

line(this → x,this → y,d2.x,d2.y);

}

void DIEM:: ve_tam_giac(DIEM d2, DIEM d3,int mau)

Page 221: Giao Trinh C++ Toan Tap

{

(*this).ve_doan_thang(d2,mau);

d2.ve_doan_thang(d3,mau);

d3.ve_doan_thang(*this,mau);

}

double DIEM:: chu_vi(DIEM d2, DIEM d3)

{

double s;

s=(*this).do_dai(d2)+ d2.do_dai(d3) + d3.do_dai(*this) ;

return s;

}

void main()

{

DIEM d1, d2, d3;

char tb_cv[20] ;

d1.nhapsl();

d2.nhapsl();

d3.nhapsl();

kd_do_hoa();

d1.ve_tam_giac(d2,d3,15);

double s = d1.chu_vi(d2,d3);

sprintf(tb_cv, "chu_vi = %0.2f", s);

outtextxy(10,10,tb_cv);

getch();

closegraph();

}M t s nh n xét v đ i c a ph ng th c và l i g i ph ng th c:ộ ố ậ ề ố ủ ươ ứ ờ ọ ươ ứ

Quan sát nguyên m u ph ng th c:ẫ ươ ứ

void ve_doan_thang(DIEM d2, int mau) ;s th y ph ng th c có 3 đ i:ẽ ấ ươ ứ ố

Đ i th nh t là m t đ i t ng DIEM do this tr t iố ứ ấ ộ ố ượ ỏ ớ

Đ i th hai là đ i t ng DIEM d2ố ứ ố ượ

Page 222: Giao Trinh C++ Toan Tap

Đ i th ba là bi n nguyên m uố ứ ế ẫ

N i dung ph ng th c là v m t đo n th ng đi qua các đi m *this và d2 theo mã m u mau.ộ ươ ứ ẽ ộ ạ ẳ ể ầ Xem thân c a ph ng s th y đ c n i dung này:ủ ươ ẽ ấ ượ ộ

void DIEM::ve_doan_thang(DIEM d2, int mau) ;

{

setcolor(mau);

line(this → x,this → y,d2.x,d2.y);

}Tuy nhiên trong tr ng h p này, vai trò c a this không cao l m, vì nó đ c đ a vào ch c tườ ợ ủ ắ ượ ư ỉ ố làm rõ đ i th nh t. Trong thân ph ng th c có th b t khóa this v n đ c.ố ứ ấ ươ ứ ể ỏ ừ ẫ ượ

Vai trò c a this tr nên quan tr ng trong ph ng th c ve_tam_giac:ủ ở ọ ươ ứ

voidve_tam_giac(DIEM d2, DIEM d3, int mau)Ph ng th c này có 4 đ i là:ươ ứ ố

this : tr t i m t đ i t ng ki u DIEMỏ ớ ộ ố ượ ể

d2 : m t đ i t ng ki u DIEMộ ố ượ ể

d3 : m t đ i t ng ki u DIEMộ ố ượ ể

mau : m t bi n nguyênộ ế

N i dung ph ng th c là v 3 c nh:ộ ươ ứ ẽ ạ

c nh 1 đi qua *this và d2ạ

c nh 2 đi qua d2 và d3ạ

c nh 3 đi qua d3 và *thisạCác c nh trên đu c v nh s d ng ph ng th c ve_doan_thang:ạ ợ ẽ ờ ử ụ ươ ứ

V c nh 1 dùng l nh: (*this).ve_doan_thang(d2,mau) ; ẽ ạ ệ

V c nh 2 dùng l nh: d2.ve_doan_thang(d3,mau); ẽ ạ ệ

V c nh 3 dùng l nh: d3.ve_doan_thang(*this,mau); ẽ ạ ệTrong tr ng này rõ ràng vai trò c a this r t quan tr ng. N u không dùng nó thì công vi c trườ ủ ấ ọ ế ệ ở nên khó khăn, dài dòng và khó hi u h n. Chúng ta hãy so sánh 2 ph ng án:ể ơ ươ

Ph ng án dùng this trong ph ng th c ve_tam_giac:ươ ươ ứ

void DIEM::ve_tam_giac(DIEM d2, DIEM d3, int mau)

{

(*this).ve_doan_thang(d2,mau);

Page 223: Giao Trinh C++ Toan Tap

d2.ve_doan_thang(d3,mau); d3.ve_doan_thang(*this,mau);

}ph ng án không dùng this trong ph ng th c ve_tam_giac:ươ ươ ứ

void DIEM::ve_tam_giac(DIEM d2, DIEM d3, int mau)

{

DIEM d1;

d1.x = x; d1.y = y;

d1.ve_doan_thang(d2,mau);

d2.ve_doan_thang(d3,mau);

d3.ve_doan_thang(d1,mau);

}

HÀM T O (Constructor)Ạ

Hàm t o (hàm thi t l p)ạ ế ậHàm t o cũng là m t ph ng th c c a l p (nh ng là hàm đ c bi t) dùng đ t o d ngạ ộ ươ ứ ủ ớ ư ặ ệ ể ạ ự

m t đ i t ng m i. Ch ng trình d ch s c p phát b nh cho đ i t ng sau đó s g i đ nộ ố ượ ớ ươ ị ẽ ấ ộ ớ ố ượ ẽ ọ ế hàm t o. Hàm t o s kh i gán giá tr cho các thu c tính c a đ i t ng và có th th c hi nạ ạ ẽ ở ị ộ ủ ố ượ ể ự ệ m t s công vi c khác nh m chu n b cho đ i t ng m i.ộ ố ệ ằ ẩ ị ố ượ ớ

Cách vi t hàm t oế ạ

Đi m khác c a hàm t o và các ph ng th c thông th ng:ể ủ ạ ươ ứ ườKhi vi t hàm t o c n đ ý 3 s khác bi t c a hàm t o so v i các ph ng th c khác nhế ạ ầ ể ự ệ ủ ạ ớ ươ ứ ư

sau:

Tên c a hàm t o: Tên c a hàm t o b t bu c ph i trùng v i tên c a l p.ủ ạ ủ ạ ắ ộ ả ớ ủ ớ

Không khai báo ki u cho hàm t o.ể ạ

Hàm t o không có k t qu tr v .ạ ế ả ả ề

S gi ng nhau c a hàm t o và các ph ng th c thông th ngự ố ủ ạ ươ ứ ườNgoài 3 đi m khác bi t trên, hàm t o đ c vi t nh các ph ng th c khác:ể ệ ạ ượ ế ư ươ ứ

Hàm t o có th đ c xây d ng bên trong ho c bên ngoài đ nh nghĩa l p.ạ ể ượ ự ặ ị ớ

Hàm t o có th có đ i ho c không có đ i.ạ ể ố ặ ố

Trong m t l p có th có nhi u hàm t o (cùng tên nh ng khác b đ i).ộ ớ ể ề ạ ư ộ ốVí d sau đ nh nghĩa l p DIEM_DH (Đi m đ h a) có 3 thu c tính:ụ ị ớ ể ồ ọ ộ

int x; // hoành đ (c t) c a đi mộ ộ ủ ể

int y; // tung đ (hàng) c a đi mộ ủ ể

int m; // m u c a đi mầ ủ ể

Page 224: Giao Trinh C++ Toan Tap

và đ a vào 2 hàm t o đ kh i gán cho các thu c tính c a l p:ư ạ ể ở ộ ủ ớ

// Hàm t o không đ i: Dùng các giá tr c đ nh đ kh i gán cho x, y, mạ ố ị ố ị ể ở

DIEM_DH() ;

// Hàm t o có đ i: Dùng các đ i x1, y1, m1 đ kh i gán cho x, y, mạ ố ố ể ở

DIEM_DH(int x1, int y1, int m1 = 15) ; // Đ i m1 có giá tr m c đ nh 15ố ị ặ ị

class DIEM_DH // (m u tr ng)ầ ắ

{

private:

int x, y, m ;

public:

// Hàm t o không đ i: kh i gán cho x = 0, y = 0, m = 1ạ ố ở

// Hàm này vi t bên trong đ nh nghĩa l pế ị ớ

DlEM_DH()

{

x = y = 0;

m = 1;

}

// Hàm t o này xây d ng bên ngoài đ nh nghĩa l pạ ự ị ớ

DIEM_DH(int x1, int y1, int m1 = 15) ;

// Các ph ng th c khácươ ứ

};

// Xây d ng hàm t o bên ngoài đ nh nghĩa l pự ạ ị ớ

DIEM_DH:: DIEM_DH(int x1, int y1, int m1) ;

{

x = x1; y = y1; m = m1;

}

Dùng hàm t o trong khai báoạ

Khi đã xây d ng các hàm t o, ta có th dùng chúng trong khai báo đ t o ra m t đ iự ạ ể ể ạ ộ ố t ng đ ng th i kh i gán cho các thu c tính c a đ i t ng đ c t o. D a vào cácượ ồ ờ ở ộ ủ ố ượ ượ ạ ự tham s trong khai báo mà trình biên d ch s bi t c n g i đ n hàm t o nào.ố ị ẽ ế ầ ọ ế ạ

Khi khai báo m t bi n đ i t ng có th s d ng các tham s đ kh i gán cho các thu cộ ế ố ượ ể ử ụ ố ể ở ộ tính c a bi n đ i t ng.ủ ế ố ượ

Page 225: Giao Trinh C++ Toan Tap

Khi khai báo m ng đ i t ng không cho phép dùng các tham s đ kh i gán.ả ố ượ ố ể ở

Câu l nh khai báo m t bi n đ i t ng s g i t i hàm t o 1 l n.ệ ộ ế ố ượ ẽ ọ ớ ạ ầ

Câu l nh khai báo m t m ng n đ i t ng s g i t i hàm t o n l n. ệ ộ ả ố ượ ẽ ọ ớ ạ ầVí d :ụ

DIEM_DH d; // G i t i hàm t o không đ i.ọ ớ ạ ố // K t qu d.x = 0, d.y = 0, d.m = 1ế ả

DIEM_DH u(300, 100, 5); // G i t i hàm t o có đ i.ọ ớ ạ ố // K t qu u.x = 300, u.y = 100, d.m = 5ế ả

DIEM_DH v(400, 200); // G i t i hàm t o có đ i.ọ ớ ạ ố // K t qu v.x = 400, v.y = 200, d.m = 15ế ả

DIEM_DH p[20] ; // G i t i hàm t o không đ i 20 l nọ ớ ạ ố ầChú ý: V i các hàm có đ i ki u l p, thì đ i ch xem là các tham s hình th c, vì v y khai báoớ ố ể ớ ố ỉ ố ứ ậ đ i (trong dòng đ u c a hàm) s không t o ra đ i t ng m i và do đó không g i t i các hàmố ầ ủ ẽ ạ ố ượ ớ ọ ớ t o.ạ

Dùng hàm t o trong c p phát b nhạ ấ ộ ớ

Khi c p phát b nh cho m t đ i t ng có th dùng các tham s đ kh i gán cho cácấ ộ ớ ộ ố ượ ể ố ể ở thu c tính c a đ i t ng, ví dộ ủ ố ượ ụ

DIEM_DH *q = new DIEM_DH(40, 20, 4); // G i t i hàm t o có đ iọ ớ ạ ố // K t qu q ế ả → x = 40, q → y = 20, q → m = 4

DIEM_DH *r = new DIEM_DH ; //G i t i hàm t o không đ iọ ớ ạ ố // K t qu r ế ả → x = 0, r → y = 0, r → m = 1

Khi c p phát b nh cho m t dãy đ i t ng không cho phép dùng tham s đ kh i gán,ấ ộ ớ ộ ố ượ ố ể ở ví d :ụ

int n = 30;

DIEM_DH *s = new DlEM_DH[n] ; // G i t i hàm t o không đ i 30 l n.ọ ớ ạ ố ầ

Dùng hàm t o đ bi u đi n các đ i t ng h ngạ ể ể ề ố ượ ằ

Nh đã bi t, sau khi đ nh nghĩa l p DIEM_DH thì có th xem l p này nh ư ế ị ớ ể ớ ư m tộ ki u dể ữ li u nh int, double, char, ...ệ ư

V i ki u int chúng ta có các h ng int, nh 253.ớ ể ằ ư

V i ki u double chúng ta có các h ng double, nh 75.42ớ ể ằ ư

Khái ni m h ng ki u int, h ng ki u double có th m r ng cho h ng ki u DIEM_DH ệ ằ ể ằ ể ể ở ộ ằ ể

Đ bi u di n m t h ng đ i t ng (hay còn g i: Đ i t ng h ng) chúng ta ph i dùngể ể ễ ộ ằ ố ượ ọ ố ượ ằ ả t i hàm t o. M u vi t nh sau:ớ ạ ẫ ế ư

Page 226: Giao Trinh C++ Toan Tap

Tên_l p(danh sách tham s ) ; ớ ốVí d đ i v i l p DIEM_DH nói trên, có th vi t nh sau:ụ ố ớ ớ ể ế ư

DIEM_DH(234, l 23, 4) // Bi u th m t đ i t ng ki u DIEM_DHể ị ộ ố ượ ể

// có các thu c tính x = 234, y = 123, ộ m = 4Chú ý: Có th s d ng m t h ng đ i t ng nh m t đ i t ng. Nói cách khác, có th dùngể ử ụ ộ ằ ố ượ ư ộ ố ượ ể h ng đ i t ng đ th c hi n m t ph ng th c, ví d n u vi t:ằ ố ượ ể ự ệ ộ ươ ứ ụ ế ế

DIEM_DH(234, l 23, 4).in(); thì có nghĩa là th c hi n ph ng th c in() đ i v i h ng đ i t ng.ự ệ ươ ứ ố ớ ằ ố ượ

Ví d minh h aụ ọCh ng trình sau đây minh h a cách xây d ng hàm t o và cách s dùng hàm t o trongươ ọ ự ạ ử ạ

khai báo, trong c p phát b nh và trong vi c bi u di n các h ng đ i t ng.ấ ộ ớ ệ ể ễ ằ ố ượ

#include <conio.h>

#include <iostream.h>

#include <iomanip.h>

class DIEM_DH

{

private:

int x, y, m;

public:

// Hàm b n dùng đ in đ i t ng DIEM_DHạ ể ố ượ

friend void in(DIEM_DH d)

{

cout <<"\n '' << d.x << '' ''<< d.y<<" " << d.m ;

}

// Ph ng th c dùng đ in đ i t ng DIEM_DHươ ứ ể ố ượ

void in()

{

cout <<''\n '' << x << '' ''<< y<<" " << m ;

}

// Hàm t o không đ iạ ố

DIEM_DH()

{

x = y = 0;

Page 227: Giao Trinh C++ Toan Tap

m = 1;

}

// Hàm t o có đ i, đ i m1 có giá trí m c đ nh là 15 ạ ố ố ặ ị (m u ầ tr ng)ắ

DIEM_DH(int x1, int y1, int m1 = 15);

};

// Xây d ng hàm t oự ạ

DIEM_DH::DIEM_DH(int x1, int y1, int m1)

{

x = x1; y = y1; m = m1;

}

void main()

{

DIEM_DH d1; // G i t i hàm t o không đ iọ ớ ạ ố

DIEM_DH d2(200, 200, 10); // G i t i hàm t o có đ iọ ớ ạ ố

DIEM_DH*d;

d = new DIEM_DH(300, 300); // G i t i hàm t o có đ iọ ớ ạ ố

clrscr();

in(d1); //G i hàm b n in()ọ ạ

d2.in(); //G i ph ng th c in()ọ ươ ứ

in(*d); // G i hàm b n in()ọ ạ

DIEM_DH(2, 2, 2).in(); // G i ph ng th c in()ọ ươ ứ

DIEM_DH t[3]; // 3 l n g i hàm t o không đ iầ ọ ạ ố

DIEM_DH*q; // G i hàm t o không đ iọ ạ ố

int n;

cout << "\n N = "; cin >> n;

q = new DIEM_DH[n+1]; // (n+1) l n g i hàm t o không đ iầ ọ ạ ố

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

q[i] = DIEM_DH(300+i, 200+i, 8); //(n+1) l n g i hàm t o có đ iầ ọ ạ ố

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

q[i].in(); // G i ph ng th c in()ọ ươ ứ

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

Page 228: Giao Trinh C++ Toan Tap

DIEM_DH(300+i, 200+i, 8).in(); // G i ph ng th c in()ọ ươ ứ

getch();

}

L p không có hàm t o và hàm t o m c đ nhớ ạ ạ ặ ị

N u l p không có hàm t oế ớ ạCh ng trình d ch s cung c p m t hàm t o m c đ nh không đ i (default), hàm này th cươ ị ẽ ấ ộ ạ ặ ị ố ự

ch t không làm gì c . Nh v y m t đ i t ng t o ra ch đ c c p phát b nh , còn các thu cấ ả ư ậ ộ ố ượ ạ ỉ ượ ấ ộ ớ ộ tính c a nó ch a đ c xác đ nh. Chúng ta có th ki m ch ng đi u này, b ng cách ch yủ ư ượ ị ể ể ứ ề ằ ạ ch ng trình sau:ươ

// Hàm t o m c đ nhạ ặ ị

#include <conio.h>

#include <iostream.h>

class DIEM_DH

{

private:

int x, y, m;

public:

// Ph ng th cươ ứ

void in() { cout <<"\n '' << x << '' ''<< y<<'' " << m ; }

};

void main()

{

DIEM_DH d;

d.in();

DIEM_DH *p;

p = new DIEM_DH[10];

clrscr();

d.in();

for (int i = 0; i<10; ++i) (p+i)->in();

getch();

}

Page 229: Giao Trinh C++ Toan Tap

N u trong l p đã có ít nh t m t hàm t oế ớ ấ ộ ạKhi đó hàm t o m c đ nh s không đ c phát sinh n a và m i câu l nh xây d ng đ iạ ặ ị ẽ ượ ữ ọ ệ ự ố

t ng m i đ u s g i đ n m t hàm t o c a l p. N u không tìm th y hàm t o c n g i thìượ ớ ề ẽ ọ ế ộ ạ ủ ớ ế ấ ạ ầ ọ ch ng trình d ch s báo l i. Đi u này th ng x y ra khi chúng ta không xây d ng hàm t oươ ị ẽ ỗ ề ườ ẩ ự ạ không đ i, nh ng l i s d ng các khai báo không tham s nh ví d sau:ố ư ạ ử ụ ố ư ụ

#include <conio.h>

#include <iostream.h>

class DIEM_DH

{

private:

int x, y, m;

public:

// Ph ng th c dùng đ in đ i t ng DIEM_DHươ ứ ể ố ượ

void in()

{

cout <<"\n'' << x << " "<< y<<" " << m ;

}

//Hàm t o có đ iạ ố

DIEM_DH::DIEM_DH(int x1, int y1 , int m1)

{

x = x1; y = y1 ; m = m1;

}

};

void main()

{

DIEM_DH d1(200, 200, 10); // G i t i hàm t o có đ iọ ớ ạ ố

DIEM_DH d2; // G i t i hàm t o không đ iọ ớ ạ ố

d2 = DIEM_DH(300, 300, 8); // G i t i hàm t o có đ iọ ớ ạ ố

d1.in();

d2.in();

getch();

}

Page 230: Giao Trinh C++ Toan Tap

Trong các câu l nh trên, ch có câu l nh th 2 trong hàm main() là b báo l i. Câu l nh này sệ ỉ ệ ứ ị ỗ ệ ẽ g i t i hàm t o không đ i, mà hàm này ch a đ c xây d ng.ọ ớ ạ ố ư ượ ự

Gi i pháp: cóả th ch n m t trong 2 gi i pháp sau:ể ọ ộ ả

Xây d ng thêm hàm t o không đ i.ự ạ ố

Gán giá tr m c đ nh cho t t c các đ i x1, y1 và m1 c a hàm t o đã xây d ng trên. ị ặ ị ấ ả ố ủ ạ ự ởTheo ph ng án 2, ch ng trình có th s a nh sau:ươ ươ ể ử ư

#include <conio.h>

#include <iostream.h>

class DIEM_DH

{

private:

int x, y, m;

public:

// Ph ng th c dùng đ in đ i t ng DIEM_DHươ ứ ể ố ượ

void in() { cout <<''\n '' << x << " "<< y<<" " << m ; }

// Hàm t o có đ i , t t c các đ i đ u có giá tr m c đ nhạ ố ấ ả ố ề ị ặ ị

DIEM_DH::DIEM_DH(int x1 = 0, int y1 = 0, int m1 = 15)

{

x = x1; y = y1; m = m1;

}

};

void main()

{

// G i t i hàm t o, không dùng tham s m c đ nhọ ớ ạ ố ặ ị

DIEM_DH d1(200, 200, 10);

// G i t i hàm t o, dùng 3 tham s m c đ nhọ ớ ạ ố ặ ị

DIEM_DH d2;

// G i t i hàm t o, dùng 1 tham s m c đ nhọ ớ ạ ố ặ ị

d2 = DIEM_DH(300, 300);

d1.in();

d2.in();

Page 231: Giao Trinh C++ Toan Tap

getch();

}

Hàm t o sao chép (Copy Constructor)ạ

Hàm t o sao chép m c đ nhạ ặ ịGi s đã đ nh nghĩa m t l p nào đó, ví d l p PS (phân s ). Khi đó:ả ử ị ộ ớ ụ ớ ố

Ta có th dùng câu l nh khai báo ho c c p phát b nh đ t o các đ i t ng m i, víể ệ ặ ấ ộ ớ ể ạ ố ượ ớ d :ụ

PS p1, p2 ;

PS *p = new PS ;

Ta cũng có th dùng l nh khai báo đ t o m t đ i t ng m i t m t đ i t ng đã t nể ệ ể ạ ộ ố ượ ớ ừ ộ ố ượ ồ t i, ví d :ạ ụ

PS u;

PS v(u) ; // T o v theo u ạý nghĩa c a câu l nh này nh sau:ủ ệ ư

N u trong l p PS ch a xây d ng hàm t o sao chép, thì câu l nh này s g i t i m t hàmế ớ ư ự ạ ệ ẽ ọ ớ ộ t o sao chép m c đ nh (c a C++). Hàm này s sao chép n i dung t ng bit c a u vàoạ ặ ị ủ ẽ ộ ừ ủ các bit t ng ng c a v. Nh v y các vùng nh c a u và v s có n i dung nh nhau.ươ ứ ủ ư ậ ớ ủ ẽ ộ ư Rõ ràng trong đa s các tr ng h p, n u l p không có các thu c tính ki u con trố ườ ợ ế ớ ộ ể ỏ hay tham chi u, thì vi c dùng các hàm t o sao chép m c đ nh (đ t o ra m t đ iế ệ ạ ặ ị ể ạ ộ ố t ng m i có n i dung nh m t đ i t ng cho tr c) là đ và không c n xây d ngượ ớ ộ ư ộ ố ượ ướ ủ ầ ự m t hàm t o sao chép m i.ộ ạ ớ

N u trong l p PS đã có hàm t o sao chép (cách vi t s nói sau) thì câu l nh: PS v(u); ế ớ ạ ế ẽ ệ sẽ t o ra đ i t ng m i v, sau đó g i t i hàm t o sao chép đ kh i gán v theo u.ạ ố ượ ớ ọ ớ ạ ể ở

Ví d sau s minh h a cách dùng hàm t o sao chép m c đ nh:ụ ẽ ọ ạ ặ ị

Trong ch ng trình đ a vào l p PS (phân s ):ươ ư ớ ố

Các thu c tính g m: t (t s ) và m (m u).ộ ồ ử ố ẫ

Trong l p không có ph ng th c nào c mà ch có 2 hàm b n là các hàm toán t nh pớ ươ ứ ả ỉ ạ ử ậ (>>) và xu t (<<). ấ

N i dung ch ng trình là: Dùng l nh khai báo đ t o m t đ i t ng u (ki u PS) có n iộ ươ ệ ể ạ ộ ố ượ ể ộ dung nh đ i t ng đã có d.ư ố ượ

// Ham tao sao chep mac dinh

#include <conio.h>

#include <iostream.h>

class PS

{

Page 232: Giao Trinh C++ Toan Tap

private:

int t, m ;

public:

friend ostream& operator<< (ostream&os, const PS &p)

{

os << " = " << p.t << "/" << p.m;

return os;

}

friend istream& operator>> (istream& is, PS &p)

{

cout << "\n Nhap tu va mau: " ;

is >> p.t >> p.m ;

return is;

}

} ;

void main()

{

PS d;

cout << "\n Nhap PS d "; cin >> d;

cout << "\n PS d " << d;

PS u(d);

cout << "\n PS u "<< u;

getch();

}

Cách xây d ng hàm t o sao chépự ạ

Hàm t o sao chép s d ng m t đ i ki u tham chi u đ i t ng đ kh i gán cho đ iạ ử ụ ộ ố ể ế ố ượ ể ở ố t ng m i. Hàm t o sao chép đ c vi t theo m u:ượ ớ ạ ượ ế ẫ

Tên_l p (const Tên_l p & dt)ớ ớ

{

// Các câu l nh dùng các thu c tính c a đ i t ng dtệ ộ ủ ố ượ

// đ kh i gán cho các thu c tính c a đ i t ng m iể ở ộ ủ ố ượ ớ

}

Page 233: Giao Trinh C++ Toan Tap

Ví d có th xây d ng hàm t o sao chép cho l p PS nh sau:ụ ể ự ạ ớ ư

class PS

{

private:

int t, m ;

public:

PS (const PS &p)

{

this->t = p.t ;

this->m = p.m ;

}

...

} ;

Khi nào c n xây d ng hàm t o sao chépầ ự ạ

Nh n xét: Hàm t o sao chép trong ví d trên không khác gì hàm t o sao chép m c đ nh.ậ ạ ụ ạ ặ ị

Khi l p không có các thu c tính ki u con tr ho c tham chi u, thì dùng hàm t o saoớ ộ ể ỏ ặ ế ạ chép m c đ nh là đ . ặ ị ủ

Khi l p có các thu c tính con tr ho c tham chi u, thì hàm t o sao chép m c đ nh ch aớ ộ ỏ ặ ế ạ ặ ị ư đáp ng đ c yêu c u. ứ ượ ầ

Ví d :ụ

class DT

{

private:

int n; // Bac da thuc

double *a; // Tro toi vung nho chua cac he so da thuc a0, a1, ...

public:

DT() { this->n0; this->a = NULL; }

DT(int n1)

{

this->n = n1;

this->a = new double[n1+1];

}

friend ostream& operator << (ostream& os, const DT &d);

Page 234: Giao Trinh C++ Toan Tap

friend istream& operator>> (istream& is, DT &d);

...

} ; Bây gi chúng ta hãy theo dõi xem vi c dùng hàm t o m c đ nh trong đo n ch ng trình sauờ ệ ạ ặ ị ạ ươ s d n đ n sai l m nh th nào:ẽ ẫ ế ầ ư ế

DT d ; // T o đ i t ng d ki u DTạ ố ượ ể

cin >> d ; /* Nh p đ i t ng d, g m: nh p m t s nguyên d ng và gán cho d.n, c p phát vùng nhậ ố ượ ồ ậ ộ ố ươ ấ ớ cho d.a, nh p các h s c a đa th c và ch a vào vùng nh đ c c p phát */ậ ệ ố ủ ứ ứ ớ ượ ấ

DT u(d); /* Dùng hàm t o m c đ nh đ xây d ng đ i t ng u theo d. K t qu : u.n = d.n và u.a = d.a.ạ ặ ị ể ự ố ượ ế ả Nh v y 2 con tr u.a và d.a cùng tr đ n m t vùng nh */ ư ậ ỏ ỏ ế ộ ớ

Nh n xét:ậ M c đích là t o ra m t đ i t ng u gi ng nh d, nh ng đ c l p v i d. Nghĩa là khiụ ạ ộ ố ượ ố ư ư ộ ậ ớ d thay đ i thì u không b nh h ng gì. Th nh ng m c tiêu này không đ t đ c, vì u và d cóổ ị ả ưở ế ư ụ ạ ượ chung m t vùng nh ch a h s c a đa th c, nên khi s a đ i các h s c a đa th c trong d thìộ ớ ứ ệ ố ủ ứ ử ổ ệ ố ủ ứ các h s c a đa th c trong u cũng thay đ i theo. Còn m t tr ng h p n a cũng d n đ n l iệ ố ủ ứ ổ ộ ườ ợ ữ ẫ ế ỗ là khi m t trong 2 đ i t ng u và d b gi i phóng (thu h i vùng nh ch a đa th c) thì đ iộ ố ượ ị ả ồ ớ ứ ứ ố t ng còn l i cũng s không còn vùng nh n a.ượ ạ ẽ ớ ữ

Ví d sau s minh h a nh n xét trên: Khi d thay đ i thì u cũng thay đ i và ng c l i khi uụ ẽ ọ ậ ổ ổ ượ ạ thay đ i thì d cũng thay đ i theo.ổ ổ

#include <conio.h>

#include <iostream.h>

#include <math.h>

class DT

{

private:

int n; // Bac da thuc

double *a; // Tro t i vung nho chua cac he so da thuc a0, a1 , ...ơ

public:

DT() { this->n = 0; this->a = NULL; }

DT(int n1)

{

this->n = n1 ;

this->a = new double[n1+1];

Page 235: Giao Trinh C++ Toan Tap

}

friend ostream& operator<< (ostream& os, const DT &d);

friend istream& operator>> (istream& is, DT &d);

} ;

ostream& operator<< (ostream& os, const DT &d)

{

os << " Cac he so (tu ao): ";

for (int i = 0 ; i< = d.n ; ++i)

os << d.a[i] <<" " ;

return os;

}

istream& operator >> (istream& is, DT &d)

{

if (d.a! = NULL) delete d.a;

cout << " \n Bac da thuc: " ;

cin >> d.n;

d.a = new double[d.n+1];

cout << ''Nhap cac he so da thuc:\n" ;

for (int i = 0 ; i< = d.n ; ++i)

{

cout << "He so bac "<< i << " = " ;

is >> d.a[i] ;

}

return is;

}

void main()

{

DT d;

clrscr();

cout <<"\n Nhap da thuc d " ; cin >> d;

Page 236: Giao Trinh C++ Toan Tap

DT u(d);

cout << "\n Da thuc d "<< d ;

cout << "\n Da thuc u " << u ;

cout <<"\n Nhap da thuc d " ; cin >> d;

cout << "\nDa thuc d " << d;

cout <<"\n Da thuc u " << u ;

cout <<"\n Nhap da thuc u " ; cin >> u;

cout << "\n Da thuc d "<< d ;

cout << "\n Da thuc u " << u ;

getch();

}

Ví d v hàm t o sao chépụ ề ạ

Trong ch ng trình trên đã ch rõ: Hàm t o sao chép m c đ nh là ch a thoươ ỉ ạ ặ ị ư ả mãn đ i v i l p DT. Vì v y c n vi t hàm t o sao chép đ xây d ng đ i t ngố ớ ớ ậ ầ ế ạ ể ự ố ượ m i (ví d u) t m t đ i t ng đang t n t i (ví d d) theo các yêu c u sau:ớ ụ ừ ộ ố ượ ồ ạ ụ ầ

Gán d.n cho u.n

C p phát m t vùng nh cho u.a đ có th ch a đ c (d.n + 1) h s .ấ ộ ớ ể ể ứ ượ ệ ố

Gán các h s ch a trong vùng nh c a d.a sang vùng nh c a u.aệ ố ứ ớ ủ ớ ủNh v y chúng ta s t o đ c đ i t ng u có n i dung ban đ u gi ng nh d, nh ng đ c l pư ậ ẽ ạ ượ ố ượ ộ ầ ố ư ư ộ ậ v i d.ớ

Đ đáp ng các yêu c u nêu trên, hàm t o sao chép c n đ c xây d ng nh sau:ể ứ ầ ạ ầ ượ ự ư

DT::DT(const DT &d)

{

this → n = d.n ;

this → a = new double[d.n+1];

for (int i = 0; i< = d.n; ++i)

this → a[i] = d.a[i];

}Ch ng trình sau s minh h a đi u này: S thay đ i c a d không làm nh h ng đ n u vàươ ẽ ọ ề ự ổ ủ ả ưở ế ng c l i s thay đ i c a u không làm nh h ng đ n d.ượ ạ ự ổ ủ ả ưở ế

// Vi t hàm t o sao chép cho l p DTế ạ ớ

#include <conio.h>

#include <iostream.h>

Page 237: Giao Trinh C++ Toan Tap

#include <math.h>

class DT

{

private:

int n; // Bac da thuc

double *a; // Tro toi vung nho chua cac he so da thuc a0, a1 , ...

public:

DT() { this → n = 0; this → a = NULL; }

DT(int n1)

{

this → n = n1 ;

this → a = new double[n1+1];

}

DT(const DT &d);

friend ostream& operator<< (ostream& os, const DT&d);

friend istream& operator>> (istream& is, DT&d);

};

DT::DT(const DT&d)

{

this → n = d.n;

this → a = new double[d.n+1];

for (int i = 0; i< = d.n; ++i)

this → a[i] = d.a[i];

}

ostream& operator<< (ostream& os, const DT &d)

{

os << " Cac he so (tu ao): " ;

for (int i = 0 ; i< = d.n ; ++i) os << d.a[ i] <<" " ;

return os;

}

Page 238: Giao Trinh C++ Toan Tap

istream& operator>> (istream& is, DT &d)

{

if (d.a! = NULL) delete d.a;

cout << "\n Bac da thuc: '' ;

cin >> d.n;

d.a = new double[d.n+1];

cout << ''Nhap cac he so da thuc:\n'' ;

for (int i = 0 ; i< = d.n ; ++i)

{

cout << "He so bac " << i << " = " ;

is >> d.a[i] ;

}

return is;

}

void main()

{

DT d;

clrscr();

cout <<"\n Nhap da thuc d " ; cin >> d;

DT u(d);

cout <<"\n Da thuc d " << d ;

cout << "\n Da thuc u " << u ;

cout <<"\n Nhap da thuc d " ; cin >> d;

cout << "\n Da thuc d "<< d ;

cout <<"\n Da thuc u " << u ;

cout <<"\n Nhap da thuc u " ; cin >> u;

cout << "\n Da thuc d " << d ;

cout <<"\n Da thuc u " << u ;

getch();

}

Page 239: Giao Trinh C++ Toan Tap

HÀM H Y (Destructor)Ủ

Hàm h y là m t hàm thành viên c a l p (ph ng th c) có ch c năng ng c v i hàm t o.ủ ộ ủ ớ ươ ứ ứ ượ ớ ạ Hàm h y đ c g i tr c khi gi i phóng (xoá b ) m t đ i t ng đ th c hi n m t s côngủ ượ ọ ướ ả ỏ ộ ố ượ ể ự ệ ộ ố vi c có tính ''d n d p'' tr c khi đ i t ng đ c h y b , ví d nh gi i phóng m t vùng nhệ ọ ẹ ướ ố ượ ượ ủ ỏ ụ ư ả ộ ớ mà đ i t ng đang qu n lý, xoá đ i t ng kh i ố ượ ả ố ượ ỏ màn hình n u nh nó đang hi n th , ...ế ư ể ị

Vi c h y b m t đ i t ng th ng x y ra trong 2 tr ng h p sau:ệ ủ ỏ ộ ố ượ ườ ẩ ườ ợ

Trong các toán t và các hàm gi i phóng b nh , nh delete, free, ...ử ả ộ ớ ư

Gi i phóng các bi n, m ng c c b khi thoát kh i hàm, ph ng th c.ả ế ả ụ ộ ỏ ươ ứ

Hàm h y m c đ nhủ ặ ịN u trong l p không đ nh nghĩa hàm h y, thì m t hàm h y m c đ nh không làm gì cế ớ ị ủ ộ ủ ặ ị ả

đ c phát sinh. Đ i v i nhi u l p thì hàm h y m c đ nh là đ , và không c n đ a vào m tượ ố ớ ề ớ ủ ặ ị ủ ầ ư ộ hàm h y m i.ủ ớ

Quy t c vi t hàm h yắ ế ủM i l p ch có m t hàm h y vi t theo các quy t c sau:ỗ ớ ỉ ộ ủ ế ắ

Ki u c a hàm: Hàm h y cũng gi ng nh hàm t o là hàm không có ki u, không có giá trể ủ ủ ố ư ạ ể ị tr v .ả ề

Tên hàm: Tên c a hàm h y g m m t d u ngã (đ ng tr c) và tên l p:ủ ủ ồ ộ ấ ứ ướ ớ

~Tên_l pớ

Đ i: Hàm h y không có đ iố ủ ốVí d có th ụ ể xây d ng hàm h y cho l p DT (đa th c) nh sau:ự ủ ớ ứ ư

class DT

{

private:

int n; // Bac da thua

double *a; // Tro toi vung nho chua cac he so da thuc a0, a1 , ...

public:

~DT()

{

this → n = 0;

delete this → a;

}

...

Page 240: Giao Trinh C++ Toan Tap

};

Vai trò c a hàm h y trong l p DTủ ủ ớTrong ph n tr cầ ướ đ nh nghĩa l p DT (đa th c) khá đ y đ g m:ị ớ ứ ầ ủ ồ

Các hàm t oạ

Các toán t nh p >>, xu t <<ử ậ ấ

Các hàm toán t th c hi n các phép tính +, -, *, /ử ự ệTuy nhiên v n còn thi u hàm h y đ gi i phóng vùng nh mà đ i t ng ki u DT (c n h y)ẫ ế ủ ể ả ớ ố ượ ể ầ ủ đang qu n lý.ả

Chúng ta hãy phân tích các khi m khuy t c a ch ng trình này:ế ế ủ ươ

Khi ch ng trình g i t i m t ph ng th c toán t đ th c hi n các phép tính c ng, tr ,ươ ọ ớ ộ ươ ứ ử ể ự ệ ộ ừ nhân đa th c, thì m t đ i t ng trung gian đ c t o ra. M t vùng nh đ c c pứ ộ ố ượ ượ ạ ộ ớ ượ ấ phát và giao cho nó (đ i t ng trung gian) qu n lý.ố ượ ả

Khi th c hi n xong phép tính s ra kh i ph ng th c. Đ i t ng trung gian b xoá, tuyự ệ ẽ ỏ ươ ứ ố ượ ị nhiên ch vùng nh c a các thu c tính c a đ i t ng này đ c gi i phóng. Còn vùngỉ ớ ủ ộ ủ ố ượ ượ ả nh (ch a các h s c a đa th c) mà đ i t ng trung gian đang qu n lý thì không hớ ứ ệ ố ủ ứ ố ượ ả ề b gi i phóng. Nh v y s vùng nh b chi m d ng vô ích s tăng lên.ị ả ư ậ ố ớ ị ế ụ ẽ

Nh c đi m trên d dàng kh c ph c b ng cách đ a vào l p DT hàm h y trong m c 3 trên.ượ ể ễ ắ ụ ằ ư ớ ủ ụ ở

Ví d ụPh n này chúng tôi trình bày m t ví d t ng đ i hoàn ch nh v l p các hình tròn trong chầ ộ ụ ươ ố ỉ ề ớ ế đ đ h a. Ch ng trình g m:ộ ồ ọ ươ ồ

L p HT (hình tròn) v i các thu c tính:ớ ớ ộ

int r; // Bán kính

int m; // M u hình trònầ

int xhien, yhien; // V trí hi n th hình tròn trên màn hìnhị ể ị

char *pht; // Con tr tr t i vùng nh ch a nh hình trònỏ ỏ ớ ớ ứ ả

int hienmh; // Tr ng thái hi n (hienmh = 1), n (hienmh = 0)ạ ệ ẩ

Các ph ng th c ươ ứ

Hàm t o không đ i th c hi n vi c gán giá tr b ng 0 cho các thu c tính c a l p. HT(); ạ ố ự ệ ệ ị ằ ộ ủ ớ

Hàm t o có đ i. HT(int n, int m1 = 15); ạ ốTh c hi n các vi c:ự ệ ệ

Gán r1 cho r, m1 cho m

C p phát b nh cho phtấ ộ ớ

V hình tròn và l u nh hình tròn vào vùng nh c a phtẽ ư ả ớ ủ

Page 241: Giao Trinh C++ Toan Tap

Hàm h y: ~HT(); ủTh c hi n các vi c:ự ệ ệ

Xoá hình tròn kh i màn hình ỏ (n u ế đang hi n th )ể ị

Gi i phóng b nh đã c p cho phtả ộ ớ ấ

Ph ng th c: void hien(int x, int y); ươ ứCó nhi m v hi n th hình tròn t i (x, y)ệ ụ ể ị ạ

Ph ng th c : void an()ươ ứCó nhi m v làm n hình tròn ệ ụ ẩ

Các hàm đ c l p:ộ ậ

void ktdh(); // Kh i t o đ h aở ạ ồ ọ

void ve_bau_troi(); // V b u tr i saoẽ ầ ờ

void ht_di_dong_xuong(); // V m t c p 2 hình tròn di chuy n xu ngẽ ộ ặ ể ố

void ht_di_dong_len(); // V m t c p 2 hình tròn di chuy n lên trênẽ ộ ặ ểN i dung ch ng trình là t o ra các chuy n đ ng xu ng và lên c a các hình tròn.ộ ươ ạ ể ộ ố ủ

// Lop do hoa

// Ham huy

// Trong ham huy co the goi PT khac

#include <conio.h>

#include <iostream.h>

#include <math.h>

#include <stdlib.h>

#include <graphics.h>

#include <dos.h>

void ktdh(); // Kh i t o đ h aở ạ ồ ọ

void ve_bau_troi(); // V b u tr i saoẽ ầ ờ

void ht_di_dong_xuong(); // V m t c p 2 hình tròn di chuy n xu ngẽ ộ ặ ể ố

void ht_di_dong_len(); // V m t c p 2 hình tròn di chuy n lên trênẽ ộ ặ ể

int xmax, ymax;

class HT

{

private:

int r, m ;

int xhien, yhien;

Page 242: Giao Trinh C++ Toan Tap

char *pht;

int hienmh;

public:

HT();

HT(int n, int m1 = 15);

~HT();

void hien(int x, int y);

void an();

};

HT:: HT()

{

r = m = hienmh = 0;

xhien = yhien = 0;

pht = NULL;

}

HT::HT(int n, int m1)

{

r = n; m = m1; hienmh = 0;

xhien = yhien = 0;

if (r<0) r = 0;

if (r = = 0) pht = NULL;

else

{

int size; char *pmh;

size = imagesize(0, 0, r+r, r+r);

pmh = new char[size];

getimage(0, 0, r+r, r+r, pmh);

setcolor(m);

circle(r, r, r );

setfillstyle(1, m);

floodfill(r, r, m);

Page 243: Giao Trinh C++ Toan Tap

pht = new char[size];

getimage(0, 0, r+r, r+r, pht);

putimage(0, 0, pmh, COPY_PUT);

delete pmh;

pmh = NULL;

}

}

void HT::hien(int x, int y)

{

if (pmh! = NULL && !hienmh) // Chua hien

{

hienmh = 1;

xhien = x; yhien = y;

putimage(x, y, pht, XOR_PUT);

}

}

void HT::an()

{

if (hienmh) // Dang hien

{

hienmh = 0;

putimage(xhien, yhien, pht, XOR_PUT);

}

}

HT::~HT()

{

an();

if (pht! = NULL)

{

delete pht;

Page 244: Giao Trinh C++ Toan Tap

pht = NULL;

}

}

void ktdh()

{

int mh = 0, mode = 0;

initgraph(&mh, &mode, " ");

xmax = getmaxx();

ymax = getmaxy();

}

void ve_bau_troi()

{

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

putpixel(random(xmax), random(ymax), 1+random( 15));

}

void ht_di_dong_xuong()

{

HT h(50, 4);

HT u(60, 15);

h.hien(0, 0);

u.hien(40, 0);

for (int x = 0; x< = 340; x+ = 10)

{

h.an();

u.an();

h.hien(x, x);

delay(200);

u.hien(x+40, x);

delay(200);

}

Page 245: Giao Trinh C++ Toan Tap

}

void ht_di_dong_len()

{

HT h(50, 4);

HT u(60, 15);

h.hien(340, 340);

u.hien(380, 340);

for (int x = 340; x> = 0; x- = 10)

{

h.an();

u.an();

u.hien(x, x);

delay(200);

u.hien(x+40, x);

delay(200);

}

};

void main()

{

ktdh();

ve_bau_troi();

ht_di_dong_xuong();

ht_di_dong_len();

getch();

closegraph();

}Các nh n xét:ậ

Trong thân hàm h y g i t i ph ng th c an().ủ ọ ớ ươ ứ

Đi u gì x y ra khi b đi hàm h y:ề ẩ ỏ ủ

Khi g i hàm ht_di_dong_xuong() thì có 2 đ i t ng ki u HT đ c t o ra. Trong thânọ ố ượ ể ượ ạ hàm s d ng các đ i t ng này đ v các hình tròn di chuy n xu ng. Khi thoátử ụ ố ượ ể ẽ ể ố kh i hàm thì 2 đ i t ng (t o ra trên) đ c gi i phóng. Vùng nh c a cácỏ ố ượ ạ ở ượ ả ớ ủ

Page 246: Giao Trinh C++ Toan Tap

thu c tính c a chúng b thu h i, nh ng vùng nh c p phát cho thu c tính phtộ ủ ị ồ ư ớ ấ ộ ch a đ c gi i phóng và nh c a 2 hình tròn ( phía d i màn hình) v n khôngư ượ ả ả ủ ở ướ ẫ đ c c t đi.ượ ấ

Đi u t ng t x y ra sau khi ra kh i hàm ht_di_dong_len(): vùng nh c p phát choề ươ ự ẩ ỏ ớ ấ thu c tính pht ch a đ c gi i phóng và nh c a 2 hình tròn ( phía trên mànộ ư ượ ả ả ủ ở hình) v n không đ c thu d n.ẫ ượ ọ

CÁC HÀM TR C TUY N (inline)Ự Ế

M t s m r ng c a C++ đ i v i C đã đ c trình bày trong các ch ng tr c nh bi n thamộ ố ở ộ ủ ố ớ ượ ươ ướ ư ế chi u, đ nh nghĩa ch ng hàm, hàm v i đ i m c đ nh … Ph n này ta xem m t đ c tr ng khácế ị ồ ớ ố ặ ị ầ ộ ặ ư c a C++ đ c g i là hàm tr c tuy n (inline).ủ ượ ọ ự ế

u nh c đi m c a hàmƯ ượ ể ủVi c t ch c ch ng trình thành các hàm có 2 u đi m rõ r t:ệ ổ ứ ươ ư ể ệ

Th nh t là chia ch ng trình thành các đ n v đ c l p, làm cho ch ng trình đ c tứ ấ ươ ơ ị ộ ậ ươ ượ ổ ch c m t cách khoa h c d ki m soát, d phát hi n l i, d phát tri n và m r ng.ứ ộ ọ ễ ể ễ ệ ỗ ễ ể ở ộ

Th hai là gi m đ c kích th c ch ng trình, vì m i đo n ch ng trình th c hi nứ ả ượ ướ ươ ỗ ạ ươ ự ệ nhi m v c a hàm đ c thay b ng m t l i g i hàm.ệ ụ ủ ượ ằ ộ ờ ọTuy nhiên hàm cũng có nh c đi m là làm ch m t c đ ch ng trình do ph i th c hi n m tượ ể ậ ố ộ ươ ả ự ệ ộ s thao tác có tính th t c m i khi g i hàm nh : c p phát vùng nh cho các đ ivà bi n c cố ủ ụ ỗ ọ ư ấ ớ ố ế ụ b , truy n d li u c a các tham s cho các đ i, gi i phóng vùng nh tr c khi thoát kh iộ ề ữ ệ ủ ố ố ả ớ ướ ỏ hàm.

Các hàm tr c tuy n trong C++ có kh năng kh c ph c đ c các nh c đi m nói trên.ự ế ả ắ ụ ượ ượ ể

Các hàm tr c tuy nự ếĐ bi n m t hàm thành tr c tuy n ta vi t thêm t khoá ể ế ộ ự ế ế ừ inline vào tr c khai báo nguyên m uướ ẫ hàm. N u không dùng nguyên m u thì vi t t khoá này tr c dòng đ u tiên c a đ nh nghĩaế ẫ ế ừ ướ ầ ủ ị hàm.

:

inline float f(int n, float x);

float f(int n, float x)

{

// Các câu l nh trong thân hàmệ

}ho cặ

inline float f(int n, float x)

{

Page 247: Giao Trinh C++ Toan Tap

// Các câu l nh trong thân hàmệ

}Chú ý: Trong m i tr ng h p, t khoá inline ph i xu t hi n tr c các l i g i hàm thì trìnhọ ườ ọ ừ ả ấ ệ ướ ờ ọ biên d ch m i bi t c n x lý hàm theo ki u inline.ị ớ ế ầ ử ể

Ví d hàm f trong ch ng trình sau s không ph i là hàm tr c tuy n vì t khoá inline vi t sauụ ươ ẽ ả ự ế ừ ế l i g i hàm:ờ ọ

#include <conio.h>

#include <iostream.h>

void main()

{

int s ;

s = f(5,6);

cout << s ;

getch();

}

inline int f(int a, int b)

{

return a*b;

}Chú ý: Trong C++, n u hàm đ c xây d ng sau l i g i hàm thì b t bu c ph i khai báo nguyênế ượ ự ờ ọ ắ ộ ả m u hàm tr c l i g i. Trong ví d trên, trình biên d ch Cẫ ướ ờ ọ ụ ị ++ s b t l i vì thi u khai báoẽ ắ ỗ ế nguyên ng u hàm f .ẫ

Cách biên d ch và dùng hàm tr c tuy nị ự ếCh ng trình d ch x lý các hàm inline nh các macro (đ c đ nh nghĩa trong l nh #define),ươ ị ử ư ượ ị ệ nghĩa là nó s thay m i l i g i hàm b ng m t đo n ch ng trình th c hi n nhi m v c aẽ ỗ ờ ọ ằ ộ ạ ươ ự ệ ệ ụ ủ hàm. Cách này làm cho ch ng trình dài ra, nh ng t c đ ch ng trình tăng lên do không ph iươ ư ố ộ ươ ả th c hi n các thao tác có tính th t c khi g i hàm.ự ệ ủ ụ ọ

Ph ng án dùng hàm tr c tuy n rút ng n đ c th i gian ch y máy nh ng l i làm tăng kh iươ ự ế ắ ượ ờ ạ ư ạ ố l ng b nh ch ng trình (nh t là đ i v i các hàm tr c tuy n có nhi u câu l nh). Vì v y chượ ộ ớ ươ ấ ố ớ ự ế ề ệ ậ ỉ nên dùng ph ng án tr c tuy n đ i v i các hàm nh .ươ ự ế ố ớ ỏ

S h n ch c a trình biên d chự ạ ế ủ ịKhông ph i khi g p t khoá inline là trình biên d ch nh t thi t ph i x lý hàm theo ki u tr cả ặ ừ ị ấ ế ả ử ể ự tuy n.ế

Page 248: Giao Trinh C++ Toan Tap

Có m t s hàm mà các trình biên d ch th ng không x lý theo cách inline nh các hàm ch aộ ố ị ườ ử ư ứ bi n static, hàm ch a các l nh chu trình ho c l nh goto ho c l nh switch, hàm đ quy. Trongế ứ ệ ặ ệ ặ ệ ệ tr ng h p này t khoá inline l dĩ nhiên b b qua.ườ ợ ừ ẽ ị ỏ

Th m chí t khoá inline v n b b qua ngay c đ i v i các hàm không có nh ng h n ch nêuậ ừ ẫ ị ỏ ả ố ớ ữ ạ ế trên n u nh trình biên d ch th y c n thi t (ví d đã có quá nhi u hàm inline làm cho b nhế ư ị ấ ầ ế ụ ề ộ ớ ch ng trình quá l n)ươ ớ

: Ch ng trình sau s d ng hàm inline tính chu vi và di n tích c a hình ch nh t:ươ ử ụ ệ ủ ữ ậCách 1 : Không khai báo nguyên m u. Khi đó hàm dtcvhcn ph i đ t tr c hàm main.ẫ ả ặ ướ

#include <conio.h>

#include <iostream.h>

inline void dtcvhcn(int a, int b, int &dt, int &cv)

{

dt=a*b;

cv=2*(a+b);

}

void main()

{

int a[20],b[20],cv[20],dt[20],n;

cout << "\n So hinh chu nhat: '' ;

cin >> n;

for (int i=1; i<=n; ++i)

{

cout <<"\n Nhap 2 canh cua hinh chu nhat thu " << i << ": ";

cin >> a[i] >> b[i];

dtcvhcn(a[i],b[i],dt[i], cv[i]);

}

clrscr();

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

{

cout << "\n Hinh chu nhat thu "<< i << '' : '';

cout << "\n Do dai 2 canh= '' << a[i] << '' va '' << b[i] ;

cout <<"\n Dien tich= " << dt[i] ;

cout << "\n Chu vi= '' << cv[i] ;

Page 249: Giao Trinh C++ Toan Tap

}

getch();

}Cách 2:S d ng khai báo nguyên m u. Khi đó t khoá inline đ t tr c nguyên m u.ử ụ ẫ ừ ặ ướ ẫ

Chú ý: Không đ c đ t inline tr c đ nh nghĩa hàm. Trong ch ng trình d i đây n u đ tượ ặ ướ ị ươ ướ ế ặ inline tr c đ nh nghĩa hàm thì h u qu nh sau: Ch ng trình v n d ch thông, nh ng khiướ ị ậ ả ư ươ ẫ ị ư ch y thì ch ng trình b qu n và không thoát đi đ c.ạ ươ ị ẩ ượ

#include <conio.h>

#include <iostream.h>

inline void dtcvhcn(int a, int b, int &dt, int &cv);

void main()

{

int a[20],b[20],cv[20],dt[20],n;

cout << "\n So hinh chu nhat: '' ;

cin >> n;

for (int i=1; i<=n; ++i)

{

cout <<"\n Nhap 2 canh cua hinh chu nhat thu " << i << ": ";

cin >> a[i] >> b[i];

dtcvhcn(a[i],b[i],dt[i], cv[i]);

}

clrscr();

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

{

cout << "\n Hinh chu nhat thu "<< i << '' : '';

cout << "\n Do dai 2 canh= '' << a[i] << '' va '' << b[i] ;

cout <<"\n Dien tich= " << dt[i] ;

cout << "\n Chu vi= '' << cv[i] ;

}

getch();

}

void dtcvhcn(int a, int b, int&dt, int &cv)

{

Page 250: Giao Trinh C++ Toan Tap

dt=a*b;

cv=2*(a+b);

}

CH NG 8ƯƠ

HÀM B N, Đ NH NGHĨA PHÉP TOÁN CHO L PẠ Ị Ớ

Hàm b nạĐ nh nghĩa phép toán cho l pị ớ

HÀM B N (Friend function)Ạ

Hàm b n ạĐ m t hàm tr thành b n c a m t l p, có 2 cách vi t:ể ộ ở ạ ủ ộ ớ ế

Cách 1: Dùng t khóa friend đ khai báo hàm trong l p và xây d ng hàm bên ngoài nh cácừ ể ớ ự ư hàm thông th ng (không dùng t khóa friend). M u vi t nh sau:ườ ừ ẫ ế ư

class A

{

private:

// Khai báo các thu c tínhộ

public:

...

// Khai báo các hàm b n c a l p Aạ ủ ớ

friend void f1(...);

friend double f2(...);

friend A f3(...) ;

...

} ;

// Xây d ng các hàm f1, f2, f3ự

void f1(...)

{

Page 251: Giao Trinh C++ Toan Tap

...

}

double f2(...)

{

...

}

A f3(...)

{

...

}Cách 2: Dùng t khóa friend đ xây d ng hàm trong đ nh nghĩa l p. M u vi t nh sau:ừ ể ự ị ớ ẫ ế ư

class A

{

private:

// Khai báo các thu c tínhộ

public:

// Xây d ng các hàm b n c a l p Aự ạ ủ ớ

void f1(...)

{

...

}

double f2(...)

{

...

}

A f3(...)

{

...

}

...

} ;

Tính ch t c a hàm b nấ ủ ạ

Page 252: Giao Trinh C++ Toan Tap

Trong thân hàm b n c a m t l p có th truy nh p t i các thu c tính c a các đ i t ng thu cạ ủ ộ ớ ể ậ ớ ộ ủ ố ượ ộ l p này. Đây là s khác nhau duy nh t gi a hàm b n và hàm thông th ng. ớ ự ấ ữ ạ ườ

Chú ý r ng hàm b n không ph i là ph ng th c c a l p. Ph ng th c có m t đ i nằ ạ ả ươ ứ ủ ớ ươ ứ ộ ố ẩ ( ng v i con tr this) và l i g i c a ph ng th c ph i g n v i m t đ i t ng nào đó (đ a chứ ớ ỏ ờ ọ ủ ươ ứ ả ắ ớ ộ ố ượ ị ỉ đ i t ng này đ c truy n cho con tr this). L i g i c a hàm b n gi ng nh l i g i c a hàmố ượ ượ ề ỏ ờ ọ ủ ạ ố ư ờ ọ ủ thông th ng.ườ

Ví d sau s so sánh ph ng th c, hàm b n và hàm thông th ng.ụ ẽ ươ ứ ạ ườ

Xét l p SP (s ph c), hãy so sánh 3 ph ng án đ th c hi n vi c c ng 2 s ph c:ớ ố ứ ươ ể ự ệ ệ ộ ố ứ

Ph ng án 1ươ : Dùng ph ng th cươ ứ

class SP

{

private:

double a; // ph n th cầ ự

double b; // Ph n oầ ả

public:

SP cong(SP u2)

{

SP u:

u.a = this → a + u2.a ;

u.b = this → b + u2.b ;

return u;

}

}; Cách dùng:

SP u, u1, u2;

u = u1.cong(u2); Ph ng án ươ 2: Dùng hàm b nạ

class SP

{

private:

double a; // Ph n th cầ ự

double b; // Ph n oầ ả

public:

Page 253: Giao Trinh C++ Toan Tap

friend SP cong(SP u1 , SP u2)

{

SP u:

u.a = u1.a + u2.a ;

u.b = u1.b + u2.b ;

return u;

}

}; Cách dùng

SP u, u1, u2;

u = cong(u1, u2); Ph ng án 3ươ : Dùng hàm thông th ngườ

class SP

{

private:

double a; // ph n th cầ ự

double b; // Ph n oầ ả

public:

...

};

SP cong(SP u1, SP u2)

{

SP u:

u.a = u1.a + u2.a ;

u.b = u1.b + u2.b ;

return u;

}Ph ng án này không đ c ch p nh n, trình biên d ch s báo l i trong thân hàm không đ cươ ượ ấ ậ ị ẽ ỗ ượ quy n truy xu t đ n các thu c tính riêng (private) a, b c a các đ i t ng u, u1 và u2 thu c l pề ấ ế ộ ủ ố ượ ộ ớ SP.

Hàm b n c a nhi u l p ạ ủ ề ớKhi m t hàm là b n c a nhi u l p, thì nó có quy n truy nh p t i t t c các thu c tínhộ ạ ủ ề ớ ề ậ ớ ấ ả ộ

c a các đ i t ng trong các l p này. ủ ố ượ ớ

Page 254: Giao Trinh C++ Toan Tap

Đ làm cho hàm f tr thành b n c a các l p A, B và C ta s d ng m u vi t nh sau:ể ở ạ ủ ớ ử ụ ẫ ế ư

class A; // Khai báo tr c l p Aướ ớ

class B; // Khai báo tr c l p Bướ ớ

class C; // Khai báo tr c l p Cướ ớ

// Đ nh nghĩa l p Aị ớ

class A

{

// Khai báo f là b n c a Aạ ủ

friend void f(...) ;

} ;

// Đ nh nghĩa l p Bị ớ

class B

{

// Khai báo f là b n c a Bạ ủ

friend void f(...) ;

} ;

// Đ nh nghĩa l p Cị ớ

class C

{

// Khai báo f là b n c a Cạ ủ

friend void f(...) ;

} ;

// Xây d ng hàm fụ

void f(...)

{

...

}Ch ng trình sau đây minh h a cách dùng hàm b n (b n c a m t l p và b n c a nhi u l p).ươ ọ ạ ạ ủ ộ ớ ạ ủ ề ớ Ch ng trình đ a vào 2 l p VT (véc t ), MT (ma tr n) và 3 hàm b n đ th c hi n các thao tácươ ư ớ ơ ậ ạ ể ự ệ trên 2 l p này:ớ

// Hàm b n v i l p VT dùng đ in m t véc t ạ ớ ớ ể ộ ơ

friend void in(const VT &x);

// Hàm b n v i l p MT dùng đ in m t ma tr nạ ớ ớ ể ộ ậ

Page 255: Giao Trinh C++ Toan Tap

friend void in(const MT &a);

// Hàm b n v i c 2 l p MT và VT dùng đ nhân ma tr n v i véc tạ ớ ả ớ ể ậ ớ ơ

friend VT tich(const MT &a, const VT &x); N i dung ch ng trình là nh p m t ma tr n vuông c p n và m t véc t c p n, sau đó th cộ ươ ậ ộ ậ ấ ộ ơ ấ ự hi n phép nhân ma tr n v i véc t v a nh p.ệ ậ ớ ơ ừ ậ

#include <conio.h>

#include <iostream.h>

#include <math.h>

class VT;

class MT;

class VT

{

private:

int n;

double x[20]; // Toa do cua diem

public:

void nhapsl();

friend void in(const VT &x);

friend VT tich(const MT &a, const VT &x) ;

};

class MT

{

private:

int n;

double a[20][20];

public:

friend VT tich(const MT &a, const VT &x);

friend void in(const MT &a);

void nhapsl();

} ;

void VT::nhapsl()

Page 256: Giao Trinh C++ Toan Tap

{

cout << "\n Cap vec to = ";

cin >> n ;

for (int i = 1; i< = n ; ++i)

{

cout << "\n Phan tu thu " << i <<" = " ;

cin >> x[i];

}

}

void MT::nhapsl()

{

cout <<"\n Cap ma tran = ";

cin >> n ;

for (int i = 1; i< = n ; ++i)

for (int j = 1; j< = n; ++j)

{

cout << "\n Phan tu thu: "<<i<< " hang "<< i << " cot " << j << " = ";

cin >> a[i][j];

}

}

VT tich(const MT &a, const VT &x)

{

VT y;

int n = a.n;

if (n! = x.n)

return x;

y.n = n;

for (int i = 1; i< = n; ++i)

{

y.x[i] = 0;

for (int j = 1; j< = n; ++j)

Page 257: Giao Trinh C++ Toan Tap

y.x[i] = a.a[i][j]*x.x[j];

}

return y;

}

void in(const VT &x)

{

cout << "\n";

for (int i = 1; i< = x.n; ++i)

cout << x.x[i] << " ";

}

void in(const MT &a)

{

for (int i = 1; i< = a.n; ++i)

{

cout << "\n " ;

for (int j = 1; j< = a.n; ++j)

cout << a.a[i][j] << " ";

}

}

void main()

{

MT a; VT x, y;

clrscr();

a.nhapsl();

x.nhapsl();

y = tich(a, x);

clrscr();

cout << "\n Ma tran A:";

in(a);

cout << "\n Vec to x: " ;

Page 258: Giao Trinh C++ Toan Tap

in(x);

cout << "\n Vec to y = Ax: " ;

in(y);

getch();

}

Đ NH NGHĨA PHÉP TOÁN CHO L PỊ Ớ

Đ i v i m i l p ta có th s d ng l i các kí hi u phép toán thông d ng (+, -, *, …) đ đ nhố ớ ỗ ớ ể ử ụ ạ ệ ụ ể ị nghĩa cho các phép toán c a l p. Sau khi đ c đ nh nghĩa các kí hi u này s đ c dùng nhủ ớ ượ ị ệ ẽ ượ ư các phép toán c a l p theo cách vi t thông th ng. Cách đ nh nghĩa này đ c g i là phépủ ớ ế ườ ị ượ ọ ch ng toán t (nh khái ni m ch ng hàm trong các ch ng tr c).ồ ử ư ệ ồ ươ ướ

Tên hàm toán tửG m t khoá operator và tên phép toán.ồ ừ

Ví d :ụ

operator+(đ nh nghĩa ch ng phép +)ị ồ

operator- (đ nh nghĩa ch ng phép -) ị ồ

Các đ i c a hàm toán tố ủ ử

V i các phép toán có 2 toán h ng thì hàm toán t c n có 2 đ i. Đ i th nh t ng v iớ ạ ử ầ ố ố ứ ấ ứ ớ toán h ng th nh t, đ i th hai ng v i toán h ng th hai. Do v y, v i các phép toánạ ứ ấ ố ứ ứ ớ ạ ứ ậ ớ không giao hoán (phép -) thì th t đ i là r t quan tr ng.ứ ự ố ấ ọ

Ví d : Các hàm toán t c ng, tr phân s đ c khai báo nh sau:ụ ử ộ ừ ố ượ ư

struct PS

{

int a; //T sử ố

int b; // M u sẫ ố

};

PS operator+(PS p1, PS p2); // p1 + p2

PS operator-(PS p1 , PS p2); // p1 - p2

PS operator*(PS p1, PS p2); // p1 *p2

PS operator/(PS p1, PS p2); // p1/p2

V i các phép toán có m t toán h ngớ ộ ạ , thì hàm toán t có m t đ i. Ví d hàm toán t đ iử ộ ố ụ ử ổ d u ma tr n (đ i d u t t c các ph n t c a ma tr n) đ c khai báo nh sau:ấ ậ ổ ấ ấ ả ầ ử ủ ậ ượ ư

struct MT

Page 259: Giao Trinh C++ Toan Tap

{

double a[20][20] ; // M ng ch a các ph n t ma tr nả ứ ầ ử ậ

int m ; // S hàng ma tr nố ậ

int n ; // S c t ma tr nố ộ ậ

};

MT operator-(MT x) ;

Thân c a hàm toán tủ ửVi t nh thân c a hàm thông th ng. Ví d hàm đ i d u ma tr n có th đ c đ nh nghĩa nhế ư ủ ườ ụ ổ ấ ậ ể ượ ị ư sau:

struct MT

{

double a[20][20] ; // M ng ch a các ph n t ma tr nả ứ ầ ử ậ

int m ; // S hàng ma tr nố ậ

int n ; // S c t ma tr nố ộ ậ

};

MT operator-(MT x)

{

MT y;

for (int i=1 ;i<= y.m ; ++i)

for (int j =1 ;j<= y.n ; ++j)y.a[i][j] =- x.a[i][j];

return y;

}

Cách dùng hàm toán tử

Có 2 cách dùng:

Cách 1: Dùng nh m t hàm thông th ng b ng cách vi t l i g iư ộ ườ ằ ế ờ ọ

Ví d :ụ

PS p, q, u, v ;

u = operator+(p, q) ; // u = p + q

v = operator-(p, q) ; // v= p - qCách 2: Dùng nh phép toán c a C++ ư ủ

Ví d :ụ

Page 260: Giao Trinh C++ Toan Tap

PS p, q, u, v ;

u = p + q ; // u = p + q

v = p - q ; //v = p - qChú ý: Khi dùng các hàm toán t nh phép toán c a C++ ta có th k t h p nhi u phép toán đử ư ủ ể ế ơ ề ể vi t các công th c ph c t p. Cũng cho phép dùng d u ngo c tròn đ quy đ nh th t th cế ứ ứ ạ ấ ặ ể ị ứ ự ự hi n các phép tính. Th t u tiên c a các phép tính v n tuân theo các quy t c ban đ u c a C+ệ ứ ự ư ủ ẫ ắ ầ ủ+. Ch ng h n các phép * và / có th t u tiên cao h n so v i các phép + và -ẳ ạ ứ ự ư ơ ớ

Các ví d v đ nh nghĩa ch ng toán tụ ề ị ồ ử

: Trong ví d này ngoài vi c s d ng các hàm toán t đ th c hi n 4 phép tính trên phân s ,ụ ệ ử ụ ử ể ự ệ ố còn đ nh nghĩa ch ng các phép toán << và >> đ xu t và nh p phân s . ị ồ ể ấ ậ ốHàm operator<< có 2 đ i ki u ostream& và PS (Phân s ). Hàm tr v giá tr ki u ostream& vàố ể ố ả ề ị ể đ c khai báo nh sau:ượ ư

ostream& operator<< (ostream& os, PS p); T ng t hàm operator>> đ c khai báo nh sau: ượ ự ượ ư

istream& operator>> (istream& is,PS &p); D i đây s ch ra cách xây d ng và s d ng các hàm toán t .ướ ẽ ỉ ự ử ụ ử

Chúng ta cũng s th y vi c s d ng các hàm toán t r t t nhiên, ng n g n và ti n l i.ẽ ấ ệ ử ụ ử ấ ự ắ ọ ệ ợ

#include <conio.h>

#include <iostream.h>

#include <math.h>

typedef struct

{

int a,b;

} PS;

ostream& operator<< (ostream& os, PS p);

istream& operator>> (istream& is,PS &p);

int uscln(int x, int y);

PS rutgon(PS p);

PS operator+(PS p1, PS p2);

PS operator-(PS p1, PS p2);

PS operator*(PS p1, PS p2);

PS operator/(PS p1, PS p2);

ostream& operator<< (ostream& os, PS p)

Page 261: Giao Trinh C++ Toan Tap

{

os << p.a << '/' << p.b ;

return os;

}

istream& operator>> (istream& is,PS &p)

{

cout << "\n Nhap tu va mau: '' ;

is >> p.a >> p.b ;

return is;

}

int uscln(int x, int y)

{

x=abs(x);y=abs(y);

if (x*y==0) return 1;

while (x!=y)

{

if (x>y) x-=y;

else y-=x;

}

return x;

}

PS rutgon(PS p)

{

PS q;

int x;

x=uscln(p.a,p.b);

q.a = p.a / x ;

q.b = p.b/ x ;

return q;

}

PS operator+(PS p1, PS p2)

{

PS q;

Page 262: Giao Trinh C++ Toan Tap

q.a = p1.a*p2.b + p2.a*p1.b;

q.b = p1 .b * p2.b ;

return rutgon(q);

}

PS operator-(PS p1, PS p2)

{

PS q;

q.a = p1.a*p2.b - p2.a*p1 .b;

q.b = p1.b * p2.b ;

return rutgon(q);

}

PS operator*(PS p1, PS p2)

{

PS q;

q.a = p1.a * p2.a ;

q.b = p1.b * p2.b ;

return rutgon(q);

}

PS operator/(PS p1 , PS p2)

{

PS q;

q.a = p1.a * p2.b ;

q.b = p1.b * p2.a ;

return rutgon(q);

}

void main()

{

PS p, q, z, u, v ;

PS s;

cout <<"\nNhap cac PS p, q, z, u, v: '' ;

cin >> p >> q >> z >> u >> v ;

s = (p - q*z) / (u + v) ;

cout << "\n Phan so s = " << s;

Page 263: Giao Trinh C++ Toan Tap

getch();

}

: Ch ng trình đ a vào các hàm toán t :ươ ư ửoperator- có m t đ i dùng đ đ o d u m t đa th cộ ố ể ả ấ ộ ứ

operator+ có 2 đ i dùng đ c ng 2 đa th cố ể ộ ứ

operator- có 2 đ i dùng đ tr 2 đa th cố ể ừ ứ

operator* có 2 đ i dùng đ nhân 2 đa th cố ể ứ

operator^có 2 đ i dùng đ tính giá đa th c t i xố ể ứ ạ

perator<< có 2 đ i dùng đ in đa th cơ ố ể ứ

perator>> có 2 đ i dùng đ nh p đa th cơ ố ể ậ ứ

Ch ng trình s nh p 4 đa th c: p, q, r, s. Sau đó tính đa th c: f = -(p+q)*(r-s)ươ ẽ ậ ứ ứ

Cu i cùng tính giá tr f(x), v i x là m t s th c nh p t bàn phím.ố ị ớ ộ ố ự ậ ừ

#include <conio.h>

#include <iostream.h>

#include <math.h>

struct DT

{

double a[20];// Mang chua cac he so da thuc a0, a1,...

int n ;// Bac da thuc

};

ostream& operator<< (ostream& os, DT d);

istream& operator>> (istream& is, DT &d);

DT operator-(const DT& d);

DT operator+(DT d1, DT d2);

DT operator-(DT d1, DT d2);

DT operator*(DT d1, DT d2);

double operator^(DT d, double x);// Tinh gia tri da thuc

ostream& operator<< (ostream& os, DT d)

{

os << " Cac he so (tu ao): '' ;

for (int i=0 ;i<= d.n ;++i)

Page 264: Giao Trinh C++ Toan Tap

os << d.a[i] <<" " ;

return os;

}

istream& operator>> (istream& is, DT &d)

{

cout << " Bac da thuc: '' ;

cin >> d.n;

cout << ''Nhap cac he so da thuc:" ;

for (int i=0 ;i<=d.n ;++i)

{

cout << "\n He so bac " << i <<" = '' ;

is >> d.a[i] ;

}

return is;

}

DT operator-(const DT& d)

{

DT p;

p.n = d.n;

for (int i=0 ;i<=d.n ;++i)

p.a[i] = -d.a[i];

return p;

}

DT operator+(DT d1, DT d2)

{

DT d;

int k,i;

k = d1.n > d2.n ? d1.n : d2.n ;

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

if (i<=d1.n && i<=d2.n) d.a[i] = d1.a[i] + d2.a[i];

else if (i<=d1.n) d.a[i] = d1.a[i];

else d.a[i] = d2.a[i];

i = k;

Page 265: Giao Trinh C++ Toan Tap

while (i>0 && d.a[i]==0.0) --i;

d.n=i;

return d ;

}

DT operator-(DT d1, DT d2)

{

return (d1 + (-d2));

}

DT operator*(DT d1 , DT d2)

{

DT d;

int k, i, j;

k = d.n = d1.n + d2.n ;

for (i=0;i<=k;++i) d.a[i] = 0;

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

for (j=0 ;j<= d2.n ;++j)

d.a[i+j] += d1 .a[i]*d2.a[j];

return d;

}

double operator^(DT d, double x)

{

double s=0.0 , t=1.0;

for (int i=0 ;i<= d.n ;++i)

{

s += d.a[i]*t;

t *= x;

}

return s;

}

void main()

{

DT p,q,r,s,f;

double x,g;

Page 266: Giao Trinh C++ Toan Tap

clrscr();

cout <<"\n Nhap da thuc P '' ;cin >> p;

cout <<"\n Nhap da thuc Q '' ;cin >> q;

cout <<"\n Nhap da thuc R '' ;cin >> r;

cout <<"\n Nhap da thuc S '' ;cin >> s;

cout << "\n Nhap so thuc x: '' ;cin >> x;

f = -(p+q)*(r-s);

g = f^x;

cout << "\n Da thuc f "<< f ;

cout << "\n x = '' << x;

cout << "\n f(x) = '' << g;

getch();

}

CH NG 9ƯƠ

CÁC DÒNG NH P/XU T VÀ FILEẬ Ấ

Nh p/xu t v i cin/coutậ ấ ớĐ nh d ngị ạIn ra máy in Làm vi c v i Fileệ ớNh p/xu t nh phânậ ấ ị

Trong C++ có s n m t s l p chu n ch a d li u và các ph ng th c ph c v cho các thaoẵ ộ ố ớ ẩ ứ ữ ệ ươ ứ ụ ụ tác nh p/xu t d li u c a NSD, th ng đ c g i chung là ậ ấ ữ ệ ủ ườ ượ ọ stream (dòng). Trong s các l pố ớ này, l p có tên ớ ios là l p c s , ch a các thu c tính đ đ nh d ng vi c nh p/xu t và ki m traớ ơ ở ứ ộ ể ị ạ ệ ậ ấ ể l i. M r ng (k th a) l p này có các l p ỗ ở ộ ế ừ ớ ớ istream, ostream cung c p thêm các toán tấ ử nh p/xu t nh >>, << và các hàm get, getline, read, ignore, put, write, flush … M t l p r ngậ ấ ư ộ ớ ộ h n có tên ơ iostream là t ng h p c a 2 l p trên. B n l p nh p/xu t c b n này đ c khai báoổ ợ ủ ớ ố ớ ậ ấ ơ ả ượ trong các file tiêu đ có tên t ng ng (v i đuôi *.h). S đ th a k c a 4 l p trên đ c thề ươ ứ ớ ơ ồ ừ ế ủ ớ ượ ể hi n qua hình v d i đây.ệ ẽ ướ

ios

istream ostreamiostream

Page 267: Giao Trinh C++ Toan Tap

Đ i t ng c a các l p trên đ c g i là các ố ượ ủ ớ ượ ọ dòng d li u. M t s đ i t ng thu c l pữ ệ ộ ố ố ượ ộ ớ iostream đã đ c khai báo s n (ượ ẵ chu nẩ ) và đ c g n v i nh ng thi t b nh p/xu t c đ nh nhượ ắ ớ ữ ế ị ậ ấ ố ị ư các đ i t ng ố ượ cin, cout, cerr, clog g n v i bàn phím (cin) và màn hình (cout, cerr, clog). Đi uắ ớ ề này có nghĩa các toán t >>, << và các hàm k trên khi làm vi c v i các đ i t ng này s choử ể ệ ớ ố ượ ẽ phép NSD nh p d li u thông qua bàn phím ho c xu t k t qu thông qua màn hình. ậ ữ ệ ặ ấ ế ả

Đ nh p/xu t thông qua các thi t b khác (nh máy in, file trên đĩa …), C++ cung c p thêmể ậ ấ ế ị ư ấ các l p ớ ifstream, ofstream, fstream cho phép NSD khai báo các đ i t ng m i g n v i thi tố ượ ớ ắ ớ ế b và t đó nh p/xu t thông qua các thi t b này.ị ừ ậ ấ ế ị

Trong ch ng này, chúng ta s xét các đ i t ng chu n ươ ẽ ố ượ ẩ cin, cout và m t s toán t , hàm nh pộ ố ử ậ xu t đ c tr ng c a l p ấ ặ ư ủ ớ iostream cũng nh cách t o và s d ng các đ i t ng thu c các l pư ạ ử ụ ố ượ ộ ớ ifstream, ofstream, fstream đ làm vi c v i các thi t b nh máy in và file trên đĩa.ể ệ ớ ế ị ư

NH P/XU T V I CIN/COUTẬ Ấ Ớ

Nh đã nh c trên, ư ắ ở cin là dòng d li u nh p (đ i t ng) thu c l p ữ ệ ậ ố ượ ộ ớ istream. Các thao tác trên đ i t ng này g m có các toán t và hàm ph c v nh p d li u vào cho bi n t bàn phím. ố ượ ồ ử ụ ụ ậ ữ ệ ế ừ

Toán t nh p >>ử ậToán t này cho phép nh p d li u t m t dòng Input_stream nào đó vào cho m t danh sáchử ậ ữ ệ ừ ộ ộ các bi n. Cú pháp chung nh sau:ế ư

Input_stream >> bi n1 >> bi n2 >> …ế ếtrong đó Input_stream là đ i t ng thu c l p istream. Tr ng h p Input_stream là cin, câuố ượ ộ ớ ườ ợ l nh nh p s đ c vi t:ệ ậ ẽ ượ ế

cin >> bi n1 >> bi n2 >> …ế ếcâu l nh này cho phép nh p d li u t bàn phím cho các bi n. Các bi n này có th thu c cácệ ậ ữ ệ ừ ế ế ể ộ ki u chu n nh : ki u nguyên, th c, ký t , xâu kí t . Chú ý 2 đ c đi m quan tr ng c a câuể ẩ ư ể ự ự ự ặ ể ọ ủ l nh trên.ệ

Page 268: Giao Trinh C++ Toan Tap

L nh s b qua không gán các d u tr ng (d u cách <>, d u Tab, d u xu ng dòng ệ ẽ ỏ ấ ắ ấ ấ ấ ố ↵ ) vào cho các bi n (k c bi n xâu kí t ).ế ể ả ế ự

Khi NSD nh p vào dãy byte nhi u h n c n thi t đ gán cho các bi n thì s byte còn l iậ ề ơ ầ ế ể ế ố ạ và k c d u xu ng dòng ể ả ấ ố ↵ s n m l i trong cin. Các byte này s t đ ng gán choẽ ằ ạ ẽ ự ộ các bi n trong l n nh p sau mà không ch NSD gõ thêm d li u vào t bàn phím. Doế ầ ậ ờ ữ ệ ừ v y câu l nhậ ệ

cin >> a >> b >> c;cũng có th đ c vi t thành ể ượ ế

cin >> a;

cin >> b;

cin >> c;và ch c n nh p d li u vào t bàn phím m t l n chung cho c 3 l nh (m i d li u nh p choỉ ầ ậ ữ ệ ừ ộ ầ ả ệ ỗ ữ ệ ậ m i bi n ph i cách nhau ít nh t m t d u tr ng)ỗ ế ả ấ ộ ấ ắ

: Nh p d li u cho các bi nậ ữ ệ ế

int a;

float b;

char c;

char *s;

cin >> a >> b >> c >> s;gi s NSD nh p vào dãy d li u : <><>12<>34.517ABC<>12E<>D ả ử ậ ữ ệ ↵

khi đó các bi n s đ c nh n nh ng giá tr c th sau:ế ẽ ượ ậ ữ ị ụ ể

a = 12

b = 34.517

c = 'A'

s = "BC"trong cin s còn l i dãy d li u : <>12E<>D ẽ ạ ữ ệ ↵ .

N u trong đo n ch ng trình ti p theo có câu l nh cin >> s; thì s s đ c t đ ng gán giá trế ạ ươ ế ệ ẽ ượ ự ộ ị "12E" mà không c n NSD nh p thêm d li u vào cho cin.ầ ậ ữ ệ

Qua ví d trên m t l n n a ta nh c l i đ c đi m c a toán t nh p >> là các bi n ch l y dụ ộ ầ ữ ắ ạ ặ ể ủ ử ậ ế ỉ ấ ữ li u v a đ cho ki u c a bi n (ví d bi n c ch l y m t kí t 'A', b l y giá tr 34.517) ho cệ ừ ủ ể ủ ế ụ ế ỉ ấ ộ ự ấ ị ặ cho đ n khi g p d u tr ng đ u tiên (ví d a l y giá tr 12, s l y giá tr "BC" dù trong cin v nế ặ ấ ắ ầ ụ ấ ị ấ ị ẫ còn d li u). T đó ta th y toán t >> là không phù h p khi nh p d li u cho các xâu kí t cóữ ệ ừ ấ ử ợ ậ ữ ệ ự ch a d u cách. C++ gi i quy t tr ng h p này b ng m t s hàm (ph ng th c) nh p khácứ ấ ả ế ườ ợ ằ ộ ố ươ ứ ậ thay cho toán t >>.ử

Page 269: Giao Trinh C++ Toan Tap

Các hàm nh p kí t và xâu kí tậ ự ự

Nh p kí tậ ự

cin.get() : Hàm tr l i m t kí t (k c d u cách, d u ả ạ ộ ự ể ả ấ ấ ↵ ).. Ví d :ụ

char ch;

ch = cin.get();

n u nh p ABế ậ ↵ , ch nh n giá tr 'A', trong cin còn Bậ ị ↵ .

n u nh p Aế ậ ↵ , ch nh n giá tr 'A', trong cin còn ậ ị ↵ .

n u nh p ế ậ ↵ , ch nh n giá tr 'ậ ị ↵ ', trong cin r ngỗ .

cin.get(ch) : Hàm nh p kí t cho ch và tr l i m t tham chi u t i cin. Do hàm tr l iậ ự ả ạ ộ ế ớ ả ạ tham chi u t i cin nên có th vi t các ph ng th c nh p này liên ti p trên m t đ iế ớ ể ế ươ ứ ậ ế ộ ố t ng cin. Ví d :ượ ụ

char c, d;

cin.get(c).get(d);n u nh p ABế ậ ↵ thì c nh n giá tr 'A' và d nh n giá tr 'B'. Trong cin còn 'Cậ ị ậ ị ↵ '.

Nh p xâu kí tậ ự

cin.get(s, n, fchar) : Hàm nh p cho s dãy kí t t cin. Dãy đ c tính t kí t đ u tiênậ ự ừ ượ ừ ự ầ trong cin cho đ n khi đã ế đ n – 1 kí tủ ự ho c ặ g p kí t k t thúcặ ự ế fchar. Kí t k t thúcự ế này đ c ng m đ nh là d u xu ng dòng n u b b qua trong danh sách đ i. T c cóượ ầ ị ấ ố ế ị ỏ ố ứ th vi t câu l nh trên d i d ng ể ế ệ ướ ạ cin.get(s, n) khi đó xâu s s nh n dãy kí t nh pẽ ậ ự ậ cho đ n khi đ n-1 kí t ho c đ n khi NSD k t thúc nh p (b ng d u ế ủ ự ặ ế ế ậ ằ ấ ↵ ).

Chú ý :

L nh s t đ ng gán d u k t thúc xâu ('\0') vào cho xâu s sau khi nh p xong.ệ ẽ ự ộ ấ ế ậ

Các l nh có th vi t n i nhau, ví d : ệ ể ế ố ụ cin.get(s1, n1).get(s2,n2);

Kí t k t thúc fchar (ho c ự ế ặ ↵ ) v n n m l i trong cin. Đi u này có th làm trôi các l nhẫ ằ ạ ề ể ệ get() ti p theo. Ví d :ế ụ

struct Sinhvien {

char *ht; // h tênọ

char *qq; // quê quán

};

void main()

{

int i;

for (i=1; i<=3; i++) {

cout << "Nhap ho ten sv thu " << i; cin.get(sv[i].ht, 25);

Page 270: Giao Trinh C++ Toan Tap

cout << "Nhap que quan sv thu "<< i; cin.get(sv[i].qq, 30);

}

}Trong đo n l nh trên sau khi nh p h tên c a sinh viên th 1, do kí t ạ ệ ậ ọ ủ ứ ự ↵ v n n m trong bẫ ằ ộ

đ m nên khi nh p quê quán ch ng trình s l y kí t ệ ậ ươ ẽ ấ ự ↵ này gán cho qq, do đó quê quán c aủ sinh viên s là xâu r ng.ẽ ỗ

Đ kh c ph c tình tr ng này chúng ta có th s d ng m t trong các câu l nh nh p kí t để ắ ụ ạ ể ử ụ ộ ệ ậ ự ể "nh c" d u enter còn "r i vãi" ra kh i b đ m. Có th s d ng các câu l nh sau :ấ ấ ơ ỏ ộ ệ ể ử ụ ệ

cin.get(); // đ c m t kí t trong b đ mọ ộ ự ộ ệ

cin.ignore(n); //đ c n kí t trong b đ m (v i n=1)ọ ự ộ ệ ớnh v y đ đo n ch ng trình trên ho t đ ng t t ta có th t ch c l i nh sau:ư ậ ể ạ ươ ạ ộ ố ể ổ ứ ạ ư

void main()

{

int i;

for (i=1; i<=3; i++) {

cout << "Nhap ho ten sv thu " << i; cin.get(sv[i].ht, 25);

cin.get(); // nh c 1 kí t (enter)ấ ự

cout << "Nhap que quan sv thu "<< i; cin.get(sv[i].qq, 30);

cin.get() // ho c cin.ignore(1);ặ

}

}

cin.getline(s, n, fchar): Ph ng th c này ho t đ ng hoàn toàn t ng t ph ng th cươ ứ ạ ộ ươ ự ươ ứ cin.get(s, n, fchar), tuy nhiên nó có th kh c ph c "l i enter" c a câu l nh trên. Cể ắ ụ ỗ ủ ệ ụ th hàm sau khi gán n i dung nh p cho bi n s s xóa kí t enter kh i b đ m và doể ộ ậ ế ẽ ự ỏ ộ ệ v y NSD không c n ph i s d ng thêm các câu l nh ph tr (cin.get(),ậ ầ ả ử ụ ệ ụ ợ cin.ignore(1)) đ lo i enter ra kh i b đ m. ể ạ ỏ ộ ệ

cin.ignore(n): Ph ng th c này c a đ i t ng cin dùng đ đ c và lo i b n kí t cònươ ứ ủ ố ượ ể ọ ạ ỏ ự trong b đ m (dòng nh p cin).ộ ệ ậ

Chú ý: Toán t nh p ử ậ >> cũng gi ng các ph ng th c nh p kí t và xâu kí t ch cũng ố ươ ứ ậ ự ự ở ỗ để l i kí t enter trong cinạ ự . Do v y, chúng ta nên s d ng các ph ng th c cin.get(), cin.ignore(n)ậ ử ụ ươ ứ đ lo i b kí t enter tr c khi th c hi n l nh nh p kí t và xâu kí t khác.ể ạ ỏ ự ướ ự ệ ệ ậ ự ự

T ng t dòng nh p cin, ươ ự ậ cout là dòng d li u xu t thu c l p ữ ệ ấ ộ ớ ostream. Đi u này có nghĩa dề ữ li u làm vi c v i các thao tác xu t (in) s đ a k t qu ra cout mà đã đ c m c đ nh là mànệ ệ ớ ấ ẽ ư ế ả ượ ặ ị

Page 271: Giao Trinh C++ Toan Tap

hình. Do đó ta có th s d ng toán t xu t << và các ph ng th c xu t trong các l p ios (l pể ử ụ ử ấ ươ ứ ấ ớ ớ c s ) và ostream.ơ ở

Toán t xu t <<ử ấToán t này cho phép xu t giá tr c a dãy các bi u th c đ n m t dòng Output_stream nào đóử ấ ị ủ ể ứ ế ộ v i cú pháp chung nh sau:ớ ư

Output_stream << bt_1 << bt_2 << … đây Output_stream là đ i t ng thu c l p ostream. Tr ng h p Output_stream là cout, câuở ố ượ ộ ớ ườ ợ

l nh xu t s đ c vi t:ệ ấ ẽ ượ ế

cout << bt_1 << bt_2 << …câu l nh này cho phép in k t qu c a các bi u th c ra màn hình. Ki u d li u c a các bi uệ ế ả ủ ể ứ ể ữ ệ ủ ể th c có th là s nguyên, th c, kí t ho c xâu kí t .ứ ể ố ự ự ặ ự

Đ NH D NGỊ Ạ

Các giá tr in ra màn hình có th đ c trình bày d i nhi u d ng khác nhau thông quaị ể ượ ướ ề ạ các công c đ nh d ng nh các ph ng th c, các c và các b ph n khác đ c khai báo s nụ ị ạ ư ươ ứ ờ ộ ậ ượ ẵ trong các l p ios và ostream. ớ

Các ph ng th c đ nh d ngươ ứ ị ạ

Ch đ nh đ r ng c n inỉ ị ộ ộ ầ

cout.width(n) ;S c t trên màn hình đ in m t giá tr đ c ng m đ nh b ng v i đ r ng th c (s ch s , chố ộ ể ộ ị ượ ầ ị ằ ớ ộ ộ ự ố ữ ố ữ cái và kí t khác trong giá t đ c in). Đ đ t l i đ r ng màn hình dành cho giá tr c n inự ị ượ ể ặ ạ ộ ộ ị ầ (thông th ng l n h n đ r ng th c) ta có th s d ng ph ng th c trên.ườ ớ ơ ộ ộ ự ể ử ụ ươ ứ

Ph ng th c này cho phép các giá tr in ra màn hình v i đ r ng n. N u n bé h n đ r ng th cươ ứ ị ớ ộ ộ ế ơ ộ ộ ự s c a giá tr thì máy s in giá tr v i s c t màn hình b ng v i đ r ng th c. N u n l n h nự ủ ị ẽ ị ớ ố ộ ằ ớ ộ ộ ự ế ớ ơ đ r ng th c, máy s in giá tr căn theo l ph i, và đ tr ng các c t th a phía tr c giá trộ ộ ự ẽ ị ề ả ể ố ộ ừ ướ ị đ c in. Ph ng th c này ch có tác d ng v i giá tr c n in ngay sau nó. Ví d :ượ ươ ứ ỉ ụ ớ ị ầ ụ

int a = 12; b = 345; // đ r ng th c c a a là 2, c a b là 3ộ ộ ự ủ ủ

cout << a; // chi m 2 c t màn hìnhế ộ

cout.width(7); // đ t đ r ng giá tr in ti p theo là 7ặ ộ ộ ị ế

cout << b; // b in trong 7 c t v i 4 d u cách đ ng tr cộ ớ ấ ứ ướK t qu in ra s là: 12<><><><>345ế ả ẽ

Ch đ nh kí t chèn vào kho ng tr ng tr c giá tr c n inỉ ị ự ả ố ướ ị ầ

cout.fill(ch) ;

Page 272: Giao Trinh C++ Toan Tap

Kí t đ n ng m đ nh là d u cách, có nghĩa khi đ r ng c a giá tr c n in bé h n đ r ng chự ộ ầ ị ấ ộ ộ ủ ị ầ ơ ộ ộ ỉ đ nh thì máy s đ n các d u cách vào tr c giá tr c n in cho đ v i đ r ng ch đ nh. Có thị ẽ ộ ấ ướ ị ầ ủ ớ ộ ộ ỉ ị ể yêu c u đ n m t kí t ch b t kỳ thay cho d u cách b ng ph ng th c trên. Ví d trong dãyầ ộ ộ ự ấ ấ ằ ươ ứ ụ l nh trên, n u ta thêm dòng l nh cout.fill('*') tr c khi in b ch ng h n thì k t qu in ra s là:ệ ế ệ ướ ẳ ạ ế ả ẽ 12****345.

Ph ng th c này có tác d ng v i m i câu l nh in sau nó cho đ n khi g p m t ch đ nh m i.ươ ứ ụ ớ ọ ệ ế ặ ộ ỉ ị ớ

Ch đ nh đ chính xác (s s l th p phân) c n inỉ ị ộ ố ố ẻ ậ ầ

cout.precision(n) ;Ph ng th c này yêu c u các s th c in ra sau đó s có n ch s l . Các s th c tr c khi inươ ứ ầ ố ự ẽ ữ ố ẻ ố ự ướ ra s đ c làm tròn đ n ch s l th n. Ch đ nh này có tác d ng cho đ n khi g p m t chẽ ượ ế ữ ố ẻ ứ ỉ ị ụ ế ặ ộ ỉ đ nh m i. Ví d :ị ớ ụ

int a = 12.3; b = 345.678; // đ r ng th c c a a là 4, c a b là 7ộ ộ ự ủ ủ

cout << a; // chi m 4 c t màn hìnhế ộ

cout.width(10); // đ t đ r ng giá tr in ti p theo là 10ặ ộ ộ ị ế

cout.precision(2); // đ t đ chính xác đ n 2 s lặ ộ ế ố ẻ

cout << b; // b in trong 10 c t v i 4 d u cách đ ng tr cộ ớ ấ ứ ướK t qu in ra s là: 12.3<><><><>345.68ế ả ẽ

Các c đ nh d ngờ ị ạM t s các qui đ nh v đ nh d ng th ng đ c g n li n v i các "c ". Thông th ng n uộ ố ị ề ị ạ ườ ượ ắ ề ớ ờ ườ ế đ nh d ng này đ c s d ng trong su t quá trình ch y ch ng trình ho c trong m t kho ngị ạ ượ ử ụ ố ạ ươ ặ ộ ả th i gian dài tr c khi g b thì ta "b t" các c t ng ng v i nó. Các c đ c b t s có tácờ ướ ỡ ỏ ậ ờ ươ ứ ớ ờ ượ ậ ẽ d ng cho đ n khi c v i đ nh d ng khác đ c b t. Các c đ c cho trong file tiêu đụ ế ờ ớ ị ạ ượ ậ ờ ượ ề iostream.h.

Đ b t/t t các c ta s d ng các ph ng th c sau:ể ậ ắ ờ ử ụ ươ ứ

cout.setf(danh sách c );ờ // B t các c trong danh sáchậ ờ

cout.unsetf(danh sách c );ờ // T t các c trong danh sáchắ ờCác c trong danh sách đ c vi t cách nhau b i phép toán h p bit (|). Ví d l nhờ ượ ế ở ợ ụ ệ cout.setf(ios::left | ios::scientific) s b t các c ios::left và ios::scientific. Ph ng th cẽ ậ ờ ươ ứ cout.unsetf(ios::right | ios::fixed) s t t các c ios::right | ios::fixed.ẽ ắ ờ

D i đây là danh sách các c cho trong iostream.h.ướ ờ

Nhóm căn lề

ios::left : n u b t thì giá tr in n m bên trái vùng in ra (kí t đ n n m sau).ế ậ ị ằ ự ộ ằ

ios::right : giá tr in n m bên phái vùng in ra (kí t đ n n m tr c), đây là tr ng h pị ằ ự ộ ằ ướ ườ ợ

Page 273: Giao Trinh C++ Toan Tap

ng m đ nh n u ta không s d ng c c th .ầ ị ế ử ụ ờ ụ ể

ios::internal : gi ng c ios::right tuy nhiên d u c a giá tr in ra s đ c in đ u tiên, sauố ờ ấ ủ ị ẽ ượ ầ đó m i đ n kí t đ n và giá tr s .ớ ế ự ộ ị ố

Ví d :ụ

int a = 12.3; b = −345.678; // đ r ng th c c a a là 4, c a b là 8ộ ộ ự ủ ủ

cout << a; // chi m 4 c t màn hìnhế ộ

cout.width(10); // đ t đ r ng giá tr in ti p theo là 10ặ ộ ộ ị ế

cout.fill('*') ; // d u * làm kí t đ nấ ự ộ

cout.precision(2); // đ t đ chính xác đ n 2 s lặ ộ ế ố ẻ

cout.setf(ios::left) ; // b t c ios::leftậ ờ

cout << b; // k t q a: 12.3ế ủ −345.68***

cout.setf(ios::right) ; // b t c ios::rightậ ờ

cout << b; // k t q a: 12.3***ế ủ −345.68

cout.setf(ios::internal) ; // b t c ios::internalậ ờ

cout << b; // k t q a: 12.3ế ủ −***345.68

Nhóm đ nh d ng s nguyênị ạ ố

ios::dec : in s nguyên d i d ng th p phân (ng m đ nh)ố ướ ạ ậ ầ ị

ios::oct : in s nguyên d i d ng c s 8ố ướ ạ ơ ố

ios::hex : in s nguyên d i d ng c s 16ố ướ ạ ơ ố

Nhóm đ nh d ng s th cị ạ ố ự

ios::fixed : in s th c d ng d u ph y tĩnh (ng m đ nh)ố ự ạ ấ ả ầ ị

ios::scientific : in s th c d ng d u ph y đ ngố ự ạ ấ ả ộ

ios::showpoint : in đ n ch s l c a ph n th p phân, n u t t (ng m đ nh) thì không inủ ữ ố ẻ ủ ầ ậ ế ắ ầ ị các s 0 cu i c a ph n th p phân.ố ố ủ ầ ậ

Ví d : gi s đ chính xác đ c đ t v i 3 s l (b i câu l nh cout.precision(3))ụ ả ử ộ ượ ặ ớ ố ẻ ở ệ

n u fixed b t + showpoint b t : ế ậ ậ

123.2500 đ c in thànhượ 123.250

123.2599 đ c in thànhượ 123.260

123.2 đ c in thànhượ 123.200

n u fixed b t + showpoint t t : ế ậ ắ

123.2500 đ c in thànhượ 123.25

123.2599 đ c in thànhượ 123.26

Page 274: Giao Trinh C++ Toan Tap

123.2 đ c in thànhượ 123.2

n u scientific b t + showpoint b t : ế ậ ậ

12.3 đ c in thànhượ 1.230e+01

2.32599 đ c in thànhượ 2.326e+00

324 đ c in thànhượ 3.240e+02

n u scientific b t + showpoint t t : ế ậ ắ

12.3 đ c in thànhượ 1.23e+01

2.32599 đ c in thànhượ 2.326e+00

324 đ c in thànhượ 3.24e+02

Nhóm đ nh d ng hi n thị ạ ể ị

ios::showpos : n u t t (ng m đ nh) thì không in d u c ng (+) tr c s d ng. N u b tế ắ ầ ị ấ ộ ướ ố ươ ế ậ tr c m i s d ng s in thêm d u c ng.ướ ỗ ố ươ ẽ ấ ộ

ios::showbase : n u b t s in s 0 tr c các s nguyên h 8 và in 0x tr c s h 16.ế ậ ẽ ố ướ ố ệ ướ ố ệ N u t t (ng m đ nh) s không in 0 và 0x.ế ắ ầ ị ẽ

ios::uppercase : n u b t thì các kí t bi u di n s trong h 16 (A..F) s vi t hoa, n uế ậ ự ể ễ ố ệ ẽ ế ế t t (ng m đ nh) s vi t th ng.ắ ầ ị ẽ ế ườ

Các b và hàm đ nh d ngộ ị ạiostream.h cũng cung c p m t s b và hàm đ nh d ng cho phép s d ng ti n l i h n so v iấ ộ ố ộ ị ạ ử ụ ệ ợ ơ ớ các c và các ph ng th c vì nó có th đ c vi t liên ti p trên dòng l nh xu t.ờ ươ ứ ể ượ ế ế ệ ấ

Các b đ nh d ngộ ị ạ

dec // t ng t ios::decươ ự

oct // t ng t ios::decươ ự

hex // t ng t ios::hexươ ự

endl // xu t kí t xu ng dòng ('\n')ấ ự ố

flush // đ y toàn b d li u ra dòng xu tẩ ộ ữ ệ ấVí d : ụ

cout.setf(ios::showbase) ; // cho phép in các kí t bi u th c sự ể ị ơ ố

cout.setf(ios::uppercase) ; // d i d ng ch vi t hoaướ ạ ữ ế

int a = 171; int b = 32 ;

cout << hex << a << endl << b ; // in 0xAB và 0x20

Các hàm đ nh d ng (#include <iomanip.h>)ị ạ

setw(n) // t ng t cout.width(n)ươ ự

Page 275: Giao Trinh C++ Toan Tap

setprecision(n) // t ng t cout.precision(n)ươ ự

setfill(c) // t ng t cout.fill(c)ươ ự

setiosflags(l) // t ng t cout.setf(l)ươ ự

resetiosflags(l) // t ng t cout.unsetf(l)ươ ự

IN RA MÁY IN

Nh trong ph n đ u ch ng đã trình bày, đ làm vi c v i các thi t b khác v i màn hình vàư ầ ầ ươ ể ệ ớ ế ị ớ đĩa … chúng ta c n t o ra các đ i t ng (thu c các l p ifstream, ofstream và fstream) t c cácầ ạ ố ượ ộ ớ ứ dòng tin b ng các hàm t o c a l p và g n chúng v i thi t b b ng câu l nh: ằ ạ ủ ớ ắ ớ ế ị ằ ệ

ofstream Tên_dòng(thi t b ) ;ế ịVí d đ t o m t đ i t ng mang tên Mayin và g n v i máy in, chúng ta dùng l nh:ụ ể ạ ộ ố ượ ắ ớ ệ

ofstream Mayin(4) ;trong đó 4 là s hi u c a máy in.ố ệ ủ

Khi đó m i câu l nh dùng toán t xu t << và cho ra Mayin s đ a d li u c n in vào m t bọ ệ ử ấ ẽ ư ữ ệ ầ ộ ộ đ m m c đ nh trong b nh . N u b đ m đ y, m t s thông tin đ a vào tr c s t đ ngệ ặ ị ộ ớ ế ộ ệ ầ ộ ố ư ướ ẽ ự ộ chuy n ra máy in. Đ ch đ ng đ a t t c d li u còn l i trong b đ m ra máy in chúng taể ể ủ ộ ư ấ ả ữ ệ ạ ộ ệ c n s d ng b đ nh d ng flush (Mayin << flush << …) ho c ph ng th c flushầ ử ụ ộ ị ạ ặ ươ ứ (Mayin.flush(); ). Ví d :ụ

Sau khi đã khai báo m t đ i t ng mang tên Mayin b ng câu l nh nh trên Đ in chu vi vàộ ố ượ ằ ệ ư ể di n tích hình ch nh t có c nh cd và cr ta có th vi t:ệ ữ ậ ạ ể ế

Mayin << "Di n tích HCN = " << cd * cr << endl;ệ

Mayin << "Chu vi HCN = " << 2*(cd + cr) << endl;

Mayin.flush();ho c :ặ

Mayin << "Di n tích HCN = " << cd * cr << endl;ệ

Mayin << "Chu vi HCN = " << 2*(cd + cr) << endl << flush;khi ch ng trình k t thúc m i d li u còn l i trong các đ i t ng s đ c t đ ng chuy n raươ ế ọ ữ ệ ạ ố ượ ẽ ượ ự ộ ể thi t b g n v i nó. Ví d máy in s in t t c m i d li u còn sót l i trong Mayin khi ch ngế ị ắ ớ ụ ẽ ấ ả ọ ữ ệ ạ ươ trình k t thúc.ế

LÀM VI C V I FILEỆ Ớ

Làm vi c v i m t file trên đĩa cũng đ c quan ni m nh làm vi c v i các thi t b khác c aệ ớ ộ ượ ệ ư ệ ớ ế ị ủ máy tính (ví d nh làm vi c v i máy in v i đ i t ng Mayin trong ph n trên ho c làm vi cụ ư ệ ớ ớ ố ượ ầ ặ ệ v i màn hình v i đ i t ng chu n cout). Các đ i t ng này đ c khai báo thu c l p ifstreamớ ớ ố ượ ẩ ố ượ ượ ộ ớ hay ofstream tùy thu c ta mu n s d ng file đ đ c hay ghi.ộ ố ử ụ ể ọ

Page 276: Giao Trinh C++ Toan Tap

Nh v y, đ s d ng m t file d li u đ u tiên chúng ta c n t o đ i t ng và g n choư ậ ể ử ụ ộ ữ ệ ầ ầ ạ ố ượ ắ file này. Đ t o đ i t ng có th s d ng các hàm t o có s n trong hai l p ifstream vàể ạ ố ượ ể ử ụ ạ ẵ ớ ofstream. Đ i t ng s đ c g n v i tên file c th trên đĩa ngay trong quá trình t o đ iố ượ ẽ ượ ắ ớ ụ ể ạ ố t ng (t o đ i t ng v i tham s là tên file) ho c cũng có th đ c g n v i tên file sau nàyượ ạ ố ượ ớ ố ặ ể ượ ắ ớ b ng câu l nh m file. Sau khi đã g n m t đ i t ng v i file trên đĩa, có th s d ng đ iằ ệ ở ắ ộ ố ượ ớ ể ử ụ ố t ng nh đ i v i Mayin ho c cin, cout. Đi u này có nghĩa trong các câu l nh in ra màn hìnhượ ư ố ớ ặ ề ệ ch c n thay t khóa cout b i tên đ i t ng m i d li u c n in trong câu l nh s đ c ghi lênỉ ầ ừ ở ố ượ ọ ữ ệ ầ ệ ẽ ượ file mà đ i t ng đ i di n. Cũng t ng t n u thay cin b i tên đ i t ng, d li u s đ cố ượ ạ ệ ươ ự ế ở ố ượ ữ ệ ẽ ượ đ c vào t file thay cho t bàn phím. Đ t o đ i t ng dùng cho vi c ghi ta khai báo chúngọ ừ ừ ể ạ ố ượ ệ v i l p ớ ớ ofstream còn đ dùng cho vi c đ c ta khai báo chúng v i l p ể ệ ọ ớ ớ ifstream.

T o đ i t ng g n v i fileạ ố ượ ắ ớ

M i l p ifstream và ofstream cung c p 4 ph ng th c đ t o file. đây chúng tôi chỗ ớ ấ ươ ứ ể ạ Ở ỉ trình bày 2 cách (2 ph ng th c) hay dùng.ươ ứ

Cách 1: <L p> đ i_t ng;ớ ố ượđ i_t ng.open(tên_file, ch _đ );ố ượ ế ộ

L p là m t trong hai l p ifstream và ofstream. Đ i t ng là tên do NSD t đ t. Ch đ là cáchớ ộ ớ ố ượ ự ặ ế ộ th c làm vi c v i file (xem d i). Cách này cho phép t o tr c m t đ i t ng ch a g n v iứ ệ ớ ướ ạ ướ ộ ố ượ ư ắ ớ file c th nào. Sau đó dùng ti p ph ng th c open đ đ ng th i m file và g n v i đ iụ ể ế ươ ứ ể ồ ờ ở ắ ớ ố t ng v a t o.ượ ừ ạ

Ví d :ụ

ifstream f; // t o đ i t ng có tên f đ đ c ho c ạ ố ượ ể ọ ặ

ofstream f; // t o đ i t ng có tên f đ ghiạ ố ượ ể

f.open("Baitap"); // m file Baitap và g n v i fở ắ ớ

Cách 2: <L p> đ i_t ng(tên_file, ch _đ )ớ ố ượ ế ộCách này cho phép đ ng th i m file c th và g n file v i tên đ i t ng trong câu l nh.ồ ờ ở ụ ể ắ ớ ố ượ ệ

Ví d :ụ

ifstream f("Baitap"); // m file Baitap g n v i đ i t ng f đở ắ ớ ố ượ ể

ofstream f("Baitap); // đ c ho c ghi.ọ ặSau khi m file và g n v i đ i t ng f, m i thao tác trên f cũng chính là làm vi c v i fileở ắ ớ ố ượ ọ ệ ớ Baitap.

Trong các câu l nh trên có các ch đ đ qui đ nh cách th c làm vi c c a file. Các ch đ nàyệ ế ộ ể ị ứ ệ ủ ế ộ g m có:ồ

ios::binary : quan ni m file theo ki u nh phân. Ng m đ nh là ki u văn b n.ệ ể ị ầ ị ể ả

ios::in : file đ đ c (ng m đ nh v i đ i t ng trong ifstream).ể ọ ầ ị ớ ố ượ

ios::out : file đ ghi (ng m đ nh v i đ i t ng trong ofstream), n u file đã có trên đĩaể ầ ị ớ ố ượ ế

Page 277: Giao Trinh C++ Toan Tap

thì n i dung c a nó s b ghi đè (b xóa).ios::app : b sung vào cu i fileộ ủ ẽ ị ị ổ ố

ios::trunc : xóa n i dung file đã cóộ

ios::ate : chuy n con tr đ n cu i fileể ỏ ế ố

ios::nocreate : không làm gì n u file ch a cóế ư

ios::replace : không làm gì n u file đã cóếcó th ch đ nh cùng lúc nhi u ch đ b ng cách ghi chúng liên ti p nhau v i toán t h p bit |.ể ỉ ị ề ế ộ ằ ế ớ ử ợ Ví d đ m file bài t p nh m t file nh phân và ghi ti p theo vào cu i file ta dùng câu l nh:ụ ể ở ậ ư ộ ị ế ố ệ

ofstream f("Baitap", ios::binary | ios::app);

Đóng file và gi i phóng đ i t ng ả ố ượĐ đóng file đ c đ i di n b i f, s d ng ph ng th c close nh sau:ể ượ ạ ệ ở ử ụ ươ ứ ư

đ i_t ng.close();ố ượSau khi đóng file (và gi i phóng m i liên k t gi a đ i t ng và file) có th dùng đ i t ng đả ố ế ữ ố ượ ể ố ượ ể g n và làm vi c v i file khác b ng ph ng th c open nh trên.ắ ệ ớ ằ ươ ứ ư

: Đ c m t dãy s t bàn phím và ghi lên file. File đ c xem nh file văn b n (ng m đ nh), cácọ ộ ố ừ ượ ư ả ầ ị s đ c ghi cách nhau 1 d u cách.ố ượ ấ

#include <iostream.h>

#include <fstream.h>

#include <conio.h>

void main()

{

ofstream f; // khai báo (t o) đ i t ng fạ ố ượ

int x;

f.open("DAYSO"); // m file DAYSO và g n v i fở ắ ớ

for (int i = 1; i<=10; i++) {

cin >> x;

f << x << ' ';

}

f.close();

}

: Ch ng trình sau nh p danh sách sinh viên, ghi vào file 1, đ c ra m ng, s p x p theo tu i vàươ ậ ọ ả ắ ế ổ in ra file 2. Dòng đ u tiên trong file ghi s sinh viên, các dòng ti p theo ghi thông tin c a sinhầ ố ế ủ viên g m h tên v i đ r ng 24 kí t , tu i v i đ r ng 4 kí t và đi m v i đ r ng 8 kí t .ồ ọ ớ ộ ộ ự ổ ớ ộ ộ ự ể ớ ộ ộ ự

#include <iostream.h>

Page 278: Giao Trinh C++ Toan Tap

#include <iomanip.h>

#include <fstream.h>

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <ctype.h>

struct Sv {

char *hoten;

int tuoi;

double diem;

};

class Sinhvien {

int sosv ;

Sv *sv;

public:

Sinhvien() {

sosv = 0;

sv = NULL;

}

void nhap();

void sapxep();

void ghifile(char *fname);

};

void Sinhvien::nhap()

{

cout << "\nS sinh viên: "; cin >> sosv;ố

int n = sosv;

sv = new Sinhvien[n+1]; // B ph n t th 0ỏ ầ ử ứ

for (int i = 1; i <= n; i++) {

cout << "\nNh p sinh viên th : " << i << endl;ậ ứ

cout << "\nH tên: "; cin.ignore(); cin.getline(sv[i].hoten);ọ

cout << "\nTu i: "; cin >> sv[i].tuoi;ổ

Page 279: Giao Trinh C++ Toan Tap

cout << "\nĐi m: "; cin >> sv[i].diem;ể

}

}

void Sinhvien::ghi(char fname)

{

ofstream f(fname) ;

f << sosv;

f << setprecision(1) << setiosflags(ios::showpoint) ;

for (int i=1; i<=sosv; i++) {

f << endl << setw(24) << sv[i].hoten << setw(4) << tuoi;

f << setw(8) << sv[i].diem;

}

f.close();

}

void Sinhvien::doc(char fname)

{

ifstream f(fname) ;

f >> sosv;

for (int i=1; i<=sosv; i++) {

f.getline(sv[i].hoten, 25);

f >> sv[i].tuoi >> sv[i].diem;

}

f.close();

}

void Sinhvien::sapxep()

{

int n = sosv;

for (int i = 1; i < n; i++) {

for (int j = j+1; j <= n; j++) {

if (sv[i].tuoi > sv[j].tuoi) {

Page 280: Giao Trinh C++ Toan Tap

Sinhvien t = sv[i]; sv[i] = sv[j]; sv[j] = t;

}

}

void main() {

clrscr();

Sinhvien x ;

x.nhap(); x.ghi("DSSV1");

x.doc("DSSV1"); x.sapxep(); x.ghi("DSSV2");

cout << "Đã xong";

getch();

}

Ki m tra s t n t i c a file, ki m tra h t fileể ự ồ ạ ủ ể ếVi c m m t file ch a có đ đ c s gây nên l i và làm d ng ch ng trình. Khi x y ra l i mệ ở ộ ư ể ọ ẽ ỗ ừ ươ ả ỗ ở file, giá tr tr l i c a ph ng th c bad là m t s khác 0. Do v y có th s d ng ph ng th cị ả ạ ủ ươ ứ ộ ố ậ ể ử ụ ươ ứ này đ ki m tra m t file đã có trên đĩa hay ch a. Ví d :ể ể ộ ư ụ

ifstream f("Bai tap");

if (f.bad()) {

cout << "file Baitap ch a có";ư

exit(1);

}Khi đ c ho c ghi, con tr file s chuy n d n v cu i file. Khi con tr cu i file, ph ngọ ặ ỏ ẽ ể ầ ề ố ỏ ở ố ươ th c eof() s tr l i giá tr khác không. Do đó có th s d ng ph ng th c này đ ki m tra đãứ ẽ ả ạ ị ể ử ụ ươ ứ ể ể h t file hay ch a.ế ư

Ch ng trình sau cho phép tính đ dài c a file Baitap. File c n đ c m theo ki u nh phân.ươ ộ ủ ầ ượ ở ể ị

#include <iostream.h>

#include <fstream.h>

#include <stdlib.h>

#include <conio.h>

void main()

{

clrscr();

long dodai = 0;

Page 281: Giao Trinh C++ Toan Tap

char ch;

ifstream f("Baitap", ios::in | ios::binary) ;

if (f.bad()) {

cout << "File Baitap không có";

exit(1);

}

while (!f.eof()) {

f.get(ch));

dodai++;

}

cout << "Đ dài c a file = " << dodai;ộ ủ

getch();

}

Đ c ghi đ ng th i trên fileọ ồ ờĐ đ c ghi đ ng th i, file ph i đ c g n v i đ i t ng c a l p fstream là l p th a k c a 2ể ọ ồ ờ ả ượ ắ ớ ố ượ ủ ớ ớ ừ ế ủ l p ifstream và ofstream. Khi đó ch đ ph i đ c bao g m ch đ nh ios::in | ios::out. Ví d :ớ ế ộ ả ượ ồ ỉ ị ụ

fstream f("Data", ios::in | ios::out) ;ho c ặ

fstream f ;

f.open("Data", ios::in | ios::out) ;

Di chuy n con tr fileể ỏCác ph ng th c sau cho phép làm vi c trên đ i t ng c a dòng xu t (ofstream).ươ ứ ệ ố ượ ủ ấ

đ i_t ng.seekp(n)ố ượ ; Di chuy n con tr đ n byte th n (các byte đ c tính t 0)ể ỏ ế ứ ượ ừ

đ i_t ng.seekp(n, v trí xu t phát) ; ố ượ ị ấ Di chuy n đi n byte (có th âm ho c d ng) tể ể ặ ươ ừ v trí xu t phát. V trí xu t phát g m:ị ấ ị ấ ồ

ios::beg : t đ u fileừ ầ

ios::end : t cu i fileừ ố

ios::cur : t v trí hi n t i c a con tr .ừ ị ệ ạ ủ ỏ

đ i_t ng.tellp(n) ; ố ượ Cho bi t v trí hi n t i c a con tr .ế ị ệ ạ ủ ỏĐ làm vi c v i dòng nh p tên các ph ng th c trên đ c thay t ng ng b i các tên : ể ệ ớ ậ ươ ứ ượ ươ ứ ở seekg và tellg. Đ i v i các dòng nh p l n xu t có th s d ng đ c c 6 ph ng th c trên.ố ớ ậ ẫ ấ ể ử ụ ượ ả ươ ứ

Ví d sau tính đ dài t p đ n gi n h n ví d trên.ụ ộ ệ ơ ả ơ ụ ở

Page 282: Giao Trinh C++ Toan Tap

fstream f("Baitap");

f.seekg(0, ios::end);

cout << "Đ dài b ng = " << f.tellg();ộ ằ

: Ch ng trình nh p và in danh sách sinh viên trên ghi/đ c đ ng th i.ươ ậ ọ ồ ờ

#include <iostream.h>

#include <iomanip.h>

#include <fstream.h>

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <ctype.h>

void main() {

int stt ;

char *hoten, *fname, traloi;

int tuoi;

float diem;

fstream f;

cout << "Nh p tên file: "; cin >> fname;ậ

f.open(fname, ios::in | ios::out | ios::noreplace) ;

if (f.bad()) {

cout << "T p đã có. Ghi đè (C/K)?" ;ệ

cin.get(traloi) ;

if (toupper(traloi) == 'C') {

f.close() ;

f.open(fname, ios::in | ios::out | ios::trunc) ;

} else exit(1);

}

stt = 0;

f << setprecision(1) << setiosflags(ios::showpoint) ;

// nh p danh sáchậ

while (1) {

stt++;

cout << "\nNh p sinh viên th " << stt ;ậ ứ

Page 283: Giao Trinh C++ Toan Tap

cout << "\nH tên: "; cin.ignore() ; cin.getline(hoten, 25);ọ

if (hoten[0] = 0) break;

cout << "\nTu i: "; cin >> tuoi;ổ

cout << "\nĐi m: "; cin >> diem;ể

f << setw(24) << hoten << endl;

f << setw(4) << tuoi << set(8) << diem ;

}

// in danh sách

f.seekg(0) ; // quay v đ u danh sáchề ầ

stt = 0;

clrscr();

cout << "Danh sách sinh viên đã nh p\n" ;ậ

cout << setprecision(1) << setiosflags(ios::showpoint) ;

while (1) {

f.getline(hoten,25);

if (f.eof()) break;

stt++;

f >> tuoi >> diem;

f.ignore();

cout << "\nSinh viên th " << stt ;ứ

cout << "\nH tên: " << hoten;ọ

cout << "\nTu i: " << setw(4) << tuoi;ổ

cout << "\nĐi m: " << setw(8) << diem;ể

}

f.close();

getch();

}

NH P/XU T NH PHÂNẬ Ấ Ị

Khái ni m v 2 lo i file: văn b n và nh phânệ ề ạ ả ị

File văn b nảTrong file văn b n m i byte đ c xem là m t kí t . Tuy nhiên n u 2 byte 10 (LF), 13ả ỗ ượ ộ ự ế

(CR) đi li n nhau thì đ c xem là m t kí t và nó là kí t xu ng dòng. Nh v y file văn b n làề ượ ộ ự ự ố ư ậ ả

Page 284: Giao Trinh C++ Toan Tap

m t t p h p các dòng kí t v i kí t xu ng dòng có mã là 10. Kí t có mã 26 đ c xem là kíộ ậ ợ ự ớ ự ố ự ượ t k t thúc file.ự ế

File nh phânịThông tin l u trong file đ c xem nh dãy byte bình th ng. Mã k t thúc file đ c ch n là -1,ư ượ ư ườ ế ượ ọ đ c đ nh nghĩa là EOF trong stdio.h. Các thao tác trên file nh phân th ng đ c ghi t ng byteượ ị ị ườ ọ ừ m t, không quan tâm ý nghĩa c a byte.ộ ủ

M t s các thao tác nh p/xu t s có hi u qu khác nhau khi m file d i các d ng khác nhau.ộ ố ậ ấ ẽ ệ ả ở ướ ạ

: gi s ch = 10, khi đó f << ch s ghi 2 byte 10,13 lên file văn b n f, trong khi đó l nh này chả ử ẽ ả ệ ỉ khi 1 byte 10 lên file nh phân.ịNg c l i, n u f la file văn b n thì f.getc(ch) s tr v ch 1 byte 10 khi đ c đ c 2 byte 10,ượ ạ ế ả ẽ ả ề ỉ ọ ượ 13 liên ti p nhau.ế

M t file luôn ng m đ nh d i d ng văn b n, do v y đ ch đ nh file là nh phân ta c n sộ ầ ị ướ ạ ả ậ ể ỉ ị ị ầ ử d ng c ios::binary.ụ ờ

Đ c, ghi kí tọ ự

put(c); // ghi kí t ra fileự

get(c); // đ c kí t t fileọ ự ừ

: Sao chép file 1 sang file 2. C n sao chép và ghi t ng byte m t do v y đ chính xác ta s mầ ừ ộ ậ ể ẽ ở các file d i d ng nh phân.ướ ạ ị

#include <iostream.h>

#include <fstream.h>

#include <stdlib.h>

#include <conio.h>

void main()

{

clrscr();

fstream fnguon("DATA1", ios::in | ios::binary);

fstream fdich("DATA2", ios::out | ios::binary);

char ch;

while (!fnguon.eof()) {

fnguon.get(ch);

fdich.put(ch);

}

fnguon.close();

Page 285: Giao Trinh C++ Toan Tap

fdich.close();

}

Đ c, ghi dãy kí tọ ự

write(char *buf, int n); // ghi n kí t trong buf ra dòng xu tự ấ

read(char *buf, int n); // nh p n kí t t buf vào dòng nh pậ ự ừ ậ

gcount(); // cho bi t s kí t read đ c đ cế ố ự ọ ượ

: Ch ng trình sao chép file trên có th s d ng các ph ng th c m i này nh sau:ươ ở ể ử ụ ươ ứ ớ ư

#include <iostream.h>

#include <fstream.h>

#include <stdlib.h>

#include <conio.h>

void main()

{

clrscr();

fstream fnguon("DATA1", ios::in | ios::binary);

fstream fdich("DATA2", ios::out | ios::binary);

char buf[2000] ;

int n = 2000;

while (n) {

fnguon.read(buf, 2000);

n = fnguon.gcount();

fdich.write(buf, n);

}

fnguon.close();

fdich.close();

}

Đ c ghi đ ng th iọ ồ ờ

#include <iostream.h>

#include <iomanip.h>

#include <fstream.h>

Page 286: Giao Trinh C++ Toan Tap

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <ctype.h>

struct Sv {

char *hoten;

int tuoi;

double diem;

};

class Sinhvien {

int sosv;

Sv x;

char fname[30];

static int size;

public:

Sinhvien(char *fn);

void tao();

void bosung();

void xemsua();

};

int Sinhvien::size = sizeof(Sv);

Sinhvien::Sinhvien(char *fn)

{

strcpy(fname, fn) ;

fstream f;

f.open(fname, ios::in | ios::ate | ios::binary);

if (!f.good) sosv = 0;

else {

sosv = f.tellg() / size;

}

Page 287: Giao Trinh C++ Toan Tap

}

void Sinhvien::tao()

{

fstream f;

f.open(fname, ios::out | ios::noreplace | ios::binary);

if (!f.good()) {

cout << "danh sach da co. Co tao lai (C/K) ?";

char traloi = getch();

if (toupper(traloi) == 'C') return;

else {

f.close() ;

f.open(fname, ios::out | ios::trunc | ios::binary);

}

}

sosv = 0

while (1) {

cout << "\nSinh viên th : " << sosv+1;ứ

cout << "\nH tên: "; cin.ignore(); cin.getline(x.hoten);ọ

if (x.hoten[0] == 0) break;

cout << "\nTu i: "; cin >> x.tuoi;ổ

cout << "\nĐi m: "; cin >> x.diem;ể

f.write((char*)(&x), size);

sosv++;

}

f.close();

}

void Sinhvien::bosung()

{

fstream f;

f.open(fname, ios::out | ios::app | ios::binary);

if (!f.good()) {

Page 288: Giao Trinh C++ Toan Tap

cout << "danh sach chua co. Tao moi (C/K) ?";

char traloi = getch();

if (toupper(traloi) == 'C') return;

else {

f.close() ;

f.open(fname, ios::out | ios::binary);

}

}

int stt = 0

while (1) {

cout << "\nB sung sinh viên th : " << stt+1;ổ ứ

cout << "\nH tên: "; cin.ignore(); cin.getline(x.hoten);ọ

if (x.hoten[0] == 0) break;

cout << "\nTu i: "; cin >> x.tuoi;ổ

cout << "\nĐi m: "; cin >> x.diem;ể

f.write((char*)(&x), size);

stt++;

}

sosv += stt;

f.close();

}

void Sinhvien::xemsua()

{

fstream f;

int ch;

f.open(fname, ios::out | ios::app | ios::binary);

if (!f.good()) {

cout << "danh sach chua co";

getch(); return;

}

cout << "\nDanh sách sinh viên" << endl;

int stt ;

Page 289: Giao Trinh C++ Toan Tap

while (1) {

cout << "\nC n xem (sua) sinh viên th (0: d ng): " ;ầ ứ ừ

cin >> stt;

if (stt < 1 || stt > sosv) break;

f.seekg((stt-1) * size, ios::beg);

f.read((char*)(&x), size);

cout << "\nH tên: " << x.hoten; ọ

cout << "\nTu i: " << x.tuoi;ổ

cout << "\nĐi m: " << x.diem;ể

cout << "Có s a không (C/K) ?"; ử

cin >> traloi;

if (toupper(traloi) == 'C') {

f.seekg(-size, ios::cur);

cout << "\nH tên: "; cin.ignore(); cin.getline(x.hoten);ọ

cout << "\nTu i: "; cin >> x.tuoi;ổ

cout << "\nĐi m: "; cin >> x.diem;ể

f.write((char*)(&x), size);

}

}

f.close();

}

void main()

{

int chon;

Sinhvien SV("DSSV") ;

while (1) {

clrscr();

cout << "\n1: T o danh sách sinh viên";ạ

cout << "\n2: B sung danh sách";ổ

cout << "\n3: Xem – s a danh sách";ử

cout << "\n0: K t thúc";ế

chon = getch();

Page 290: Giao Trinh C++ Toan Tap

chon = chon – 48;

clrscr();

if (chon == 1) SV.tao();

else if (chon == 2) SV.bosung();

else if (chon == 3) SV.xemsua();

else break;

}

}

Mét sè Bµi tËp thùc hµnh

m«n kü thuËt lËp tr×nh­­­­­­­­­­­­­­­

Ch¬ng I: BiÕn – biÓu thøc – c¸c lÖnh nhËp xuÊt

1. NhËp hai sè nguyªn, tÝnh tæng, hiÖu, tÝch, th¬ng, ®ång d.

2. NhËp mét sè nguyªn, in ra mµn h×nh c¸ch ®äc sè nguyªn ®ã (VD: sè 1252 ®äc lµ: mét ngµn hai tr¨m n¨m chôc hai ®¬n vÞ).

3. ViÕt ch¬ng tr×nh tÝnh gi¸ trÞ biÓu thøc:

F(x) = (x2+ex+sin2(x))/sqrt(x2+1) 

Ch¬ng II: c¸c cÊu tróc ®iÒu khiÓn

1. ViÕt ch¬ng tr×nh nhËp vµo mét sè nguyªn n. KiÓm tra xem n ch½n hay lÎ.

Page 291: Giao Trinh C++ Toan Tap

2. ViÕt ch¬ng tr×nh gi¶i vµ biÖn luËn ph¬ng tr×nh bËc nhÊt theo hai hÖ sè a, b nhËp tõ bµn phÝm.

3. ViÕt ch¬ng tr×nh gi¶i vµ biÖn luËn ph¬ng tr×nh bËc hai víi c¸c hÖ sè a, b, c nhËp tõ bµn phÝm.

4. ViÕt ch¬ng tr×nh nhËp vµo sè tiÒn ph¶i tr¶ cña kh¸ch hµng. In ra sè tiÒn khuyÕn m∙i víi quy ®Þnh: nÕu sè tiÒn ph¶i tr¶ thuéc [200.000, 300.000) th× khuyÕn m∙i 20%. NÕu sè tiÒn ph¶i tr¶ tõ 300.000 trë lªn th× khuyÕn m∙i 30%. Cßn l¹i th× kh«ng khuyÕn m∙i.

5. ViÕt ch¬ng tr×nh nhËp vµo ®iÓm tæng kÕt cña mét häc sinh vµ in ra xÕp lo¹i cho häc sinh ®ã víi quy ®Þnh:

- XÕp lo¹i giái nÕu tæng ®iÒm tõ 8.00 trë lªn.

- XÕp lo¹i kh¸ nÕu tæng ®iÓm tõ 7.00 tíi cËn 8.00.

- XÕp lo¹i trung b×nh nÕu tæng ®iÓm tõ 5.00 tíi cËn 7.00.

- Cßn l¹i, xÕp lo¹i yÕu.

­­­­­­­­­­­­­­­­­­­

6. ViÕt ch¬ng tr×nh nhËp vµo mét th¸ng bÊt kú, sau ®ã in ra sè ngµy cã trong th¸ng (quy ®Þnh th¸ng 2 cã 28 ngµy).

­­­­­­­­­­­­­­­­­­­

7. ViÕt ch¬ng tr×nh tÝnh n!

8. NhËp vµo mét sè nguyªn, kiÓm tra xem mét sè võa nhËp cã ph¶i lµ sè nguyªn tè kh«ng, in kÕt luËn ra mµn h×nh.

9. ViÕt ch¬ng tr×nh nhËp vµo mét sè nguyªn n, sau ®ã tÝnh gi¸ trÞ biÓu thøc:

S =  n

1...

3

1

2

11 ++++

10. ViÕt ch¬ng tr×nh nhËp vµo mét sè nguyªn n, sau ®ã tÝnh gi¸ trÞ biÓu thøc

F = 

+

+++++

lΠ n   nÕ u                    

ch½ n  n   nÕ u

12

1...

2

1

2

1

2

11

2

32

n

n

11. ViÕt ch¬ng tr×nh nhËp vµo mét sè thùc x vµ sè nguyªn n, sau ®ã tÝnh gi¸ trÞ biÓu thøc:

Page 292: Giao Trinh C++ Toan Tap

S = 

ch½ n  n   nÕulΠ n       nÕu                        

++++ −

03

...33 12

32

n

nxxxx

12. ViÕt ch¬ng tr×nh nhËp vµo mét sè nguyªn n trong kho¶ng [10, 20] (nÕu sè nhËp vµo kh«ng thuéc kho¶ng ®ã th× yªu cÇu nhËp l¹i tíi khi tho¶ m∙n). Sau ®ã tÝnh tæng c¸c sè liªn tiÕp tõ 1 tíi n.

13.  ViÕt ch¬ng tr×nh nhËp vµo mét sè nguyªn d¬ng n, sau ®ã tÝnh tæng c¸c gi¸ trÞ ch½n, lΠthuéc ®o¹n [1, n].

14. ViÕt ch¬ng tr×nh nhËp vµo c¸c sè nguyªn d¬ng n, m, sau ®ã in ra:

- Tæng c¸c sè ch½n d¬ng trong kho¶ng [­ n, m].

- Tæng c¸c sè ch½n ©m trong kho¶ng [­ n, m].

- Tæng c¸c sè lΠd¬ng trong kho¶ng [­ n, m].

- Tæng c¸c sè lΠ©m trong kho¶ng [­ n, m].

15. ViÕt ch¬ng tr×nh nhËp vµo mét sè nguyªn n, sau ®ã tÝnh tæng c¸c sè nguyªn tè thuéc ®o¹n [1..n]. Cho biÕt cã bao nhiªu sè nguyªn tè thuéc ®o¹n ®ã.

16.  Dïng while (sau ®ã viÕt l¹i, dïng do/ while) ®Ó viÕt ch¬ng tr×nh in ra sè lµ luü thõa 2 bРnhÊt lín h¬n 1000.

17. Cho d∙y sè x[] = { 12.3,  ­45.4, 12, 15, 10.1, 12.5}. ViÕt ch¬ng tr×nh ®¶o ngîc d∙y sè trªn.

18.  ViÕt ch¬ng tr×nh t×m sè nguyªn d¬ng n nhá nhÊt tho¶ m∙n: 1 + 2 + 3 + … + n > 1000.

19.  §Ó tÝnh c¨n bËc hai cña mét sè d¬ng a, ta sö dông c«ng thøc lÆp 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 abs((a(n+1) – x(n))/x(n)) < ε.

vµ khi ®ã x(n+1) ®îc xem lµ gi¸ trÞ gÇn ®óng cña sqrt(a).

ViÕt ch¬ng tr×nh tÝnh c¨n bËc hai cña a víi ®é chÝnh x¸c  ε  = 0.00001.

20.  LËp tr×nh ®Ó tÝnh sin(x) víi ®é chÝnh x¸c ε = 0.00001 theo c«ng thøc :

Page 293: Giao Trinh C++ Toan Tap

sin(x) =  x – x3/3! + x5/ 5! + …+ (­1)nx(2n+1)/ (2n+1)!.

21.  LËp tr×nh ®Ó tÝnh tæ hîp chËp m cña n theo c«ng thøc:

C(m, n) = (n(n­1)…(n­m+1))/ m!.

Ch¬ng III: kü thuËt lËp tr×nh ®¬n thÓ

1. ViÕt hµm kiÓm tra xem mét sè nguyªn n cã ph¶i lµ sè nguyªn tè kh«ng. Sau ®ã, trong ch¬ng tr×nh chÝnh, nhËp vµo mét sè nguyªn n, kiÓm tra tÝnh nguyªn tè cña sè n vµ th«ng b¸o ra mµn h×nh.

2. ViÕt hµm tÝnh n! sau ®ã, trong ch¬ng tr×nh chÝnh, nhËp vµo mét sè nguyªn n vµ tÝnh, in ra kÕt qu¶ cña biÓu thøc:

S =  )!1(

1!

++

n

n

3. ViÕt hµm tÝnh gi¸ trÞ biÓu thøc F (trong bµi sè 10 ch¬ng II) víi ®èi vµo lµ n. Sau ®ã, trong ch¬ng tr×nh chÝnh, nhËp vµo hai sè a, b, tÝnh vµ in ra mµn h×nh kÕt qu¶ cña biÓu thøc:

S =  )(

)()(

baF

bFaF

−−

4. ViÕt hµm s¾p xÕp mét chuçi ký tù (tõ A­>Z). Sau ®ã, trong ch¬ng tr×nh chÝnh, nhËp vµo mét x©u ký tù bÊt kú, in x©u ®∙ ®îc s¾p lªn mµn h×nh.

5. ViÕt ch¬ng tr×nh gi¶i ph¬ng tr×nh trïng ph¬ng : ax4 + bx2   + c = 0.

Kü thuËt §Ö quy

6. USCLN cña hai sè a, b ®îc ®Þnh nghÜa nh sau:

 USCLN(a, b) = a nÕu b = 0

                       = USCLN(b, a%b) nÕu b <> 0

ViÕt hµm ®Ö quy t×m USCLN cña hai sè nguyªn a, b. Trong ch¬ng tr×nh chÝnh, nhËp vµo hai sè nguyªn a, b. T×m vµ in USCLN cña hai sè ®ã lªn mµn h×nh.

7. USCLN cña hai sè a, b ®îc ®Þnh nghÜa nh sau:

 USCLN(a, b) = a nÕu a = b

                       = USCLN(a­b, b) nÕu a > b

Page 294: Giao Trinh C++ Toan Tap

  = USCLN(a, b­a) nÕu a < b

ViÕt hµm ®Ö quy t×m USCLN cña hai sè nguyªn a, b. Trong ch¬ng tr×nh chÝnh, nhËp vµo hai sè nguyªn a, b. T×m vµ in USCLN cña hai sè ®ã lªn mµn h×nh.

8. ViÕt hµm t×m kiÕm ®Ö quy trªn mét d∙y sè nguyªn ®∙ ®îc s¾p.

9. C¸c sè Fibonacci F[i] ®îc ®Þnh nghÜa ®Ö quy nh sau:

F[0] =1; F[1] =1;

F[i] = F[i­1] + F[i­2]  (víi i > 1);

(VD: 1, 1, 2, 3, 5, 8, 13…)

ViÕt hµm ®Ö quy t×m sè Fibonacci thø n trong d∙y.

10. ViÕt hµm ®Ö quy tÝnh n!. (n ∈ Z+)

11. ViÕt hµm ®Ö quy tÝnh f(x, n) = xn. (x∈R, n ∈ Z). ViÕt ch¬ng tr×nh chÝnh sö dông hµm trªn ®Ó nhËp vµo sè nguyªn n, sè thùc x tõ bµn phÝm. TÝnh vµ in ra mµn h×nh gi¸ trÞ cña f(x, n).

12.  ViÕt hµm ®Ö quy tÝnh f(x, n) = n!xn. (x∈R, n ∈ Z). ViÕt ch¬ng tr×nh chÝnh sö dông hµm trªn ®Ó nhËp vµo sè nguyªn n, sè thùc x tõ bµn phÝm. TÝnh vµ in ra mµn h×nh gi¸ trÞ cña f(x, n).

13. ViÕt hµm ®Ö quy ®Ó ®Õm sè ch÷ sè cã trong mét sè nguyªn bÊt bú (VÝ dô sè 1263 cã 4 ch÷ sè…). ViÕt ch¬ng tr×nh chÝnh sö dông hµm trªn ®Ó cho phÐp nhËp vµo mét sè nguyªn bÊt kú. In ra mµn h×nh sè ch÷ sè cña sè nguyªn võa nhËp.

14.  D∙y Catalan ®îc ®Þnh nghÜa ®Ö quy nh sau:

C1 = 1;          

Cn =  Σ Ci* Cn­i ∀ n > 1.

VÝ dô: { 1,  1,  2,  5,…}

H∙y x©y dùng hµm ®Ö quy tÝnh sè Catalan thø n bÊt kú (n  ∈ Z +). ViÕt ch¬ng tr×nh chÝnh sö dông hµm trªn ®Ó tÝnh sè Catalan thø n bÊt kú 

víi n nhËp tõ bµn phÝm (n  ∈ Z +).

Ch¬ng IV: kü thuËt lËp tr×nh dïng m¶ng.

1. Cho hai vector x(x1, x2…xn) vµ y(y1, y2…yn). ViÕt ch¬ng tr×nh in ra TÝch v« híng cña hai vector trªn.

Page 295: Giao Trinh C++ Toan Tap

2. Cho hai m¶ng a vµ b cã c¸c phÇn tö ®Òu ®∙ ®îc s¾p t¨ng. LËp ch¬ng tr×nh trén hai m¶ng trªn ®Ó thu ®îc mét m¶ng thø 3 còng s¾p theo thø tù t¨ng b»ng hai ph¬ng ph¸p.

3. ViÕt ch¬ng tr×nh nhËp vµo mét m¶ng n sè nguyªn, s¾p xÕp m¶ng theo chiÒu t¨ng dÇn vµ in kÕt qu¶ lªn mµn h×nh b»ng c¸c ph¬ng ph¸p:

- S¾p xÕp næi bät.

- S¾p xÕp chän.

- S¾p xÕp chÌn.

4. ViÕt ch¬ng tr×nh nhËp vµo mét m¶ng n sè nguyªn, tÝnh tæng c¸c phÇn tö ch½n, c¸c phÇn tö lÎ, c¸c phÇn tö chia hÕt cho 3 vµ in kÕt qu¶ ra mµn h×nh.

5. ViÕt ch¬ng tr×nh nhËp vµo mét d∙y sè thùc, t×m phÇn tö lín nhÊt (t¬ng tù, t×m phÇn tö nhá nhÊt) cña d∙y vµ in kÕt qu¶ ra mµn h×nh.

6. ViÕt ch¬ng tr×nh nhËp vµo mét d∙y sè nguyªn. TÝnh tæng cña c¸c sè nguyªn tè trong d∙y vµ in kÕt qu¶ ra mµn h×nh.

7. ViÕt ch¬ng tr×nh nhËp vµo mét d∙y sè nguyªn vµ mét sè nguyªn c. §Õm sè lÇn xuÊt hiÖn vµ vÞ trÝ xuÊt hiÖn cña c trong d∙y. In c¸c kÕt qu¶ ra mµn h×nh.

8. ViÕt ch¬ng tr×nh nhËp vµo mét d∙y n sè nguyªn. TÝnh trung b×nh céng cña d∙y vµ in kÕt qu¶ tÝnh ®îc ra mµn h×nh.

9. Mét d∙y sè a gäi lµ ®îc s¾p t¨ng nÕu a[i] <= a[i+1] víi mäi i;

D∙y gäi lµ ®îc s¾p gi¶m nÕu a[i] >= a[i+1] víi mäi i;

D∙y gäi lµ ®îc s¾p t¨ng ngÆt nÕu a[i] < a[i+1] víi mäi  i;

D∙y gäi lµ ®îc s¾p gi¶m ngÆt nÕu a[i] > a[i+1] víi mäi i;

ViÕt ch¬ng tr×nh nhËp mét d∙y n sè thùc, kiÓm tra xem d∙y ®∙ ®îc s¾p hay cha. NÕu ®∙ ®îc s¾p th× s¾p theo trËt tù nµo (t¨ng, t¨ng ngÆt, gi¶m, gi¶m ngÆt?). NÕu cha th× s¾p xÕp d∙y theo chiÒu t¨ng dÇn. In c¸c kÕt qu¶ lªn mµn h×nh.

10. ViÕt hµm t×m kiÕm lÆp trªn mét d∙y sè nguyªn ®∙ ®îc s¾p víi ®é phøc t¹p tèt h¬n O(n).

11. ViÕt ch¬ng tr×nh nhËp vµo mét ma trËn m x n sè nguyªn. T×m c¸c phÇn tö lín nhÊt vµ bРnhÊt trªn c¸c dßng (t¬ng tù c¸c cét) cña ma trËn. (sö dông for sau ®ã dïng while, do/ while).

Page 296: Giao Trinh C++ Toan Tap

12. ViÕt ch¬ng tr×nh t×m phÇn tö ©m ®Çu tiªn trong ma trËn (theo chiÒu tõ tr¸i qua ph¶i, tõ trªn xuèng díi).

13. ViÕt ch¬ng tr×nh nhËp vµo mét ma trËn m x n sè nguyªn. T×m phÇn tö lín nhÊt (t¬ng tù t×m phÇn tö nhá nhÊt) cña ma trËn võa nhËp. In kÕt qu¶ ra mµn h×nh. Cã thÓ söa l¹i bµi ®Ó t×m phÇn tö lín nhÊt (nhë nhÊt) trªn c¸c cét (c¸c dßng) ®îc kh«ng?

14. ViÕt ch¬ng tr×nh nhËp vµo hai ma tr©n A, B cã n hµng, m cét. TÝnh ma trËn C = A + B vµ in kÕt qu¶ ra mµn h×nh.

15. ViÕt ch¬ng tr×nh nhËp vµo hai ma trËn A, B, tÝnh vµ in ra mµn h×nh tÝch cña hai ma trËn ®ã.

16. ViÕt ch¬ng tr×nh nhËp vµo mét ma trËn A cã n dßng, m cét. In ra mµn h×nh ma trËn chuyÓn vÞ cña A. (A’ ®îc gäi lµ ma trËn chuyÓn vÞ cña A nÕu A’[i, j] = A[j, i] víi mäi i, j).

17.  Ma trËn A ®îc gäi lµ ®èi xøng qua ®êng chÐo chÝnh nÕu A[i, j] = A[j, i] víi mäi i kh¸c j. ViÕt ch¬ng tr×nh nhËp vµo mét ma trËn A, kiÓm tra xem A cã ®èi xøng qua ®êng chÐo chÝnh kh«ng. In kÕt luËn lªn mµn h×nh.

Ch¬ng V: Kü thuËt lËp tr×nh dïng con trá

TÊt c¶ c¸c bµi tËp vÒ m¶ng ë trªn ®Òu cã thÓ söa l¹i ®Ó dïng con trá thay v× dïng m¶ng. Ngoµi ra h∙y cµi ®Æt thªm c¸c bµi tËp sau:

1. ViÕt ch¬ng tr×nh nhËp vµo mét m¶ng a gåm n phÇn tö nguyªn. S¾p xÕp m¶ng theo chiÒu gi¶m dÇn (lu ý sö dông tªn m¶ng nh con trá vµ sö dông con trá).

2.  H∙y dïng mét vßng for ®Ó nhËp vµo mét ma trËn vu«ng cÊp n víi c¸c phÇn tö thùc vµ t×m phÇn tö Max cña ma trËn nµy.

3. ViÕt hµm ho¸n vÞ hai biÕn thùc a, b b»ng c¸ch sö dông con trá (®èi vµo lµ hai con trá). ViÕt ch¬ng tr×nh chÝnh nhËp hai sè thùc a, b. Sö dông hµm trªn ®Ó ®æi chç a vµ b. 

4. ViÕt hµm gi¶i hÖ ph¬ng tr×nh bËc nhÊt víi s¸u ®èi vµo lµ a, b, c, d, e, f vµ 2 ®èi ra lµ x vµ y.

5. ViÕt hµm tÝnh gi¸ trÞ ®a thøc: 

f(x) = a0xn + … + an­1x + an. víi ®èi vµo lµ biÕn nguyªn n vµ m¶ng thùc a.

6. ViÕt hµm céng hai ma trËn vu«ng a vµ b cÊp n (sö dông con trá). 

Page 297: Giao Trinh C++ Toan Tap

7. ViÕt ch¬ng tr×nh tÝnh tÝch ph©n cña f(x) trªn ®o¹n [a, b] b»ng c«ng thøc h×nh thang. Theo ®ã, tÝch ph©n cña f(x) trªn [a, b] b»ng: h * s. Trong ®ã:

h lµ ®é dµi kho¶ng ph©n ho¹ch ®o¹n [a, b] thµnh n kho¶ng.

s lµ tæng tÊt c¶ c¸c f(a+i*h) víi i tõ 1 tíi n. 

Sö dông hµm trªn ®Ó tÝnh tÝch ph©n trong ®o¹n [­1, 4] cña:

f(x) = (ex­2sin(x2))/ (1+x4). (nghiªn cøu c¸ch ®a con trá vµo gi¶i quyÕt bµi to¸n).

//================Tham kh¶o code mét sè hµm ®Ö quy========

#include "iostream.h"#include "conio.h"//hµm tÝnh n giai thõa =======================================long gt(int n){if (n==0)

return 1;else

return n*gt(n­1);}//hµm t×m sè Fibonacci thø n===========================long Fibo(int n){if (n<=1)  return 1;else return Fibo(n­1)+ Fibo(n­2);}

//hµm USCLN cña a va b===============================int USCLN(int a, int b){if (b==0)  return a;else  return USCLN(b, a%b);}//Hµm main=========================================void main(){ int n;cout<<"nhap n ";cin>> n;long S = gt(n);cout<<"n gt "<<S;getch();//=====================================long T = Fibo(n);cout<<"\n so fibonaci thu "<<n<<" la "<<T;getch();

Page 298: Giao Trinh C++ Toan Tap

//=====================================int a, b;cout<<"nhap a ";cin>> a;cout<<" nhap b ";cin>>b;cout<<"\n USCLN cua "<<a<<" va "<<b<<" la "<<USCLN(a,b);getch();}