SỬ DỤNG HÀM TRONG C
CHƯƠNG 6 KIỂU DỮ LIỆU CON TRỎ
6.1 MỘT SỐ KHÁI NIỆM CƠ BẢN
Khi khai báo một biến có kiểu bất kỳ, máy tính sẽ cấp phát số ô nhớ tương
đương với kiểu
dữ liệu đã khai báo. Trong bộ nhớ máy tính, mỗi ô nhớ tương đương với 1 byte.
Chẳng hạn, để
biểu diễn 1 ký tự thường cần 1 ô nhớ tương đương với 1 byte, để biểu diễn 1 số thực (float) cần
4 ô nhớ (4 byte).
Các ô nhớ trên đều có địa chỉ. Để biết được một biến a bất kỳ được lưu ở địa
chỉ nào trong
bộ nhớ máy tính, ta có thể sử dụng toán tử lấy địa chỉ & đặt trước tên biến như trong ví dụ sau:
Ví dụ 6.1:
#include
<stdio.h
>
intmain(
) {
long int a;
printf("size of:
%d\n",sizeof(a));
printf("memory address:
%ld\n",&a); } 6.1.2 Khái niệm con trỏ
Một con trỏ là một biến, nó chứa địa chỉ vùng nhớ của một biến khác, chứ
không lưu trữ
giá trị của biến đó. Nếu một biến chứa địa chỉ của một biến khác, thì biến này
được gọi là con
trỏ đến biến còn lại. Một con trỏ cung cấp phương thức gián tiếp để truy xuất giá
trị của các
phần tử dữ liệu. Cụ thể hơn, giả sử ta có một biến kiểu nguyên a có giá trị bằng 10 và biến này
99
p a p
a 10.
Các con trỏ có thể trỏ đến các biến của các kiểu dữ liệu cơ sở như int, char,hay double
,
Một máy tính thông thường có một mảng liên tiếp các ô nhớ có địa chỉ riêng
rẽ hoặc nối
tiếp nhau thành nhóm. Một cặp của các ô 1 byte có thể tương ứng như là một
kiểu short
integer và 4 bytes liền kề nhau là kiểu long. Một con trỏ là nhóm các ô (thường là
2 hoặc 4) để
tổ chức thành 1 địa chỉ. Nếu c là một ký tự và p là một con trỏ trỏ vào nó, ta có
thể biểu diễn
như sau:
Con trỏ có thể được sử dụng trong một số trường hợp sau:
Để trả về nhiều hơn một giá trị từ một hàm.
Để làm việc với các phần tử của mảng thay vì truy xuất trực tiếp vào các phần tử này. Để cấp phát bộ nhớ động và truy xuất vào vùng nhớ được cấp phát này.
6.1.4
Con trỏ được khai báo như sau:
> *<Tên con trỏ>;
p nguyên p
như sau:
int * p;
Kiểu dữ liệu xác định kiểu của biến mà con trỏ trỏ đến. Về mặt kỹ thuật, một con trỏ có kiểu bất kỳ có thể trỏ đến bất kỳ vị trí nào trong bộ nhớ. Tuy nhiên, tất cả các phép toán số học trên con trỏ đều có liên quan đến kiểu cơ sở của nó, vì vậy khai báo kiểu dữ liệu của con trỏ một cách rõ ràng là điều rất quan trọng.
6.1.5
Hai toán tử đặc biệt được dùng với con trỏ * và &.
&: Là một toán tử một ngôi và nó trả về địa chỉ của toán hạng :
in
t a
= 10
; in t
*p
;
p = &a
a p a
&a p = &a = 1000.
*: Được dùng với con trỏ là phần bổ sung của toán tử &. Nó là một toán tử một
ngôi và trả về giá trị chứa trong vùng nhớ được trỏ bởi giá trị của biến con trỏ.
100
Ở đoạn mã lệnh trên, sau phép gán p = &a, p sẽ được gọi là con trỏ trỏ đến biến a
và p có giá trị bằng 1000. Khi đó, phép toán *p sẽ trả về giá trị lưu trữ ở ô nhớ đang trỏ
bởi biến p. Như vậy: *p = a = 10;
Chương trình sau đây sẽ khai báo một biến kiểu nguyên a, một con trỏ p trỏ tới
biến a và cho
phép người dùng nhập vào giá trị của a. Sau đó chương trình sẽ in ra các giá trị a, &a, p và *p.
Ví dụ 6.2:
#include
<stdio.h
> int main()
{ int a,*p;
printf("Enter an integer a = ");
scanf("%d",&a);
p = &a;
printf("--- ----\n");
printf(" &a = %d, p=
%d\n", &a, p);
printf("--- ----\n");
printf(" a = %d, *p=
%d\n", a, *p);
}
Kết quả thực hiện của chương trình trên như sau:
Enter an integer a = 50
---
&a = 1245024, p=1245024 ---
--- a = 50,
*p=50
Khi khai báo dữ liệu con trỏ, máy tính cũng tương tự cấp phát một ô nhớ tương đương với kiểu dữ liệu con trỏ và đồng thời cũng cung cấp địa chỉ cho nó.
Giả sử có 3 biến x, y, và con trỏ p. Có địa chỉ bộ nhớ lần lượt là 100, 200 và 300. Khi đó, kết quả thực hiện của các phép toán &, * được thể hiện cụ thể như sau.
101
Như đã đề cập ở trên, trong một số trường hợp, ta có thể sử dụng để thao tác với các phần tử mảng một cách gián tiếp.
Chương trình sau đây sẽ nhập giá cho các phần tử của mảng một chiều A một cách gián tiếp thông qua con trỏ p.
Ví dụ 6.3:
#include
<stdio.h
>
intmain(
){
int i, n, A[100],*p;
printf("Enter number of elements: "); scanf("%d",
&n);
for (i=0;
i<n; i++){
p =
&A[i];
printf("A[%d ] = ", i);
scanf("%d", } p);
printf("---\n");
printf("Display entered array:\n"); for (i=0;
i<n; i++)
printf("%d ", A[i]);
}
Kết quả thực hiện của chương trình như sau:
Enter number of elements: 5 A[0] = 2
A [ 1 ]
= 3
A [ 2 ]
= 4
A [ 3 ]
= 6
A [ 4 ]
= 7
--- Display entered array:
2 3 4 6 7