Quả thật thì mình thấy con trỏ là một cái gì đó cực kì dễ hiểu.
Trong lập trình người ta cần phải làm việc với vùng nhớ. Vùng nhớ đó nhiều lúc không có tên, không nằm trong phạm vi chương trình và ta chỉ biết địa chỉ của nó nên không thể dùng như biến thông thường.
Một loại biến đặc biệt mang trong nó địa chỉ của vùng nhớ đó chính là con trỏ. Thông qua con trỏ, người ta làm việc với vùng nhớ mà nó đang trỏ tới. Khi người ta nói con trỏ đang trỏ tới biến này, hàm kia là chưa chính xác. Phải nói con trỏ đang trỏ tới vùng nhớ của biến này hay hàm kia…
Thật sự thì con trỏ dùng làm gì?
Nó dễ hiểu nhưng nếu mà chỉ biết sử dụng để nó trỏ lung tung thì thật tệ. nói chung con trỏ nó làm mình hiểu sâu hơn về một chương trình làm việc với bộ nhớ như thế nào.
chuẩn cơm mẹ nấu ăn với canh chua luôn
- con trỏ giúp cấp phát vùng nhớ động >> dùng tới đâu cấp phát tới đó , dùng xong thì có thể giải phóng vùng nhớ >> tiết kiệm được bộ nhớ (cái này thấy rõ nhất ở việc dùng mảng và dslk)
- có khả năng trỏ đến nhiều vùng nhớ khác nhau
- khi muốn tương tác với 1 vùng dữ liệu nào đó thay vì phải khai báo 1 vùng dữ liệu tương đương thì ta có thể trỏ trực tiếp đến vùng dữ liệu đó và thao tác trên đó
vì C/C++ có thể tác động trực tiếp đến vùng nhớ nên các ctr chạy bằng C/C++ thường chạy và xử lý rất nhanh , vì thế người ta hay dùng C++ đề viết game…
vì truyền con trỏ vào hàm là truyền địa chỉ của biến chứ không phải là truyền dữ liệu của biến vào.
Bác nói chuẩn giảng thế ai cũng hiểu
Con trỏ là một tính năng của ngôn ngữ cấp thấp. Nó cho phép bạn thao tác với các ô nhớ một cách dễ dàng hơn. Nó tạo cho bạn sự linh hoạt trong việc kiểm soát các phần tử của chương trình.
Nói một cách sâu hơn. Dữ liệu trong các ô nhớ có thể type cast về mọi kiểu. Ví dụ thường thấy là void *
.
Hoặc thú vị hơn, ta có thể cấp phát bộ nhớ và tao tác với mảng bằng con trỏ. Hoặc tạo ra các cấu trúc dữ liệu và thuật toán trên nó (linked list…). Sử dụng con trỏ cũng sẽ tiết kiệm bộ nhớ hơn thay vì phải copy giá trị biến thì ta trỏ tới địa chỉ nhớ mà chứa giá trị biến.
Việc sử dụng con trỏ yêu cầu người sử dụng phải hiểu sâu về ngôn ngữ cũng như hệ thống. Nếu không chương trình sẽ khó sửa vì không biết được con trỏ trỏ tới đâu, hoặc trỏ tới vùng nhớ có giá trị sai. Dễ bị memory leak
nếu không thu hồi và cấp phát hợp lý.
e co the xin vi du cua tung li do duoc khong a?
con trỏ (pointer) dùng để thay đổi biến, giá trị, hàm… thay vì nhập một hàm có giá trị n=7, thì n=7 chỉ chạy trong 1 hàm. khi dùng con trỏ có thể thay đổi hàm theo biến và biến theo hàm. mới thi con trỏ xong. :>, con trỏ chỉ lưu địa chỉ của 1 biến và có thể thay đổi địa chỉ đó. , đây nha các bác hi vọng các bác hiểu.
cũng đúng, mình thấy thực tế k dùng gì lắm, hoặc là tầm nhìn của mình hạn hẹp nên chưa thấy, chỉ thấy con trỏ dùng nhiều ở lúc làm bài tập, bài toán thôi
Con trỏ thật sự hết sức cơ bản. Mỗi con trỏ có thể chứa 1 địa chỉ của ô nhớ (hoặc là rác ). Vùng nhớ là một dãy các ô nhớ có kích thước đồng nhất và có địa chỉ liên tục, khi trỏ đến vùng nhớ nghĩa là trỏ đến ô nhớ đầu tiên. Với memory-mapped I/O thì tương tác với thiết bị ngoại vi sẽ thông qua địa chỉ, nhiều thao tác chỉ là đọc/ghi 1 vùng nhớ.
Con trỏ đóng vai trò quan trọng quản lý bộ nhớ, vì vùng nhớ dùng để quản lý bộ nhớ tách rời với vùng nhớ được cấp phát, nên bắt buộc phải dùng con trỏ. Con trỏ ngoài việc mang địa chỉ và kích thước vùng nhớ, còn có nhiều thông tin phục vụ việc quản lý bộ nhớ. Thêm vào đó, con trỏ giúp tiết kiệm bộ nhớ qua việc chia sẻ vùng nhớ. Ví dụ như, thay vì mỗi đối tượng cứ phải na theo 1 copy các phương thức thì chỉ cần mang theo địa chỉ của 1 bảng các con trỏ đến chúng (vtable). Khi hiểu được con trỏ bạn sẽ hiểu được cách truyền tham số ở nhiều ngôn ngữ thông dụng (call by object reference).
con trỏ dùng để quản lý bộ nhớ :V Biến trong C++ được lưu trữ trên bộ nhớ chia ra làm 4 loại storage duration là automatic, static, thread, và dynamic.
-
Automatic là các biến tồn tại giữa
{
và}
, khi gặp}
sẽ được tự động xóa đi. - Static là các biến tồn tại từ lúc chương trình bắt đầu tới lúc chương trình kết thúc.
- Thread là các biến tồn tại từ lúc thread bắt đầu tới lúc thread kết thúc.
- Dynamic là các biến chỉ tồn tại khi người sử dụng yêu cầu cấp phát, và kết thúc khi người sử dụng yêu cầu giải phóng.
Chính ở loại biến dynamic này mà cần con trỏ để biết biến nào cần được giải phóng (nó giống như id/cmnd/căn cước của biến ấy, cần free biến nào chỉ cần đưa id ra là free biến đó ngay), còn 3 loại kia trình biên dịch nó tự động làm được :V Vì vậy nên con trỏ cực kì quan trọng chứ :V
C++ chỉ quy định có 4 loại biến này, còn stack, heap gì là người ta chế ra :V :V
automatic --> biến cục bộ (local, nằm trên “stack”)
static --> biến toàn cục (global, nằm trên data/bss)
thread --> biến thread_local
:V :V
dynamic --> biến động :V (nằm trên “heap”)
ví dụ 1 file ảnh đâu biết kích thước WxH là bao nhiêu, ko xài con trỏ để cấp phát/giải phóng động làm sao cấp phát bộ nhớ tương ứng? Xài biến cục bộ/toàn cục thì phải biết trước kích thước của nó, vì trình dịch nó tự động cấp phát/giải phóng cho nó phải biết kích thước của biến đó khi biên dịch. 1 file ảnh có thể có chiều dài/chiều cao lên tới 4 tỷ pixel, làm sao tạo sẵn mảng pixel 2 chiều 4 tỷ dòng x 4 tỷ cột được :V :V Phải đọc header của file ảnh đó vào xem width bao nhiêu, height bao nhiêu, rồi cấp phát động mảng width x height tương ứng. Khi người dùng cần đọc ảnh khác kích thước khác thì xóa mảng cũ đi, tạo mảng mới, v.v…
Con trỏ dùng ở nhiều trường hợp nhưng 3 trường hợp hay dùng và buộc phải dùng đó là :
- Cấp phát động khi kích thước dữ liệu chỉ được xác định ở runtime (khi chạy chương trình).
- Truyền tham chiếu.
- Truy cập dữ liệu ngoài chương trình (can thiệp vào dữ liệu của chương trình khác).
Ngoài những việc trên thì nhiều chỗ có thể chơi con trỏ vào. Nhưng vì là những trường hợp không cần thiết phải dùng con trỏ nên sẽ thấy nó vô ích và rườm rà, rắc rối.
Lâpj trình ở mức low level ( trên các board mạch với dụng lượng khiêm tốn) con trỏ mới phát huy tác dụng của nó , vì nó có thể cấp phát bộ nhớ động , sử dụng như một mảng , linh động trong việc khai báo bộ nhớ . Khiến chương trình được tối ưu hơn nhanh hơn về mặt tốc độ. Còn đối với lập trình bậc cao thì con trỏ k có tác dụng lắm
Con trỏ dùng để truy cập dữ liệu trong bộ nhớ. Không con trỏ = Không dữ liệu. Không dữ liệu thì chả có cái phần mềm vẹo nào cả. Bạn không hiểu ý nghĩa con trỏ thì có thể bạn chỉ quen tiếp xúc với những ngôn ngữ bậc cao nơi người ta chỉ nói đến biến một cách rất trừu tượng . Bạn có thể tìm hiểu qua assembly và kiến trúc máy tính của x86 hoặc ARM.
Các thao tác trên biến thực tế cũng là trên con trỏ nhưng compiler tối ưu giùm bạn rồi nên bạn không thấy tầm quan trọng của nó. Nhưng vì là máy làm nên tối ưu của nó đôi khi không bằng con người được. Cho nên, các ngôn ngữ “bậc hơi thấp” như C/C++ cho phép bạn can thiệp con trỏ để bạn tối ưu khi cần.
Không phải rồi.
Làm việc với con trỏ chậm hơn và tốn nhiều bộ nhớ hơn.