Một nơi phổ biến nơi con trỏ hữu ích là khi bạn đang viết hàm. Các hàm nhận đối số của chúng 'theo giá trị', có nghĩa là chúng nhận được một bản sao của những gì được truyền vào và nếu một hàm gán một giá trị mới cho một trong các đối số của nó sẽ không ảnh hưởng đến người gọi. Điều này có nghĩa rằng bạn không thể viết một "nhân đôi" chức năng như thế này:
void doubling(int x)
{
x = x * 2;
}
này có ý nghĩa bởi vì nếu không điều gì sẽ chương trình làm gì nếu bạn gọi tăng gấp đôi như thế này:
doubling(5);
Pointers cung cấp một công cụ để giải quyết vấn đề này bởi vì chúng cho phép bạn viết các hàm lấy địa chỉ của một biến, ví dụ:
void doubling2(int *x)
{
(*x) = (*x) * 2;
}
Hàm ở trên lấy địa chỉ của một số nguyên a s đối số của nó. Một dòng trong các hàm dereferences body function có địa chỉ hai lần: ở phía bên tay trái của dấu bằng chúng ta đang lưu trữ vào địa chỉ đó và bên phải chúng ta đang nhận giá trị nguyên từ địa chỉ đó và nhân nó với 2 Kết quả cuối cùng là giá trị tìm thấy tại địa chỉ đó hiện đã tăng gấp đôi. Ngoài ra, khi chúng tôi muốn gọi hàm mới này, chúng tôi không thể chuyển giá trị bằng chữ (ví dụ: doubling2(5)
) vì nó sẽ không biên dịch vì chúng tôi không cung cấp địa chỉ cho hàm đúng cách. Một cách để cung cấp cho nó một địa chỉ sẽ trông như thế này:
int a = 5;
doubling2(&a);
Kết quả cuối cùng này sẽ là biến a
của chúng tôi sẽ chứa 10
Khi học tôi tìm thấy nó dễ dàng hơn để nhớ rằng con trỏ chỉ là các biến mà giữ một địa chỉ bộ nhớ không có vấn đề như thế nào phức tạp nó trông. Vì vậy, 'char *** p' là khủng khiếp để suy nghĩ về nhưng cuối cùng nó chỉ giữ một địa chỉ bộ nhớ duy nhất. – teppic
Điều gì xảy ra nếu 'biến ban đầu' là bộ đệm mạng 10MB? Làm thế nào bạn sẽ vượt qua đó vào một chức năng, sao chép nó? Làm thế nào bạn sẽ xếp hàng nó vào một chủ đề khác, sao chép nó hai lần? –
@MartinJames gợi ý hay. – Gewure