Con tr
Chúng ta đã biết các biến chính là các ô nh chúng ta có th truy xut dưới các
tên. Các biến này được lưu tr ti nhng ch c th trong b nh. Đối vi chương
trình ca chúng ta, b nh máy tính ch là mt dãy gm các ô nh 1 byte, mi ô có
mt địa ch xác định.
Mt s mô hình tt đối vi b nh máy tính chính là mt ph trong mt thành
ph. Trên mt ph tt c các ngôi nhà đều được đánh s tun t vi mt cái tên
duy nht nên nếu chúng ta nói đến s 27 ph Trn Hưng Đạo thì chúng ta có th
tìm được nơi đó mà không lm ln vì ch có mt ngôi nhà vi s như vy.
Cũng vi cách t chc tương t như vic đánh s các ngôi nhà, h điu hành t
chc b nh thành nhng s đơn nht, tun t, nên nếu chúng ta nói đến v trí
1776 trong b nh chúng ta biết chính xác ô nh đó vì ch có mt v trí vi địa ch
như vy.
Toán t ly địa ch (&).
Vào thi đim mà chúng ta khai báo mt biến thì nó phi được lưu tr trong mt
v trí c th trong b nh. Nói chung chúng ta không quyết định nơi nào biến đó
được đặt - tht may mn rng điu đó đã được làm t động bi trình biên dch và
h điu hành, nhưng mt khi h điu hành đã gán mt địa ch cho biến thì chúng ta
có th mun biết biến đó được lưu tr đâu.
Điu này có th được thc hin bng cách đặt trước tên biến mt du và (&), có
nghĩa là "địa ch ca". Ví d:
ted = &andy;
s gán cho biến ted địa ch ca biến andy, vì khi đặt trước tên biến andy du và
(&) chúng ta không còn nói đến ni dung ca biến đó mà ch nói đến địa ch ca nó
trong b nh.
Gi s rng biến andy đưc đặt ô nhđịa ch 1776 và chúng ta viết như
sau:
andy = 25;
fred = andy;
ted = &andy;
kết qu s ging như trong sơ đồ dưới đây:
Chúng ta đã gán cho fred ni dung ca biến andy như chúng ta đã làm rt ln
nhiu khác trong nhng phn trước nhưng vi biến ted chúng ta đã gán địa ch
mà h điu hành lưu giá tr ca biến andy, chúng ta va gi s nó là 1776.
Nhng biến lưu tr địa ch ca mt biến khác (như ted trong ví d trước) được
gi là con tr. Trong C++ con tr có rt nhiu ưu đim và chúng được s dng rt
thường xuyên, Tiếp theo chúng ta s thy các biến kiu này được khai báo như thế
nào.
Toán t tham chiếu (*)
Bng cách s dng con tr chúng ta có th truy xut trc tiếp đến giá tr được lưu
tr trong biến được tr bi nó bng cách đặ trước tên biến con tr mt du sao (*)
- đây có th được dch là "giá tr được tr bi". Vì vy, nếu chúng ta viết:
beth = *ted;
(chúng ta có th đọc nó là: "beth bng giá tr được tr bi ted" beth s mang giá
tr 25, vì ted bng 1776 và giá tr tr bi 177625.
Bn phi phân bit được rng ted có giá tr 1776, nhưng *ted (vi mt du sao
đằng trước) tr ti giá tr được lưu tr trong địa ch 1776, đó là 25. Hãy chú ý s
khác bit gia vic có hay không có du sao tham chiếu.
beth = ted; // beth bng ted ( 1776 )
beth = *ted; // beth bng giá tr được tr bi( 25 )
Toán t ly địa ch (&)
được dùng như là mt tin t ca biến và có th được dch là "địa ch ca", vì
vy &variable1 có th được đọc là "địa ch ca variable1".
Toán t tham chiếu (*)
Nó ch ra rng cái cn được tính toán là ni dung được tr bi biu thc được coi
như là mt địa ch. Nó có th được dch là "giá tr được tr bi"..
*mypointer được đọc là "giá tr được tr bi mypointer".
Vào lúc này, vi nhng ví d đã viết trên
andy = 25;
ted = &andy;
bn có th d dàng nhn ra tt c các biu thc sau là đúng:
andy == 25
&andy == 1776
ted == 1776
*ted == 25
Khai báo biến kiu con tr
Vì con tr có kh năng tham chiếu trc tiếp đến giá tr mà chúng tr ti nên cn
thiết phi ch rõ kiu d liu nào mà mt biến con tr tr ti khai báo nó. Vì vy,
khai báo ca mt biến con tr s có mu sau:
type * pointer_name;
trong đó type là kiu d liu được tr ti, không phi là kiu ca bn thân con
tr. Ví d:
int * number;
char * character;
float * greatnumber;
đó là ba khai báo ca con tr. Mi biến đầu tr ti mt kiu d liu khác nhau
nhưng c ba đều là con tr và chúng đều chiếm mt lượng b nh như nhau (kích
thước ca mt biến con tr tùy thuc vào h điu hành). nhưng d liu mà chúng
tr ti không chiếm lượng b nh như nhau, mt kiu int, mt kiu char và cái
còn li kiu float.
Tôi phi nhn mnh li rng du sao (*) mà chúng ta đặt khi khai báo mt con tr
ch có nghĩa rng: đó là mt con tr và hoàn toàn không liên quan đến toán t
tham chiếu mà chúng ta đã xem xét trước đó. Đó đơn gin ch là hai tác v khác
nhau được biu din bi cùng mt du.
// my first pointer
#include <iostream.h>
int main ()
{
int value1 = 5, value2 =
15;
int * mypointer;
mypointer = &value1;
*mypointer = 10;
mypointer = &value2;
*mypointer = 20;
cout << "value1==" <<
value1 << "/ value2==" <<
value2;
return 0;
}
value1==10 / value2==20
Chú ý rng giá tr ca value1value2 được thay đổi mt cách gián tiếp. Đầu
tiên chúng ta gán cho mypointer địa ch ca value1 dùng toán t ly địa ch
(&) và sau đó chúng ta gán 10 cho giá tr được tr bi mypointer, đó là giá tr
được tr bi value1 vì vy chúng ta đã sa biến value1 mt cách gián tiếp
Để bn có th thy rng mt con tr có th mang mt vài giá tr trong cùng mt
chương trình chúng ta s lp li quá trình vi value2 và vi cùng mt con tr.
Đây là mt ví d phc tp hơn mt chút:
// more pointers
#include <iostream.h>
int main ()
value1==10 / value2==20
{
int value1 = 5, value2 =
15;
int *p1, *p2;
p1 = &value1; // p1
= địa ch ca value1
p2 = &value2; // p2
= địa ch ca value2
*p1 = 10; // giá
tr tr bi p1 = 10
*p2 = *p1; // giá
tr tr bi p2 = giá tr
tr bi p1
p1 = p2; // p1
= p2 (phép gán con tr)
*p1 = 20; // giá
tr tr bi p1 = 20
cout << "value1==" <<
value1 << "/ value2==" <<
value2;
return 0;
}
Mt dòng có th gây s chú ý ca bn là:
int *p1, *p2;
dòng này khai báo hai con tr bng cách đặt du sao (*) trước mi con tr.
Nguyên nhân là kiu d liu khai báo cho c dòng là int và vì theo th t t phi
sang trái, du sao được tính trước tên kiu. Chúng ta đã nói đến điu này trong bài
1.3: Các toán t.
Con tr và mng.
Trong thc tế, tên ca mt mng tương đương vi địa ch phn t đầu tiên ca nó,
ging như mt con tr tương đương vi địa ch ca phn t đầu tiên mà nó tr ti,
vì vy thc tế chúng hoàn toàn như nhau. Ví d, cho hai khai báo sau:
int numbers [20];
int * p;