Trong bài học này, Lập trình không khó sẽ hướng dẫn các bạn cách sử dụng con trỏ trong ngôn ngữ lập trình C. Bài viết này sẽ giúp các bạn hiểu thế nào là con trỏ, các khái niệm cơ bản liên quan đến con trỏ cũng như cách sử dụng con trỏ trong C. Con trỏ là phần kiến thức khá rộng, do đó bài viết này sẽ hướng dẫn về con trỏ cơ bản; Các bài viết tiếp theo sẽ trình bày chi tiết hơn con trỏ khi làm việc với mảng, cấp phát bộ nhớ và quản lý bộ nhớ,… Mình hi vọng loạt bài học về con trỏ trong C này sẽ giúp các bạn tự tin hơn.
Tóm tắt nội dung bài viết
Địa chỉ của biến trong C
Để hiểu và sử dụng được con trỏ trong C, thứ nhất bạn cần hiểu về khái niệm địa chỉ ở trong C. Nếu bạn nào theo dõi khóa học C bá đạo của mình từ đầu thì chắc đã thấy mình nhắc tới khái niệm này rồi. Phần này ta sẽ làm rõ yếu tố này .
0
Bạn đang đọc: Hiểu rõ 100% bản chất của con trỏ
12345
intnumber;
printf(” \ nNhap number = “);
scanf(” % d “,và number ) ;
printf(” \ nnumber = % d “,number);
Bạn hãy nhìn ví dụ trên, tại sao khi dùng hàm scanf
chúng ta cần truyền vào &number
, còn hàm printf
ta lại không có dấu &
kia? Bởi vì nếu bạn muốn nhập giá trị cho biến, hàm scanf
cần biết địa chỉ của biến đó ở trong bộ nhớ.
Mỗi biến mà bạn khai báo đều có địa chỉ riêng của nó và giá trị mà nó đang lưu trữ. Để xem được địa chỉ của biến, bạn thêm dấu &
vào trước tên biến. Xem xét ví dụ dưới đây:
01234567891011
#include
intmain()
{
intnumber=5;
printf(” Gia tri cua number = % d “,number);
/ / truy xuất địa chỉ bằng cách thêm và trước tên biến
printf(” \ nDia chi cua number = % d “,và number ) ;
return0;
}
Kết quả khi chạy chương trình :
0123
Gia tri cua number = 5Dia chi cua number = 6487580
Chú ý:
- Bạn có thể sẽ nhận được các địa chỉ khác nhau mỗi khi chạy code trên.
- Để nhận giá trị địa chỉ là
hexa
như ảnh ở đâu bài, bạn thay%d
bằng%x
là được.
Con trỏ trong C
Con trỏ là gì? Con trỏ trong C cũng chỉ là là biến, cũng có thể khai báo, khởi tạo và lưu trữ giá trị và có địa chỉ của riêng nó. Nhưng biến con trỏ không lưu giá trị bình thường, nó là biến trỏ tới 1 địa chỉ khác, tức mang giá trị là 1 địa chỉ.
Chúng ta cùng thống nhất 1 số khái niệm khi thao tác với con trỏ nhé :
- Giá trị của con trỏ: địa chỉ mà con trỏ trỏ đến.
- Địa chỉ của con trỏ: địa chỉ của bản thân biến con trỏ đó.
- Giá trị của biến nơi con trỏ đang trỏ tới.
- Địa chỉ của biến nơi con trỏ đang trỏ tới = giá trị của con trỏ.
Chính vì con trỏ mang địa chỉ, nó là 1 biến đặc biệt quan trọng có thêm những quyền lực mà biến thông thường không có. Nhờ việc nó mang địa chỉ, nó hoàn toàn có thể trỏ lung tung trong bộ nhớ. Đây là 1 điểm mạnh nếu ta khai thác tốt nhưng nếu quản trị không tốt thì lại là 1 tai hại .
Cách khai báo con trỏ
Con trỏ trong C cũng hoàn toàn có thể khai báo giống như biến thông thường, tên biến là một định danh hợp lệ. Cú pháp như sau :
012
Trong đó :
- Kiểu dữ liệu có thể là: void, int, float, double,…
- Dấu * trước tên biến là ký hiệu báo cho trình biên dịch biết ta đang khai báo con trỏ.
0123456
int*p_i;/ / khai báo con trỏ để trỏ tới biến kiểu nguyên
int*p,val;/ / khai báo con trỏ p kiểu int, biến val ( không phải con trỏ ) kiểu int
float*p_f;/ / khai báo con trỏ để trỏ tới biến kiểu thực
char*p_char;/ / khai báo con trỏ để trỏ tới biến kiểu ký tự
void*p_v;/ / con trỏ kiểu void ( không kiểu )
Gán giá trị cho con trỏ
Sau khi khai báo con trỏ, bạn cần khởi tạo giá trị cho nó. Nếu con trỏ được sử dụng mà không được khởi tạo, giá trị của nó sẽ là giá trị rác, điều này sẽ làm chương trình của bạn chạy không đúng, thậm chí còn là nguy khốn nếu giá trị rác đó chẳng may lại chính là địa chỉ của 1 biến nào đó bạn đang dùng .
01234
int*p,value;
value=5;
p=và value/ / khởi tạo giá trị cho con trỏ p là địa chỉ của value
Hoặc bạn cũng hoàn toàn có thể khai báo và khởi tạo đồng thời :
0123
intvalue=5;
int*p=và value/ / khai báo con trỏ p và khởi tạo giá trị cho con trỏ là địa chỉ của value
Lưu ý:
- Con trỏ khi khai báo nên được khởi tạo giá trị ngay.
- Con trỏ kiểu
void
là loại biến con trỏ tổng quát, nó có thể nhận địa chỉ của biến bất kỳ ở bất cứ kiểu dữ liệu nào.
01234567891011121314
#include
intmain()
{
intnumber=5;
float*p_int=và number
}
/ / Ouput :
PSG:\c_cources\day_63>g++.\Pointer.cpp
.\Pointer.cpp:Infunction’ int main ( ) ‘:
.\Pointer.cpp:5:19:error:cannotconvert’ int * ‘to’ float * ‘ininitialization
float*p_int=và number
^
- Khởi tạo con trỏ bằng địa chỉ
NULL
nếu chưa cần dùng theo cách sau:int *p = NULL
. Khi đó con trỏNULL
luôn có giá trị0
.
0123456789
#include
intmain()
{
void*p_int=NULL;
printf(” Gia tri cua con tro la % d “,p_int);
}
/ / Output
/ / Gia tri cua con tro la 0
Bản chất của con trỏ trong C
Bạn sẽ hiểu rõ hơn những quyền lực của con trỏ trong phần này, cũng xem ví dụ dưới đây nào :
01234567891011121314151617181920212223242526272829303132333435
36
373839404142434445464748495051525354555657
#include
intmain()
{
/ / Khai báo + khởi tạo biến value = 10
intvalue=10;
/ / Lấy giá trị của biến value
printf(” \ nGia tri cua ` value ` = % d “,value);
/ / Lấy địa chỉ của biến value
printf(” \ nDia tri cua ` value ` = % d “,và value ) ;
printf(” \ n ——————- \ n “);
/ *
Khai báo + khởi tạo biến con trỏ p
có giá trị là địa chỉ của biến value
* /
int*p=và value
/ / Lấy giá trị của con trỏ p
printf(” \ nGia tri cua con tro ` p ` = % d “,p);
/ / Lấy địa chỉ của con trỏ p
printf(” \ nDia tri cua con tro ` p ` = % d “,và p ) ;
/ / Lấy giá trị của biến ma con trỏ p đang trỏ tới dùng toán tử *
printf(” \ nGia tri cua bien ma con tro ` p ` dang tro toi = % d “,*p);
printf(” \ n ——————- \ n “);
/ *
Thay đổi giá trị của biến value trải qua con trỏ p
Giống như hàm scanf ( ) hoàn toàn có thể biến hóa giá trị của biến khi nhận vào địa chỉ ,
con trỏ khi có địa chỉ của 1 biến trọn vẹn hoàn toàn có thể biến hóa giá trị của
biến đó theo cách dưới đây :
* /
/ / Lấy giá trị của biến value
printf(” \ nGia tri cua ` value ` = % d “,value);
/ / Thay đổi giá trị của biến value trải qua ` p `
*p=100;
/ / Lấy giá trị của biến value
printf(” \ nGia tri cua ` value ` = % d “,value);
/ / Lấy giá trị của biến ma con trỏ p đang trỏ tới dùng toán tử *
printf(” \ nGia tri cua bien ma con tro ` p ` dang tro toi = % d “,*p);
printf(” \ n ——————- \ n “);
/ *
Việc lấy giá trị của biến trải qua con trỏ
chỉ là 1 cách khác để lấy được giá trị của biến đó .
* /
value=1000;
/ / Lấy giá trị của biến value
printf(” \ nGia tri cua ` value ` = % d “,value);
/ / Lấy giá trị của biến ma con trỏ p đang trỏ tới dùng toán tử *
printf(” \ nGia tri cua bien ma con tro ` p ` dang tro toi = % d “,*p);
}
Kết quả chạy :
01234567891011121314151617
Gia tri cua ` value ` = 10Dia tri cua ` value ` = 6487580——————-Gia tri cua con tro ` p ` = 6487580Dia tri cua con tro ` p ` = 6487568Gia tri cua bien ma con tro ` p ` dang tro toi = 10——————-Gia tri cua ` value ` = 10Gia tri cua ` value ` = 100Gia tri cua bien ma con tro ` p ` dang tro toi = 100——————-Gia tri cua ` value ` = 1000Gia tri cua bien ma con tro ` p ` dang tro toi = 1000
Qua ví dụ này, bạn hoàn toàn có thể thấy rõ sự đúng đắn của những Kết luận sau đây về con trỏ :
- Địa chỉ của biến
value
chính là giá trị của con trỏp
, đều là6487580
. Lưu ý mỗi lần chạy thì giá trị địa chỉ này có thể khác nhau nhé. - Con trỏ có thể lấy giá trị của biến mà nó đang trỏ tới bằng toán tử
*
:printf("\nDia tri cua con tro
p= %d", *p);
- Con trỏ có thể thay đổi giá trị của biến mà nó đang trỏ tới. Do nó mang địa chỉ của biến, khi đó nó hoàn toàn có quyền thay đổi giá trị của biến đó. Như ở ví dụ trên ta thay đổi giá trị từ 10 lên 100.
Bài học thời điểm ngày hôm nay tất cả chúng ta sẽ chỉ dừng lại ở những kiến thức và kỹ năng phía trên, những bài học kinh nghiệm sau tất cả chúng ta sẽ cùng nhau đi khám phá về mối liên hệ giữa con trỏ với mảng và con trỏ với hàm cũng như cách quản trị bộ nhớ khi thao tác với con trỏ trong C .
Các lỗi thường gặp khi làm việc với con trỏ
Giả sử bạn muốn khởi tạo giá trị của con trỏ p
trỏ tới địa chỉ của biến value
, khi đó:
0123456789101112131415161718
intvalue,*p;
/ / Sai ! p cần địa chỉ cơ ,
/ / value không phải là cái địa chỉ đó .
p=value;
/ / Sai ! * p là giá trị của biến mà con trỏ đang trỏ tới ,
/ / và value là địa chỉ .
*p=và value
/ / Đúng rồi ! p cần 1 địa chỉ ,
/ / và value là địa chỉ của biến value .
p=và value
/ / Đúng ! * p là giá trị của biến mà con trỏ đang trỏ tới, và
/ / c cũng là giá trị ( không phải địa chỉ ) .
*p=value;
Các bạn khi mới học con trỏ sẽ mông lung về dấu *
ở phần khai báo và khi lấy giá trị của biến mà con trỏ đang trỏ tới:
01234567891011121314151617
#include
intmain()
{
intc=5;
/ / Dấu * ở đây để tất cả chúng ta biết tất cả chúng ta đang khai báo con trỏ .
/ / Không phải lấy giá trị của nó nhé
int*p=và c
/ / Khai báo trên tương tự
/ / int * p ;
/ / p = và c
/ / Nếu bạn muốn phân biệt 2 thằng này, khi khai báo hoàn toàn có thể viết như sau :
/ / int * p = và c
/ / Lấy giá chỉ của biến mà con trỏ đang trỏ tới, chính là giá trị của c
printf(” % d “,*p);/ / 5
}
Tài liệu tham khảo
Mặc dù mình đã cố gắng nỗ lực trình diễn tỉ mỉ, nhưng hoàn toàn có thể còn thiếu sót. Dưới đây là 1 số tài liệu bạn nên đọc thêm để hiểu hơn về con trỏ trong C :
Source: http://wp.ftn61.com
Category: Tin Tức
Để lại một bình luận