<;s.
P H Ạ M V Ã N Ấ T ( C h u b i ê n ) - L Ê T R Ư Ờ N G T1IÔNCỈ
GIÁO TRINH
+ +
&
LẬP TRÌNH HƯỞNG ĐÔÌ TƯỢNG
NHÀ XUẤT BẢN HỔNG ĐỨC
LỜI NÓI ĐẤU
Lập trình cấu trúc
thủ tục. Ch ủn g dược
Thô ng q u a các ngôn
quen biết với phương
là ph ư ơn g pháp tồ chức, phân chia chương trình thành các hàm,
d ù n g đ c x ứ lý d ữ liệu nhưng lại tách rời các câu trúc d ừ liệu.
n g ừ Foxpro. Pascal, c da s ố những người làm Tin học đà khá
pháp lập trình này.
Lặp trình h ướng đôi t ượng (objcct-oricnicd programming) dựa trẽn việc tô chức
chương trình thành các lớp (class). Khác với hàm và thù tục, lớp ỉà một đơn vị bao gôm
cả dừ liệu và các phương t hức x ử lý. Vì vậy lớp cỏ thê mô lả các thực thê một cách chân
thực, đầy đủ cà phẩn d ừ liệu và yêu cầu quán lý. T ư tưởng lập trình hướng đôi tượng
được áp dụng cho hầu hết các ngôn ng ữ mỏi chạy trên môi trường Windows như
Microsoft Access, Visual Basic, Visual c. Vì vậy việc nghiên cứu phương pháp lập trình
mói này là rất cần thiết đối với tất cả những người quan tâm, vêu thích Tin học.
c ‘h ra dời năm 1973 với mục đích ban đầu ỉà dề viết hệ điều hành Unix trên máy
tính mini PDP. Sau đỏ c da đ ư ợc sử đ ụ n g rộng rài trẽn nhiêu loại máy lính khác nhau
và đà trò thành một ngôn n g ừ lập trình cấu trúc rât được ưa c huộng trẽn toàn the giới.
Để đưa c vào the giới hưởng đối tượng, năm 1980 nhà khoa học người Mỹ
B. Stroustrup 1đ à cho ra dời một ngôn ng ừ c mới có tên ban đầu là "C cỏ lớp", sau đó
đén nãm 1983 thì gọi là c **. Ngôn n g ừ c
là một sự phát triển mạnh I1ÌÕ cùa c. Trong
c ' chant», những d ư a vào tất cà các khái niệm, công cụ c ùa lặp trinh lìirởng đôi tượng mà
còn đưa vào nhiêu khả năng mới mẻ cho lìàm. Nh ư vậy c
là một ngôn ngừ lai cho phcp
tô chức durant* trình theo các lớp và các hàm. c ỏ thê nói c~~ đà thúc đây ngôn rigữ c
vỏn dà rất thuvêt phục đi vào thô giới lập trinh hướng dối tượng và c* ’ dà trờ thành ngôn
n gừ hưởng đôi t ượng nôi bật irong những năm 90.
C u ố n sách này sẽ trinh bày một cách hệ t hống các khái niệm của làp trình hướng
đối t ư ợ n g dược cài dặt t rong c
n hư lứp. dôi urợng (object), s ự thừa kẽ (inheritance),
tinh t ươn Li ứng bội (polym orphism ) v à các khả năng mới trong x ã y dựng, sử dựng hàm
nhu : dối tham chiếu, dôi mặc định, hàm irùng ten, hàm toán tử. C ó một sô vân đẽ còn ÍI
dược biết den lìhir cách xây d ự n g hàm với sổ dối bất định t rong C cũng se được giỏi
thiệu. Các chương lừ 1 d en 11 với cách giải thích li mi và với gân 100 chương trình
minh họa SÜ cung cap c ho bạn dọc các khái niệm, phương pháp và kinh nghiệm lộp
trình hirởnu, dối t ơựng trẽn c . Có một phụ lục cuối sách ( Phụ lục 6) sC hộ thông ngủn
uọn plnronu pháp phân tích, thiết kc và lập trình hướng đối t uợng trôn hình diện chung.
Cuõn sách uôm 12 c h ư ơ n g và 7 phụ lục.
Chưư/Iị* ì luiỏim dần cácỉì làm việc vái plum m ề m TC
3.0 dc tlìừ nghiệm các
c h ư o n g trinh, trinh b à y SƯ lược về các phương pháp lập trinh và giới thiệu một sô mở
rộng đ ơ n giản cúa c
Clìỉtơnx 2 trinh bày các khả nâng mới trong việc xây d ự n g và sử dụng hàm trong
c n hư bien t ham chiêu, dôi cỏ kiêu tham chiêu, dôi cỏ g i á trị mộc (lịnh, hàm trực
tuyến, hàm trùng tên, hàm toán lử.
Chương 3 nói về một khải niệm truni* tâm cùa lập trình hướng đối tượng là lớp gồm:
Dịnh nghĩa lớp, khai báo các bien, mảng đối tượng (kiểu ỉóp), pliưong ilìửc, dùr.g c j n trỏ
this tron« phương thức, phạm vi truy xuẩl cùa c ỉx ilìâr h phán, các phương thức toán tử.
‘ 1Tác uiã etìu c là nhà khoa học Dei.i'.ls Ritchie.
(2) Björne Slroustmp's và Dennis Ritchie íteu làm việc ở Bell Lab (Mỹ) - nơi quy tụ ral nhiều nhà
khoa học và nghiên cửu hàng dầu về lĩnh vực máy tinh.
3
(
C hưrng 4 trình bày các vắn đề tạo dựng, sao chop, huỷ bỏ các dối t ượng vả các vấn
đề khác có liên quan như: Hàm tạo, hàm tạo sao chép, hàm huý, toán tử gán, cấp phái
bộ nhớ cho đối tượng, hàm bạn. lớp bạn.
Chmrtiịi 5 trinh bày một khái niệm quan trọng tạo nén khả năng mạnh của lặp trinh
hưởng dôi tượng trong việc phát triền, mớ rộng phân mèm, đỏ là khả nảng thừa kê cùa
các lớp.
Clnnmg 6 trình bày một khái niệm quan trọng khác cho phcp xử lý các vấn dề khác
nhau, các thực thê khác nhau, các thuật toán khác nhau theo cùng một lược đồ thorn*
nhất, đó là tính tương ừng bội và phương thức ảo. Các công cụ này cho phép dề dàng tô
chức chương trình quàn lý nhiêu dạng dôi tượng khác nhau.
Chương 7 trình bây các thao tác trẽn tệp như: tạo một tệp mới, iihi d ừ liệu từ bộ nhở
lẽn tệp, đọc d ừ liệu từ tệp vào hộ n h ớ , ...
Chương 8 nói về việc tố chức vào/ra trong c . c dưa vào mội khái niệm mới gọi
là các dòng tin (Stream). Các thao tác vào/ra sẽ thực hiện trao dôi dừ liệu gi ũa bộ nhớ
với dòng tin: Vào là chuyển dữ liệu từ cong nhập vào bộ nhớ. ra là chuyền d ữ liệu từ
bộ nhớ lẽn dòng xuất. Đẻ nhập xuất dừ liệu trẽn một thiết bị cụ thể nào, ta chi cần gán
dòng nhập xuât với thiêt bị dỏ. Việc tô chức vào ra theo cách n hư vậv là rảt khoa học
và tiện lợi vì nó có tính độc lập thiết bị.
Clurœig 9 trinh bày các hàm dồ họa sử dụng trong c vả c . Các hàm này được sứ
dụnii rải rác trong toàn bộ cuốn sách đế xây dựng các đổi tượng dồ họa.
Chương 10 trình bày các hàm truy xuất trực tiếp vào bộ nhở cùa máy tỉnh, trong đó
có bộ nhớ màn hỉnh. Các hàm này sỗ được sử dụng trong chương 11 để xây dụng các
lớp menu và cửa số.
C'hương / ' giới thiệu 5 chương trinh tương đối hoàn chinh n..àm minh họa thêm
khả năng và kỹ thuật lập trinh hưởng đối tượng trẽn c ” .
Chương 12 trinh bày thêm một sô chương trinh hướng đôi lượng trẽn c . Đây là
các clurơng trình tương dối phức tạp, hữu ích và sử dụng các công cụ rnạnh của c .
Phụ lục / trinh bày các phép toán trong c và thứ t ự ưu liên cùa chúng.
Phụ ¡ục 2 liệt kê một danh sách các từ khoá cùa c
.
Phụ lục 3 trình bày bàng mã ASCII và mã quét của các ký tự.
Phụ lục 4 trinh bày một vấn dè quan trọng nhưng còn ít được nói đến trong các tài
liệu, đó là cách sử dụng con trỏ void đê xây dựng các hàm với số dôi không cô định
giông như các hàm printf và s canf của c .
Phụ lục 5 sể giới thiệu tóm tẳt hơn 200 hàm dê bạn đọc tiện việc tra cứu. (Vì trong
c vẫn sử dụng các hàm của C).
Phụ lục 6 trinh bày một cách ngẳn gọn phương pháp phân tích, thiết kế và lập '.rinh
hướng đối tượng trẽn binh diện chung.
Phụ lục 7 trinh bày một số chương trinh minh họa thuật tcán đệ quy kiêu quay lui.
Khi viết chúng tôi ctò hết sức cố gẳng để cuốn sách dược hoàn chinh, song chác
chăn không tranh khỏi thiêu sót, vi vậy rát mong nhặn dược sự góp ý của độc giả.
Nhân dịp này chúng tôi xin chân thành cám ơn Thạc sĩ Nguyền Văn Phác dà tận
tinh giúp đờ trong việc hiệu đinh ''à biên tập cuốn sách này.
CÁC TÁC GIẢ
4
C hương I
C " & LẬP
TRÌNH HƯỚNG ĐÔI TƯỢNG
m
m
TrotĩiỊ chirơMỊ này trìnli bày các vấn dè sau:
- ( 'ácli.sir iliing phân mỡnt'IX '
3.11
c
- X liih iii sư a d ũ i c ầ n tliiết một c h ư ơ n g tr ìn h
đ ê b iế n n õ th à n h m ột
chươiìii irình c
(chạy ihrực trong m ôi tnrờng c )
- T õ m h r ự c v ề c á c p h ic tm g p h á p lậ p t r ìn h c ấ u tr ú c Ví) lậ p trình
h ư ớ n g đ ồ i lư ợ n g
- Nlìữns’ m ơ rộng ciici c '
so với
c
§1. T U R B O CM 3.0
Các ví dụ ironu cuốn sách này sẽ viết và thực hiện trên môi trường T C ri
3.0. Bộ cài dặt T ( " 3.0 íiồm 5 dĩa. Sau khi cài dặt (già sử vào ilnr :r.ục
C:\TC) ihì tro n u thư 111ỊIC TC sẽ gồm các thư mục con sau:
C':VIV B( il cliửa các lộp tluỏi BG1 và Cl IR
C:\TC\liIN chứa các lộp chương trinh (duôi EXE) như TC. TCC. TI.IB,
TI.INK
C:\TC\INCLUDK chửa các tệp liêu dề duôi 11
C:\Tl'\I.IB chứa các tệp đuôi LIB. OBJ
l)ô vào mỏi trưừníi cua T C " chi cần thực hiện tệp chương trình TC
trong thư mục C:\TC\BIN. Kết qua nhận dược hệ menu chính cùa T C ’ ' với
màu nền xanh uẩn uiống như hệ menu quen thuộc của T C ( Turbo C). Hệ
menu cua T C ” uồm các menu: File. Edit. Search, Run. Compile, Debug,
Project. Options. Window. Help.
Cách soạn tháo, bien dịch và chạy chương trình trong T C " cũng giống
như tro lili TC, nuoại Irừ diêm sau: Tệp cliươnti trình trong hệ soạn thào của
T C ” có đuôi mặc dịnli lá ( T P còn Irong T C lliì tệp chương trình luôn có
duôi c.
I'rona
có thể ilụrc hiện cá chươim trinh c và c ++. De thực hiện
ch u o n u trinh c cần dims: đuôi c đế dặt ten cho tệp chương trình, dè thực
hiện durư im trình c ' cun climu đuôi CPP dê dặt lên cho tệp chương trình.
§2. c ~ V À c
- Có thế nói c " là sụ' m ở rộng (đáng kể) của c. Điều đ ó có nghĩa là
mọi khá năng, mọi khái niệm trong C’ đêu dùng dược trong c '.
- Vì iron Li C ' sư dụng gần như toàn bộ các khái niệm, định nghĩa, các
kiều dữ liệu, các câu trúc lệnh, các hàm và các công cụ khác cùa c . nên yêu
cầu bảt buộc dổi với các dọc già c +’ là phải biết sử dụng tươ ng dối thành
thạo ngôn nmì' ('.
- Vi
c
là sự mơ rộng cua c. nên bán thân m ột ch ư ơ n g trình c đã là
chương trinh c " (chi can thay đuôi c bang đuôi CPP). T uy nhiên Trình
biên dịch r c
yêu cầu mọi hàm chuấn dùng trong ch ư ơ n g trình đều phải
khai báo imuyên mầu bàng một câu lệnh //include, trong khi diều nảy không
bát buộc dối với Trình biên dịch của TC.
Trong c có thể dùng một hàm chuẩn mà bó qua câu lệnh ¿/include đổ
khai báo nguyên mẫu của hàm dược dùng. Diều này không báo lỗi khi biên
dịch, nhưng có the dẫn đèn kểt qua sai khi chạy chương trình.
Ví dụ khi biên dịch chương trình sau trong môi tnrờng c sC không gặp
các dòng cảnh báo (warning) và thông báo lồi (eiTor). N h u n g khi chạy sẽ
nhận dược két quả sai.
tin ciu d e
v o i d mai n ()
{
f l o a t ¿ỉ, b , c , p , s ;
p r i n t í ( " \ n N h a p a , b, c :
");
s c a n I ( "V, (r. L'Ầf , &a, &b,
&c) ;
p
{a I b » c ) / 2 ;
s
sqrtiíp * (p - a) * (p - b) * (p - c) );
printf("NnDién tich
s);
g e t c h ();
}
Nêu biên dịch chương trình này trong T C ’ ’ sẽ nhận được các thông báo
lỗi sau:
E r o r : FunLi on
E r o r : Flint, i o n
' s q r t r s h o u ld have a p r o to ty p e
'q e tc h ' s h o u ld have a p ro to ty p e
Dc biến chươnsỊ trình ircn thành một chương trinh c +^ cằn:
* Đặt tên chương trình với duôi CPP
+ Them 2 câu lệnh //includc dc khai háo nguyên m ẫ u cho các hàm sqrt,
uetch:
IIi n c l u d e < m a t h . h >
iỉ i n c l u d e < c o n i o . h >
6
ìu.
§3. LẬP TRÌNH CẤU TRÚC & LẬP TRÌNH Đ ố l TƯỢNG
3.1. Phuo'ng p h á p lập trình cấu trúc
Tư tuớnii chính cùa lập trinh cấu trúc là tố chức chương trình thành
các chươnu trình con. Trong PASCAL có 2 kiêu ch ương trình con là thủ tục
và hàm. Trong c chi có một loại chương trinh con là hàm.
Hàm là một dơn vị chương trình dộc lập dùng để Ihực hiện một phần
việc nào đó như: N hập số liệu, in kết quả hay thực hiện một số 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 dối d ữ liệu giữa các hàm thực hiện thông qua các dối và các
biến toàn bộ.
Các imôn nmì như c. PASCAL. FOXPRO là các ngôn ngữ cho phép
triên khai ph irons’ pháp lập trinh cáu trúc.
MỘI ch ưong trình cấu trúc gồm các cấu trúc d ữ liệu (như biến, màng,
ban ghi) và các hàm. thú tục.
Nhiệm vụ chính cua việc tố chức thiết kế chương trình cấu trúc là tổ
chức clnrơnu trình thành các hàm, thú tục: Chương trình sẽ bao gồm các
hàm. thu tục nào.
Ví dụ 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 irì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ựntì 2 hàm:
I làm nhapsl dùng dể nhập loạ dộ n điểm, hàm này có một đối là biến
nguyên 11 và được khai báo như sau:
VO i d nhaps 1 ( i riL n) ;
I làm do dai dùnu đế tính độ dài đoạn thẳng đi qua 2 điếm có chỉ số là i
và j, nó dưựe khai báo như sau:
float
do < l a i ( i n t i ,
int
j);
Chươnu trình c cho bài toán trên được viết như sau:
# in clu d e < s td io .h >
#in clu d e
Hi n c l u d e < i ĩ i a t h . h >
f l o a t X [ 1 OD] , y [ 1 0 0 j ;
flo at d o d a i( in t i, int
j)
{
return
s q r t (pow( x [i]
- x [ j j f 2)
+ pow(y[i]
-
y[j],
2));
}
7
A
void nhapsl(i.nL
n)
{
int
for
i;
( i = 1;
i <=n;
1 +i )
f
p r i n t f ( " \ n N h a p t o a d o X, y c u a d i e m t h ư %d:
s c a n f & x | i ] ,
& y[i]);
",
i);
)
}
v o i d ma i n ()
Í
i n t n , i , j , i m a x , jrnax;
f l o a t (1/ dniax;
p r i n t i ("\nSo diem N
");
s c a n f ( ' " ¿ d " , &n) ;
nhapsi(n);
dmax = d o d a i f l , 2 ) ; i m a x = 1 ;
f o r (i 1; i< n - 1 ; + »i)
f o r (j = i H ; j< n; ++j)
jmax = 2 ;
{
d
if
do daj ( i ,
( d > dmax)
j );
{
dmax
imax
jrnax
d;
i;
j;
}
}
p r I nt . ] ( " \ n l ) o a n Lhancj I o n n h a t CO d o d a i = % 0 . 2 f " # dm a x ) ;
p r i n t . ! ( " \ n l ) i q u a 2 d i e m CO c h i s o l a %d, %d " , i m a x , j m a x ) ;
getchO ;
)
3.2. P h u o n g pháp lộp trình hiróng đối t ư ọ n g
+ Khái niộm Irunu tâm cùa lập trình hướng đối tượng là lớ p (class). Có
thể xem lớp lá sự kốt hợp các thành phần dữ liệu và các hàm. C ù n g có thê
xem lớp là sự mơ rộng cua cấu trúc trong c (struct) bàng cách d ư a them vào
các phương thức (method) hay còn gợi là hàm thành viên (m em ber
function). Một lớp đưựe (.lịnh nghĩa như sau:
c l a s s Tôn
lớp
{
//
//
Khai b á o c á c t h ả n h p h ả n d ữ l i ệ u
Khai báo c á c phương thức
};
+ C á c p hư ơng thức c ó thể được viết ( x ây d ự n g ) bên t r o n g h oặc bèn
8
ngoài (phía dưới) phần định nghiă lớp. c ấ u trúc (cách viết) p hư ơng
thức tươ nu lự n h ư hàm nuoại trừ quy tắc sau: Khi xây d ự n g m ột phương
thức bên ngoài d in h imhìa lớp thi trong d ò n g d â u tiên cân dùng tên lớp
v à 2 d ầ u : dặl tn r ớ c tên plurơng thức dê chi rõ p h ư ơ n g thức thuộc lớp
náo (x em ví dụ bên dưới).
+ Sứ dụng các thành phần dừ liệu trong phương thức: Vì phương thức
và các thành phan dừ liệu thuộc cùng một lóp và vì phương thức dược lập
lên cốt dế x u lý các thánh phần d ù liệu, nên trong thân của phương thức có
quyền truy nhập đốn các thành phần d ữ liệu (của cùng lóp).
+ Biỏn lớp: Sau khi dịnh nghĩa một lớp. có thê dùng tôn lớp dê khai
b á o các biến kicu lớ p hay còn gọi là đôi lượng. Mỗi đôi tượng SC có các
thành phần dừ liệu và các plnrơnu thức. Lời gọi một phương thức cần chứa
tên dối tượng dế xác định p h ư ơ n u thức ihực hiện từ đối lượng nào.
+ Một clurơnsì trình h ư ớ n g đối tư ợ n g SC bao g ồ m cá c lớp có quan
hệ với nhau.
+ Việc phân lich. iliiỏi kố chirơng trình iheo phương pháp hướng đổi
tượníi nham thiết kế. xây dựng các lớp.
+ T ừ khái niệm lớp nấy sinh hàng loạt khái niệm khác như: Thành
phần d ữ liệu, phương thức, phạm vi, sự đóng gói, hàm tạo, hàm huý, sự thừa
kế. lớp cơ sử. lớp dần xuất, tươim ứng bội, phương thức á o , ...
+ Ư u điếm c ù a việc thiếl kề hướng dổi tượ ng là tậ p trung xác định
các lớp đo mô tã các tlụrc thổ cùa bài toán. Mồi lớp đ ư a v à o các thành
phàn d ữ liệu cùa thục thô và xây d ự n g luôn các p h ư ơ n g ihíre dê xir lý
d ữ liệu. Nlur vậy việc thiết kố ch ư ơ n g trình xuất phát từ cá c nội dụng,
các vân d c cùa bài toán.
+ Các ngôn niùr thuần tuy hướng đối tượng (như Smalltalk) chi hỗ trợ
các khái niệm vồ lớp. khôim cỏ các khái niệm hàm.
» (■
và hàm.
là niiôn Iiỉũr lai. nó cho phép sir d ụ n g cà cá c c ô n g c ụ c ủ a lớp
IX
m in h h ọ a cá c khái niệm vừa nêu về lập trin h h ư ớ n g đối tượ ng
ta trớ lụi xct bài luán tìm (.lộ dài lá n n h â t đi q u a 2 d iê m . T r o n g bài toán
này la lìặp một thực Ihé là dày điế m . C á c thành p h ầ n d ữ liệu c ù a lớp
dãy di ốm uỏm:
- Biến nguycn n là số diêm của dãy
- Con tro X kicu tlụrc trỏ dốn vùng nhớ chúa dãy hoành độ
- Coil tro V kiêu thực irò dồn vùng nhớ chứa dãy tung độ
Các phương tl'úc cần dira vào theo yêu cầu bài toán gồm:
- Nhập tọa độ một diem
- Tính dộ dài doạn ihắnc đi qua 2 điểm
Dưới dây là chirưnsi trình viết theo thiết kế hướng dối tượng. Đề thực
hiện chương trình này nhớ đặt tên tệp có duôi CPP. X e m chương trinh ta
thấy thêm một điều mới trong c +f là:
Các khai báo biến, m ãng có thể viết bất kỳ chỗ nào Irong chương trình
(tất nhiên phái trước khi sử dụng biến, màng).
#i n c l u d e < std .io .h >
IIi n c l u d e < c o n i o . h >
ttin c lu d e
#include
c l a s s daydicm
í
publi c:
i n t n;
f l o a t *x, *y;
f l o a t do d ai (int.
i,
ỉ n t j)
{
r e t u r n s q r t ; ( pow ( x I i ] -
x[j],
pow (y [i ] -
2) 4
y [j ],
2) ) ;
í
v o i d nhcip.sl ( v o i d ) ;
I;
v o i d daycJicm: : n h a p s l ( v o i d )
in t i;
p r i n t f ("\nS o diem N = ");
s c a n f ( " % d w/ & n ) ;
X = ( f l o a t * )m a l l o c ( (n+1)* s i z e o f (f l o a t ) ) ;
y = ( f l o a t * ) m a ilo c ((n + 1 ) * s i z e o f ( f l o a t ) );
f o r ( i = l ; i < - n ; +Ki )
{
p r i n t f ( " \ n N h a p t o a d o X, y c u a d i e m t h u %d:
s c a n f ( " %f % f Mr & x [ i | , & y [ i ] ) ;
)
}
void
rna i n ()
{
d a y d i cm p ;
p . n h a p s l();
i n t n r i # ) t imax,
f l o a t d , d ma x ;
n = p.n;
10
jmax;
nề i ) ;
dmax
p.do
for
(i
for
l;
d a i(l,
2);
n-1;
+ •-i )
i<
(j-iil;
j<~n;
ima x
=
1;
jmax
=
2;
CO d o d a i
=
f +j )
{
d
if
p.do dai ( i,
( d > drnax)
j );
{
dinax = d ;
i ma x
jrnax
i;
j;
}
}
p r i n t ! ("\nl)oan
p r L n t f: ( " \ n l ) i
Lhang
q u ¿1 2
ion
diem
nhat
CO c h i
so
la
%d,
dmax) ;
%d",
imax,
jm ax);
g c L c h ();
§4. MỘT S Ố MỞ RỘNG ĐƠN GIẢN C Ủ A c ~ s o VỚI c
T rong mục này trinh bày một số m ờ rộng cùa C H\ tuy dơn giàn, ngắn
gọn nhưng dem lại rất nhiều tiện lợi.
4.1. Viết các d ò n g ghi chú
Trong c ’ 1 vẫn có the viết các dòníi ghi chú trong các dấu /* và */ như
trơnư ('. Cách này cho phép viel các uhi chú trên nhiều dòng hoặc trên một
dònu. Nuoùi ru trong c ' ' còn cho phép viết ghi chú trên một dòng sau 2 dấu
gạch chéo, vi dụ:
inL
X,
y;
//
Kh a i
báo
2
biến
thực
4.2. Khai b áo linh hoat
Tron» c tầt ca các câu lệnh khai báo biến, mảng cục bộ phải đặt tại đầu
khối. Do vậy nhiều khi, vị iri khai báo và vị trí sữ dụng cùa biến khá xa
nhau, gây khó khăn trong việc kiểm soát chương trình. C “ đã khắc phục
nhược điểm này bàng cách cho phép các lệnh khai báo biến, máng có thê đặt
bất kỳ chồ nào trong chương trình trước khi các biến, m à n g được sừ dụng.
Vi dụ ch ư ơ n g trình nhập một dãy số thực rồi sắp xếp theo th ứ tự tăng dần có
thê viel trong c ' ' như sau:
II i n c l u d e < s t d i . o . h >
» in clu d e
# i n c I u d o < a I 1o c . h>
void müin()
{
in t n;
11
p r i n t f ( " \ n S o phan tu cua day N = " ) ;
s c a n f ( "%dM, fcn);
f l o a t *x
( f l o a t . * ) ma H o c ( ( n H ) * s i z c o f ( f l o a t ) ) ;
f o r ( j n t i 1; i< n; i + i )
{
printf("\nX[%d] = ", i);
scaní: ("% f", X »i );
«
1
for (i= l;
i< n - 1 ;
for (in t j= ỉ* l;
if
++i)
j<=n;
H i )
( x | i | > x [ j ])
<
float
tq
= X[L ];
XI i I
X[ j 1 ;
x|;j|
tq;
}
p r i n L I ( "\ nl )
H includc
void
<<:onio.h>
m a i n ()
i
inL n;
p r i n t í ( " \ n S o p h a n Lu c u a d a y N = ") ;
s c a n í ( M%d", &n) ;
flo a t s - 0.0;
for
(in t
1-1;
i.<=n;
M ỉ)
s ■»= float (i+l )/float (i) ; // Ép kiểu theo c'*
printf ("S
%0.2f", s ) ;
qe t c h {);
12
4.4. I l ằ n g có kiểu
Dc tạo ra một hãim có kiêu, ta sử dụng từ khoá const đặt trước một khai
háo cỏ khởi gán giá trị. Sau dây là một số ví dụ.
+ I lang rmuyên:
c o n s t ; i nt .
m a x s i z e = 1000;
inL a [ m a x s i z e l ;
+ c ấ u trúc hàng:
typedoí’
struct
(
i n t X, y ;
i n t ma u ;
} DIEM ;
c o n s t DIEM
/ / Toạ độ cùa điểm
/ / Mã màu c ủ a d i ổ m
d = (320,
240,
15};
Chương trình dưới đây minh họa cách dùng hằng có kiêu. Chương
trình tạo một cấu trúc hằng (kiều DIEM) mô tà điểm giữa m àn hình đồ họa
với màu trăng. Diêm này dược hiên thị trên màn hình đồ họa.
II i n c l u d e < s t d . i . o . h >
11i n c l u d e < c o n i o . h >
II i n c l-ude
II i n c 1 u đ e < s tci 1 i b . h >
tiyp edef sLruct:
{
i n t X, y ;
i n L ma u ;
} DIEM;
v o i d ma i.n ()
{
i n t nih = 0, mo d e = 0 ;
i n i t q r a p h ( & m h , &mode,
i n t l o i = g r a p h r e s u l t {);
if (loi)
{
p r i n t f ("\nL oi
g e lc h ();
do
hoa:
;
%s wr
grap h errorm sq(l o i ) );
e x i t (0);
}
c o n s t : D1KM qmh = {q e t m a x x ( ) / 2 , g e t m a x y ( ) / 2 ,
p u l p i x e J (qmh . X, g i n h . y , q m h . m o u ) ;
q e l i c h () ;
c Io seq ra p h ();
WHITE);
»
C hú ý:
a.
Có the d ù n g các hàm dê gán giá trị cho các hằng có kiểu (trong
chương trình trên dù n g các hàm gctmaxx và getmaxy).
13
b.
Mọi câu lệnh nhầm thay đối giá trị hằng có kiểu đều bị báo lỗi khi
biên dịch chương trình. Ví dụ nếu trong chương trình đưa vào câu lệnh:
qmh.x
= 200;
thì khi dịch chương trình sè nhận được thông báo lỗi như sau:
Cannot
m odify
a
const
object
4.5. C á c kiều ch a r và int
Troim c một harm ký lự dược xem là nuuyên do d ó nỏ có kích thước 2
byte, ví dụ trong C:
s i / c o f ( 'A' )
s i /.eof (. i n t ) = 2
Còn trong c 1 một hang ký tự dược xem là giá trị kiểu char và có kích
thước một bytc. Nlur vậy trong c rf thi;
siz e o f('A ')
= sizeof(char)
= 1
4.6. Lấy địa chỉ các phần tử m ả n g thực 2 chiều
Trong TC 2.0 không cho phép dùng phcp & dế lấy địa chi các phần tử
máng thực 2 chiều. Vi vậy khi nhập một ma trân thực (dùng scanf) ta phái
nhập qua một biến trung gian sau dó mới gán cho các phần từ màng.
Trong T C " 3.0 cho phép lấy dịa chi các phần từ m àn g thực 2 chiều, do
đó cỏ the dùng scan f dô nhập trực tiếp vào các phần tử mảng
Chương trình C " dưới dây sẽ minh họa diều này. C hươ ng trình nhập
một ma Irận thực cap mxn và xác định phần tử có giá trị lớn nhất.
II L n c l u d c : < c o n i o . h >
lỉ i n c l u d e < s l d i o . h >
v o i d m. i i n ()
{
f l o a t a [ 2 0 | | 2 0 | , í ỉ i na x;
i . n t m, n , i , i , ¡Wf'jx, j r n a x ;
c l r s c r () ;
p u t s ( " C h o b i o L ĨỈO h a n q v a s o c o t c u a ma
scarvf
&m, &n) ;
f o r ( 1 - 1 ; i < rn; h + i.)
for
(j= l;
j<=n;
tran:
")
;
♦»] )
I
prinLf (H\naf%dl |%dl = ",
scaní (
í ",
6 ;
»
p u t s ( " \ n \ n P h a n t u ma x : " ) ;
p r j n t f (" \ n c o q i a t r i = % 6 -lf " / sm ax);
p r I n t i ( " \ r i T a i h a n g %d c o t %d " , i m a x ,
q e t c h ();
jmax) ;
}
§ 5 . V À O RA TR O N G c ~
5.1. C á c toán từ v à p h u o ì i g thức xuất nhập
Dẻ in d ữ liệu ra màn hình và nhập dữ liệu từ bàn phím, trong c ++ vần có
thê d ù n u các hàm printf và scanf (như chi ra trong các chương trình c + ơ
các mục trôn).
Ngoài ra tronii c ' còn dùng toán từ xuât:
c o u t << b i ố u
t h ứ c << . . .
<< b i ể u
thức;
dê d ưa uiá trị các biêu thức ra màn hình, dùng toán tử nhập:
c i n >> b i ế n >> . . .
>> b i ê n ;
để nhập các ỉiiá trị số (nguyên thực) từ bàn phím và gán cho các biến.
Dỏ nhập một dày không quá n ký tự và chứa vào mảng lì (kiểu char) có
thê d ù n u phươnu thức cin.eel như sau:
cin.geL (h,
n);
C h ú Ỷ ỉ: Toán lử nhập cin » sẽ đô lại ký tự c huyê n d ò n g fc\ n ’ trong
bộ dộm, k ý tự này có thổ làm trôi p hư ơng thức cin.get. Đc khắc phục lình
trạng trẽn cân d ù n g p h ư ơ n g thức cin .ignore đê bò q u a m ột ký tự chuyên
dò n g n h ư sau:
c i n . ig n o re (1);
C h ú ý 2: Dc s ử dụ nu các toán tử và phương thức nói trên cần khai báo
tệp tiêu đề:
Hi n c l u d e < i o s t. r e a m . h>
Chircniíi trình sau m in h h ọ a việc s ử d ụ n g cá c c ô n g cụ vào ra mới
c ù a c " đc nhập m ột danh sách n thí sinh. D ữ liệu m ỗi thí sinh gồm họ
t ê n , c á c d i ê m t o á n , lý, h o á . S a u đ ó in d a n h s á c h t h í s i n h t h e o t h ứ l ự
g iả m cu a tô n g diêm.
I i n c l u d e < i o s t r e a m . h>
lỉn c lu d c
v o i d ma i . n ( )
{
struct
<
char h t[2 b |;
f l o a t L, 1 , h , t d ;
} t s I 5 0 ], Iq;
i n t n, i , j ;
c l r s c r ();
cout «
"So t h i s i n h :
c i n >> n ;
for
(1=1;
i<=n;
H-:i )
I
cout «
"NnThi s i n h " c< i ;
cout «
"\nllo t e n :
c i n . i qriore (1 ) ;
c i n . q e t (t s [ i I . h t , 2 5 ) ;
c o u L << " C a c d i e m L o a n , l y , h o a :
cin »
t : s | i | . L » L s [ i ] . l >> t s f i j . h ;
t:s I i I . Ld - t . s | i ] . t I t s [ i ] . l I L s [ i ] . h ;
}
f o r ( i = i ; ij)
if ( t s [ i ] . L d < t s ( 'j j . t d )
{
t cj = I s I i I ;
ts[i]
-
ts[j];
ts[j]
= Lq;
}
cout «
M\ n l ) a n h s a c h t : h i s i n h s a u
f o r { i 1; i < n ; ♦ + i )
khi s a p xep
{
cout. «
"\nllo t e n : " «
L s[i].hl;
cout «
"Tonq d i e m : " « t s [ i ] . t : d ;
I
q o t . c h () ;
)
5.2. Đ ịn h d ạ n g khi in ra màn hình
H* ỉ ) ể q u y đ ị n h s ố ill ự c ( f l oat , d o u b l e ) d ư ợ c in ra c ó đ ú n g p c h ừ s ố s au
d ấ u c h ấ m i h ậ p p h â n , t a sir d ụ n g d ồ n g t hời c á c h à m s a u :
s e t i o s í l a q s ( i o s : : sh o w p o i n t ) ; //lìậl- c ờ h i ệ u s h o w p o i n t
setprccision(p);
Các hàm này cần đặt trong toán ur xuất r.hư sau:
cout
<< s o L L o s í l a g s ( L o s : : s h o w p o i n t )
<< s e t p r e c i s i o n ( p ) ;
C âu lệnh trôn sẽ có hiệu lực dối với tất cá các toán từ xuất tiếp theo cho
đôn khi uặp một câu lệnh dịnh dạng mới.
+ Dê quy dịnh dộ rộng lối thiểu là w vị trí cho giá trị (nguyên, thực,
chuồi) dược in trong các toán tứ xuất, ta dùng hàm:
s e l w ( w)
I
làm này cần đặt trontĩ toán tứ xuất và nó chi có hiệu lực cho một giá trị
dược ¡11 uần nhất. Các giá trị in ra tiếp theo sẽ có độ rộng tối thiếu mặc định
là 0. N h ư vậy câu lệnh:
cout
«
s e lw (3)
Sè in
«
"All" «
"CD"
ra 5 ký tự là: một dấu cách và 4 chữ cái A, B,
c
và D.
C h ú ý: M u ố n s ư d ụ n g cá c h à m trên c ầ n đ ư a v à o câu lệnh
# i n c l u d e sau:
K includc
T r ơ lại c h ư ơ n g tr ìn h trên ta th ấ y danh s á c h th í sin h in ra sẽ
k h ô n g th ă n g C Ộ I. Dề k hác p h ụ c đ iề u này cần v iế t lại đ o ạ n c h ư ơ n g
trin h in n h ư sau:
c o u t - << ” \ n l ) a n h s a c h t h i
sinh sau
khi
sap xep M ;
c o u l . << s o i i o s í i a g s ( i Oi ỉ ; : s h o w p o i n t ) << s e t p r e c i s i o n (1 )
f o r ( i 1; i < n; M i )
;
{
c o u t << "Nnl l o t e n : " « s c t w ( 2 5 )
COUL «
"Tong dicin: " « s e t w ( 5 )
«
«
L s|i].h t;
ts[i].td ;
I
q c tc h ();
C h ư ơ n g trình dưới dây là m ộ t minh h ọ a khác về việc sir dụng các
to á n tir n h ậ p xuất và cá ch định d ạ n g trong C +\ C h ư ơ n g trình nhập một
m a trận thự c c ấ p m X n. Sau dó in m a trận dưới d ạ n g b à n g và tìm một
p h ầ n tư lởn nhất.
í i n c l u d c < i o s t r e a m . h>
H i n c l u c i c < i o md ni p . h>
lincL udo
v o i d m u i n ()
f 1 oat . c) I 2 0 ] 1201 ,
in t
m,
n,
i,
j,
ĐAI HỌC QUỐC GIA HA NỌI_
ĨRUNG TẦM ĨHỎNG TIN THƯ V!ẾN
srnax;
imax,
jmax;
c 1r s c r ( ) ;
c o u l << " C h o b i . e t s o hancj v a s o c o t c u a ma t r a n :
c i n >> rn >> n ;
f o r ( i 1 ; L<=m; M i )
";
17
f o r (j = l ; j < = n ; ++j )
{
cout «
"a[" «
i «
cin » a [ i ] [j ];
}
«
j «
"J = ";
smax = a [ 1 1 [ 1 ) ;
im ax = 1;
jmax =
1;
f o r ( j = l ; i <=m; + + i )
f o r (j = l ; j< =n ; ++j )
i f (smax < a [ i ] [ j ])
{
smax = a f i ] [ j ] ;
imax
=
Ỉ;
j ma X = j ;
Ì
cout «
"\n\nMa t r a n " ;
cout «
s e t i o s f l a g s (i o s : : show point) « s e t p r e c i s i o n (1 );
f o r ( i = l ; i <=m; f + i )
f o r (j = l ; j<=n; ++j)
{
i f ( j = = l ) c o u t << ' \ n f ;
c o u t « s e tw (6 ) « a [ i ] [j ];
}
cout «
"\n\n" «
"Phan tu max:" «
' \n ';
c o u t << " c o g i a t r i = " « s e t w ( 6 ) « s m a x ;
cout «
" \ n T a i hang M « imax «
" cot " «
jmax;
g e t c h ();
»
§6. CẤU TRÚC, H Ợ P VÀ KIỂU LIỆT KẼ
6.1. Tên sau t ừ khoá struct đưọ'c x em như tên kiểu cấu trúc
Trong c +’ một kiểu cấu trúc cũng được định nghĩa n h ư c iheo mẫu:
stru ct
Tên k i é u c t
{
/ / Khai báo các th àn h phần cùa cấu t r ú c
);
Sau dỏ để khai báo các biến, m ảng cấu trúc, trong c d ù n g m ẫ u sau:
s t r u c t Tên k i ể u c t
danh sách b iế n ,
mảngcấu
trúc;
N h ư vậy trong c , lên viết sau từ khoá struct chư a phải lã tên kiêu và
chưa có thê dùng dc khai báo.
Trong C ’ ’ xem tên viết sau từ khoá struct là tên kiểu cấu trúc và có thể
dùng nó dế khai báo. N h ư vậy đế khai báo các biến, màng cấu trúc trong
c * \ ta có thể dùng m ầ u sau:
18
T ô n k i ồ u ct- d a n h s á c h b i ế n ,
mỏng c ấ u t r ú c ;
Vi dụ sau sẽ: Dịnh nghĩa kiểu cấu irúc TS (thí sinh) gồm các thành
phần: ht (họ tên), sobd (số báo danh), dt (điểm toán), dl (điểm lý), dh (điểm
hoá) và td (tống diêm), sau đó khai báo biến cấu trúc h và mãng cấu trúc ts.
s t r u c t TS
{
c h a r ht [25];
lonq sobd;
f l o a t d t , đ l , dh,
};
TS h , t s [ 1 0 0 0 1 ;
td;
6.2. T ê n sau t ừ khoá union đ u ọ c xem n h ư tên kiồu h ọ p
Trong
t h e o màu:
C '‘
m ộ t k ic u h ợ p (u n io n ) cũ n g d ư ợ c đ ịn h n g h ĩa n h ư
c
u n i o n Ten k i ề u họp
{
//
K h a i b á o c á c t h ả n h p h ầ n c ù a hợp
Sau dó đc khai báo các biến, mảng kiểu hợp, trong
u n i o n Tôn k i ỏ u hợp d a n h s á c h b i ế n ,
c
dùng mẫu sau:
mảng_kiẻu_hợp;
N hư vậy irong c, tên viết sau từ khoá union chưa phải là tên kiểu và
c h ư a c ó thể dùng dể khai bcáo.
Trong c " xcm tên viết sau từ khoá union là tên kiểu hợp và cỏ thể
d ù n a nó đố khai báo. N hư vậy để khai báo các biến, màng kiểu hợp. trong
c +có thể dùng mẫu sau:
Tên Kiẻu họp danh s á c h b iế n ,
mả ng k i ể u h ợ p ;
6 .3 . Các union khôn» tên
Trong c * ' cho phép dùng các union không tên dạng:
union
{
/ / Kha i
báo c á c th àn h phần
};
Khi dó các thành phần (khai báo trong union) sc dùng chung một vùng
nhớ. Điều này cho phép tiết kiệm bộ nhớ và cho phép dỗ dàng tách các byte
c ủ a một vùn g nliớ.
Ví dụ nếu các hiến nguyên i, biến ký tự ch v à biến thực X không đồng
thời sứ dụng thì có thố khai báo chúng trong một union không tên như sau:
union
{
int
i;
19
char ch;
f 10*11 X;
I;
Khi đó các bit'll i. ch và f sir dụng chung một vùng nh ớ 4 byte.
X é t vi d ụ klìác. d e t á c h c á c b y t e c ú a m ộ t b i ế n u n s i g n e d l o n g t a d ù n g
u n i o n k h ô n g l ỏn sau:
union
(
u n s i g n e d l o n g u;
unsigned ch ar b M I;
};
u
Khí d ó n ê u gán:
OxDDCCIỈBAA;
//
s ố h ệ 16
thi:
b I 0 ị = OxAA
bin
OxiiB
b 1 2 ] - OxCC
b [ 3] - 0x1)1)
6.4. Kiôu liệt ke (enum)
+ C ũ n g g i ổ n g như c ấ u t r ủ c v à h ợ p , t ê n v i é t s a u t ừ k h o á e n u r n được x e m
l à k i ê u liộl k c v à c ó t he d ù n g đ ế k ha i báo, ví dụ:
e n u m MAU { x a n h , đ o , Li m, v a n g };
/ / Đ ị n h n g h ĩ a k i ể u MAU
MAU rn, đsrn [ 1 0 1; / / Kha i b á o c á c b i ế n , mà n g k i ể u MAIJ
+ C á c ui á trị k i ể u liệt k ê ( e n u m ) là c á c s ố n g u y ô n . I )o đ ỏ c ó t h ể t h ụ c
hiện các phép lính trôn các giá trị enum, có thổ in các giá trị cnum, có the
gán ui á trị ciiuin cho biên niìuvên, ví dụ:
MAU nil, m 2 ;
i n t n 1, n 2 ;
ml
L im;
m'A
vanq;
n 1 = ml; / /
n1
2
r\2
ml I 1117;
/ / ĩ\2
5
printif ("\n v»d " t m 2 );
// in ra số 3
+ Không thê gán Irực tiếp mội giá trị nguycn c h o một biến cnum má
phái dùnii phép ép kiêu, ví dụ:
ml = 2 ; / / l ỗ i
ml = M A U (2 );
II
dứng
§ 7 . C Ấ P PHÁT BỘ NHỚ
c
7.1. Trong C ' ' có thế sừ dụng các hàm cấp phát bộ nhở dộng cùa như: hàm
malìoc dô cap phát bộ nhớ, hàm free để íiiài phóng bộ nh ớ được cấp phát.
20