icantech
Lập trình C
2309
28/11/2023

Những điều bạn cần biết về con trỏ trong C

Nếu bạn đang học hoặc chỉ đang tìm hiểu về ngôn ngữ lập trình C, chắc hẳn bạn đã từng nghe đến thuật ngữ “con trỏ”. Con trỏ trong C là một trong những tính năng quan trọng và mạnh mẽ nhất của ngôn ngữ lập trình này. Con trỏ được sử dụng ở mọi nơi trong C, cho phép bạn thao tác trực tiếp vào bộ nhớ, điều này rất hữu ích khi lập trình. Trong bài viết dưới đây, hãy cùng ICANTECH tìm hiểu về con trỏ trong C nhé!

1. Khái quát về con trỏ trong C

Con trỏ là 1 tính năng hữu ích và thật sự hữu ích. Tuy nhiên, việc sử dụng con trỏ sai cách có thể gây ra lỗi và các sự cố liên quan đến bộ nhớ. Chính vì thế mà điều quan trọng là bạn phải hiểu cách sử dụng con trỏ C một cách chính xác.

con-tro-trong-c

1.1. Con trỏ trong C là gì?

Trong lập trình C, con trỏ là một biến dùng để lưu trữ địa chỉ bộ nhớ của một biến khác. Con trỏ cho phép các chương trình có quyền thao tác trực tiếp vào bộ nhớ, điều này đặc biệt hữu ích khi bạn thực hiện các tác vụ như cấp phát bộ nhớ động hay làm việc với mảng.

Một con trỏ được khai báo bằng ký hiệu (*) đặt trước tên biến. Ví dụ: để khai báo một con trỏ tới một số nguyên, bạn sẽ sử dụng cú pháp: int *ptr;

1.2. Các cách sử dụng con trỏ

Trong ngôn ngữ lập trình C, con trỏ được sử dụng trong các trường hợp sau:

  • Tạo cấu trúc dữ liệu động (dynamic data structures): cấu trúc dữ liệu được xây dựng từ các khối bộ nhớ được phân bổ từ vùng heap, dựa theo thời gian chạy.
  • Xử lý các tham số biến thiên được truyền cho hàm.
  • Con trỏ trong C cung cấp một cách khác để truy cập vào thông tin lưu trữ trong mảng.

Trong một số trường hợp, lập trình viên cũng sử dụng con trỏ khi lập trình C để tăng hiệu quả code.

1.3. Thuật toán con trỏ

Vì con trỏ chứa các địa chỉ bộ nhớ nên bạn có thể thực hiện các phép tính số học trên đó, để di chuyển chúng đến các vị trí khác nhau của bộ nhớ. 

Điều này thường được sử dụng trong các hoạt động của mảng, khi mà bạn sử dụng con trỏ để truy cập các phần tử của mảng.

Ví dụ để in phần tử đầu tiên của mảng số nguyên bằng con trỏ, bạn có đoạn code như sau:

int arr[] = {1, 2, 3};

int *p = arr; // p points to the first element of arr
printf("%d\n", *p); // prints 1

Trong đó:

  • p được dùng để trỏ đến phần tử đầu tiên của mảng
  • *p: hủy đăng ký con trỏ để lấy giá trị của phần tử đầu tiên (là 1)

2. Hướng dẫn sử dụng con trỏ C cơ bản trong ngôn ngữ lập trình C

Tiếp theo, ICANTECH sẽ hướng dẫn bạn một vài cách sử dụng con trỏ trong C cơ bản.

2.1. Khai báo con trỏ

Để khai báo một biến con trỏ trong C, chúng ta sử dụng ký hiệu dấu * đứng trước tên biến. Có hai cách khai báo biến con trỏ trong ngôn ngữ C là:

int *p;

int* p;

Cả hai cách khai báo này đều mang ý nghĩa tương đương nhau. Chúng khai báo một biến con trỏ có tên "p", có chứa địa chỉ bộ nhớ của một số nguyên.

Tuy nhiên, nếu bạn khai báo nhiều biến trong một câu lệnh, bạn cần thêm dấu * trước mỗi tên biến để hệ thống ghi nhận tất cả chúng đều là con trỏ. Ví dụ:

int *p, *q, *r;

Ở ví dụ trên, chúng ta đang khai báo ba biến con trỏ có tên "p", "q" và "r" và có chứa địa chỉ bộ nhớ của một số nguyên.

2.2. Khởi tạo con trỏ

Khi bạn khai báo một biến con trỏ, nó sẽ không tự động trỏ đến bất kỳ vị trí cụ thể nào trên bộ nhớ. Để khởi tạo một con trỏ có thể trỏ đến 1 biến hoặc 1 vị trí cụ thể, bạn cần sử dụng ký hiệu toán tử & để lấy địa chỉ của biến đó.

Ví dụ, để khởi tạo con trỏ p để trỏ tới một biến số nguyên có tên là x. Bạn sẽ viết cú pháp như mẫu để khai báo giá trị của p là địa chỉ bộ nhớ của x.
int x = 42;
int *p = &x;

2.3. Hủy đăng ký một con trỏ

Khi có một con trỏ, bạn có thể truy cập, sửa đổi giá trị được lưu trữ tại vị trí đó bằng cách hủy đăng ký con trỏ.

Để hủy đăng ký một con trỏ, bạn sử dụng ký hiệu dấu * đứng ở phía trước chính biến con trỏ. Ví dụ: để in giá trị của số nguyên mà p trỏ tới, bạn có mẫu sau:

printf("%d\n", *p);

2.4. Con trỏ tới con trỏ

Một con trỏ cũng có thể trỏ tới một biến của con trỏ khác, việc này được gọi là "con trỏ tới con trỏ". Bạn thực hiện khai báo một con trỏ tới một con trỏ bằng cách sử dụng hai dấu **. Ví dụ:

int x = 42;

int *p = &x;
int **q = &p;

Trong ví dụ trên, q là một con trỏ tới một con trỏ. Nó trỏ đến địa chỉ của biến p, từ đó trỏ đến địa chỉ của biến x.

2.5. Truyền con trỏ tới hàm

Bạn có thể truyền con trỏ trong C tới hàm dưới dạng đối số, việc này cho phép hàm sửa đổi giá trị của biến được truyền vào ban đầu. Người ta còn gọi việc chuyển con trỏ tới hàm là "truyền theo tham chiếu".

Để truyền một con trỏ tới một hàm, bạn chỉ cần khai báo tham số của hàm dưới dạng một con trỏ. Ví dụ:

void increment(int *p) {

     (*p)++;

}

int main() {

     int x = 42;

     int *p = &x;

     increment(p);

     printf("%d\n", x); // prints 43

     return 0;

}

Ở ví dụ trên, hàm tăng lấy một con trỏ tới một số nguyên (int *p) và tăng giá trị của số nguyên đó lên 1 đơn vị ((*p)++).

Trong main(), chúng ta khai báo số nguyên x và con trỏ p trỏ tới x. Sau đó chúng ta gọi hàm tăng, truyền vào con trỏ p. Sau khi gọi hàm, x đã được tăng lên 43.

2.6. Sử dụng con trỏ trong C để phân bổ bộ nhớ động

Một trong những ứng dụng hữu ích nhất của con trỏ C là cấp phát bộ nhớ động. Điều này cho phép bạn phân bổ bộ nhớ ngay trong thời gian chạy chương trình, thay vì phải chờ đến lúc biên dịch.

Ví dụ dưới đây là cách sử dụng hàm malloc để cấp phát động bộ nhớ và trả về một con trỏ tới bộ nhớ vừa được cấp phát.

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

Ở đây, p là một con trỏ tới một số nguyên đã được cấp phát bằng malloc. Toán tử sizeof được sử dụng để xác định kích thước của một số nguyên tính theo byte.

Sau khi cấp phát bộ nhớ, bạn có thể sử dụng biến con trỏ như với bất kỳ con trỏ nào khác. Khi sử dụng xong, bạn nên giải phóng bộ nhớ được phân bổ cho p bằng hàm free. Ví dụ:

free(p);

2.7. Chuyển con trỏ

Khi cần chuyển một con trỏ từ kiểu này sang kiểu khác, bạn áp dụng cú pháp (type *). Ví dụ:

double *p = (double *)malloc(sizeof(double));

Ở ví dụ trên, p được chuyển thành con trỏ kiểu double.

3. Lời Kết

Con trỏ trong C là một công cụ mạnh mẽ với lập trình viên ngôn ngữ C. Tính năng con trỏ không những phổ biến mà còn rất hữu ích trong việc lập trình. Thành thạo con trỏ C, sẽ giúp bạn thao tác với bộ nhớ cũng như làm việc với các cấu trúc dữ liệu phức tạp dễ dàng hơn.

Cảm ơn bạn đã đọc bài viết, nếu bạn đang quan tâm đến học lập trình online thì hãy tham khảo ngay các khóa học lập trình dưới đây tại ICANTECH nhé!

Nguồn ảnh: ICANTECH.

Share
Tags
Lập trình C

Bài tương tự