Thảo luận về biến kiểu Pointers trong ngôn ngữ C
[THẢO LUẬN]
Sau khi học C một thời gian thì chắc chắc các bạn sẽ phải làm quen và làm việc với biến kiểu con trỏ pointer.
Trong topic này, mọi người cùng thảo luận về các vấn đề sau nhé
pointer à gì? Tại sao cần biết đến pointer?
Cách tận dụng bộ nhớ khi dùng pointer.
Sử dụng pointer với chuỗi ký tự như thế nào?
Theo như mình biết thì pointer là một biến loại đặc biệt, chỉ chứa ĐỊA CHỈ của một ô nhớ, kích thước của 1 biến kiểu pointer tùy thuộc vào loại máy tính đang dùng (ví dụ máy mình cài win 64 bit thì bộ nhớ của 1 biến pointer là 8 byte vì 8 bit= 1 byte)
Ngôn ngữ C, cái mạnh nhất của nó là có thể can thiệp đến phần cứng và pointer là phương tiện để làm điều đó (thầy giáo mh bảo thế :3) - pointer là thứ quen thuộc như cơm bữa với những ai đang theo học lập trình nhúng hay liên quan đến phần cứng - đó là tầm quan trọng của pointer.
Thêm 1 điều thú vị là dữ liệu kiểu mảng (array) mà ngày thường chúng ta hay dùng khi truyền vào cho hàm nào đó (ví dụ void input(int array[], int k) thì thứ mà truyền vào hàm input đó lại chỉ là địa chỉ phần từ đầu tiên trong mảng (array[0])
Từ đó dẫn đến 1 tương quan giữa mảng và pointer. nếu ta khai báo 1 mảng A gồm 100 phần tử double nhưng chỉ dùng có 10 phần tử thì đã lãng phí 90 phần tử (~90x8=720 byte). Tuy nhiên, biến kiểu pointer lại giải quyết được vấn đề này. Khi khai báo, ta chỉ mất 8 byte(máy của mình) cho 1 biến pointer và sau khi biết số phần tử của mảng, ta xin cấp phát bộ nhớ cho pointer bằng hàm calloc, malloc, khi nào cấn thêm phần từ thì lại yêu cầu cấp thêm bộ nhớ bằng hàm relloc, khi nào không dùng đến nữa có thể giải phóng bộ nhớ bằng hàm free. Vì thế sẽ không bị lãng phí bộ nhớ khi chạy chương trình.
Pointer mình nói đến trong ví dụ trên là pointer 1 sao (mình gọi thế vì khi khai báo biến này nó có 1 sao ở trước ví dụ: int *arr;) Và pointer 1 sao có thể tham chiếu tới các ô nhớ có địa chỉ lệch i ô từ ô mà pointer *arr mình khai báo. Ví dụ sau khi khai báo 1 mảng array và 1 pointer *arr, mình có thể gán cho arr địa chỉ của phần tử đầu tiên của dãy array, đó là: arr=array; hoặc: arr=&array[0];
muốn gọi ra phần tử thứ i trong dãy, ta làm như sau: S=array[i]; hoặc S= *(array+i) hoặc S=arr[i]; hoặc S= *(arr+i);
Sở dĩ có thể gán S như vậy vì khi khai báo mảng array xong, máy sẽ cấp phát cho biến array một số lượng ô nhớ LIỀN KỀ NHAU
Như vậy pointer 1 sao và mảng 1 chiều thực sự rất giống nhau, tuy nhiên pointer có lợi thế là tận dụng bộ nhớ và có thể làm việc trực tiếp với ô nhớ trong RAM.
Câu hỏi đặt ra cho mọi người cùng thảo luận thêm, đó là: 1 chuỗi có cách tham chiếu tới các ký tự y hệt như mảng. vậy liệu có thể dùng pointer để tiết kiệm bộ nhớ giống như đã làm với mảng không? và nếu được thì dùng như thế nào?
Bonus: Vì pointer cũng là 1 biến, nên nó cũng sẽ có địa chỉ, và để lưu địa chỉ của nó thì cũng có thể dùng 1 pointer khác (pointer 2 sao). Để dễ hình dung thì các bạn có thể liên tưởng pointer 1 sao như mình nói ở trên có thể giống giống với mảng 1 chiều, còn pointer 2 sao thì lại lưu địa chỉ các poiner 1 sao - giống với mảng 2 chiều.
Nói chung về pointer thì có rất nhiều thứ để nói, nhưng nếu viết dài quá sợ mọi người không muốn đọc, và mình cũng đang tìm hiểu để mở rộng thêm kiến thức phần pointer nên sự góp ý, thảo luận của mọi người là vô cùng quý giá! ^^
Những clip tổng hợp về pointer: