Con trỏ (pointer) từ cơ bản tới nâng cao phần 1


Chắc hẳn nếu ai đã từng lập trình C/C++ thì đã từng nghe qua về con trỏ (hay pointer). Đây có thể nói là một trong những phần khó nhất trong C. Đại khái là nó khó hiểu và dễ quên nữa. Vậy làm cách nào để bạn biết và hiểu về con trỏ, làm thế nào để bạn có thể hoàn thành tốt các kì phỏng vấn cho một kĩ sư lập trình nhúng, mà khi người ta hỏi tới C, thì 90% là hỏi về con trỏ. Ôi **. hahaha.

 

Con trỏ là gì?

Câu trả lời, con trỏ là một biến nguyên bình thường, nó chứa một giá trị trong đó. Vậy giá trị nó lưu trong đó là gì? Câu trả lời là địa chỉ của một ô nhớ. Ta lập trình trên ARM 32 bit, thì con trỏ chứa giá trị 32 bit (8 số hex).
Ủa, vậy tại sao lại có char*, int*, void*, double*, vv? Câu trả lời là: con trỏ chứa địa chỉ, con trỏ kiểu char trỏ tới “vùng nhớ” kiểu char (nghĩa là các ô nhớ ở đây chứa dữ liệu kiểu char), con trỏ kiểu int thì trỏ tới vùng nhớ kiểu int….

 

Chúng ta đi sâu hơn về bộ nhớ (memory)

contro

Nhìn vào hình và ta sẽ giải thích như sau:
1. Khi chúng ta khai báo một biến, máy tính sẽ tạo ra một vùng nhớ để lưu giá trị cho biến đó (hay còn gọi là cấp phát bộ nhớ).
2. Nếu biến được khai báo trong hàm main(), thì những ô nhớ được cấp phát sẽ nằm trong vùng stack (như trong hình là biên x)
3. Nếu biến được khai báo ngoài hàm main() và ngoài tất cả các hàm, thì những ô nhớ được cấp phát sẽ nằm trong vùng global của bộ nhớ (trong hình là biến y).
Giả sử máy tính cấp phát cho biến x một “vị trí” (vị trí này chính là địa chỉ đấy – địa chỉ của vùng nhớ, tại sao mình không nói là ô nhớ, bởi vì tùy vào CPU mà kiểu int có thể được chứa ở nhiều ô nhớ) là 4,100,000. Chúng ta đã gán 4 vào x thì cái “vị trí” 4,100,000 sẽ lưu giá trị 4.
Và…con trỏ là cái thứ lưu cái số 4,100,000 như ví dụ ở trên đấy! Nếu muốn trỏ tới thằng x, thì phải dùng con trỏ kiểu int, bởi vì giá trị của x là integer.

Khai báo con trỏ

Kiểu dữ liệu *tên con trỏ;
Kiểu dữ liệu ở đây bao gồm:
– Kiểu dữ liệu có sẵn: int, char, void, long, ….
– Kiểu dữ liệu do chúng ta tự định nghĩa: struct, union.
– Kiểu dữ liệu là lớp (class) do chúng ta định nghĩa (c++).
– Kiểu dữ liệu dẫn xuất, kiểu con trỏ hàm (nâng cao).
Ví dụ:
int *p;
– p ở đây là con trỏ, và con trỏ p này trỏ đến vùng nhớ kiểu int. Lưu ý *p không phải là con trỏ mà là giá trị của vùng nhớ mà con trỏ p trỏ tới (giả sử p trỏ tới thằng x trong hình đầu thì *p = 4 nhé!).
Tiếp ví dụ:
int *a, *b;  // thì a và b đều là con trỏ
int *a, b;   // a là con trỏ, b là biến integer
int* a, b;   // a là con trỏ, b là biến nguyên, khai báo này đúng, nhưng dễ gây nhầm lẫn
void *a;     // đúng! Có con trỏ kiểu void này nhé

Khởi tạo giá trị cho biến con trỏ

Khởi tạo (initialize) khác với khai báo (declared) các bạn nhé! Sau khi khai báo 1 biến, bạn gán giá trị lần đầu tiên cho biến đó thì gọi là khởi tạo! Mình khuyên các bạn nên khởi tạo biến mỗi khi khai báo, vì khi không khởi tạo, nhiều trình biên dịch sẽ tự khởi tạo một giá trị rác cho biến đó, hoặc nhiều khi gây lỗi.
Khởi tạo cho con trỏ:
tên con trỏ = địa chỉ vùng nhớ;
– Toán tử lấy địa chỉ: toán tử & 1 ngôi (unary operator), toán tử này hoàn toàn khác với toán tử & 2 ngôi (bitwise).
ví dụ:
int bienInteger = 100; // khai báo và khởi tạo biến integer
int *conTro;           // khai báo con trỏ kiểu int
conTro = &bienInteger;           // con trỏ conTro trỏ tới biến bienInteger
– Lúc này *conTro tương đương với bienInteger, mọi thao tác với *conTro cũng chính là thao tác với bienInteger, hay mọi thao tác với bienInteger cũng chính là thao tác với *conTro.
– Câu lệnh bienInteger = 5; hoàn toàn tương đương với *conTro = 5;.
bienInteger++; hoàn toàn tương đương với (*conTro)++; (Khác với *conTro++ nhé!).

 

Tham khảo:
diendan.congdongcviet.com
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s