Sáng kiến Dạy học theo định hướng STEM một số chủ đề phần “vật sống”, Khoa họ...
Lap trinh huong_doi_tuong
1. PH M VĂN T (Ch biên)
NGUY N HI U CƯ NG
L P T R Ì NH
H Ư NG ð I T Ư NG
V À C ++
NHÀ XU T B N GIAO THÔNG V N T I
2. L I NÓI ð U
L p trình hư ng ñ i tư ng và C ++ là m t môn h c quan tr ng ñ i v i sinh
viên ngành Công ngh thông tin và m t s ngành h c khác. L p trình hư ng
ñ i tư ng là phương pháp l p trình ch ñ o hi n nay trong công nghi p ph n
m m và tư tư ng hư ng ñ i tư ng ñư c áp d ng trong h u h t các ngôn ng l p
trình hi n ñ i như C++ , Visual C++ , C#, Java...
Phương pháp l p trình ph bi n nh t trong nh ng năm 70 và 80 c a th k
trư c là l p trình c u trúc. ðó là phương pháp t ch c, phân chia chương
trình thành các hàm, th t c. Thông qua các ngôn ng như Pascal và C, ña s
nh ng ngư i làm Tin h c ñã khá quen bi t v i phương pháp l p trình này. Tuy
nhiên phương pháp l p trình này cũng d n b c l nhi u h n ch .
Phương pháp l p trình hư ng ñ i tư ng ñã kh c ph c ñư c nh ng h n ch c a
l p trình c u trúc và m ra m t giai ño n phát tri n m i trong công nghi p ph n
m m. L p trình hư ng ñ i tư ng d a trên vi c t ch c chương trình thành các l p.
Khác v i hàm và th t c, l p là m t ñơn v bao g m c d li u và các phương th c
x lý. Vì v y l p có th mô t các th c th m t cách chân th c, ñ y ñ và ch t ch
hơn.
Ngôn ng C ra ñ i năm 1973 v i m c ñích ban ñ u là ñ vi t h ñi u hành
Unix trên máy tính mini PDP. Sau ñó C ñã ñư c s d ng r ng rãi trên nhi u lo i
máy tính khác nhau và ñã tr thành m t ngôn ng l p trình c u trúc r t ñư c ưa
chu ng. ð ñưa C vào th gi i hư ng hư ng ñ i tư ng, năm 1980 B. Stroustrup ñã
cho ra ñ i m t ngôn ng m i g i là C++, là m t s phát tri n m nh m c a ngôn ng
C. Ngôn ng C++ là m t ngôn ng lai, t c là nó cho phép t ch c chương trình theo
c các l p và các hàm. Có th nói C++ ñã thúc ñ y ngôn ng C v n ñã r t thuy t
ph c ñi vào th gi i l p trình hư ng ñ i tư ng và C++ ñã tr thành ngôn ng hư ng
ñ i tư ng m nh và ñư c s d ng r ng rãi nh t t nh ng năm 1990.
Giáo trình này s trình b y m t cách h th ng các khái ni m c a l p trình
hư ng ñ i tư ng ñư c cài ñ t trong C++ như l p, ñ i tư ng, s th a k , tính tương
ng b i, khuôn hình và các kh năng m i trong xây d ng, s d ng hàm như: ñ i
tham chi u, ñ i m c ñ nh, hàm trùng tên, hàm toán t . Cu i m i chương ñ u có các
bài t p nh ng m c ñ khác nhau ñ ñ c gi t rèn luy n thêm.
Các v n ñ ph c t p thư ng ñòi h i ph i phân tích và thi t k tương ñ i ñ y ñ
trư c khi có th vi t chương trình. Tuy giáo trình này không t p trung vào phân tích
2
3. thi t k , nhưng trong ph l c 4 chúng tôi cũng gi i thi u v n t t v phương pháp
phân tích, thi t k hư ng ñ i tư ng.
Cu n sách g m 9 chương và 4 ph l c.
Chương 1 hư ng d n cách làm vi c v i ph n m m TC++ 3.0 ñ th nghi m các
chương trình, trình b y sơ lư c v các phương pháp l p trình và gi i thi u m t s m
r ng ñơn gi n c a C++ .
Chương 2 trình b y các kh năng m i trong vi c xây d ng và s d ng hàm
trong C++ như bi n tham chi u, ñ i có ki u tham chi u, ñ i có giá tr m c ñ nh, hàm
tr c tuy n, hàm trùng tên, hàm toán t .
Chương 3 nói v m t khái ni m trung tâm c a l p trình hư ng ñ i tư ng.
Chương 4 trình bày chi ti t hơn v ñ nh nghĩa ch ng các toán t
Chương 5 trình b y các v n ñ t o d ng, sao chép, hu b các ñ i
tư ng và các v n ñ khác có liên quan.
Chương 6 trình b y m t khái ni m quan tr ng t o nên kh năng m nh c a l p
trình hư ng ñ 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.
Chương 7 trình b y m t khái ni m quan tr ng khác trong l p trình hư ng ñ i
tư ng là tính tương ng b i và phương th c o.
Chương 8 nói v vi c t ch c vào/ra trong C++.
Chương 9 trình b y v khuôn hình (template) trong C++.
Ph l c 1 trình b y các phép toán trong C ++ và th t ưu tiên c a
chúng.
Ph l c 2 trình b y v b ng mã ASCII và mã quét c a các ký t .
Ph l c 3 là t p h p m t s câu h i tr c nghi m và ñáp án ñ b n ñ c t ki m
tra l i ki n th c.
Ph l c 4 trình b y m t cách ng n g n phương pháp phân tích, thi t k và l p
trình hư ng ñ i tư ng.
Cu i cùng là danh m c m t s thu t ng chuyên ngành s d ng trong giáo
trình này cùng v trí tham chi u ñ ñ c gi ti n tra c u, và m t s tài li u tham kh o
chính.
N i dung chính c a giáo trình ñư c PGS. TS. Ph m Văn t biên so n d a trên
n n cu n “C++ & l p trình hư ng ñ i tư ng” c a tác gi , nhưng có m t s b sung
và s a ch a. ThS. Nguy n Hi u Cư ng biên so n chương 4, ph l c 3, các bài t p
cu i m i chương và hi u ch nh giáo trình.
3
4. Khi vi t giáo trình này chúng tôi ñã h t s c c g ng ñ giáo trình ñư c hoàn
ch nh, song ch c không tránh kh i thi u sót, vì v y chúng tôi r t mong nh n ñư c s
góp ý c a ñ c gi .
Các tác gi
Chương 1
CÁC KHÁI NI M CƠ B N
Chương này trình b y các v n ñ sau:
- Cách s d ng ph n m m Turbo C++ 3.0
- Tóm lư c v các phương pháp l p trình c u trúc và l p trình hư ng ñ i
tư ng
- Nh ng m r ng c a C++ so v i C
§ 1. LÀM VI C V I TURBO C++ 3.0
Các ví d trong giáo trình này ñư c vi t và th c hi n trên môi trư ng Turbo C++
(TC++ phiên b n 3.0). Sau khi cài ñ t (gi s vào thư m c C:TC) thì trong thư m c
TC s g m có các thư m c con sau:
C:TCBGI ch a các t p ñuôi BGI và CHR
C:TCBIN ch a các t p chương trình (ñuôi EXE) như TC, TCC, TLIB,
TLINK, …
C:TCINCLUDE ch a các t p tiêu ñ ñuôi H
C:TCLIB ch a các t p ñuôi LIB, OBJ
ð vào môi trư ng c a TC++ ch c n th c hi n t p chương trình TC.EXE trong thư
m c C:TCBIN . Sau khi vào môi trư ng TC++ chúng ta th y vùng so n th o chương
trình và h menu chính c a TC++ (g n gi ng như h menu quen thu c c a Turbo C).
H menu c a TC++ g m các menu: File, Edit, Search, Run, Compile, Debug, Project,
Options, Window, Help.
Cách so n th o, biên d ch và ch y chương trình trong TC++ cũng gi ng như trong
TC, ngo i tr ñi m sau: T p chương trình trong h so n th o c a TC++ có ñuôi m c
ñ nh là CPP còn trong TC thì t p chương trình có ñuôi là C. Trong TC++ có th th c
hi n c chương trình C và C++.
§ 2. NGÔN NG C VÀ C++
Có th nói C++ là s m r ng ñáng k c a C. ði u ñó có nghĩa là ngoài nh ng kh
năng m i c a C++, m i kh năng, m i khái ni m trong C ñ u dùng ñư c trong C++.
Vì trong 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 s thu n l i hơn n u ñ c
4
5. gi ñã bi t s d ng tương ñ i thành th o ngôn ng C. Giáo trình này ch y u t p
trung vào các khái ni m l p trình hư ng ñ i tư ng cùng ngôn ng C++, và do ñó nó s
không trình bày l i các ch ñ cơ b n trong ngôn ng C như các ki u d li u, các c u
trúc ñi u khi n, …
Vì C++ là s m r ng c a C, nên b n thân m t chương trình C ñã là chương trình
C++. Tuy nhiên Trình biên d ch TC++ yêu c u m i hàm chu n dùng trong chương
trình ñ u ph i khai báo nguyên m u b ng m t câu l nh #include, trong khi ñi u này
không b t bu c ñ i v i Trình biên d ch c a TC.
Trong C ta 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 ñư c dùng. ði u này không báo l i khi biên d ch, nhưng có th
d n ñ n k t qu sai khi ch y chương trình.
Ví d khi biên d ch chương trình sau trong môi trư ng C s không g p các dòng
c nh báo (warning) và thông báo l i (error). Nhưng khi ch y s nh n ñư c k t qu
sai.
#include <stdio.h>
void main()
{
float a,b,c,p,s;
printf("nNhap a, b, c ");
scanf("%f%f%f",&a,&b,&c);
p=(a+b+c)/2;
s= sqrt(p*(p-a)*(p-b)*(p-c));
printf("nDien tich = %0.2f",s);
getch();
}
N u biên d ch chương trình này trong TC++ s nh n ñư c các thông báo l i sau:
Error: Funtion ‘sqrt’ should have a prototype
Error: Funtion ‘getch’ should have a prototype
ð bi n chương trình trên thành m t chương trình C++ c n:
+ ð t tên chương trình v i ñuôi CPP
+ Thêm hai câu l nh #include ñ khai báo nguyên m u cho các hàm sqrt và getch:
#include <math.h>
#include <conio.h>
§ 3. L P TRÌNH C U TRÚC VÀ L P TRÌNH HƯ NG ð I TƯ NG
3.1. Phương pháp l p trình c u trúc
5
6. Tư tư ng chính c a 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 PASCAL có hai ki u chương trình con là th t c (procedure) và
hàm (fuction). 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 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 b .
Các ngôn ng như C, PASCAL là các ngôn ng cho phép tri n khai phương pháp
l p trình c u trú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 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 hai m ng th c toàn b x và y ñ ch a to ñ d y ñi m
+ Xây d ng hai 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 cho bài toán 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));
}
void nhapsl(int n)
{
int i;
for (i=1;i<=n;++i)
{
printf("nNhap toa do x, y cua diem thu %d : ",i);
scanf("%f%f", &x[i], &y[i]);
6
7. }
}
void main()
{
int n,i,j,imax,jmax;
float d,dmax;
printf("nSo 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();
}
3.2. Phương pháp l p trình hư ng ñ i tư ng
Khái ni m trung 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ũng có th xem l p là s m r ng
c a c u trúc (struct) trong C b ng cách ñưa thêm vào các phương th c (methods) hay
còn g i là hàm thành viên (member functions). M t l p ñư c ñ nh nghĩa như sau:
class Tên_l p
{
// Khai báo các thành ph n d li u
// Khai báo các phương th c
};
7
8. Các phương th c có th ñư c vi t (xây d ng) bên trong ho c bên ngoài (phía
dư i) ph n ñ nh nghiã l p. Cách vi t m t phương th c tương t như vi t m t
hàm, ngo i tr quy t c sau: Khi xây d ng m t phương th c bên ngoài ñ nh nghĩa
l p thì trong dòng ñ u tiên c n dùng tên l p và hai d u hai ch m (::) ñ t trư c
tên phương th c ñ ch rõ phương th c ñó thu c l p nào.
Vì phương th c và các thành ph n d li u thu c cùng m t l p, hơn n a phương
th c ñư c l p lên c t ñ x 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).
Sau khi ñ nh nghĩa m t l p, có th dùng tên l p ñ khai báo các bi n ki u l p hay
còn g i là ñ i tư ng. M i ñ i tư ng s có các thành ph n d li u và các phương th c.
L i g i m t phương th c c n ch a tên ñ i tư ng ñ xác ñ nh phương th c th c hi n
t ñ i tư ng nào.
M t chương trình hư ng ñ i tư ng s bao g m các l p có quan h v i nhau.
Vi c phân tích, thi t k chương trình theo phương pháp hư ng ñ i tư ng nh m 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ương ng b i, phương th c o, ...
Thi t k hư ng ñ i tư ng là t p trung xác ñ nh các l p ñ mô t các th c 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 ng
luôn các phương th c ñ x lý d li u. Như v y vi c thi t k chương trình xu t
phát t các n i d ng các v n ñ c a bài toán.
Các ngôn ng thu n tuý hư ng ñ i tư ng (như Smalltalk) ch h tr các khái ni m
v l p, không có các khái ni m hàm. C ++ là ngôn ng lai, nó cho phép s d ng c
các công c c a l p và hàm.
ð minh ho các khái ni m v a nêu v l p trình hư ng ñ i tư ng 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. Xây d ng l p dãy ñi m (daydiem), trong ñó 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. ð th c hi n chương
trình này nh ñ t tên t p có ñuôi CPP.
Xem chương trình ta th y thêm m t ñi u m i trong C++ là: Các khai báo bi n,
m ng có th vi t b t kỳ ch nào trong chương trình (t t nhiên ph i trư c khi s d ng
bi n, m ng).
#include <stdio.h>
8
9. #include <conio.h>
#include <math.h>
#include <alloc.h>
class daydiem
{
public:
int n;
float *x, *y;
float do_dai(int i, int j)
{
return sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2));
}
void nhapsl(void); // khai báo phương th c
};
void daydiem::nhapsl(void) // ñ nh nghĩa (xây d ng) phương th c
{
int i;
printf("nSo 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("nNhap toa do x, y cua diem thu %d : ",i);
scanf("%f%f",&x[i],&y[i]);
}
}
void main()
{
daydiem p;
int n,i,j;
int imax,jmax;
float d, dmax;
p.nhapsl();
n=p.n;
dmax=p.do_dai(1,2); imax=1;jmax=2;
9
10. for (i=1;i<=n-1;++i)
for (j=i+1;j<=n;++j)
{
d=p.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();
}
§ 4. M T S M R NG ðƠN GI N C A C++ SO V I C
Trong m c này trình b y m t s m r ng c a C++, tuy ñơn gi n nhưng ñem l i khá
nhi u ti n l i.
4.1. Vi t các dòng ghi chú
Trong C++ v n có th vi t các dòng ghi chú trong các d u /* và */ như trong C.
Cách vi t này cho phép vi t các ghi chú trên nhi u dòng ho c trên m t dòng. Ngoài
ra trong C++ còn cho phép vi t ghi chú trên m t dòng sau hai d u g ch chéo r t ti n
l i, ví d :
int x,y ; // Khai báo 2 bi n th c
4.2. Khai báo linh ho t
Trong C t t c 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 trí 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 ng ñó ñư c s d ng.
Ví d chương 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
vi t trong C++ như sau:
#include <stdio.h>
#include <alloc.h>
10
11. void main()
{
int n; // khai bao n
printf("n So phan tu cua day n = ");
scanf("%d",&n);
float *x= (float*)malloc((n+1)*sizeof(float));
for (int i=1;i<=n;++i) // khai bao i
{
printf("nX[%d]= ",i);
scanf("%f",x+i);
}
for (i=1;i<=n-1;++i)
for (int j=i+1;j<=n;++j)
if (x[i]>x[j]) {
float tg=x[i];
x[i]=x[j];
x[j]=tg;
}
printf("nDay sau khi sap xepn");
for (i=1;i<=n;++i)
printf("%0.2f ",x[i]);
}
4.3. Toán t ép ki u
Toán t này ñư c vi t trong C như sau:
(Ki u) bi u_th c
Trong C++ v n có th dùng cách vi t này. Ngoài ra C++ cho phép vi t m t cách
khác ti n l i hơn như sau:
Ki u(bi u_th c)
Ví d ñ in ra k t qu chính xác c a phép chia hai bi n nguyên (a chia cho b)
trong C++ ta c n th c hi n ép ki u:
printf("Ket qua = % ", float(a)/b);
4.4. H ng có ki u
ð t o ra m t h ng có ki u, ta s d ng t khoá const ñ t trư c m t khai báo có
kh i gán giá tr . Sau ñây là m t s ví d :
+ H ng nguyên:
11
12. const int maxsize = 1000;
int a[maxsize] ;
+ C u trúc h ng:
typedef struct
{
int x, y ; // To ñ c a ñi m
int mau ; // Mã m u c a ñi m
} DIEM ;
const DIEM d = {320, 240, 15};
Chương trình dư i ñây minh ho 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 ñ ho v i m u tr ng. ði m
này ñư c hi n th trên màn hình ñ ho .
#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
typedef struct
{
int x,y;
int mau;
} DIEM;
void main()
{
int mh=0, mode=0;
initgraph(&mh,&mode,"");
int loi=graphresult();
if (loi)
{
printf("nLoi do hoa: %s",grapherrormsg(loi));
getch();
exit(0);
}
const DIEM gmh = {getmaxx()/2,getmaxy()/2,WHITE}; // khai bao hang
putpixel(gmh.x, gmh.y, gmh.mau);
closegraph();
}
Chú ý:
+ Có th dùng các hàm ñ gán giá tr cho các h ng có ki u (trong chương trình
trên dùng các hàm getmax và getmaxy).
12
13. + 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:
gmh.x=200;
thì khi d ch chương trình s nh n ñư c thông báo l i như sau:
Cannot modify a const object
4.5. Các ki u char và int
Trong C m t h ng ký t ñư c xem là nguyên do ñó nó có kích thư c hai byte, ví
d trong C:
sizeof(‘A’) = sizeof(int) = 2
Còn trong C++ m t h ng ký t ñư c xem là giá tr ki u char và có kích thư c m t
byte. Như v y trong C++ thì:
sizeof(‘A’) = sizeof(char) = 1
4.6. L y ñ a ch các ph n t m ng th c hai chi u
Trong TC 2.0 không cho phép dùng phép & ñ l y ñ a ch các ph n t m ng th c
hai chi u. Vì v y khi nh p d li u cho m t ph n t c a ma tr n th c (dùng scanf) ta
ph i nh p qua m t bi n trung gian sau ñó m i gán cho các ph n t m ng.
Trong TC ++ 3.0 cho phép l y ñ a ch các ph n t m ng th c hai chi u, do ñó có
th dùng scanf ñ nh p tr c ti p vào các ph n t m ng.
Chương trình C++ dư i ñây s minh ho ñi u này. Chương trình nh p m t ma tr n
th c c p mxn và xác ñ nh ph n t có giá tr l n nh t.
#include <stdio.h>
void main()
{
float a[20][20], smax;
int m,n,i,j, imax, jmax;
puts( "Cho biet so hang va so cot cua ma tran: ") ;
scanf("%d%d",&m,&n) ;
for (i=1;i<=m;++i)
for (j=1;j<=n;++j)
{
printf("na[%d][%d]= ",i,j);
scanf("%f",&a[i][j]); // L y ñ a ch ph n t m ng th c hai chi u
}
13
14. smax = a[1][1]; imax=1; jmax=1;
for (i=1;i<=m;++i)
for (j=1;j<=n;++j)
if (smax<a[i][j])
{
smax = a[i][j]; imax=i ; jmax = j;
}
puts( "nnPhan tu max:" );
printf("nco gia tri = %6.1f", smax);
printf("nTai hang %d cot %d " ,imax, jmax) ;
}
4.7. Hàm trong C++
Trong C++ có nhi u m r ng, c i ti n v hàm làm cho vi c xây d ng và s d ng
hàm r t ti n l i. ði u này s trình b y k trong chương sau. Trong m c này ch th ng
kê m t s ñi m m i v hàm mà C++ ñưa vào.
ð i ki u tham chi u
Trong C, ñ nh n k t qu c a hàm qua các ñ i ta c n dùng ñ i con tr , làm cho
vi c xây d ng cũng như s d ng hàm khá phi n ph c. Trong C++ ñưa vào ñ i ki u
tham chi u dùng ñ ch a k t qu c a hàm, khi n cho vi c t o l p cũng như s d ng
hàm ñơn gi n hơn.
ð i tham chi u const
ð i tham chi u có ñ c ñi m là các câu l nh trong thân hàm có th truy nh p t i và
d dàng làm cho giá tr c a nó thay ñ i. Nhi u khi ta mu n dùng ñ i ki u tham chi u
ch ñ tăng t c ñ trao ñ i d li u gi a các hàm, không mu n dùng nó ñ ch a k t
qu c a hàm. Khi ñó có th dùng ñ i tham chi u const ñ b o toàn giá tr c a ñ i
trong thân hàm.
ð i có giá tr m c ñ nh
Trong nhi u trư ng h p ngư i dùng vi t m t l i g i hàm nhưng còn chưa bi t nên
ch n giá tr nào cho các ñ i . ð kh c ph c khó khăn này, C++ ñưa ra gi i pháp ñ i có
giá tr m c ñ nh. Khi xây d ng hàm, ta gán giá tr m c ñ nh cho m t s ñ i. Ngư i
dùng n u không cung c p giá tr cho các ñ i này, thì hàm s dùng giá tr m c ñ nh.
Hàm tr c tuy n (inline)
ð i v i m t ño n chương trình nh (s l nh không l n) thì vi c thay các ño n
chương trình này b ng các l i g i hàm s làm cho chương trình g n nh ñôi chút
nhưng làm tăng th i gian máy. Trong các trư ng h p này có th dùng hàm tr c tuy n
v a gi m kích thư c chương trình ngu n, v a không làm tăng th i gian ch y máy.
Các hàm trùng tên (ñ nh nghĩa ch ng các hàm)
14
15. ð l y giá tr tuy t ñ i c a m t s , trong C c n l p ra nhi u hàm v i tên khác
nhau, ví d abs cho s nguyên, fabs cho s th c, labs cho s nguyên dài, cabs cho s
ph c. ði u này rõ ràng gây phi n toái cho ngư i s d ng. Trong C++ cho phép xây
d ng các hàm trùng tên nhưng khác nhau v ki u ñ i. Như v y ch c n l p m t hàm
ñ l y giá tr tuy t ñ i cho nhi u ki u d li u khác nhau.
ð nh nghĩa ch ng toán t
Vi c dùng các phép toán thay cho m t l i g i hàm rõ ràng làm cho chương trình
ng n g n, sáng s a hơn nhi u. Ví d ñ th c hi n phép c ng 2 ma tr n n u dùng phép
c ng và vi t:
C=A+B;
thì r t g n v i toán h c. Trong C++ cho phép dùng các phép toán chu n ñ ñ t tên
cho các hàm (g i là ñ nh nghĩa ch ng toán t ), sau ñó có th thay l i g i hàm b ng
các phép toán như nói trên.
§ 5. VÀO RA TRONG C++
5.1. Các toán t và phương th c xu t nh p
ð 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ùng
các hàm printf và scanf (như ñã ch ra trong các chương trình C++ các m c trên).
Ngoài ra trong C++ còn dùng toán t xu t ñ ñưa giá tr các bi u th c ra màn hình:
cout << bi u th c << ... << bi u th c ;
++
C dùng toán t nh p ñ nh p các giá tr t bàn phím và gán cho các bi n:
cin >> bi n >> ... >> bi n;
ð nh p m t d y không quá n ký t và ch a vào m ng h (ki u char) có th dùng
phương th c cin.get như sau:
cin.get(h,n);
Chú ý:
+ Toán t nh p cin >> s ñ l i ký t chuy n dòng ‘n’ trong b ñ m, ký t này
có th làm trôi phương th c cin.get. ð kh c ph c tình tr ng trên c n dùng
phương th c cin.ignore ñ b qua m t ký t chuy n dòng như sau:
cin.ignore(1);
+ ð s d ng các toán t và phương th c nói trên c n khai báo t p tiêu ñ :
#include <iostream.h>
15
16. Chương trình sau minh ho vi c s d ng các công c vào ra m i c a 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 ñi m toán,
lý, hoá. Sau ñó in danh sách thí sinh theo th t gi m c a t ng ñi m.
#include <iostream.h>
#include <conio.h>
void main()
{
struct
{
char ht[25];
float t,l,h,td;
} ts[50],tg;
int n,i,j;
cout << "So thi sinh: " ; cin >> n ;
for (i=1;i<=n;++i)
{
cout << "n Thi sinh " << i ;
cout << "n Ho ten: " ;
cin.ignore(1);
cin.get(ts[i].ht,25) ; // Chú ý nh p chu i ký t
cout << "Cac diem toan, ly, hoa: ";
cin >> ts[i].t >> ts[i].l >> ts[i].h ;
ts[i].td = ts[i].t + ts[i].l + ts[i].h ;
}
for (i=1;i<=n-1;++i)
for (j=i+1;j<=n;++j)
if (ts[i].td < ts[j].td ) {
tg=ts[i];
ts[i]=ts[j];
ts[j]=tg;
}
cout << "nDanh sach thi sinh sau khi sap xep " ;
for (i=1;i<=n;++i)
{
cout << "n Ho ten: " << ts[i].ht;
cout << " Tong diem: " << ts[i].td;
}
16
17. getch();
}
5.2. ð nh d ng khi in ra màn hình
ð quy ñ nh s th c (float, double) ñư c in ra có ñúng p ch s sau d u ch m
th p phân, ta s d ng ñ ng th i các hàm sau:
setiosflags(ios::showpoint); // B t c hi u showpoint
setprecision(p);
Các hàm này c n ñ t trong toán t xu t như sau:
cout << setiosflags(ios::showpoint) << setprecision(p) ;
Câu l nh trên s có hi u l c ñ i v i t t c các toán t xu t ti p theo cho ñ n khi
g p m t câu l nh ñ nh d ng m i.
ð quy ñ nh ñ r ng t i thi u là w v trí cho giá tr (nguyên, th c, chu i) ñư c in
trong các toán t xu t, ta dùng hàm
setw(w)
Hàm này c n ñ t trong toán t xu t và nó ch có hi u l c cho m t giá tr ñư c in
g 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. Như v y câu
l nh:
cout << setw(3) << “AB” << “CD”;
S in ra 5 ký t là: m t d u cách và 4 ch cái A, B, C và D.
Chú ý: Mu n s d ng các hàm trên c n ñưa vào câu l nh khai báo thư
vi n:
#include <iomanip.h>
Tr l i chương trình trên ta th y danh sách thí sinh in ra s không th ng
c t. ð kh c ph c ñi u này c n vi t l i ño n chương trình in như sau:
cout << "nDanh sach thi sinh sau khi sap xep " ;
cout << setiosflags(ios::showpoint) << setprecision(1) ;
for(i=1;i<=n;++i)
{
cout << "n Ho ten: " << setw(25) << ts[i].ht;
cout << " Tong diem: " << setw(5)<< ts[i].td;
}
Chương trình dư i ñây là m t minh ho khác v vi c s d ng các toán t
nh p xu t và cách ñ nh d ng trong C++ . Chương trình nh p m t ma tr n th c c p
mxn. Sau ñó in ma tr n dư i d ng b ng và tìm m t ph n t l n nh t.
#include <iostream.h>
#include <iomanip.h>
void main()
17
18. {
float a[20][20], smax;
int m,n,i,j,imax, jmax;
cout << " Cho biet so hang va so cot cua ma tran: " ;
cin >> m >> n ;
for (i=1;i<=m;++i)
for (j=1;j<=n;++j)
{
cout << "a[" << i << "," << j << "]= " ;
cin >> a[i][j] ;
}
smax = a[1][1];
imax= jmax= 1;
for (i=1;i<=m;++i)
for (j=1;j<=n;++j)
if (smax<a[i][j])
{
smax = a[i][j];
imax=i ;
jmax = j;
}
cout << "nn Ma tran" ;
cout << setiosflags(ios::showpoint) << setprecision(1) ;
for (i=1;i<=m;++i)
for (j=1;j<=n;++j)
{
if (j==1) cout << 'n' ;
cout << setw(6) << a[i][j];
}
cout << "nn" << "Phan tu max:" << 'n' ;
cout << "co gia tri = " << setw(6) << smax;
cout << "nTai hang: " << imax << " cot: " << jmax ;
}
§ 6. CÁC KI U C U TRÚC, H P VÀ LI T KÊ
6.1. Tên sau t khoá struct ñư c xem như tên ki u c u trúc
18
19. Trong C++ m t ki u c u trúc cũng ñư c ñ nh nghĩa như C theo m u:
struct Tên_ki u_ct
{
// Khai báo các thành ph n c a c u trúc
};
Sau ñó ñ khai báo các bi n, m ng c u trúc, trong C dùng m u sau:
struct Tên_ki u_ct danh sách bi n, m ng c u trúc ;
Như v y trong C, tên vi t sau t khoá struct chưa ph i là tên ki u và chưa có th
dùng ñ 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ó
ñ khai báo. Như 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:
Tên_ki u_ct danh sách bi n, m ng c u trúc ;
Ví d : ð nh nghĩa ki u c u trú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 ñi m), sau ñó khai báo bi n c u trúc h và m ng c u trúc ts.
struct TS
{
char ht [25];
long sobd;
float dt, dl, dh, td;
};
TS h, ts[1000] ;
6.2. Tên sau t khoá union ñư c xem như tên ki u h p
Trong C ++ m t ki u h p (union) cũng ñư c ñ nh nghĩa như C theo m u:
union Tên_ki u_h p
{
// Khai báo các thành ph n c a h p
};
Sau ñó ñ khai báo các bi n, m ng ki u h p , trong C dùng m u sau:
union Tên_ki u_h p danh sách bi n, m ng ki u h p ;
Như v y trong C, tên vi t sau t khoá union chưa ph i là tên ki u và chưa có th
dùng ñ khai báo.
Trong C++ xem tên vi t sau t khoá union là tên ki u h p và có th dùng nó ñ
khai báo. Như 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ách bi n, m ng ki u h p ;
19
20. 6.3. Ki u li t kê (enum)
Cũng gi ng như c u trúc và h p, tên vi t sau t khoá enum ñư c xem là ki u li t
kê và có th dùng ñ khai báo, ví d :
enum MAU { xanh, do, tim, vang } ; // ð nh nghĩa ki u MAU
MAU m, dsm[10] ; // Khai báo các bi n, m ng ki u MAU
Các giá tr ki u li t kê (enum) là các s nguyên. Do ñó có th th c hi n các phép
tính trên các giá tr enum, có th in các giá tr enum, có th gán giá tr enum cho bi n
nguyên, ví d :
MAU m1 , m2 ;
int n1, n2 ;
m1 = tim ;
m2 = vang ;
n1 = m1 ; // n1 = 2
n2 = m1 + m2 ; // n2 = 5
printf (“n %d “ , m2 ); // in ra s 3
Chú ý: Không th gán tr c ti p m t giá tr nguyên cho m t bi n enum mà ph i
dùng phép ép ki u, ví d :
m1 = 2 ; // l i
m1 = MAU(2) ; // ñúng
§ 7. C P PHÁT B NH
Trong C++ có th s d ng các hàm c p phát b nh ñ ng c a C như: hàm malloc
ñ c p phát b nh , hàm free ñ gi i phóng b nh ñư c c p phát. Ngoài ra trong C++
còn ñưa thêm toán t new ñ c p phát b nh và toán t delete ñ gi i phóng b nh
ñư c c p phát b i new.
7.1. Cách dùng toán t new ñ c p phát b nh như sau:
Trư c h t c n khai báo m t con tr ñ ch a ñ a ch vùng nh s ñư c c p phát:
Ki u *p;
ñây Ki u có th là:
+ Các ki u d li u chu n c a C++ như int, long, float, double, char, ...
+ Các ki u t ñ nh nghĩa như: m ng, h p, c u trúc, l p, ...
Sau ñó dùng toán t new theo m u:
p = new Ki u ; // C p phát b nh cho m t bi n (m t ph n t )
p = new Ki u[n] ; // C p phát b nh cho n ph n t
Ví d ñ c p phát b nh cho m t bi n th c ta dùng câu l nh sau:
float *px = new float ;
ð c p phát b nh cho 100 ph n t nguyên ta dùng các câu l nh:
int *pn = new int[100] ;
20
21. 7.2. Hai cách ki m tra s thành công c a new
Khi dùng câu l nh:
Ki u *p = new Ki u[n] ;
ho c câu l nh:
Ki u *p = new Ki u ;
ñ c p phát b nh s xu t hi n m t trong hai kh năng: c p phát thành công ho c
không thành công.
+ N u thành công thì p s ch a ñ a ch ñ u vùng nh ñư c c p phát.
+ N u không thành công thì p = NULL.
ðo n chương trình sau minh ho m t cách ki m tra l i c p phát b nh :
double *pd ;
int n ;
cout << “n S ph n t : “ ;
cin >> n ;
pd = new double[n] ;
if (pd==NULL) // Ki m tra
{
cout << “ L i c p phát b nh “
exit (0) ;
}
Cách th hai ñ ki m tra s thành công c a toán t new là dùng con tr
hàm:
_new_handler
ñư c ñ nh nghĩa trong t p “new.h”. Khi g p l i trong toán t new (c p phát không
thành công) thì chương trình s th c hi n m t hàm nào ñó do con tr _new_handler
tr t i. Cách dùng con tr này như sau:
+ Xây d ng m t hàm dùng ñ ki m tra s thành công c a new
+ Gán tên hàm này cho con tr _new_handler
Như v y hàm ki m tra s ñư c g i m i khi có l i x y ra trong toán t new.
ðo n chương trình ki m tra theo cách th nh t có th vi t theo cách th hai như
sau:
void kiem_tra_new(void) // L p hàm ki m tra
{
cout << “ L i c p phát b nh “
exit (0) ;
}
_new_handler = kiem_tra_new // Gán tên hàm cho con tr
21
22. double *pd ;
int n ;
cout << “n S ph n t : “ ;
cin >> n ;
pd = new double[n] ; // Khi x y ra l i s g i hàm ki m_tra_new
Chú ý: Có th dùng l nh gán ñ gán tên hàm x lý l i cho con tr _new_handler
như trong ño n chương trình trên, ho c dùng hàm:
set_new_handler(Tên hàm) ;
7.3. Toán t delete dùng ñ gi i phóng vùng nh ñư c c p phát b i new
N u p là con tr xác ñ nh vùng nh ñư c c p b ng new, thì ñ gi i phóng vùng
nh ñã c p ta dùng câu l nh sau:
delete p ;
Ví d :
float p, *px ;
p = new float; // C p phát b nh cho m t ph n t th c
px = new float[2000] ; // C p phát b nh cho m ng 2000 ph n t th c
// S d ng b nh ñư c c p phát
…
delete p; // Gi i phóng b nh c a m t ph n t
delete [] px ; // Gi i phóng b nh c a c m ng
7.4. Các chương trình minh ho
Chương trình th nh t minh ho cách dùng new ñ c p phát b nh ch a n thí
sinh. M i thí sinh là m t c u trúc g m các trư ng ht (h tên), sobd (s báo danh) và
td (t ng ñi m). Chương trình s nh p n, c p phát b nh ch a n thí sinh, ki m tra l i
c p phát b nh (dùng cách 1); sau ñó nh p n thí sinh, s p x p thí sinh theo th t
gi m c a t ng ñi m, in danh sách thí sinh sau khi s p x p, và cu i cùng là gi i phóng
b nh ñã c p phát.
#include <iomanip.h>
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
struct TS
{
char ht[20];
long sobd;
float td;
};
22
23. void main(void) {
TS*ts ;
int n;
cout << "n So thi sinh n = " ; cin >> n;
ts = new TS[n+1];
if(ts==NULL)
{
cout << "nLoi cap phat bo nho " ;
getch();
exit(0);
}
for (int i=1;i<=n;++i)
{
cout <<"nThi sinh thu " << i;
cout << "nHo ten: " ;
cin.ignore(1) ;
cin.get(ts[i].ht,20);
cout << "So bao danh: " ;
cin >> ts[i].sobd ;
cout << "Tong diem: " ;
cin >> ts[i].td ;
}
for (i=1;i<=n-1;++i)
for (int j=i+1;j<=n;++j)
if (ts[i].td < ts[j].td)
{
TS tg=ts[i];
ts[i]=ts[j];
ts[j]=tg;
}
cout << setiosflags(ios::showpoint) << setprecision(1) ;
for (i=1;i<=n;++i)
cout << "n" << setw(20) << ts[i].ht
<< setw(6)<< ts[i].sobd <<setw(6)<< ts[i].td;
delete ts;
getch();
}
23
24. Chương trình th hai minh ho cách dùng con tr _new_handler ñ ki m tra s thành
công c a toán t new. Chương trình s c p phát b nh cho m t m ng con tr và s theo
dõi khi nào thì không ñ b nh ñ c p phát.
#include <new.h>
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
int k;
void loi_bo_nho(void)
{
cout << "nLoi bo nho khi cap phat bo nho cho q[" << k << "]";
getch();
exit(0);
}
void main()
{
double *q[100] ;
long n;
clrscr();
set_new_handler(loi_bo_nho) ;
// Ho c _new_handler=loi_bo_nho;
n=10000;
for ( k=0;k<100;++k)
q[k] = new double[n];
cout << "Khong loi";
getch();
}
BÀI T P CHƯƠNG 1
Bài 1. Vi t chương trình nh p m t s t nhiên n. Ki m tra xem n có ph i s
nguyên t không.
Bài 2. Vi t chương trình nh p m t dãy s th c. In các s dương trên m t dòng và
các s âm trên dòng ti p theo.
Bài 3. Vi t chương trình nh p m t dãy s th c. S p x p dãy s trên theo th t
tăng d n.
Bài 4. Vi t chương trình nh p hai dãy s th c ñ u ñư c s p tăng d n. Ghép hai
dãy s trên thành m t dãy cũng ñư c s p tăng d n.
Bài 5. Trong m t trư ng trung h c, hoc sinh b t bu c ph i h c ba môn toán, lý và
hoá. Ngoài ra h c sinh nam h c thêm môn k thu t còn h c sinh n h c thêm môn n
24
25. công. Vi t chương trình th c hi n các công vi c: Nh p h tên, gi i tính và ñi m c a
n h c sinh. In s li u v các h c sinh ra màn hình.
Bài 6. Trong m c 7.1 ñã ñ c p ñ n vi c c p phát b nh ñ ng cho m t bi n và
m t m ng m t chi u. Bài này yêu c u cao hơn: Vi t chương trình c p phát b nh
ñ ng cho m t m ng hai chi u, sau ñó nh p d li u vào m ng ñó và in k t qu ra màn
hình.
25
26. CHƯƠNG 2
HÀM TRONG C++
Chương này trình b y nh ng kh năng m i c a C++ trong vi c xây d ng và s
d ng các hàm. ðó là:
- Bi n tham chi u và vi c truy n d li u cho hàm b ng tham chi u
- ð i có giá tr m c ñ nh
- Hàm tr c tuy n
- ð nh nghĩa ch ng các hàm
- ð nh nghĩa ch ng các toán t
§ 1. BI N THAM CHI U
1.1. Hai lo i bi n dùng trong C
Trư c khi nói ñ n bi n tham chi u, chúng ta nh c l i hai lo i bi n ñã g p trong C
là:
+ Bi n giá tr dùng ñ ch a d li u (nguyên, th c, ký t , ... )
+ Bi n con tr dùng ñ ch a ñ a ch
Các bi n này ñ u ñư c cung c p b nh và có ñ a ch . Ví d câu l nh khai báo:
double x , *px;
s t o ra bi n giá tr ki u double là x và bi n con tr ki u double là px. Bi n x có
vùng nh 8 byte, bi n px có vùng nh 4 byte (n u dùng mô hình b nh Large). Bi n
x dùng ñ ch a giá tr ki u double, ví d l nh gán:
x = 3.14;
s ch a giá tr 3.14 vào bi n x. Bi n px dùng ñ ch a ñ a ch c a m t bi n th c, ví d
câu l nh:
px = &x ;
s lưu tr ñ a ch c a bi n x vào con tr px.
1.2. Bi n tham chi u
Trong C++ cho phép s d ng lo i bi n th ba là bi n tham chi u (reference
variable). So v i hai lo i bi n nói trên thì bi n tham chi u có nh ng ñ c ñi m sau:
+ Bi n tham chi u không ñư c c p phát b nh , không có ñ a ch riêng.
+ Nó dùng làm bí danh (alias) cho m t bi n (ki u giá tr ) nào ñó và nó s d ng
vùng nh c a bi n này. Ví d câu l nh:
float u, v, &r = u ;
26
27. t o ra các bi n th c u, v và bi n tham chi u th c r. Bi n r không ñư c c p phát b
nh riêng, nó ch là m t tên khác (bí danh) c a u và nó dùng chung vùng nh c a
bi n u.
Khi r là bí danh c a u thì ta nói r tham chi u ñ n bi n u. Như v y hai thu t ng
trên ñư c hi u như nhau.
Khi r là bí danh c a u thì r dùng chung vùng nh c a u, do ñó :
+ Trong m i câu l nh, vi t u hay vi t r ñ u có ý nghĩa như nhau, vì ñ u truy nh p
ñ n cùng m t vùng nh .
+ Có th dùng bi n tham chi u ñ truy nh p ñ n m t bi n ki u giá tr .
Ví d :
int u, v, &r = u;
r = 10 ; // u=10
cout << u ; // in ra s 10
r++ ; // u = 11
++ u ; // r = 12
cout << r ; // in ra s 12
v=r; // v=12
&r; // Cho ñ a ch c a u
Vài chú ý v bi n tham chi u:
+ Bi n tham chi u thư ng ñư c s d ng làm ñ i c a hàm ñ cho phép hàm truy
nh p ñ n các tham s bi n trong l i g i hàm.
+ Vì bi n tham chi u không có ñ a ch riêng, nó ch là bí danh c a m t bi n ki u
giá tr nên trong khai báo ph i ch rõ nó tham chi u ñ n bi n nào. Ví d n u khai báo:
double &x ;
thì Trình biên d ch s báo l i:
Reference variable ‘x’ must be initialized
+ Bi n tham chi u có th tham chi u ñ n m t ph n t m ng, ví d :
int a[10] , &r = a[5];
r = 25 ; // khi ñó a[5] = 25
+ Không cho phép khai báo m ng tham chi u
+ Bi n tham chi u có th tham chi u ñ n m t h ng. Khi ñó nó s s d ng
vùng nh c a h ng và nó có th làm thay ñ i giá tr ch a trong vùng nh này.
Ví d n u khai báo:
int &s = 23 ;
thì Trình biên d ch ñưa ra c nh báo:
Temporary used to initialize 's'
27
28. Tuy nhiên chương trình v n làm vi c. Các câu l nh dư i ñây v n th c hi n và cho
k t qu như sau:
s++;
cout << "ns= " << s; // In ra s=24
§ 2. TRUY N GIÁ TR CHO HÀM THEO THAM CHI U
2.1. Hàm trong C
Trong C ch có m t cách truy n d li u cho hàm theo giá tr , ñư c th c hi n như
sau:
+ C p phát vùng nh cho các ñ i.
+ Gán giá tr các tham s trong l i g i hàm cho các ñ i sau ñó hàm làm
vi c trên vùng nh c a các ñ i ch không liên quan gì ñ n các tham s .
Như vây chương trình s t o ra các b n sao (các ñ i) c a các tham s và hàm s
thao tác trên các b n sao này, ch không làm vi c tr c ti p v i các tham s . Phương
pháp này có nh ng như c ñi m chính: T n kém v th i gian và b nh vì ph i t o ra
các b n sao, và không thao tác tr c ti p trên các tham s , vì v y không làm thay ñ i
ñư c giá tr các tham s .
2.2. Truy n giá tr cho hàm theo tham chi u
C++ cung c p thêm cách truy n d li u cho hàm theo tham chi u b ng cách dùng
ñ i là bi n tham chi u ho c ñ i là h ng tham chi u. Cách này có ưu ñi m: Không c n
t o ra các b n sao c a các tham s , do ñó ti t ki m b nh và th i gian ch y máy, và
hàm s thao tác tr c ti p trên vùng nh c a các tham s , do ñó có th d dàng thay
ñ i giá tr các tham s khi c n.
2.3. M i quan h gi a ñ i và tham s trong l i g i hàm
N u ñ i là bi n ho c h ng tham chi u ki u gì thì tham s (trong l i g i hàm) ph i
là bi n ho c ph n t m ng ki u ñó. Ví d :
+ ð i là bi n (ho c h ng) tham chi u ki u double, thì tham s là bi n ho c ph n t
m ng ki u double
+ ð i là bi n (ho c h ng) tham chi u ki u c u trúc, thì tham s là bi n ho c ph n
t m ng ki u c u trúc
2.4. Các chương trình minh ho
/* Chương trình 1:
G m các hàm:
+ Nh p d y s ki u double
+ Hoán v 2 bi n ki u double
+ S p x p d y s ki u double theo th t tăng d n
Chương trình s nh p m t d y s và in d y sau khi s p x p
*/
28
29. #include <iostream.h>
#include <conio.h>
#include <stdio.h>
void nhapds(double *a, int n)
{
for (int i=1; i<= n ; ++i)
{
cout << "nPhan tu thu " << i << " : " ;
cin >> a[i] ;
}
}
// Hàm hoán v , dùng ñ i tham chi u
void hv(double &x, double &y)
{
double tg=x;
x=y;
y= tg;
}
void sapxep(double * a, int n)
{
for (int i=1; i <= n-1 ;++i)
for (int j=i+1 ; j<=n ;++j)
if (a[i] > a[j])
hv(a[i],a[j]);
}
void main()
{
double x[100];
int i, n;
cout <<"n N= ";
cin >> n;
nhapds(x,n);
sapxep(x,n);
for (i=1;i<=n;++i)
printf("n%0.1lf",x[i]);
getch();
29
30. }
/* Chương trình 2:
G m các hàm:
+ Nh p d y c u trúc (m i c u trúc ch a d li u m t thí sinh)
+ Hoán v 2 bi n c u trúc
+ S p x p d y thí sinh theo th t gi m c a t ng ñi m
+ In m t c u trúc (in h tên và t ng ñi m)
Chương trình s nh p d li u m t danh sách thí sinh, nh p ñi m chu n và in
danh sách thí sinh trúng tuy n
*/
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>
struct TS
{
char ht[20];
float t,l,h,td;
};
void ints(const TS &ts)
{
cout << setiosflags(ios::showpoint) << setprecision(1) ;
cout << "nHo ten: " << setw(20) << ts.ht << setw(6) << ts.td ;
}
void nhapsl(TS *ts, int n)
{
for (int i=1;i<=n;++i)
{
cout << "n Thi sinh " << i ;
cout << "n Ho ten: " ;
cin.ignore(1);
cin.get(ts[i].ht,25) ;
cout << "Cac diem toan, ly, hoa: ";
cin >> ts[i].t >> ts[i].l >> ts[i].h ;
ts[i].td = ts[i].t + ts[i].l + ts[i].h ;
}
30
33. § 3. HÀM TR V CÁC THAM CHI U
Hàm có th có ki u tham chi u và tr v giá tr tham chi u. Khi ñó có th dùng
hàm ñ truy nh p ñ n m t bi n ho c m t ph n t m ng nào ñó. Dư i ñây là m t s ví
d .
Ví d 1 trình b y m t hàm tr v m t tham chi u ñ n m t bi n toàn b . Do ñó có
th dùng hàm ñ truy nh p ñ n bi n này.
#include <iostream.h>
int z ; // Bi n toàn b
int &f() // Hàm tr v m t bí danh c a bi n toàn b z
{
return z;
}
void main(void)
{
f()=50;
cout <<"nz= " << z; // z = 50
}
Ví d 2 trình b y m t hàm tr v bí danh c a m t bi n c u trúc toàn b . Khác v i
ví d trên, ñây không dùng hàm m t cách tr c ti p mà gán hàm cho m t bi n tham
chi u, sau ñó dùng bi n tham chi u này ñ truy nh p ñ n bi n c u trúc toàn b .
#include <iostream.h>
#include <conio.h>
struct TS
{
char ht[25];
float t,l,h,td;
};
TS ts;
TS &f()
{
return ts;
}
void main()
{
TS &h=f(); // h tham chi u ñ n bi n ts
cout << "n Ho ten: " ;
33
34. cin.get(h.ht,25) ;
cout << "Cac diem toan, ly, hoa: ";
cin >> h.t >> h.l >> h.h ;
h.td = h.t + h.l + h.h ;
cout << "n Ho ten: " << ts.ht;
cout << "n Tong diem: " << ts.td;
getch();
}
Ví d 3 trình b y m t hàm tr v bí danh c a m t ph n t m ng c u toàn b .
Hàm s ki m tra xem ch s m ng có vư t ra ngoài mi n quy ñ nh hay không. Sau ñó
dùng hàm này ñ truy nh p ñ n các ph n t m ng c u trúc.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
struct TS
{
char ht[25];
float t,l,h,td;
};
TS *ts;
void cap_phat_bo_nho_nhapsl(int n)
{
ts = new TS[n+1] ;
if (ts==NULL)
{
cout << "Loi cap phat bo nho " ;
exit(1);
}
for (int i=1;i<=n;++i)
{
TS &h=ts[i];
cout << "nThi sinh thu " << i ;
cout << "n Ho ten: " ;
cin.ignore(1);
cin.get(h.ht,25) ;
cout << "Cac diem toan, ly, hoa: ";
34
35. cin >> h.t >> h.l >> h.h ;
h.td = h.t + h.l + h.h ;
}
}
TS &f(int i, int n) // Cho bi danh ts[i]
{
if (i<1 || i>n)
{
cout << "Chi so mang khong hop le " ;
exit(1);
}
return ts[i];
}
void main()
{
int n, i ;
cout << "n So thi sinh : " ;
cin >> n;
cap_phat_bo_nho_nhapsl(n);
while (1)
{
cout << "nCan xem thi sinh thu may: " ;
cin >> i;
TS &h=f(i,n);
cout << "n Ho ten: " << h.ht;
cout << "n Tong diem: " << h.td;
}
}
§ 4. ð I CÓ GIÁ TR M C ð NH
4.1. Th nào là ñ i có giá tr m c ñ nh
Thông thư ng s tham s trong l i g i hàm ph i b ng s ñ i c a hàm. M i
ñ i s ñư c kh i gán giá tr theo tham s tương ng c a nó. Trong C ++ cho
phép t o giá tr m c ñ nh cho các ñ i. Các ñ i này có th có ho c không có
tham s tương ng trong l i g i hàm. Khi không có tham s tương ng, ñ i
ñư c kh i gán b i giá tr m c ñ nh.
Ví d hàm delay v i ñ i s m c ñ nh ñư c vi t theo m t trong 2 cách sau:
Cách 1 (Không khai báo nguyên m u):
void delay(int n=1000)
35
36. {
for (int i=0 ; i<n ; ++i)
;
}
Cách 2 (Có khai báo nguyên m u):
void delay(int n=1000) ;
void delay(int n)
{
for (int i=0 ; i<n ; ++i)
;
}
Cách dùng:
+ Cung c p giá tr cho ñ i n (Có tham s trong l i g i hàm)
delay(5000) ; // ð i n = 5000
+ S d ng giá tr m c ñ nh c a ñ i (Không có tham s trong l i g i)
delay() ; // ð i n = 1000
4.2. Quy t c xây d ng hàm v i ñ i m c ñ nh
+ Các ñ i m c ñ nh c n ph i là các ñ i cu i cùng tính t trái sang ph i. Gi s có
5 ñ i theo th t t trái sang ph i là: d1, d2, d3, d4, d5
Khi ñó (các ví d ñúng):
n u m t ñ i m c ñ nh thì ph i là d5
n u hai ñ i m c ñ nh thì ph i là d4, d5
n u ba ñ i m c ñ nh thì ph i là d3, d4, d5
...
Các ví d sai:
d3 và d5 m c ñ nh (ch ñúng khi d4 cũng ph i m c ñ nh)
d3 và d4 m c ñ nh (ch ñúng khi d5 cũng ph i m c ñ nh)
+ Khi xây d ng hàm, n u s d ng khai báo nguyên m u, thì các ñ i m c ñ nh c n
ñư c kh i gán ngay trong nguyên m u, ví d :
// Kh i gán giá tr cho 3 ñ i m c ñ nh d3, d4 và d5)
void f(int d1, float d2, char *d3=”HA NOI”, int d4 = 100, double d5=3.14) ;
void f(int d1, float d2, char *d3, int d4, double d5)
{
// Các câu l nh trong thân hàm
36
37. }
Không ñư c kh i gán l i cho các ñ i m c ñ nh trong dòng ñ u c a ñ nh nghĩa
hàm. N u vi ph m ñi u này thì Chương trình d ch s thông báo l i.
+ Khi xây d ng hàm, n u không khai báo nguyên m u, thì các ñ i m c ñ nh ñư c
kh i gán trong dòng ñ u c a ñ nh nghĩa hàm, ví d :
// Kh i gán giá tr cho 3 ñ i m c ñ nh d3, d4 và d5)
void f(int d1, float d2, char *d3=”HA NOI”,
int d4 = 100, double d5=3.14)
{
// Các câu l nh trong thân hàm
}
+ Có th dùng các h ng, các bi n toàn b , các hàm ñ kh i gán cho ñ i m c ñ nh,
ví d :
int MAX = 10000;
void f(int n, int m = MAX, int xmax = getmaxx(),
int ymax = getmaxy() ) ;
4.3. Cách s d ng hàm có ñ i m c ñ nh
L i g i hàm c n vi t theo quy ñ nh: Các tham s thi u v ng trong l i g i hàm ph i
tương ng v i các ñ i m c ñ nh cu i cùng (tính t trái sang ph i).
Nói cách khác: ðã dùng giá tr m c ñ nh cho m t ñ i (t t nhiên ph i là ñ i m c
ñ nh) thì cũng ph i s d ng giá tr m c ñ nh cho các ñ i còn l i.
Ví d v i hàm có ba ñ i m c ñ nh:
void f(int d1, float d2, char *d3=”HA NOI”, int d4 = 100, double d5=3.14) ;
Thì các l i g i sau là ñúng:
f(3,3.4,”ABC”,10,1.0) ; // ð y ñ tham s
f(3,3.4,”ABC”) ; // Thi u 2 tham s cu i
f(3,3.4) ; // Thi u 3 tham s cu i
Các l i g i sau là sai:
f(3) ; // Thi u tham s cho ñ i không m c ñ nh d2
f(3,3.4, ,10) ; // ðã dùng giá tr m c ñ nh cho d3, thì cũng
// ph i dùng giá tr m c ñ nh cho d4 và d5
4.4. Các ví d
37
38. Ví d hàm ht trong chương trình sau dùng ñ hi n th chu i ký t dc trên n dòng
màn hình. Các ñ i dc và n ñ u có giá tr m c ñ nh.
#include <iostream.h>
void ht(char *dc="HA NOI",int n=10) ;
void main()
{
ht(); // In dòng ch “HA NOI” trên 10 dòng
ht("ABC",3); // In dòng ch “ABC” trên 3 dòng
ht("DEF"); // In dòng ch “DEF” trên 10 dòng
}
void ht(char *dc , int n )
{
for (int i=0; i<n; ++i) cout << "n" << dc;
}
Ví d dư i ñây trình b y hàm hi n th m t chu i str trên màn hình ñ ho , t i
v trí (x,y) và có m u m. Các ñ i x, y và m là m c ñ nh. Dùng các hàm
getmaxx() và getmaxy() ñ kh i gán cho x, y. Dùng h ng RED gán cho m.
#include <conio.h>
#include <graphics.h>
void hiendc(char *str, int x = getmaxx()/2,
int y = getmaxy()/2,
int m= RED);
void main()
{
int mh=0, mode=0;
initgraph(&mh, &mode,"");
setbkcolor(BLUE);
hiendc("HELLO"); // HELLO m u ñ gi a màn hình
hiendc("CHUC MUNG",1,1); // hi n CHUC MUNG m u ñ t i v trí (1,1)
hiendc("XIN CHAO",1,400,YELLOW); // hi n XIN CHAO m u vàng t i
// v trí (1,400)
getch();
}
void hiendc(char *str, int x,int y, int m)
{
int mau_ht = getcolor(); // Luu mau hien tai
setcolor(m);
38
39. outtextxy(x,y,str) ;
setcolor(mau_ht); // Khoi phuc mau hien tai
}
§ 5. CÁC HÀM TR C TUY N
5.1. Ư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, 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 cách t ch c thành các 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 ñ i và 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 (inline functions) trong C++ giúp cho chương trình v n có th
t ch c thành các hàm nhưng kh c ph c ñư c như c ñi m nói trên.
5.2. Xây d ng 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á inline trư c dòng
ñ u tiên c a ñ nh nghĩa hàm.
Ví d :
inline float f(int n, float x); // nguyên m u
float f(int n, float x)
{
// Các câu l nh trong thân hàm
}
ho c (không dùng nguyên m u):
inline float f(int n, float x)
{
// Các câu l nh trong thân hàm
}
5.3. Cách biên d ch hàm tr c tuy n
39
40. Trình biên 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 .
Chú ý: Dùng macro và hàm tr c tuy n ñ u d n ñ n hi u qu tương t nhau, tuy
nhiên ngư i ta thích dùng hàm tr c tuy n hơn, vì cách này ñ m b o tính c u trúc c a
chương trình, d s d ng và tránh ñư c các sai sót l t v t thư ng g p khi dùng
#define (như thi u các d u ngo c, d u ch m ph y)
5.4. 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 cũng nh t thi t ph i x lý
hàm theo ki u tr c tuy n. T khoá inline ch là m t s g i ý cho Trình biên d ch ch
không ph i là m t m nh l nh b t bu c.
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 l p, l nh goto ho c l nh switch, hàm ñ
quy. Trong các trư ng h p này t khoá inline s 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)
Ví d : 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 ñư c xây d ng
trên hàm main.
#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 hat: " ;
cin >> n;
for (int i=1;i<=n;++i)
{
cout << "nNhap 2 canh cua hinh chu nhat thu " <<i<< ": ";
40
41. cin >> a[i] >> b[i] ;
dtcvhcn(a[i],b[i],dt[i],cv[i]);
}
for (i=1;i<=n;++i)
{
cout << "n Hinh chu nhat thu " << i << " : ";
cout << "nDo dai 2 canh= " << a[i] << " va " << b[i] ;
cout << "nDien tich= " << dt[i] ;
cout << "nChu vi= " << cv[i] ;
}
}
Cách 2: S d ng khai báo nguyên m u. Khi ñó t khoá inline ñ t trư c nguyên
m u.
#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 hat: " ;
cin >> n;
for (int i=1;i<=n;++i)
{
cout << "nNhap 2 canh cua hinh chu nhat thu " <<i<< ": ";
cin >> a[i] >> b[i] ;
dtcvhcn(a[i],b[i],dt[i],cv[i]);
}
for (i=1;i<=n;++i)
{
cout << "n Hinh chu nhat thu " << i << " : ";
cout << "nDo dai 2 canh= " << a[i] << " va " << b[i] ;
cout << "nDien tich= " << dt[i] ;
cout << "nChu vi= " << cv[i] ;
}
}
void dtcvhcn(int a, int b, int &dt, int &cv)
{
dt=a*b;
41
42. cv=2*(a+b);
}
Chú ý: Không ñư c ñ t inline trư c ñ nh nghĩa hàm. Trong chương trình trên
ñâ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, không thoát ñư c.
§ 6. ð NH NGHĨA CH NG CÁC HÀM
6.1. Khái ni m v ñ nh nghĩa ch ng (overloading)
ð nh nghĩa ch ng hay còn g i s t i b i các hàm là vi c dùng cùng m t tên ñ
ñ nh nghĩa các hàm khác nhau. ðây là m t m r ng r t có ý nghĩa c a C++.
Như ñã bi t, trong C và các ngôn ng khác (PASCAL,...) m i hàm ñ u ph i có m t
tên phân bi t. ðôi khi ñây là m t s h n ch l n, vì ph i dùng nhi u hàm khác nhau ñ
th c hi n cùng m t lo i công vi c. Ví d ñ l y giá tr tuy t ñ i trong C c n dùng t i 3
hàm khác nhau:
int abs(int i); // L y giá tr tuy t ñ i giá tr ki u int
longt labs(longt l); // L y giá tr tuy t ñ i giá tr ki u long
double fabs(double d); // L y giá tr tuy t ñ i giá tr ki u double
Nh kh năng ñ nh nghĩa ch ng, trong C++ có th dùng chung m t tên cho c 3
hàm trên như sau:
int abs(int i) ; // L y giá tr tuy t ñ i giá tr ki u int
longt abs(longt l) ; // L y giá tr tuy t ñ i giá tr ki u long
double abs(double d) ; // L y giá tr tuy t ñ i giá tr ki u double
6.2. Yêu c u ñ i v i các hàm ñ nh nghĩa ch ng
Khi dùng cùng m t tên ñ ñ nh nghĩa nhi u hàm, Trình biên d ch C++ s d a vào
s khác nhau v t p ñ i c a các hàm này ñ ñ i tên các hàm. Như v y, sau khi biên
d ch m i hàm s có m t tên khác nhau. T ñó cho th y: các hàm ñư c ñ nh nghĩa
trùng tên ph i có t p ñ i khác nhau (v s lư ng ho c ki u). N u hai hàm hoàn
toàn trùng tên và trùng ñ i thì Trình biên d ch s không có cách nào phân bi t
ñư c. Ngay c trong trư ng h p hai hàm này có ki u khác nhau thì Trình biên
d ch v n báo l i.
6.3. S d ng các hàm ñ nh nghĩa ch ng
Khi g p m t l i g i, Trình biên d ch s căn c vào s lư ng và ki u c a các
tham s ñ g i hàm có ñúng tên và ñúng b ñ i s tương ng.
Ví d :
abs(123); // Tham s ki u int, g i hàm int abs(int i) ;
abs(123L); // Tham s ki u long, g i hàm long abs(long l);
abs(3.14); // Tham s ki u double, g i hàm double abs(double d);
42
43. Khi không có hàm nào có b ñ i cùng ki u v i b tham s (trong l i g i) thì Trình
biên d ch s ch n hàm nào có b ñ i g n ki u nh t (phép chuy n ki u d dàng nh t).
Ví d :
abs(‘A’) ; // Tham s ki u char, g i hàm int abs(int i) ;
abs(3.14F); // Tham s ki u float, g i hàm double abs(double d);
Như ñã nói trên, khi xây d ng cũng như s d ng các hàm trùng tên, Trình biên
d ch C++ ñã ph i suy ñoán và gi i quy t nhi u trư ng h p khá nh p nh ng. Vì v y
không nên l m d ng quá ñáng kh năng ñ nh nghĩa ch ng, vì ñi u ñó làm cho chương
trình khó ki m soát và d d n ñ n sai sót. Vi c ñ nh nghĩa ch ng s hi u qu hơn n u
ñư c s d ng theo các qui t c sau:
+ Ch nên ñ nh nghĩa ch ng các hàm th c hi n nh ng công vi c như nhau nhưng
trên các ñ i tư ng có ki u khác nhau. Ví d trong chương trình c n xây d ng các
hàm: c ng hai ma tr n vuông ki u double, c ng hai ma tr n vuông ki u int, c ng hai
ma trân ch nh t ki u double, c ng hai ma tr n ch nh t ki u int, thì b n hàm trên
nên ñ nh nghĩa ch ng (ñ t cùng tên).
+ Nên dùng các phép chuy n ki u ñ b tham s trong l i g i hoàn toàn trùng ki u
v i b ñ i s c a m t hàm ñư c ñ nh nghĩa ch ng. Vì như th m i tránh ñư c s
nh p nh ng cho Trình biên d ch và do ñó nó s ch n ñúng hàm c n g i.
6.4. L y ñ a ch các hàm trùng tên
Gi s có b n hàm ñ u có tên là tinh_max ñư c khai báo như sau:
int tinh_max(int a, int b, int c) ; // Max c a ba s nguyên
double tinh_max(double a, double b, double c); // Max c a ba s th c
int tinh_max(int *a, int n) ; // Max c a m t d y s nguyên
double tinh_max(double *a, int n) ; //Max c a m t d y s th c
V n ñ ñ t ra là làm th nào l y ñư c ñ a ch c a m i hàm. Câu tr l i như sau: ð
l y ñ a ch c a m t hàm, ta khai báo m t con tr hàm có ki u và b ñ i như hàm c n
l y ñ a ch . Sau ñó gán tên hàm cho con tr hàm.
Ví d :
int (*f1)(int , int, int );
f1 = tinh_max ; // L y ñ a ch c a hàm th nh t
double (*f2)(double , double, double);
f2 = tinh_max ; // L y ñ a ch c a hàm th hai
int (*f3)(int *, int );
f3 = tinh_max ; // L y ñ a ch c a hàm th ba
double (*f4)(double *, int );
f4 = tinh_max ; // L y ñ a ch c a hàm th tư
Ví d : Chương trình gi i bài toán tìm max c a m t d y s nguyên và max c a m t
d y s th c. Trong chươmg trình có sáu hàm. Hai hàm dùng ñ nh p d y s nguyên
và d y s th c có tên chung là nhapds. B n hàm: tính max hai s nguyên, tính max
43
44. hai s th c, tính max c a d y s nguyên, tính max c a d y s th c ñư c ñ t chung
m t tên là max.
#include <iostream.h>
#include <iomanip.h>
void nhapds(int *x, int n);
void nhapds(double *x, int n);
int max(int x, int y);
double max(double x, double y);
int max(int *x, int n);
double max(double *x, int n);
void nhapds(int *x, int n)
{
for (int i=1;i<=n;++i)
{
cout << "Phan tu " << i << " = " ;
cin >> x[i] ;
}
}
void nhapds(double *x, int n)
{
for (int i=1;i<=n;++i)
{
cout << "Phan tu " << i << " = " ;
cin >> x[i] ;
}
}
int max(int x, int y)
{
return x>y?x:y ;
}
double max(double x, double y)
{
return x>y?x:y ;
}
int max(int *x, int n)
{
44
45. int s=x[1];
for (int i=2;i<=n;++i) s = max(s,x[i]);
return s;
}
double max(double *x, int n) {
double s=x[1];
for (int i=2;i<=n;++i)
s = max(s,x[i]);
return s;
}
void main()
{
int a[20] , n , ni, nd, maxi ;
double x[20] , maxd ;
cout << "nSo phan tu nguyen ni = " ;
cin >> ni ;
cout << "Nhap day so nguyenn " ;
nhapds(a,ni);
cout << "nSo phan tu thuc nd = " ;
cin >> nd ;
cout << "Nhap day so thucn " ;
nhapds(x,nd);
maxi = max(a,ni);
maxd = max(x,nd);
cout << "nMax cua day nguyen = " << maxi ;
cout << "nMax cua day thuc = " << maxd ;
}
§ 7. ð NH NGHĨA CH NG CÁC TOÁN T
7.1. Các phép toán trên các ki u d li u chu n
Trong C và C++ có khá nhi u các phép toán dùng ñ th c hi n các thao tác trên các
ki u d li u chu n. Ví d các phép s h c ( + , - , * , / ) áp d ng cho các ki u d li u
nguyên, th c, phép l y ph n dư % áp d ng ñ i v i ki u nguyên.
7.2. Th c hi n các phép toán trên các ki u d li u không chu n
45
46. Vi c th c hi n các phép toán trên các ñ i tư ng t ñ nh nghĩa (như m ng, c u
trúc) là nhu c u b t bu c trong th c t . Ch ng h n c n th c hi n các phép s h c trên
s ph c, trên phân s , trên ña th c, trên véc tơ, trên ma tr n. ð ñáp ng yêu c u này,
ta s d ng các hàm trong C.
Ví d sau ñây là m t chương trình C g m các hàm nh p phân s , in phân s và
th c hi n các phép c ng tr nhân chia phân s . Chương trình s nh p 5 phân s : p, q,
z, u, v và tính phân s s theo công th c: s = (p – q*z)/(u + v)
#include <stdio.h>
#include <math.h>
typedef struct
{
int a,b;
} PS;
void nhap(PS *p);
void in(PS p);
int uscln(int x, int y);
PS rutgon(PS p);
PS cong(PS p1, PS p2);
PS tru(PS p1, PS p2);
PS nhan(PS p1, PS p2);
PS chia(PS p1, PS p2);
void nhap(PS *p)
{
int t, m;
printf("nTu va mau: ");
scanf("%d%d", &t, &m);
p->a = t; p->b = m;
}
void in(PS p)
{
printf(" %d/%d",p.a,p.b);
}
int uscln(int x, int y)
{
x=abs(x); y=abs(y);
if (x*y==0) return 1;
while (x!=y)
46
48. 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 tu,mau, s;
printf("n Nhap phan so p: "); nhap(&p);
printf("n Nhap phan so q: ");nhap(&q);
printf("n Nhap phan so z: ");nhap(&z);
printf("n Nhap phan so u: ");nhap(&u);
printf("n Nhap phan so v: ");nhap(&v);
tu = nhan(q,z);
tu = tru(p,tu) ;
mau = cong(u,v) ;
s = chia(tu,mau);
printf(“n Phan so s = “); in(s);
}
Nh n xét: Vi c s d ng các hàm ñ th c hi n các phép tính không ñư c t nhiên
và t ra dài dòng. Câu h i ñ t ra là có cách nào ñ ch c n vi t ñúng công th c toán
h c, mà v n nh n ñư c k t qu mong mu n hay không?
Trong C++ có th ñáp ng ñư c mong mu n này b ng cách v n có th s d ng các
phép toán chu n c a nó cho các ki u d li u t ñ nh nghĩa (m ng, c u trúc, ...). Nói
cách khác C++ cho phép dùng các phép toán ñ ñ nh nghĩa các hàm, mà ta thư ng g i
là ñ nh nghĩa ch ng các toán t (hay còn g i là s t i b i các toán t ).
7.3. Cách ñ nh nghĩa ch ng các toán t
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 :
48
49. + V i các phép toán có hai toán h ng thì hàm toán t c n có hai ñ 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 (như 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í d chương trình ñ nh nghĩa và s d ng m t toán t nhân hai phân s .
#include <iostream.h>
typedef struct
{
int x,y;
} PS;
PS operator*(PS p1, PS p2)
{
PS p;
p.x=p1.x * p2.x;
p.y=p1.y * p2.y;
return p;
}
void main()
{
PS ps1, ps2, ps;
cout<<"Nhap phan so 1: ";
cin>>ps1.x>>ps1.y;
cout<<"Nhap phan so 2: ";
cin>>ps2.x>>ps2.y;
ps= ps1*ps2;
cout<<"Phan so 3: "<<ps.x<<"/"<<ps.y;
}
+ 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
{
double a[20][20] ; // M ng ch a các ph n t ma tr n
int m ; // S hàng ma tr n
49
50. 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<= m ;++i)
for (int j=1; j<= n ;++j)
y[i][j] = - x[i][j] ;
return y;
}
7.4. Cách dùng hàm toán t
Có hai 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 - q
Cách 2: Dùng như phép toán c a C++ .
Ví d :
PS p, q, u, v ;
u = p + q ; // u = p + q
v = p - q ; // v = p - q
Chú ý: 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 m t cách g n gàng. 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
50
51. 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 ưu tiên cao hơn so v i các phép + và - .
Ví d :
PS p, q, u, v, s1, s2 ;
s1 = p*q - u/v ; // s1 = (p*q)
s2 = (p - q)/(u + v) ; // s2 = (p - q)/(u + v)
BÀI T P CHƯƠNG 2
Bài 1. Xác ñ nh k t qu c a m i chương trình sau:
/* Chương trình 1 */
#include<stdio.h>
void doi(int *a, int b);
void main()
{
int x, y;
doi(&x, y=2);
printf("%d %d",x, y);
}
void doi(int *a, int b)
{
*a=b; *a+=b++;
}
/* Chương trình 2 */
#include<stdio.h>
int x=2;
int swap(int &x, int &y);
void main()
{
int x=10;
int y=12;
swap(x,y);
printf("Sau hoan vi:n x=%d y=%d",x, y);
}
int swap(int x, int y)
51
52. {
int tam=x; x=y; y=tam;
}
Bài 2. Vi t chương trình nh p hai dãy s ñã ñư c s p x p tăng d n, sau ñó ghép
hai dãy s trên thành m t dãy cũng ñư c s p tăng d n.
Bài 3. Vi t chương trình ñ nh nghĩa m t c u trúc phân s và các phép toán c ng
(+), tr (-), nhân (*), chia (/) hai phân s .
Nh p các phân s p, q, z, u, v. Tính giá tr bi u th c (p – q*z)/(u + v).
52
53. CHƯƠNG 3
L P VÀ ð I TƯ NG
L p (class) là khái ni m trung tâm trong l p trình hư ng ñ i tư ng, nó là s m
r ng c a khái ni m c u trúc (struct) c a C. Ngoài các thành ph n d li u (gi ng như
c u trúc), l p còn ch a các thành ph n hàm, còn g i là phương th c (method) hay
hàm thành viên (member function). Cũng gi ng như c u trúc, l p có th ñư c xem
như m t ki u d li u. Vì v y l p còn ñư c g i là ki u ñ i tư ng và do ñó có th 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 (object) khác nhau. M i ñ i tư ng có vùng nh riêng c a mình.
Chương này s trình b y cách ñ nh nghĩa l p, cách xây d ng các phương th c,
gi i thích v ph m vi truy nh p, s d ng các thành ph n c a l p, cách khai báo bi n,
m ng c u trúc, l i g i t i các phương th c, …
§ 1. ð NH NGHĨA L P
1.1. ð nh nghĩa l p
L p ñư c ñ nh nghĩa theo m u:
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
};
// ð nh nghĩa (xây d ng) các phương th c
Chú ý:
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à ki u con tr
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
...
};
1.2. Các thành ph n c a l p
Khi báo các thành ph n c a l p (thu c tính 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 u không
53
54. quy ñ nh c th (không dùng các t khoá private hay public) thì C++ m c ñ nh hi u ñó
là private.
Các thành ph n private (riêng) ch ñư c s d ng bên trong l p (trong thân c a các
phương th c c a l p). Các hàm 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ác thành ph n public (chung) ñư c phép s d ng c
bên trong và bên ngoài l p.
Các thành ph n d li u thư ng khai báo là private (nhưng không b t bu c) ñ 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 d li u c a l p. Các phương th c 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.
Các phương th c có th ñư c xây d ng bên ngoài ho c bên trong ñ nh nghĩa l p.
Thông thư ng, các phương th c ng n ñư c vi t bên trong ñ nh nghĩa l p, còn các
phương th c dài thì vi t bên ngoài ñ nh nghĩa l p.
Trong thân phương th c c a m t l p (gi s l p A) có th s d ng:
+ Các thu c tính c a l p A
+ Các phương th c c a l p A
+ Các hàm t l p 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:
class DIEM
{
int x, y, m ;
public:
void nhapsl() ;
void hien() ;
void an()
{
54
55. putpixel(x, y, getbkcolor());
}
};
void DIEM::nhap()
{
cout << “nNh p hoành ñ (c t) và tung ñ (hàng) c a ñi m: “
cin >> x >> y ;
cout << “nNh p mã m u c a ñi m: “
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 ñi u c n nh sau:
+ Trong c ba 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 (như các phương th c nhap, hien)
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 th c ñ quy
ñ nh rõ ñây là phương th c c a l p nào.
§ 2. BI N, M NG ð I TƯ NG
2.1. Khai báo bi n, m ng ñ i tư ng
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 l p DIEM §1, có th khai báo các bi n, m ng DIEM như sau:
55
56. 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 chúng. 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:
sizeof(d1) = sizeof(d2) = sizeof(d3) = 3*sizeof(int) = 6
sizeof(d) = 20*6 = 120
2.2. 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ó ba
thu c tính là x, y, m. 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 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
2.3. 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:
d1.nhapsl();
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
Câu l nh:
d[3].nhapsl() ;
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
Chúng ta s minh ho 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 ba ñi m, hi n r i n các ñi m v a nh p.
#include <conio.h>
#include <iostream.h>
#include <graphics.h>
56
57. class DIEM
{
int x, y, m ;
public:
void nhapsl();
void an()
{
putpixel(x,y,getbkcolor());
}
void hien();
};
void DIEM::nhapsl()
{
cout << "nNhap hoanh do (cot) va tung do (hang) cua diem: " ;
cin >> x >> y ;
cout << " nNhap 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() // Kh i ñ ng ñ h a
{
int mh, mode ;
mh=mode=0;
initgraph(&mh, &mode, "");
}
void main()
{
DIEM d1, d2, d3 ;
d1.nhapsl();
d2.nhapsl();
57
58. d3.nhapsl();
kd_do_hoa();
setbkcolor(BLACK);
d1.hien();
d2.hien();
d3.hien();
getch();
d1.an();
d2.an();
d3.an();
getch();
closegraph();
}
§ 3. 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 *Tên_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 ñ i tư ng 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
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:
58
59. 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
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 ra m t d y
ñ i tư ng.
#include <conio.h>
#include <iostream.h>
#include <graphics.h>
class DIEM
{
int x, y, m ;
public:
void nhapsl();
void an()
{
putpixel(x,y,getbkcolor());
}
void hien();
};
void DIEM::nhapsl()
{
cout <<"nNhap hoanh do (cot) va tung do (hang) cua diem:" ;
cin >> x >> y ;
cout << " nNhap ma mau cua diem: " ;
cin >> m ;
}
void DIEM::hien()
{
int mau_ht;
mau_ht = getcolor() ;
putpixel(x,y,m);
setcolor(mau_ht);
}
59
60. void kd_do_hoa()
{
int mh, mode ;
mh=mode=0;
initgraph(&mh, &mode, "");
}
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();
for (i=1; i<=n; ++i)
p[i].an();
getch();
closegraph();
}
§ 4. ð I C A PHƯƠNG TH C, CON TR THIS
4.1. 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 <<"nNhap hoanh do (cot) va tung do (hang) cua diem:" ;
cin >> x >> y ;
cout << " nNhap ma mau cua diem: " ;
cin >> m ;
}
Rõ ràng 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
60
61. trong m c trư c. Song s th là: C ++ s d ng con tr ñ c bi t this trong các
phương th c. 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. Phương th c nhapsl có th vi t m t cách tư ng
minh như sau:
void DIEM::nhapsl()
{
cout << "nNhap hoanh do (cot) va tung do (hang) cua diem:" ;
cin >> this->x >> this->y ;
cout << " nNhap ma mau cua diem: " ;
cin >> this->m ;
}
T góc ñ hàm s có th k t lu n r ng: Phương th c c a l p 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.
4.2. 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 = &d1
Do ñó:
this->x chính là d1.x
this->y chính là d1.y
this->m chính là d1.m
*this chính là d1
Như 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:
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.
4.3. 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 như 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).
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:
61
62. 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 b n 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 ba ñi m, v tam giác có ñ nh là ba ñ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
{
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)
{
62
63. 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 <<" nNhap 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)
{
(*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;
d1.nhapsl();
63