Bạn đã học từ chương trước rằng chúng ta có thể lấy địa chỉ bộ nhớ của một biến bằng toán tử tham chiếu &
Thí dụ
int myAge = 43;
printf["%d", myAge];
printf["%p", &myAge]; // Outputs the memory address of myAge [0x7ffe5367e044]
Trong ví dụ trên, &myAge
còn được gọi là con trỏ
Con trỏ là một biến lưu trữ địa chỉ bộ nhớ của một biến khác làm giá trị của nó
Một biến con trỏ trỏ đến một kiểu dữ liệu [như int
] cùng loại và được tạo bằng toán tử *
. Địa chỉ của biến bạn đang làm việc được gán cho con trỏ
Thí dụ
// Xuất giá trị của myAge [43]
printf["%d\n", myAge];
// Xuất địa chỉ bộ nhớ của myAge [0x7ffe5367e044]
printf["%p\n", &myAge];
// Xuất địa chỉ bộ nhớ của myAge bằng con trỏ [0x7ffe5367e044]
printf["%p\n", ptr];
Ví dụ giải thích
Tạo một biến con trỏ có tên ptr
, trỏ đến một biến int
[myAge
]. Lưu ý rằng loại con trỏ phải khớp với loại biến bạn đang làm việc với
Sử dụng toán tử &
để lưu địa chỉ bộ nhớ của biến myAge
và gán nó cho con trỏ
Bây giờ, ptr
giữ giá trị địa chỉ bộ nhớ của myAge
quy định
Trong ví dụ trên, chúng ta đã sử dụng biến con trỏ để lấy địa chỉ bộ nhớ của một biến [được sử dụng cùng với toán tử tham chiếu &
]
Tuy nhiên, bạn cũng có thể lấy giá trị của biến mà con trỏ trỏ tới, bằng cách sử dụng toán tử *
[toán tử quy ước]
Thí dụ
int myAge = 43;
int* ptr = &myAge; // Pointer declaration
//Tham khảo. Xuất địa chỉ bộ nhớ của myAge bằng con trỏ [0x7ffe5367e044]
printf["%p\n", ptr];
// Dereference. Xuất giá trị của myAge bằng con trỏ [43]
printf["%d\n", *ptr];
Lưu ý rằng dấu hiệu *
có thể gây nhầm lẫn ở đây, vì nó thực hiện hai điều khác nhau trong mã của chúng tôi
- Khi được sử dụng trong khai báo [
&myAge
4], nó tạo ra một biến con trỏ - Khi không được sử dụng trong khai báo, nó hoạt động như một toán tử quy ước
tốt để biết. Có 3 cách khai báo biến con trỏ nhưng cách thứ nhất được sử dụng nhiều nhất
int* myNum;
int *myNum;
int * myNum;
Tại sao tôi nên tìm hiểu về con trỏ?
Con trỏ là một trong những điều khiến C nổi bật so với các ngôn ngữ lập trình khác, như Python và Java
Chương này chỉ là một phần giới thiệu ngắn về Con trỏ. Chúng rất quan trọng trong C, vì chúng cung cấp cho bạn khả năng thao tác dữ liệu trong bộ nhớ của máy tính - điều này có thể làm giảm mã và cải thiện hiệu suất. Tuy nhiên, con trỏ phải được xử lý cẩn thận vì có thể làm hỏng dữ liệu được lưu trữ trong các địa chỉ bộ nhớ khác
Con trỏ trong C rất dễ học một số tác vụ trong ngôn ngữ C được thực hiện bằng cách sử dụng con trỏ. Và một số tác vụ như cấp phát bộ nhớ động chỉ được thực hiện bằng cách sử dụng con trỏ. Vì vậy, nó là điều cần thiết để tìm hiểu con trỏ. POINTER là biến lưu địa chỉ của biến kia. Một con trỏ cũng được dùng để chỉ một hàm con trỏ. Và con trỏ có thể được tăng hoặc giảm, nghĩa là nếu con trỏ được tăng lên thì nó trỏ đến vị trí tiếp theo và nếu con trỏ bị giảm thì nó trỏ đến vị trí bộ nhớ trước đó. Mục tiêu của con trỏ là tiết kiệm không gian bộ nhớ và thực hiện nhanh hơn. Và kích thước của con trỏ trong C là 8 byte nhưng trên máy 32 bit, chúng chiếm tới 4 byte
Con trỏ hoạt động như thế nào?
- Nếu chúng ta khai báo một biến Y kiểu Integer[Int] thì Y sẽ thực sự lưu trữ giá trị
số nguyên Y= 1;
Y bây giờ bằng một
- Tuy nhiên, mọi biến đều có cả giá trị và địa chỉ và địa chỉ đó có thể được truy xuất bằng cách đặt dấu và trước tên biến như thế này
"&Y"
- Nếu bạn sẵn sàng in địa chỉ của một biến thì địa chỉ đó có thể là một số ngẫu nhiên và số ngẫu nhiên đó sẽ khác bất cứ khi nào bạn chạy chương trình của mình. có nghĩa là cùng một chương trình có thể cho kết quả đầu ra khác nhau
Thí dụ
#bao gồm
int chính []
{
intY=1;
printf[“%d”, &Y];
trả về 0;
}
đầu ra. 123756948 và nếu bạn chạy cùng một mã lần thứ hai, đầu ra có thể khác
Nói một cách đơn giản, giá trị lưu trữ biến và con trỏ lưu trữ địa chỉ của biến
Khai báo con trỏ
Giống như biến, con trỏ cần được khai báo trước khi sử dụng nó trong chương trình. Chúng ta có thể đặt tên cho con trỏ bất cứ thứ gì miễn là chúng tuân theo quy tắc đặt tên của C
cú pháp. Kiểu_dữ_liệu *tên_biến_con_trỏ;
Thí dụ. int*a;
Khởi tạo một con trỏ
Sau khi khai báo con trỏ, chúng ta phải khởi tạo con trỏ với địa chỉ biến chuẩn
Nếu con trỏ không được khởi tạo thì có thể có vấn đề ở đầu ra
cú pháp. con trỏ = biến;
Thí dụ. p= &a;
Con trỏ rỗng
Một con trỏ trỏ đến không có gì được gọi là con trỏ Null. Một số ưu điểm của con trỏ Null là
Chúng ta có thể khởi tạo một biến con trỏ khi biến con trỏ đó không được gán bất kỳ địa chỉ bộ nhớ thực tế nào
Chúng ta có thể chuyển một con trỏ null đến một đối số hàm khi chúng ta không sẵn sàng chuyển bất kỳ địa chỉ bộ nhớ thực tế nào
ví dụ 1
int * aInt = NULL;
ví dụ 2
vui vẻ int [int * ptr]
{
trả lại 15;
}
vui vẻ[NULL];
ví dụ 3
tôi xỉu. = KHÔNG]
{ //một số mã}
khác
{//một số mã}
Con trỏ trống
Con trỏ void trong C là con trỏ không liên kết với bất kỳ kiểu dữ liệu nào. Điều này trỏ đến một số vị trí dữ liệu trong bộ lưu trữ có nghĩa là trỏ đến địa chỉ đó của các biến. Nó còn được gọi là con trỏ đa năng. Trong C, hàm malloc[] và calloc[] trả về void * hoặc con trỏ chung
Thí dụ
intx=10;
char y= ‘a’;
void *p= &x //con trỏ void chứa địa chỉ của int x
p = &y //bỏ con trỏ giữ của char y
Con trỏ hoang dã
Con trỏ không được khởi tạo được gọi là con trỏ hoang dã. Con trỏ này có thể được khởi tạo thành giá trị rác không phải NULL, giá trị này có thể không phải là địa chỉ hợp lệ.
Thí dụ
int chính []
{
int *p;
*p=10;
}
Hãy nhớ rằng nếu một con trỏ p trỏ đến bất kỳ biến đã biết nào, thì đó không phải là một con trỏ hoang dã. Trong chương trình dưới đây p là một con trỏ hoang dã cho đến khi nó trỏ tới x
int chính []
{
int = *p;
intx=20;
p= &x // p bây giờ không phải là một con trỏ hoang dã
}
Con trỏ lủng lẳng
Một con trỏ trỏ đến một vị trí bộ nhớ đã bị xóa được gọi là con trỏ lơ lửng.
ví dụ 1
Phân bổ bộ nhớ
#bao gồm
#bao gồm
int chính []
{
int *ptr = [int *]malloc[sizeof[int]];
miễn phí [ptr];
ptr = NULL;
}
ví dụ 2
gọi hàm
#bao gồm
int *vui vẻ[]
{
int y= 15;
trả lại &y
}
int chính []
{
int *p = func[]
tuôn ra [stdin]
printf[“%d”, *p];
trả về 0;
}
Con trỏ phức tạp
Trước khi biết cách đọc các con trỏ phức tạp, trước tiên bạn nên biết tính kết hợp và mức độ ưu tiên
tính liên kết. Các toán tử thứ tự có mức độ ưu tiên như nhau trong một biểu thức được sử dụng
Quyền ưu tiên. Toán tử ưu tiên mô tả thứ tự mà C đọc các biểu thức
Nhà điều hành
Quyền ưu tiên
liên kết
[],[]
1
trái sang phải
*,Số nhận dạng
2
Phải sang trái
Loại dữ liệu
3
–
- []. Toán tử này được sử dụng để khai báo và định nghĩa hàm
[]. đây là một toán tử chỉ số mảng
*. đây là toán tử con trỏ
định danh. đây là tên của một con trỏ
Loại dữ liệu. đây là loại biến.
Thí dụ
int [*p][int [*][3], int [*]void]]
gần con trỏ
- Con trỏ gần có nghĩa là một con trỏ được sử dụng cho địa chỉ bit lên đến 16 bit trong một phần nhất định của bộ nhớ máy tính được kích hoạt 16 bit
- Nó chỉ có thể truy cập dữ liệu có kích thước nhỏ khoảng 64 kb trong một khoảng thời gian nhất định, đây là nhược điểm chính của loại con trỏ này
Thí dụ
#bao gồm
int chính []
{
inta=300;
int gần * ptr;
ptr= &a;
printf[“%d”,sizeof ptr];
trả về 0;
}
đầu ra. 3
con trỏ xa
- Một con trỏ xa thường là 32 bit có thể truy cập bộ nhớ bên ngoài phân đoạn hiện tại đó.
- Để sử dụng con trỏ xa, trình biên dịch cho phép một thanh ghi đoạn lưu địa chỉ đoạn, sau đó một thanh ghi khác lưu phần bù bên trong đoạn hiện tại
Thí dụ.
#bao gồm
int chính []
{
inta=10;
int xa *ptr;
ptr=&a;
print[“%d”, sizeof ptr];
trả về 0;
}
con trỏ khổng lồ
- Tương tự như con trỏ xa, con trỏ lớn cũng thường là 32 bit có thể truy cập bên ngoài phân khúc
- Một con trỏ xa được cố định và do đó, một phần của khu vực mà chúng nằm trong đó không thể thay đổi theo bất kỳ cách nào;
Thí dụ
#bao gồm
int chính []
{
char khổng lồ *xa *a;
printf[“%d%d%d”, sizeof[a], size[*a], sizeof[**a]];
trả về 0;
}
đầu ra. 4 4 1
Con trỏ cấu trúc
- Con trỏ có thể được sử dụng để chỉ một cấu trúc theo địa chỉ của nó. Điều này giúp truyền các cấu trúc cho một hàm
- Con trỏ có thể được hủy đăng ký bởi toán tử *
- Toán tử -> dereferences con trỏ sang toán hạng bên trái và sau đó truy cập giá trị của một thành viên của toán hạng bên phải
Ưu điểm của con trỏ trong C
- Con trỏ cho phép quản lý các cấu trúc được cấp phát bộ nhớ động
Con trỏ cho phép truyền địa chỉ của cấu trúc thay vì toàn bộ cấu trúc cho các hàm.
Kiểu dữ liệu của con trỏ trong C là gì?
Con trỏ là một biến lưu trữ địa chỉ bộ nhớ của một biến khác làm giá trị của nó. Biến con trỏ trỏ đến kiểu dữ liệu [như int ] cùng kiểu và được tạo bằng toán tử *.Có con trỏ this trong C không?
Master C và Lập trình C nhúng- Học khi bạn đi . Con trỏ this là một tham số ẩn cho tất cả các hàm thành viên. Do đó, bên trong một hàm thành viên, this có thể được sử dụng để chỉ đối tượng gọiC++ này là loại con trỏ gì?
Loại con trỏ 'this' trong C++ Trong C++, con trỏ this tham chiếu đến đối tượng hiện tại của lớp và chuyển nó làm tham số cho một phương thức khác. 'this pointer' is passed as a hidden argument to all non-static member function calls.Tại sao con trỏ này được sử dụng?
Con trỏ 'this' được được truyền dưới dạng đối số ẩn cho tất cả lệnh gọi hàm thành viên không tĩnh và có sẵn dưới dạng biến cục bộ trong phần thân . Con trỏ 'this' không khả dụng trong các hàm thành viên tĩnh vì các hàm thành viên tĩnh có thể được gọi mà không cần bất kỳ đối tượng nào [với tên lớp].