Thứ Sáu, 12 tháng 4, 2024

35.Con trỏ và mảng trong C

Chúng ta biết rằng: 

  • Mỗi mảng có nhiều phần tử khác nhau. Ví dụ A[0], A[1], A[2]...
  • Mỗi phần tử có các giá trị khác nhau. Ví dụ A[0]=4, A[1]=9...
  • Mỗi phần tử trong mảng lại có các địa chỉ khác nhau trong bộ nhớ.

Chúng ta sẽ thử lại trên IDE Online để nhớ lại:

Đây là một chương trình đơn giản in giá trị từng phần tử của mảng A[] gồm có 4 phần tử.

 

#include <stdio.h>

int main() {
  int A[4] = {25, 50, 75, 100};
  int i;

  for (i = 0; i < 4; i++) {
    printf("%d\n", A[i]);
  }

  return 0;
}

Bấm Run để chạy thử, kết quả:

Con trỏ và mảng trong lập trình C


Vẫn với mảng A[], chúng ta thêm lệnh để in địa chỉ:

for (i = 0; i < 4; i++) {
    printf("%p\n", &A[i]);
  }

Bấm Run để chạy chương trình, ta sẽ thấy



Tóm lại, tới đây ta đã hiểu mỗi phần tử của mảng sẽ có các giá trị khác nhau và cũng có những địa chỉ trong bộ nhớ khác nhau.

Trong ngôn ngữ lập trình C, tên của mảng thực sự là một con trỏ đến địa chỉ của phần tử đầu tiên của mảng

Thêm 2 lệnh in sau vào chương trình trên:

 

 printf("Địa chỉ của mảng A: %p\n", A); // Lấy địa chỉ bộ nhớ của mảng A
 printf("Địa chỉ phần tử đầu tiên của mảng: %p\n", &A[0]); // Lấy địa chỉ bộ nhớ của phần tử mảng đầu tiên

Bấm Run để chạy


Nhìn kết quả ta sẽ thấy rõ ràng tên của mảng A cũng chính là địa chỉ của phần tử đầu tiên &A[0]

Nó sẽ tương tự như một biểu thức khai báo con trỏ thế này (Để bạn hình dung, thực tế không cần lệnh gán p=&A[0];)

int A[4] = {25, 50, 75, 100};
int *p; // Khai báo con trỏ p
p=&A[0]; // Không cần, chỉ để hình dung: Gán giá trị địa chỉ của A[0] cho con trỏ p cũng chính là tên mảng A, p=A

Khi dùng lệnh print:

A: Là địa chỉ bộ nhớ của A[0]. Tức là A là con trỏ, trỏ đến địa chỉ bộ nhớ của A[0].

A[0] là phần tử đầu tiên của mảng. Trong ví dụ trên, giá trị của  A[0] là 25

&A[0]: Cũng là địa chỉ bộ nhớ của A[0] (Bất cứ biến nào, dùng toán tử & để lấy địa chỉ bộ nhớ). Tức là printf A và printf &A[0] đều có kết quả giống nhau. Y như khi ta printf p và printf &number trong phần trước.

Vòng vo một chặp, chúng ta sẽ cần hiểu rằng ý nghĩa thật sự của việc này đó là: 

Chúng ta có thể làm việc với mảng thông qua con trỏ. Vì A là một con trỏ, trỏ tới phần tử đầu tiên của mảng A[] nên ta có thể sử dụng toán tử * để truy cập nó (Trong phần trước, ta đã biết rằng ta có thể sử dụng toán tử * trước tên con trỏ để lấy giá trị của biến đó.)

Ví dụ, lện printf("%d", *myNumbers); sẽ in ra số 25 cho chương trình trên. Nếu muốn truy cập các phần tử tiếp theo, chúng ta chỉ cần cộng 1,2..

Ví dụ ta thêm hai lệnh in sau vào chương trình:

// Giá trị phần tử thứ hai A[1]
printf("%d\n", *(A + 1));

// Giá trị phần tử thứ ba A[2]
printf("%d", *(A + 2));

Bấm Run để chay chương trình




Phần tiếp theo

Phần trước

Không có nhận xét nào:

Đăng nhận xét