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

Một phần của tài liệu Giao trinh C (Trang 67 - 71)

Trong C có mối quan hệ chặt chẽ giữa con trỏ và mảng : các phần tử của mảng có thể

được xác định nhờ chỉ số hoặc thông qua con trỏ.

7.2.1.Phép toán lấy địa chỉ :

Phép toán này chỉ áp dụng cho các phần tử của mảng một chiều. Giả sử ta có khai báo : double b[20];

Khi đó phép toán :

&b[9]

sẽ cho địa chỉ của phần tử b[9].

7.2.2. Tên mảng là một hằng địa chỉ : Khi khai báo :

float a[10];

máy sẽ bố trí bố trí cho mảng a mười khoảng nhớ liên tiếp, mỗi khoảng nhớ là 4 byte. Như vậy, nếu biết địa chỉ của một phần tử nào đó của mảng a, thì ta có thể dễ dàng suy ra địa chỉ của các phần tử khác của mảng.

Víi C ta cã :

a tương đương với &a[0]

a+i tương đương với &a[i ]

*(a+i) tương đương với a[i]

7.2.3. Con trỏ trỏ tới các phần tử của mảng một chiều : Khi con trỏ pa trỏ tới phần tử a[k] thì :

pa+i trỏ tới phần tử thứ i sau a[k], có nghĩa là nó trỏ tới a[k+i].

pa-i trỏ tới phần tử thứ i trước a[k], có nghĩa là nó trỏ tới a[k-i].

*(pa+i) tương đương với pa[i].

Như vậy, sau hai câu lệnh : float a[20],*p;

p=a;

thì bốn cách viết sau có tác dụng như nhau : a[i] *(a+i) p[i] *(p+i)

VÝ dô :

Vào số liệu của các phần tử của một mảng và tính tổng của chú ng :

Cách 1:

#include "stdio.h"

main() {

float a[4],tong;

int i;

for (i=0;i<4;++i) {

printf("\n a[%d]=",i);

scanf("%f",a+i);

} tong=0;

for (i=0;i<4;++i) tong+=a[i];

printf("\n Tong cac phan tu mang la :%8.2f ",tong);

}

Cách 2 :

#include "stdio.h"

main() {

float a[4],tong, *troa;

int i;

troa=a;

for (i=0;i<4;++i) {

printf("\n a[%d]=",i);

scanf("%f",&troa[i]);

} tong=0;

for (i=0;i<4;++i) tong+=troa[i];

printf("\n Tong cac phan tu mang la :%8.2f ",t ong);

}

Cách 3 :

#include "stdio.h"

main() {

float a[4],tong,*troa;

int i;

troa=a;

for (i=0;i<4;++i) {

printf("\n a[%d]=",i);

scanf("%f",troa+i);

} tong=0;

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

tong+=*(troa+i);

printf("\n Tong cac phan tu mang la :%8.2f ",tong);

}

Chó ý :

Mảng một chiều và con trỏ tương ứng phải cùng kiểu.

7.2.4. Mảng, con trỏ và xâu ký tự :

Như ta đã biết trước đây, xâu ký tự là một dãy ký tự đặt trong hai dấu nháy kép, ví dụ như

:

"Viet nam"

Khi gặp một xâu ký tự, máy sẽ cấp phát một khoảng nhớ cho một mảng kiểu char đủ lớn

để chứa các ký tự của xâu và chứa thêm ký tự ' \0' là ký tự dùng làm ký tự kết thúc của một xâu ký tự. Mỗi ký tự của xâu được chứa trong một phần tử của mảng.

Cũng giống như tên mảng, xâu ký tự là m ột hàng địa chỉ biểu thị địa chỉ đầu của mảng chứa nó. Vì vậy nếu ta khai báo biến xau như một con trỏ kiểu char :

char *xau;

thì phép gán :

xau="Ha noi"

là hoàn toàn có nghĩa. Sau khi thực hiện câu lệnh này trong con trỏ xau sẽ có địa chỉ đầu của mảng (kiểu char) đang chứa xâu ký tự bên phải. Khi đó các câu lệnh :

puts("Ha noi");

puts(xau);

sẽ có cùng một tác dụng là cho hiện lên màn hình dòng chữ Ha noi.

Mảng kiểu char thường dùng để chứa một dãy ký tự đọc vào bộ nhớ. Ví dụ, để nạp từ bàn phím tên của một người ta dùng một mảng kiểu char với độ dài 25, ta sử dụng các câu lệnh sau :

char ten[25];

printf("\n Ho ten :");

gets(ten);

Bây giờ ta xem giữa mảng kiểu char và con trỏ kiểu char có những gì giống và khác nhau. Để thấy được sự khác nhau của chúng, ta đưa ra sự so sánh sau :

char *xau, ten[15];

ten="Ha noi"

gets(xau);

Các câu lệnh trên là không hợp lệ. Câu lệnh thứ hai sai ở chỗ : ten là một hằng địa chỉ và ta không thể gán một hằng địa chỉ này cho một hằng địa chỉ khác. Câu lệnh thứ ba kh ông thực hiện được, mục đích của câu lệnh là đọc từ bàn phím một dãy ký tự và lưu vào một vùng nhớ mà con trỏ xau trỏ tới. Song nội dung của con trỏ xau còn chưa xác định. Nếu trỏ xau đã trỏ tới một vùng nhớ nào đó thì câu lệnh này hoàn toàn có ý nghĩa. Ch ẳng hạn như sau khi thực hiện câu lệnh :

xau=ten;

thì cách viết :

gets(ten) ; và gets(xau);

đều có tác dụng như nhau.

Một phần của tài liệu Giao trinh C (Trang 67 - 71)

Tải bản đầy đủ (PDF)

(141 trang)