Tải bản đầy đủ (.pdf) (12 trang)

Con trỏ (pointer)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (152.48 KB, 12 trang )

Kỹ thuật lập trì nh
85
CHƯƠNG 4 CON TRỏ (POINTER)

I. ĐịNH NGHĩA
Con trỏ là một kiể u dữ liệ u dùng để chứa địa chỉ . Biế n con trỏ là một biế n
chứa địa chỉ của một thực thể nào đó, thực thể đó là biến hoặc là hàm.
Con trỏ thường đ ược dùng để :
- Trả về nhiề u trị từ hà m qua cơ chế truyề n theo tham số theo địa chỉ trong
hà m (tham số hì nh thức biế n).
- Tạ o cá c cấ u trúc dữ liệ u phức tạ p như danh sá ch liê n kế t và câ y nhị phâ n.
- Truyề n mả ng và chuỗi giữa cá c hà m khá thuậ n lợi.
I.1. Khai báo
: Khai bá o biế n pi là con trỏ trỏ đế n một số nguyê n.
int *pi;
Lúc nà y, pi chiế m 2 bytes chứa địa chỉ của số nguyê n mà nó đang chỉ
đế n, đồng thời trì nh biê n dịch của C cũng biế t pi đang chỉ đế n một số nguyê n
(do khai bá o). Để đ ưa một giá trị nguyê n và o vùng nhớ mà pi đang trỏ đế n, ta
dùng lệ nh: *pi = 1;
Ví dụ
:
void main()
{ int x=4, y=10;
int *px, *py ; // px, py là cá c biế n con trỏ
px = &x ; // đ ưa địa chỉ của x,y và o px và py
py = &y;
*px = *px + *py; // tă ng giá trị của vùng nhớ mà px đang trỏ tới
// thê m y , tương đ ương với x = x+y
}
Minh họa chương trì nh trê n trong bộ nhớ
:


Biế n int x=4, y=10;
int *px, *py;
px=&x;
py=&y;
*px = *px + *py;
x 950 4 4 14
951
y 952 10 10 10
953

px 950 950

py 952 952

Kỹ thuật lập trì nh
86
Hì nh 7.1. Cơ chế truy xuấ t giá trị qua biế n con trỏ.
Tổng quá t
: Kiểu *biến;
I.2. Truyề n địa chỉ cho hàm
: Trong 1 số trường hợp ta muốn gởi địa chỉ của
1 biế n x cho hà m. Nhờ và o cơ chế truyề n theo địa chỉ nà y mà hà m có thể trả về
nhiề u giá trị cho chương trì nh gọi.
Ví dụ
: Hà m hoá n đổi giá trị của 2 biế n x, y
void hoandoi (int *a, int *b)
{ int tam;
tam = *a;
*a = *b;
*b = tam;

}
void main()
{ int x,y;
printf ("x, y = ");
scanf ("%d %d", &x, &y);
giaohoan(&x, &y); // Truyề n địa chỉ của 2 biế n x,y cho hà m hoandoi
}
II Các phép toán trên biến con trỏ:

II.1. Toán tử địa chỉ &:

Nế u x là biế n thông thường, &x sẽ là địa chỉ của biế n x
Ví dụ
: float x, *pf;
x = 50;
pf = x; // sai vì pf là biế n con trỏ nê n ta viế t pf = & x;
x = pf; // sai ; ta viế t x = *pf; { lấ y nội dung của pf }
II.2. Toán tử nội dung * :

Nế u p là pointer thì *p là nội dung của nó.
Ví dụ
: int x,y, *p;
x = 50;
p = &x; // p chứa địa chỉ của vùng nhớ x
y = *p; // y= *p = 50 vì p chứa địa chỉ của vùng nhớ x
Ví dụ
: a =2;
p = & a;
b = (*p) + + + 3; // b =5, *p = 3, a= 3.
( vì p trỏ tới địa chỉ a nê n *p tă ng thì a tă ng)

Tóm lại
: *x là biế n mà x giữ địa chỉ
&x là địa chỉ của x nế u x là biế n thông thường
Kỹ thuật lập trì nh
87
II.3. Phép cộng trừ biế n con trỏ với một số nguyê n:
Nế u p là biế n pointer thì p+n là địa chỉ của một biế n mới cá ch nó n biế n
theo chiề u tă ng, còn p-n thì ngược lạ i.
Chú ý
:
- Phép cộng con trỏ với một số nguyê n chỉ đ ược á p dụng trê n một d y biế n
cùng kiể u
- Không đ ược cộng 2 pointer với nhau
- Không đ ược nhâ n, chia, lấ y dư biế n con trỏ với bấ t kỳ số nà o
Ví dụ
: Giả sử ta có mả ng nums[]= {10,20,30,40,50}. Việ c tham khả o tới
nums[i] thực chấ t là dùng dạ ng ký hiệ u con trỏ, vì khi biê n dịch, trì nh biê n dịch
sẽ chuyể n đổi ký hiệ u mả ng thà nh ký hiệ u con trỏ.
void main()
{ static int nums [] = {10,20,30,40,50};
for (int i =0; i<5; i++)
printf (%d\n, *(nums + i));
}
Lưu ý
: *(nums+i) tương đ ương với nums[i]
II.4. Phép gán và phép so sánh
:
- Phép gán: cá c biế n con trỏ có thể gá n cho nhau với điề u kiệ n phả i cùng
kiể u
Ví dụ

: int *p1, *p2;
*p1 = 10;
p2 = p1; // lúc nà y *p2 = 10;
- Phép so sánh: ta có thể so sá nh 2 biế n con trỏ xem có cùng địa chỉ hay
không, đ ương nhiê n 2 biế n con trỏ đó phả i cùng kiể u với nhau.
II.5. Sự chuyể n kiể u:

Cú phá p
: ( Kiể u) *tê nbiế n
Ví dụ
: int *p1, num ;
float *p2;
num =5;
p1 = &num;
*p2 = (float ) *p1; // * p2 = 5.0
Ví dụ
: int num, *p, n;
char c;
p = &num;
Kỹ thuật lập trì nh
88
*p = 97; // num =97
n = *p; // n=97
c = (char) *p; // c = a
Chú ý
: Địa chỉ của một biế n đ ược xem như một con trỏ hằ ng, do đó nó
không đ ược phép gá n, tă ng hoặ c giả m.
Ví dụ
: int num, *p, n;
p = & num;

p ++; // đúng
( & num) ++; // sai
con trỏ hằ ng
II.6. Khai báo một con trỏ hằng và con trỏ chỉ đế n đối tượng hằng:

a. Con trỏ hằng:
Kiể u * const p = giá trị;
b. Con trỏ chỉ đến đối tượng hằng:
Kiể u const *p = giá trị hằ ng;
hoặ c Const kiể u *p = giá trị hằ ng;
Ví dụ
: char *const p2 = ABCD
const char *p1= ABCD
p2 + + ; // sai
p1 + + ; // đúng; *p1= B ; p1 = "BCD"
III. Sự tương quan giữa con trỏ và mảng

Ví dụ
: Ta có mả ng A như sau:
int A[10] , *p;
thì A = &A[0]
Nế u p = A thì để truy xuấ t tới phầ n tử thứ i của mả ng A, ta có cá c cá ch sau:
A[i]

*(A + i)

*( p + i)
& A[i]

(A + i)


(p +i )
Ví dụ
: Nhậ p mả ng A:
int A[10] , *p, i;
p = A;
for (i = 0; i< 9; i++)
scanf (%d, p+i );
Xuấ t mả ng A
:
for (i = 0; i< 9;i++)
printf (%d, *(p+i));
Kü thuËt lËp tr× nh
89
VÝ dô: S¾ p xÕ p m¶ ng b» ng c¸ ch tham kh¶ o con trá.
const n =10 ;
int a[n], *p;
void main()
{ int j,temp;
clrscr();
p=a;
printf("\Nhap day so A :\n");
for (int i=0; i<n; i++)
{ printf("A[%d] = ",i+1);
scanf("%d",p+i);
}
// Sap xep mang A theo giai thuat Bubble Sort
for ( i=1; i<n; i++)
for (j=n-1; j>=i; j--)
if (*(p+j-1) > *(p+j))

{ temp = *(p+j);
*(p+j) = *(p+j-1);
*(p+j-1) = temp;
}
printf("\n Mang A sau khi sap xep :\n");
for ( i=0; i<n; i++)
printf("%8d",*(p+i));
}
* §èi víi m¶ ng 2 chiÒ u
:
NÕ u ta khai b¸ o : KiÓ u a [10] [20] , *p; th× m¶ ng a cã d¹ ng:
a 0 1 2 3 ..... 18 19
0
1
2
3
a[i]
.
9
NhËn xÐt:
a = &a[0][0] = &a[0]
a[i] = &a[i][0]

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×