64
"e>dit an address",
"d>isplay an address"
};
static char tieude[40]="main menu\n\n";
thucdon(tieude,chon,3);
getch();
return 0;
}
void thucdon(char *tieude,char *lua[],int
kichthuoc)
{
int i;
printf(tieude);
for (i=0;i<kichthuoc;i++)
printf("%s\n",*(lua +i));
}
2.5. Con tr
2.5.1. Khái niệm con trỏ
Con trỏ là mt biến chứa địa chỉ của một biến.
nhiều loại địa chỉ nên cũng nhiều kiểu con trỏ tương ứng. Con trỏ
int chứa địa chcủa các biến kiểu int, con trỏ kiểu float, kiểu double,... Cũng tương
t như vậy.
Trong C, con tr thường được sử dụng vì với con trỏ thì chương trình th
được viết ngắn gọn hơn và hiệu quản những cấu trúc khác.
2.5.2. Khai báo con tr
Cũng ncác biến khác, một con trỏ phải được khai báo trước khi sử dụng.
Người lập trình phải chỉ ra kiểu của biến được trỏ tới.
Mẫu khai báo
kiểu_của_biến_được_tr *tên_biến_trỏ;
65
ví d: int *p;
*p là d liệu được chứa trong địa chỉ là p. Nói cách khác p vùng nh chứa
địa chỉ của *p. Hay p là con trtrỏ tới biến chứa giá trị *p.
Khi ta khai báo một biến con trỏ, máy sẽ cấp phát một vùng bnhớ là 2 byte
hoặc 4 byte tu theo kiểu của biến được trỏ.
d: khai báo int *p; thì y scấp phát một vùng nh 2 byte liên tiếp
cho biến trỏ p.
Khai báo
float x=90.8; - máy scấp phát một vùng nhớ là 4 byte liên tiếp cho biến x.
Con trỏ và địa chcủa biến
Địa chỉ của biến là s th tự của byte đầu tiên được cấp phát trong dãy các
byte cấp pt cho biến (các byte được đánh số từ 0)
Như đã trình bày trên, con tr là một biến gm một nhóm các ô nhớ (2 hoặc
4 byte) để lưu trữ các địa chỉ.
Phép toán một ngôi & xác định địa chỉ của đối tượng mà con tr trỏ tới.
Phép toán mt ngôi * sử dụng với biến trỏ để xác định giá trị địa chỉ mà
con trỏ trỏ tới.
Ví d: giả sử ta khai báo các biến x, p và phép gán như sau:
int x=12; // x là biến có giá trị bằng 15
int *p; // con trỏ p trỏ tới dữ liệu kiểu số nguyên
p=&x; // p nhận giá trị địa chỉ của x.
Đầu tiên biến trỏ p chứa mt giá trị xác định, sau khi phép gán p=&x;
thì biến p chứa địa chcủa ô nhớ x, và tất nhiên cũng chứa địa chỉ của bản thân
. Khi biến trỏ kng chứa bất kì một địa chỉ nào t g tr ca nó là null.
Cách dùng con tr
Ta có thể sử dụng tên con trỏ hoặc khai báo của nó trong các biểu thức.
Không nhập giá trị cho con trỏ từ bàn phím.
Quy cách in con trđịa chỉ là: *p
tên biến trỏ
chỉ rằng đây là biến trỏ
kiểu biến được trỏ
66
+ S dụng tên con tr: con trỏ cũng mt biến nên thdùng trong biểu
thc vì giá trị của sẽ được dùng trong biểu thức này (nng chú ý rằng giá trị của
con tr địa chỉ của biến nào đó). Khi tên con trỏ đứng ở vế trái của biểu thức gán
thì vế phải (phải là địa chỉ của biến) được gán cho con trỏ.
Ví dụ: float a, *p, *q; // khai báo a là mt s thc, p và q là hai con tr
p=&a; // địa chỉ của biến a được gán cho con trỏ p
q=p; // giá trị của con trỏ p được gán cho con trỏ q
Cũng ncác biến khác, nội dung của con trỏ thể được thay đi và ta
thể sử dụng quy tắc này để biến đổi địa chỉ.
Sdụng dng khai báo ca con trỏ
giả sử tacác khai báo
int x,y,z,*px,*py;
px=&x;
py=&y;
Thì con tr px tr tới x (hay n i px cha địa chỉ của x) con tr py tr
ti y (py chứa địa ch của y). Khi đó ta có các cách viết x *px như nhau,
nghĩa là
*px=x;
*py=y
*px, *py là giá trmà con trpx, py trtới
ví d: kiểm định các giá trị của con trỏ
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int so;
int *contro;
so=10;
printf(“\ndia chi cua so:%p “,&so);
printf(“\ngia tri cua so:%d “,so);
contro=&so;
67
printf(“\ndia chi cua con tro:%p “,&contro);
printf(“\ngia tri cua con tro:%p “,contro);
printf(\ng_tri duoc con tro tro toi:%d,*contro);
getch();
return;
}
Gisử địa chỉ của biến so là fff4 và địa chỉ của contro fff2, khi đó chương
trình sẽ cho kết quả là:
2.5.3. Các phép toán trên con tr
Phép toán một ngôi & xác định địa chỉ của đối tượng mà con tr trỏ tới.
Phép toán mt ngôi * sử dụng với biến trỏ để xác định giá trị địa chỉ mà
con trỏ trỏ tới.
c phép toán số học:
Pp cng mt con trỏ với một snguyên được một con tr cùng kiu
Pp trmột con tr với một s nguyên được mt con trỏ có cùng kiu
Pp trhai con tr cùng kiu sẽ được mt snguyên giả sử ta có khai
báo: int *p, i=5;
thế thì:
- phép ++p là: tăng giá trị ca p lên mt đơn vị
- phép --p là: giảm giá trị của p một đơn vị
Đơn vị tăng hay giảm của một con trỏ luôn luôn có kích thước của biến được
tr vào. Nếu giá trị của biến được trỏ vào thuộc kiểu int thì mt đơn vị ng gim là
2 byte. Nếu giá trị của biến được trỏ vào thuộc kiểu float thì mt đơn vị ng giảm
là 4 byte ... .
dia chi cua so: fff4
gia tri cua so: 10
dia chi cua con tro: fff2
gia tri cua con tro: fff4
gia tri duoc con tro tro toi: 10
68
c phép giữa các biến con trỏ:
Phép gán: =
Các phép so sánh: = (bằng nhau), != (khác nhau)
Lưu ý:
Phép toán & chthực hiện cho các đi tượng trong bnhớ, nghĩa là ch
thc hiện đối với các biến và các phn tử của mng (mà thực chất là các biến
cùng tên), không được sử dụng được với các hằng, biểu thức và các biến thanh ghi.
Nếu p là con trtrỏ tới một biến nguyên a thì p th xuất hiện trong các
biu thức, các câu lệnh giống nx.
Ví dụ: *p=10+ ++*p;
Con trkiểu tổng quát: Con trỏ kiểu tổng quát là con tr có thtrỏ tới
mọi kiểu con trỏ, nhưng ngưc lại thì không được mà phải dùng phép ép kiểu.
Con trkiểu tng quát là con trỏ khai báo kiểu void.
Các phép ng, gim địa chỉ và phép so sánh không dùng với con trỏ
tổng quát.
ví d:
void *tongquat;
int *nguyen;
char *kitu;
tongquat = nguyen; //phộp gỏn hợp lệ
*nguyen = *tongquat; //khụng hợp lệ
kitu = (char)tongquat; //s dụng đúng phép ép
kiểu
2.5.4. Con trỏ và xâu ký t
Vthực chất xâu tự chính là mt mng các phần tử là các tự, do
vậy việc mi quan hgiữa u tvà con tr chính là mi quan hgiữa mảng
một chiều với con trỏ, và điều này ta đã nghiên cứu ở phn trước.
Tên u tlà mt hằng địa chỉ biểu thị địa chỉ phn tử đu của mảng chứa
xâu ký tự đó.
Khai báo
char *tên;
Ví dụ: