Sự tương quan giữa con trỏ và mảng

Một phần của tài liệu Giáo trình cấu trúc dữ liệu và giải thuật (ngành quản trị mạng) (Trang 142 - 145)

4. Mối liên quan giữa con trỏ, hàm, mảng, chuỗi và cấu trúc

4.3. Sự tương quan giữa con trỏ và mảng

Con trỏ và mảng một chiều.

Với khai báo:

int a[10], *p;

Thực chất C qui định a tương đương với &a[0], nghĩa là tên mảng là địa chỉ, hay con trỏ trỏ tới phần tử đầu tiên của mảng.

Ta có thể viết: p=a; hay p=&a[0];

Khi đó để 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 )

Chúng ta cần lưu ý là chỉ có tên của mảng mới mang giá trị địa chỉ (tức con trỏ), còn phần tử của mảng (a[i]) chỉ là biến bình thường. Cụ thể, a hay a[] là biến con trỏ còn a[0], a[1],… là các giá trị của biến.

Ví dụ 13: Hàm nhập mảng và hiện mảng:

#include <stdio.h> #include <conio.h> #include <alloc.h>

//định nghĩa hàm Nhapmang

void Nhapmang(int *p,int n)

{ int i;

for (i = 0; i< n; i++)

{printf("\n nhap a[%d]:",i); scanf ("%d", p+i );

} }

//định nghĩa hàm Hienmang

void Hienmang(int *p, int n)

{ int i;

for (i = 0; i<n;i++) printf ("%4d", *(p+i)); } //định nghĩa hàm chính main void main(void) { int a[100]; int n=10;

Nhapmang(a,n); //Biến mảng tương đương biến con trỏ

Hienmang(a,n);

getch(); }

Sự khác nhau giữa con trỏ và mảng:

Biến con trỏ thì có thể tăng, giảm hoặc gán còn biến mảng là một con trỏ hằng do đó không thể tăng, giảm hoặc gán.

Ta có thể lấy địa chỉ của con trỏ nhưng không thể lấy địa chỉ của mảng vì bản thân mảng đã là địa chỉ .

Khi ta khai báo một mảng thì chương trình dịch sẽ cấp phát một vùng nhớ cho nó. Còn biến con trỏ khi được khai báo chỉ được cấp một nhớ mà nội dung của nó thường chưa xác định: ⇒ phải có p = a để p chỉ tới a

Khi khai báo mảng ta phải chỉ ra số lương phần tử, nếu thừa nhiều sẽ lãng phí bộ nhớ, Nếu thiếu chương trình sẽ lỗi. Ta có thể khắc phục điều này bằng cách tạo một mảng bằng con trỏ và phải xin cấp phát một vùng nhớ bằng hàm malloc (), nếu thiếu có thể dùng hàm realloc() để xin cấp phát thêm ô nhớ.

/*Viết lại hàm main của ví dụ 3.12 bằng cách dù̀ng biến con trỏ thay mảng*/ void main(void)

{int *p, n=10;

p =(int*) malloc (10 * sizeof (int));

Nhapmang(p,n); Hienmang(p,n); getch();

}

Con trỏ và mảng hai chiều.

Chúng ta đã biết, C quan niệm mảng hai chiều như mảng (một chiều) của mảng.

Khi đó ta có các phần tử:

trỏ tới a[0][0];a[0];

a+1 trỏ tới a[0][1];a[1];

a+2 trỏ tới a[0][2];a[2];

+3 trỏ tới a[1][0];a[3];

Mảng 2 chiều và biến con trỏ:

Ví dụ 15: float a[2][3], *p; Khi đó:

p=(float *)a;//với mảng 2 chiều phải dù̀ng phép ép kiểu

( Không nên dùng: p=a; vì đây là phép gán được dùng với mả̉ng một chiều) Sau phép gán trên thì:

p trỏ tới địa chỉ a[0][0] p+1 trỏ tới địa chỉ a[0][1] p +2 trỏ tới địa chỉ a[0][2] …

Và *p trỏ tới giá trị a[0][0]

*(p+1) trỏ tới giá trị a[0][1]

Ví dụ 16 : Hàm hiện mảng 2 chiều: #include <stdio.h> #include <alloc.h> #include <conio.h> void hienMT(int *p) {

for (int i=0;i<6;i++)

printf("%d %c", *(p+i),(i==2)? '\n':' '); } void main() {clrscr(); int *p,a[2][3]={1,2,3,4,5,6}; printf("\n");

hienMT((int *)a); //phải dù̀ng phép ép kiểu

getch();

}

Một phần của tài liệu Giáo trình cấu trúc dữ liệu và giải thuật (ngành quản trị mạng) (Trang 142 - 145)