Xem thêm

Con trỏ trong C++: Khám phá khái niệm cơ bản

Huy Erick
Con trỏ, hoặc được gọi là Pointer trong C++, là một khái niệm khá phức tạp nhưng cũng rất thú vị. Nếu bạn có kiến thức chắc chắn về cách sử dụng con trỏ trong...

Con trỏ, hoặc được gọi là Pointer trong C++, là một khái niệm khá phức tạp nhưng cũng rất thú vị. Nếu bạn có kiến thức chắc chắn về cách sử dụng con trỏ trong C++, bạn sẽ dễ dàng thực hiện các thao tác cao cấp liên quan đến bộ nhớ. Điều này quan trọng nếu bạn muốn trở thành một lập trình viên chuyên nghiệp. Trong bài viết này, chúng ta sẽ nhanh chóng tìm hiểu các khái niệm cơ bản về con trỏ C++. Cùng bắt đầu nhé!

Khám phá khái niệm của con trỏ trong C++

Để hiểu khái niệm của con trỏ trong C++, chúng ta cần khám phá cấu trúc của máy tính trước tiên, cụ thể là bộ nhớ hay còn được gọi là RAM. RAM là viết tắt của Random Access Memory (Bộ nhớ truy cập ngẫu nhiên). RAM được sử dụng như một bộ nhớ tạm thời để xử lý các dữ liệu trong điều kiện được cung cấp điện. Nếu RAM mất điện, nó sẽ không hoạt động được nữa.

RAM được cấu tạo từ rất nhiều ô nhớ, với mỗi ô có kích thước là 1 byte = 8 bit và có một địa chỉ duy nhất. Các ô nhớ được đánh số bắt đầu từ 0 trở đi.

Mỗi kiểu dữ liệu có kích thước khác nhau, vì vậy không phải kiểu dữ liệu nào cũng nằm trong một ô nhớ duy nhất. Địa chỉ của biến chính là địa chỉ của ô nhớ mà nó đang nằm trong. Ví dụ, nếu kiểu int chiếm tới 4 ô nhớ, thì địa chỉ của nó là gì? Khi một biến chiếm nhiều ô nhớ, địa chỉ của nó sẽ là địa chỉ của ô nhớ đầu tiên trong chuỗi các ô nhớ liền kề nhau.

Khi trình biên dịch code hoạt động, nó sẽ dành riêng một vùng để ghi nhớ các biến. Địa chỉ của biến là địa chỉ của ô nhớ đầu tiên trong chuỗi liền kề. Khi được gọi tên, biến sẽ tự truy xuất đến địa chỉ thích hợp. Các biến khác nhau không cần phải liền kề nhau.

Con trỏ trong C++ có những liên quan gì? Con trỏ trong C++ có những liên quan gì?

Cấp phát bộ nhớ trong C++

Khi chúng ta khai báo tên và vùng nhớ cố định cho một biến, đó được gọi là biến tĩnh hoặc biến được cấp phát tĩnh. Vì nó gắn liền với một vùng nhớ cố định, trong quá trình chương trình được thực thi, không thể tác động lên nó được. Việc tác động ở đây bao gồm việc xóa và thay đổi kích thước. Tất cả những điều này chỉ có thể thực hiện khi chương trình kết thúc.

dang-ky-lap-trinh

Vì vậy, biến tĩnh gây phiền phức trong nhiều trường hợp. Khi một biến trở nên vô dụng hoặc bành trướng quá mức mà ta không thể xóa và chỉnh sửa nó, điều này sẽ dẫn đến tình trạng chiếm dụng bộ nhớ và lãng phí tài nguyên. Giải pháp trong trường hợp này chính là sử dụng biến động hoặc biến được cấp phát động trong C++.

Biến động là một kiểu dữ liệu đã được định nghĩa. Nó có tên nhưng không được khai báo biến. Biến động sẽ được cấp phát một vùng nhớ trong RAM, có thể sử dụng khi có nguồn điện và không hoạt động khi không có nguồn điện. Biến động sẽ được điều khiển bằng con trỏ trong C++.

Biến con trỏ trong C++

Bản thân một con trỏ trong C++ là một biến, nên nó chứa địa chỉ của ô nhớ đầu tiên trong vùng nhớ. Con trỏ C++ có thể chứa địa chỉ của cả biến tĩnh và biến động. Tuy nhiên, như đã đề cập ở trên, biến động không có tên, vì vậy con trỏ C++ sẽ chịu trách nhiệm quản lý biến động đó. Khi đó, chúng ta nói rằng con trỏ này trỏ đến biến kia hoặc con trỏ này tham chiếu đến vùng nhớ khác. Mỗi con trỏ chứa một địa chỉ khác nhau, vì vậy chúng cũng có kích thước khác nhau.

Dùng con trỏ C++ không đơn giản Dùng con trỏ C++ không đơn giản

Khi làm việc với con trỏ C++, chúng ta không thể tự ý thay đổi địa chỉ của nó, điều này là việc hệ điều hành chịu trách nhiệm. Ngoài ra, không phải vùng nhớ nào con trỏ C++ cũng tham chiếu được. Nó chỉ có thể trỏ đến loại dữ liệu thích hợp. Bản chất của con trỏ C++ là quản lý địa chỉ, vì vậy ta không thể trỏ nó đến biểu thức hoặc hằng, những đối tượng này không có địa chỉ.

Cách sử dụng con trỏ trong C++

Khai báo con trỏ C++

Để khai báo con trỏ C++, chúng ta thực hiện một công thức giống như khi khai báo các biến thông thường:

 *

Trong đó, kiểu dữ liệu có thể là nguyên thủy như int, char, double hoặc các struct, class như vector , queue >. Tất cả đều khả thi. Tuy nhiên, nếu một con trỏ trỏ vào nhiều biến khác nhau trong những thời điểm khác nhau, thì các biến này phải có cùng một kiểu dữ liệu. Cần có kiểu dữ liệu chung giữa các biến để có thể khai báo. Dấu * trong công thức có nghĩa là ta đang báo hiệu hoạt động khai báo con trỏ cho trình biên dịch.

Dưới đây là một số ví dụ thường gặp về kiểu khai báo cho các loại dữ liệu khác nhau:

  • Nếu biến có kiểu dữ liệu int, cú pháp khai báo sẽ là int p hoặc int p.
  • Nếu biến có kiểu dữ liệu string hoặc queue , cú pháp khai báo sẽ là string s hoặc queue q.

Cấu tạo của con trỏ trong C++ Cấu tạo của con trỏ trong C++

Gán giá trị cho con trỏ

Sau khi khai báo con trỏ, chúng ta cần gán giá trị cho nó trong C++. Bạn cũng cần lưu ý rằng, nếu sử dụng con trỏ mà không khởi tạo, thì giá trị của nó sẽ không có ý nghĩa, hay còn được gọi là giá trị rác. Rất nhiều rủi ro có thể xảy ra nếu chương trình dính giá trị rác, đặc biệt là khi giá trị rác trùng với một địa chỉ biến mà bạn đang sử dụng.

Để khởi tạo và khai báo giá trị cho con trỏ, tham khảo ví dụ sau:

int *p, value;
value = 5;
p = &value; // khởi tạo giá trị cho con trỏ p là địa chỉ của value

// Hoặc bạn cũng có thể khai báo và khởi tạo đồng thời:
int value = 5;
int *p = &value; // khai báo con trỏ p và khởi tạo giá trị cho con trỏ là địa chỉ của value

// Nếu lỡ khai báo con trỏ rồi mà nó vẫn chưa có giá trị thích hợp, ta tạm thời khởi tạo giá trị NULL cho nó:
int *p_int = NULL

lap-trinh-cho-tre

Truy cập vào biến mà con trỏ trỏ tới

Con trỏ được sử dụng để đặt tên khác cho một biến bất kỳ. Khi bạn muốn truy cập vào biến p mà con trỏ trỏ tới, hãy quan tâm đến p. p sẽ có kiểu xuất hiện giống với p. Vì vậy, cách truy cập p chính là truy cập *p. Điều này được thể hiện trong ví dụ sau:

int *p_int = …; // something which does not matter
string *p_string = …; // something which does not matter

*p_int = 5;
(*p_int)++;
cout << *p_int << endl;

if (!(*p_string).empty())
    for (int i = 0; i < (*p_string).size(); i++)
        printf("%c", (*p_string)[i]);

Cấu tạo của con trỏ trong C++

Kết luận

Với những kiến thức căn bản vừa được trình bày, chúng ta đã có cái nhìn sơ bộ về con trỏ trong C++. Đây không phải là một lĩnh vực dễ khám phá. Tuy nhiên, nó lại ẩn chứa nhiều điều rất thú vị. Vì vậy, việc tìm hiểu sâu hơn về con trỏ trong C++ không bao giờ là lãng phí thời gian. Lời khuyên của Teky là bạn nên thực hành nhiều lần và áp dụng thường xuyên vào công việc của mình nếu có thể. Chúc bạn có thể nhanh chóng làm chủ lĩnh vực này!

Tìm hiểu về Teky Học Viện Công Nghệ Trẻ Hàng Đầu Việt Nam

TEKY là Học viện sáng tạo công nghệ với chương trình giảng dạy STEAM (Science - Technology - Engineering - Art - Mathematics) theo chuẩn Mỹ đầu tiên tại Việt Nam dành cho trẻ em từ 4 đến 18 tuổi.

Được thành lập vào tháng 6 năm 2016, TEKY quyết tâm mang đến cho thế hệ trẻ Việt Nam kiến thức toàn diện về STEAM, đặc biệt là các tư duy công nghệ, khoa học máy tính và kỹ năng thế kỷ 21 - 4Cs (Critical Thinking: Tư duy phản biện - Communication: Giao tiếp - Creativity: Sáng tạo - Collaboration: Làm việc nhóm).

Chương trình giảng dạy tại TEKY bao gồm Lập trình và phát triển ứng dụng, Lập trình game, Lập trình web với Python, Lập trình Scratch, Robotics Engineering, Công nghệ 3D và Multimedia. Chúng tôi tin rằng trẻ em Việt Nam có cơ hội phát triển mạnh mẽ trong một nền kinh tế số và cần được trang bị sẵn sàng để trở thành những doanh nhân công nghệ trong tương lai.

Liên hệ ngay học viện công nghệ sáng tạo TEKY để được tư vấn khóa học:

  • Hotline Hà Nội: 024-7109-6668 | 0975-241-015
  • Hotline Hồ Chí Minh: 028-7109 9948 | 097-900-8642

Website: https://teky.edu.vn Email: [email protected]

1