You are on page 1of 18

Bi 2: Pointer

Con tr
n lc chng ta tm hiu v con tr. Hy ra ht mt hi tht su trc khi bt u v ti bit
bi hc ny chc chn s khng khin bn thy th v. Nhng con tr l mt khi nim c s
dng rt thng xuyn trong C. Ni v tm quan trng, chng ta khng th no lp trnh trn ngn
ng C m khng dng n con tr, v bn cng tng dng n m khng bit.
Phn ln nhng ngi bt u hc C thng xuyn vp ng trong phn kin thc v con tr. V
ti hi vng bi hc ny s gip cc bn khng nm trong s . Hy tp trung gp i bnh thng
v b thm thi gian hiu r tng biu , v d c trong bi hc ny.

Mt vn nan gii
y l mt trong nhng vn ln lin quan n con tr, cc bn mi bt u thng b nhm ln,
cm thy kh khn trong vic nm vng cch hot ng v s dng.
"Con tr rt cn thit, v chng ta s thng xuyn dng n n, hy tin ti !"
Ti s cho bn xem mt v d m cc bn khng th no gii quyt c nu khng s dng n
con tr. y cng l tiu im ca bi hc ny, ti s hng dn cch gii quyt cui bi hc.
y l vn : Ti mun vit mt function tr v hai gi tr. Vic ny l khng th v mi function
ch c th tr v duy nht mt gi tr.
C code:
int function ( )
{
return giatri;
}
Nu ta khai bo function vi type int, th ta s nhn c mt s dng int (nh vo instruction
return).
Chng ta cng hc cch vit mt function khng tr v bt c gi tr no vi t kha void:
C code:
void function( )
{
}
Nhng nhn c hai gi tr tr v cng lc tht s l vic khng th. Chng ta khng th s
dng hai return cng lc.

Gi s ti mun vit mt function, trong parameter ti s cho n mt gi tr tnh bng pht, ti


mun n chuyn thnh gi v pht tng ng:
1. Nu ta a vo gi tr 45, function s tr v 0 gi v 45 pht.
2. Nu ta a vo gi tr 60, function s tr v 1 gi v 0 pht.
3. Nu ta a vo gi tr 60, function s tr v 1 gi v 30 pht .

Nhn c v kh n gin, nhng hy cng test on code sau:


C code:
#include <stdio.h>
#include <stdlib.h>
/* Toi dat cac prototypes tren cung. Vi day la mot chuong trnh kha nho nen toi khong
dat chung trong mot file.h, nhung trong mot chuong trinh that su, toi se dat chung trong
mot file.h nhu da huong dan o bai truoc*/
void chuyenDoi(int gio, int phut);
int main (int argc, char *argv[ ])
{
int gio = 0, phut = 90;
/*Chung ta co bien so "phut" gi tr 90. Sau khi ket thuc function, toi muon bien so
"gio" nhan gia tri 1 v bien so "phut" nhan gia tri 30 */
chuyenDoi(gio, phut);
printf ("%d gio va %d phut", gio, phut);
return 0;
}
void chuyenDoi(int gio, int phut)
{
gio= phut/ 60; // 90 / 60 = 1
phut= phut% 60; // 90 % 60 = 30
}

V y l kt qu:
Console
0 gio va 90 phut
c... chng trnh khng hot ng. V sao vy?
Khi bn gi gi tr ca mt bin s vo v tr parameter ca mt function, mt bn sao ca bin s
ny c to ra. Ni cch khc, bin s "gio" trong function chuyenDoi khng phi l bin s "gio"
trong function main! N ch l bn sao!
Function chuyenDoi thc hin nhim v ca n. Trong function chuyenDoi, nhng bin s "gio"
v "phut" nhn gi tr chnh xc: 1 v 30.
Nhng sau , function kt thc khi du ngoc } ng li. Nh ta hc bi hc trc, tt c
nhng bin s to ra trong mt function s b xa i khi function kt thc. V y, bin s
gio v phut b xa i. Sau chng trnh tip tc phn tip theo ca main, v bin s gio
v phut ca main gi tr vn l 0 v 90. l l do bn tht bi!

Cn ghi thm y, function to ra mt bn sao cho bin s ta gi vo n, nn


bn khng cn phi gi tn bin s chnh xc ging nh cch bn gi main.
r rng hn, bn xem on code sau:
void chuyenDoi (int g, int p)
(g thay cho gio v p thay cho pht)

V tip theo, hy th tm nhiu cch khc sa i chng trnh trn, nh tr v mt gi tr sau khi
kt thc function (s dng return v thay i type function thnh int), bn ch nhn c mt trong
hai gi tr bn cn. Bn khng th no nhn c cng lc hai gi tr. V bn tuyt i khng c
s dng bin s global, l do ti gii thch bi trc.
V l vn kh khn t ra

, vy con tr s gii quyt vn trn nh th no?

a ch trong b nh
Nhc li kin thc
Bn cn nh bi hc v nhng bin s khng?
D c hay khng, ti vn khuyn khch bn xem li phn u ca bi hc, phn "Cng vic ca
b nh".
Trong c mt biu kh quan trng m ti cn nhc li trc khi dy bn nhng kin thc
mi:

Cch sp xp trong b nh (RAM)

l cch trnh by mt RAM trong my tnh ca bn.


Hy c k tng dng trong biu . Dng u tin tng ng vi "" u tin ca b nh (RAM).
Mi tng ng vi mt s, l a ch ca n (address)! B nh cha mt s lng ln a ch,
bt u t a ch 0 n mt s no (mt s v cng ln, s lng a ch ph thuc vo dung
lng b nh c lp t trong tng my tnh).
Mi a ch c th cha mt s. Mt v ch mt. Ta khng th no cha 2 s trong cng mt a
ch.
B nh ca bn to ra ch cha nhng con s. N khng th cha ch ci cng nh on vn.
gii quyt vn ny, ngi ta to ra nhng bng m cha trong s v ch ci tng ng.
V d "S 89 tng ng vi ch ci Y". Vn ny s c gii thch r hn bi hc sau. By
gi, chng ta ch tp trung vo cch hot ng ca b nh.

a ch v gi tr
Khi bn to ra mt bin s tuoi type int, ly v d:
C code:
int tuoi = 10;
... chng trnh ca bn s yu cu h iu hnh (v d l Windows) quyn s dng mt t b nh.
H iu hnh s tr li bng cch a ra a ch b nh c php cha con s bn cn.
y cng l mt trong nhng nhim v chnh ca h iu hnh:
Khi chng ta yu cu mn b nh cho chng trnh. My tnh ging nh ng ch, n iu hnh
tng chng trnh v kim tra xem chng c quyn s dng b nh ti v tr c cp hay khng.
V y l mt trong nhng nguyn nhn khin my tnh bn b : Nu chng trnh t nhin
hot ng trn mt vng b nh khng cho php. H iu hnh (OS) s t chi v dng ngay
chng trnh, ging nh ni vi bn "My ngh ai l ch y?" Ngi dng, s nhn thy mt
ca s hin ln thng bo dng "Chng trnh b dng li do thc hin mt cng vic khng c
php".
Quay tr li vi bin s tuoi. Gi tr 10 c a vo mt v tr no trong b nh, ly v d n
c a vo a ch 4655. V iu xy ra y l (nhim v ca compiler), t tuoi trong chng
trnh s thay th bng a ch 4655 khi c chy.
Vic ging nh, mi khi bn in vo tuoi trong code source, chng s c chuyn thnh
4655, v my tnh s bit c cn n a ch no trong b nh ly gi tr . V ngay sau ,
my tnh xem gi tr c cha trong a ch 4655 v tr li chng ta "bin s tuoi co gi tr l
10"!
V ly gi tr mt bin s, n gin ch cn nh tn ca bin s vo code source. Nu ta
mun hin th tui, ta c th s dng function printf:
C code:
printf ("Bien so tuoi co gia tri la : %d", tuoi);
Khng c iu g mi vi dng code trn ng ko.

Khuyn mi thm!
Bn bit cch hin th gi tr ca mt bin s, nhng bn c bit chng ta cng c th hin th
a ch ca bin s ?
...ng nhin l bn cha bit ri
hin th a ch ca mt bin s, chng ta cn s dng k hiu %p (p y vit tt ca t
pointer) trong printf. Mt khc, chng ta phi a vo printf a ch ca bin s v lm vic
ny, bn cn phi t k hiu & trc bin s (tuoi), ging nh cch ti hng dn bn s dng
scanf, xem code sau:
C code:
printf ("Dia chi cua bien so tuoi la %p", &tuoi);
Kt qu
Console
Dia chi cua bien so tuoi la 0023FF74
l a ch ca bin s tuoi trong thi im chng trnh hot ng. Vng, 0023FF74 l mt s,
n n gin ch c vit trn h hexadecimal (thp lc phn), thay v h decimal (thp phn) m
chng ta thng s dng. Nu bn thay k hiu %p thnh %d, bn s nhn c mt s thp phn
m bn bit.
Nu bn chy chng trnh ny trn my tnh ca bn, a ch s khc hon ton. Tt c ph
thuc vo phn trng c trong b nh, chng trnh bn ang dng,... Hon ton khng c kh
nng bo trc a ch no ca bin s s c cp. Nu bn th chy chng trnh lin tc nhiu
ln, a ch c th s khng i trong thi im . Nhng nu bn khi ng li my tnh, chng
trnh chc chn s hin th mt gi tr khc.
Vy chng ta s lm g vi tt c nhng th ?
Ti cn bn nm vng nhng iu sau:

tuoi: tng trng cho gi tr ca bin s.


&tuoi: tng trng cho a ch ca bin s.

Vi tuoi, my tnh s c v gi li gi tr ca bin s.


Vi &tuoi, my tnh s ni vi chng ta a ch no s tm thy bin s.

Cch s dng pointers (con tr)


n by gi, bn ch c th to bin s cha cc s hng. V sau y chng ta s hc cch to
ra nhng bin s cha a ch ca chng, nhng bin s ny gi l con tr.

Nhng... a ch cng l mt s ng khng? Nh vy s ny cn phi cha


trong mt bin s khc v c nh th n s lp li mi sao?
Chnh xc. Nhng cc con s ny s c mt k hiu c bit nhn bit: a ch ca mt bin s
khc trong b nh.
Cch to mt con tr
to mt bin s dng con tr, ta cn phi thm k t * trc tn ca bin s.
C code:
int *pointer;

Bn cn bit rng chng ta cng c th vit:


int* pointer;
vn hot ng tng t nh trn. Nhng cch vit u c khuyn khch hn. Bi v
trong trng hp bn cn khai bo cng lc nhiu con tr trong cng mt dng, bn bt
buc phi t * trc mi tn con tr:
int *pointer1, *pointer2, *pointer3;
Ging nh iu ti dy bn khi khai bo bin s, bn cn cho n gi tr ngay khi khi to, rt quan
trng, bng cch cho n gi tr 0 (ly v d vi bin s). V i vi con tr, iu ny cn quan
trng hn na! khi to con tr, c ngha l cho n mt gi tr mc nh, ngi ta khng dng
gi tr 0 m dng t kha NULL (phi c vit hoa):
C code:
int *pointer = NULL;
Bn khi to mt con tr gi tr NULL. Nh vy, bn chc rng con tr ca bn khng cha a
ch no.
Vic ny din ra nh th no? on m trn s t trc mt ch trong b nh, ging nh cch
bn to ra mt bin s thng thng. Nhng iu thay i y l gi tr ca con tr ch dng
cha a ch ca mt bin s khc.

Vy th xem vi a ch ca tuoi th sao?


V y l cch ch ra a ch ca mt bin s (tuoi) da trn gi tr ca n (bng cch s dng k
t &), no bt u thi!
C code:
int tuoi = 10;
int *pointerTuoi = &tuoi;
Dng th nht : "To mt bin s type int c gi tr l 10".
Dng th hai : "To mt con tr c gi tr l a ch ca bin s tuoi".
Dng th hai thc hin cng lc hai vic. Nu bn thy phc tp nn khng mun gp hai vic vi
nhau, ti s tch bit chng bng cch chia thnh hai giai on, xem on code sau :
C code:
int tuoi = 10;
int *pointerTuoi; // 1) co nghia la "Toi tao mot con tro poiterTuoi"
pointerTuoi = &tuoi; // 2) co nghia la "con tro pointerTuoi chua dia chi cua bien so tuoi"
Bn cn nh rng khng c type "pointer" nh type int hay double. Ngi ta khng ghi nh sau:
pointer pointerTuoi;
Thay v vy, chng ta s s dng k t *, sau int. Ti sao li nh vy? Tht ra, chng ta cn phi
ch r type ca bin s m con tr s cha a ch ca n.
trn, pointerTuoi s cha a ch ca bin s tuoi (type l int), vy con tr phi c type int* Nu
bin s tuoi c type l double, ta phi vit double *pointerTuoi.
Gi tr ca con tr pointerTuoi ch ra a ch ca bin s tuoi.

Hnh sau tm tt li nhng g din ra trong b nh:

Trong biu trn, bin s tuoi c t vo a ch 177450 (v bn thy ti gi tr tng


ng l 10), v con tr pointerTuoi c t vo a ch 3 (tt c a ch u c chn ngu
nhin, v cc a ch trong biu cng do ti t vit ra ).
Khi con tr c to ra, h iu hnh s dnh mt trong b nh ging nh cch n to ra vi
bin s tuoi. Khc nhau l gi tr ca pointerTuoi l a ch ca bin s tuoi.

Chng ta bt u tin vo th gii huyn diu ca nhng con tr. Th gii b mt ca nhng chng
trnh vit trn ngn ng C (C++)

Ok, nhng... n dng lm g ?


Hin nhin, n khng gip my tnh bn bin i thnh my lm ra caf. Ch l, ta c mt con tr
pointerTuoi cha a ch ca bin s tuoi. Hy dng printf xem th n cha g trong :
C code:
int tuoi = 10;
int *pointerTuoi = &tuoi;
printf ("%d", pointerTuoi);
Console
177450
uhm, tht s iu ny khng c g ngc nhin lm. Ngi ta yu cu gi tr cha trong
pointerTuoi v l a ch ca bin s tuoi (177450).
Vy lm sao c c gi tr ca bin s m pointerTuoi ch vo?
Chng ta phi t k t * trc tn ca con tr:
C code:
int tuoi = 10;
int *pointerTuoi = &tuoi;
printf ("%d", *pointerTuoi);
Console
10
, bn lm c ri y!
s tuoi.

Bng cch t k t * trc tn con tr, ta nhn c gi tr ca bin

Nu chng ta s dng k t & trc tn ca con tr, chng ta s nhn c a ch tm thy con
tr (trong trng hp ny l 3).

Vy ti t c iu g y? Ny gi ti ch thy cc vn cng lc cng


rc ri thm. Ti thy khng cn thit hin th gi tr ca bin s tuoi bng con tr! Trc
y chng ta vn c th hin th gi tr ca bin s m u cn n con tr.
y l mt cu hi chnh ng (m bn bt buc phi t ra cho bn thn). Sau tt c nhng iu
rc ri bn va c hc, hin nhin l bn mun bit tc dng ca n, nhng ti thi im ny,
ti kh c th gii thch ht, qua cc bi hc sau, tng cht mt, cc bn s thy n khng n gin
c to ra ch lm mi th phc tp thm.
Xin bn hy b qua mt bn ci cm gic kh chu ti to ra cho bn ("Tt c mi th trn ch
lm nhng vic ny thi sao?" ).
Nu bn hiu c nguyn l hot ng, th chc chn, nhng thc mc s c sng t trong cc
bi hc sau.

Nhng iu cn nm vng
y l nhng iu m bn cn hiu v nm vng trc khi tip tc bi hc:

i vi mt bin s, ly v d bin s tuoi:


o
o

tuoi c ngha l: "Ti mun gi tr ca bin s tuoi",


&tuoi c ngha l: "Ti mun a ch tm thy bin s tuoi";

i vi mt con tr, ly v d con tr pointerTuoi:


o
o

pointerTuoi c ngha l: "Ti mun gi tr ca con tr pointerTuoi" (gi tr ny l


a ch ca mt bin),
*pointerTuoi c ngha l: "Ti mun gi tr ca bin s m con tr pointerTuoi ch
vo".

c th hiu c 4 im chnh trn. Bn cn test nhiu ln hiu cch n hot ng. Biu
sau y gip bn c th hiu r hn:

Ch khng nhm ln cc ngha ca k t * Khi bn khai bo mt con tr, * c


tc dng ch ra bn mun to ra mt con tr:
int *pointerTuoi;
Cn trong printf:
printf ("%d",*pointerTuoi);
iu ny khng phi "ti mun to mt con tr" m l "ti mun gi tr ca bin s
m con tr ch vo".

Tt c nhng iu trn l c bn. Bn phi hc thuc lng v tt nhin phi hiu r. ng ngi c
i c li nhiu ln. ng xu h nu khng hiu ngay c bi hc khi ch c qua ln u tin,
c nhiu vn chng ta cn nhiu ngy c th hiu r v i khi cn nhiu thng c th s
dng thnh tho.
Nu bn c cm gic khng theo kp, th hy ngh n nhng bc thy trong vic lp trnh: khng
ai trong s h c th hiu r hon ton hot ng ca con tr trong ln u tin. Nu c mt ngi
nh vy tn ti, bn hy gii thiu vi ti nh.

Cch s dng con tr trong mt function


iu kh th v con tr l chng ta c th s dng chng trong cc function c th thay i
trc tip gi tr ca bin s trong b nh ch khng phi mt bn sao nh bn thy on u
bi hc.
Vy n hot ng nh th no? C rt nhiu cch thc s dng. y l v d u tin:
C code:
void triplePointer(int *pointerSoHang);
int main (int argc, char *argv[ ])
{
int soHang = 5;
triplePointer(&soHang); // Ta gui dia chi cua soHang vao function
printf ("%d", soHang); /* Ta hien thi bien so soHang. Va function da truc tiep thay doi gia tri
cua bien so vi no biet dia chi cua bien so nay */
return 0;
}
void triplePointer(int *pointerSoHang)
{
*pointerSoHang *= 3; // Ta x3 gia tri cua so hang duoc dua vao
}

Console
15
Function triplePointer nhn vo parameter gi tr type int * ( l mt con tr ch vo mt bin s
type int).

V y l nhng g din ra theo th t, bt u bi function main:


1. Mt bin s soHang c to ra trong main. Khi to vi gi tr 5.
2. Ta gi function triplePointer. Ta gi vo parameter a ch ca bin s.
3. Function triplePointer nhn a ch l gi tr ca pointerSoHang. V trong funtion
triplePointer, ta c mt con tr pointerSoHang cha a ch ca bin s soHang
4. lc ny, ta c mt con tr ch ln bin s soHang, ta c th thay i trc tip gi tr ca
bin s soHang trong b nh! Ch cn dng *pointerSoHang iu chnh gi tr ca bin
s soHang! v d trn, ngi ta ch n gin thc hin: nhn 3 ln gi tr ca bin s
soHang.
5. kt thc bng return trong function main, lc ny soHang c gi tr 15 v function
triplePointer trc tip thay i gi tr ca n.
Tt nhin, ti c th thc hin return tr v gi tr nh cch chng ta hc trong bi hc v
function. Nhng iu th v y l, bng cch s dng con tr, chng ta c th thay i gi tr
ca nhiu bin s trong b nh (c ngha l "chng ta c th tr v nhiu gi tr"). Khng cn gii
hn mt gi tr duy nht c tr v na !

Vy return cn gi tr s dng g khi ngi ta c th dng con tr thay i


gi tr ?
iu ny ph thuc vo bn v chng trnh bn vit. Chng ta cn hiu l cch dng return
tr v gi tr l mt cch vit kh p v c s dng thng xuyn trong C.
V thng xuyn nht, ngi ta dng return thng bo li ca chng trnh: v d, function tr
v 1 (true) nu tt c din ra bnh thng, v 0 (false) nu c li trong chng trnh.

Mt cch khc s dng con tr trong function


Trong nhng code source m chng ta va thy, khng c con tr trong function main. Duy nht
ch bin s soHang.
Con tr duy nht c s dng nm trong function triplePointer (c type int *)
Bn cn bit rng c cch vit khc cho on code va ri bng cch thm vo con tr trong
function main:
C code:
void triplePointer(int *pointerSoHang);
int main (int argc, char *argv[ ])
{
int soHang = 5;
int *pointer = &soHang; // con tro nhan dia chi cua bien so soHang
triplePointer (pointer); // Ta dua con tro (dia chi cua soHang) vao function
printf ("%d", *pointer); // Ta hien thi gia tri cua soHang voi *pointer
return 0;
}
void triplePointer(int *pointerSoHang)
{
*pointerSoHang *= 3; // Ta x3 gia tri cua soHang
}

Hy so snh on code source ny vi on code source trc . C mt s thay i nhng


chng s cho ta cng mt kt qu:
Console
15
iu cn xt n l cch a a ch ca bin s soHang vo function, cch s dng a ch ca
bin s soHang. iu khc bit xy ra y l cch to con tr trong function main.
VD trong printf, ti mun hin th gi tr ca bin s soHang bng cch vit *pointer. Bn cn bit
rng ti vn th vit soHang: kt qu s ging nhau v*pointer v soHang u c chung mt gi
tr trong b nh

Trong chng trnh "Ln hn hay nh hn", chng ta s dng con tr bt chp vic bit n
l g, trong vic s dng function scanf.
Tht ra, function ny c tc dng c nhng thng tin m ngi dng nhp vo bn phm v gi
li kt qu.
scanf c th thay i trc tip gi tr ca mt bin s bng cch nhp t bn phm, ta cn a
ch ca bin s :
C code:
int soHang = 0;
scanf ("%d", &soHang);
function lm vic vi con tr ca bin s soHang v c th thay i trc tip gi tr ca soHang.

V nh chng ta bit, chng ta c th lm nh sau:


C code:
int soHang = 0;
int *pointer = &soHang;
scanf ("%d", pointer);

Ch l ta khng t k t & trc pointer trong function scanf Ti y, pointer bn thn n


l a ch ca bin s soHang, khng cn thit phi thm & vo na !
Nu bn lm iu , bn s a cho scanf a ch ca pointer: nhng th chng ta cn l a
ch ca soHang.

Gii quyt vn nan gii u bi?


n lc chng ta xem li tm im ca bi hc. Nu bn hiu bi hc ny, bn c th t
gii quyt vn t ra. Hy th i! trc khi xem kt qu ti a bn:
C code:
#include <stdio.h>
#include <stdlib.h>
void chuyenDoi(int *pointerGio, int *pointerPhut);
int main (int argc, char *argv[ ])
{
int gio = 0, phut = 90;
// Ta dua vao dia chi cua gio va phut
chuyenDoi(&gio, &phut);
// Luc nay, gia tri cua chung da duoc thay doi !
printf ("%d gio va %d phut", gio, phut);
return 0;
}
void chuyenDoi(int *pointerGio, int *pointerPhut)
{
/*Note: dung quen dat dau * o phia truoc ten cua con tro! Bang cach nay ban co the thay doi
gia tri cua bien so chu khong phai dia chi ca no! Han la ban khong muon chia dia chi cua no
dung khong? */
*pointerGio = *pointerPhut / 60;
*pointerPhut = *pointerPhut % 60;
}

Console:
1 gio va 30 phut

Khng c g khin bn ngc nhin trong on code source ny. V nh mi khi, trnh nhng
nhm ln khng ng c, ti s gii thch nhng g din ra chc chn rng cc bn theo kp
ti, v y l mt bi hc quan trng, bn cn c gng rt nhiu hiu, v ti cng c gng ht
sc gii thch r rng gip cc bn hiu:
1. Bin s gio v phut c khi to trong function main.
2. Ta gi vo function chuyenDoi a ch ca gio v phut.
3. Function chuyenDoi nhn a ch bng cch a vo cc con tr pointerGio v pointerPhut.
Bn cn bit rng, cch gi tn con tr khng quan trng. Ti c th gi l g v p, hoc
cng c th l gio v phut.
4. function chuyenDoi thay i trc tip cc gi tr ca gio v phut trong b nh v n c
a ch ca chng trong cc con tr. V iu cn bit y, tuyt i chp hnh, l phi
t * trc tn ca con tr nu nh ta mun thay i gi tr ca gio v phut. Nu ta khng
lm vic ny, ta s thay i a ch cha trong con tr, v n chng gip ta c g.

Cc bn cn lu l chng ta vn c th gii quyt "vn " ny khng qua cch


s dng con tr. iu ny l chc chn nhng iu s ph v lut chng ta t ra:
khng s dng nhng bin s global. Hoc s dng printf trong function chuyenDoi
(nhng ta cn mt printf trong function main).
Mc ch chnh ca chng trnh l gip bn c c hng th vi vic s dng con tr.
V bn hy c gng thc y nhng hng th ny ngy mt nhiu hn trong cc bi hc
tip theo.

You might also like