Giả sử tôi có 2 con trỏ:
int *a = something;
int *b = something;
Nếu tôi muốn so sánh chúng và xem liệu chúng có trỏ cùng một nơi không thì (a == b) có hoạt động không?
Giả sử tôi có 2 con trỏ:
int *a = something;
int *b = something;
Nếu tôi muốn so sánh chúng và xem liệu chúng có trỏ cùng một nơi không thì (a == b) có hoạt động không?
Câu trả lời:
Đúng, đó là định nghĩa của bình đẳng con trỏ: cả hai đều trỏ đến cùng một vị trí (hoặc là bí danh con trỏ )
Đối với một chút sự kiện, đây là văn bản có liên quan từ các thông số kỹ thuật
Con trỏ đến các đối tượng cùng loại có thể được so sánh ngang bằng với kết quả mong đợi 'trực quan':
Từ § 5.10 của tiêu chuẩn C ++ 11:
Các con trỏ cùng loại (sau khi chuyển đổi con trỏ) có thể được so sánh cho bằng nhau. Hai con trỏ cùng kiểu so sánh bằng nhau nếu và chỉ khi chúng đều rỗng, cả hai đều trỏ đến cùng một hàm hoặc cả hai đại diện cho cùng một địa chỉ ( 3.9.2 ).
(bỏ qua chi tiết về việc so sánh các con trỏ đến thành viên và hoặc các hằng số con trỏ rỗng - chúng tiếp tục xuống cùng dòng của 'Do What I Mean' :)
- [...] Nếu cả hai toán hạng đều rỗng, chúng sẽ so sánh bằng nhau. Ngược lại, nếu chỉ có một giá trị rỗng, chúng sẽ so sánh không bằng nhau. [...]
Cảnh báo 'dễ thấy' nhất liên quan đến hình ảnh ảo, và nó dường như cũng là điều hợp lý để mong đợi:
- [...] nếu một trong hai là một con trỏ đến một hàm thành viên ảo, kết quả là không xác định. Nếu không, chúng sẽ so sánh bằng nhau nếu và chỉ khi chúng tham chiếu đến cùng một thành viên của cùng một đối tượng dẫn xuất nhất (1.8) hoặc cùng một đối tượng nếu chúng được tham chiếu đến một đối tượng giả định của loại lớp được liên kết. [...]
Từ § 5.9 của tiêu chuẩn C ++ 11:
Có thể so sánh các con trỏ đến các đối tượng hoặc hàm cùng loại (sau khi chuyển đổi con trỏ), với kết quả được xác định như sau:
- Nếu hai con trỏ p và q của điểm cùng loại với cùng một đối tượng hoặc chức năng, hoặc cả hai một thời điểm quá khứ cuối cùng một mảng, hoặc là cả hai null, sau đó
p<=q
vàp>=q
cả năng suất trung thực vàp<q
vàp>q
cả năng suất sai.- Nếu hai con trỏ p và q cùng kiểu trỏ đến các đối tượng khác nhau không phải là thành viên của cùng một đối tượng hoặc các phần tử của cùng một mảng hoặc đến các hàm khác nhau, hoặc nếu chỉ một trong số chúng là rỗng, thì kết quả của
p<q,
p>q,
p<=q,
vàp>=q
là không xác định .- Nếu hai con trỏ trỏ đến các thành viên dữ liệu không tĩnh của cùng một đối tượng, hoặc đến các subobject hoặc các phần tử mảng của các thành viên đó, theo cách đệ quy, con trỏ đến thành viên được khai báo sau sẽ so sánh lớn hơn với điều kiện hai thành viên có cùng quyền kiểm soát truy cập (Điều 11) và miễn là lớp của họ không phải là một công đoàn.
- Nếu hai con trỏ trỏ đến các thành viên dữ liệu không tĩnh của cùng một đối tượng có điều khiển truy cập khác nhau (Điều 11) thì kết quả là không xác định.
- Nếu hai con trỏ trỏ đến các thành viên dữ liệu không tĩnh của cùng một đối tượng liên hợp, chúng sẽ so sánh bằng nhau (sau khi chuyển đổi thành
void*
, nếu cần). Nếu hai con trỏ trỏ đến các phần tử của cùng một mảng hoặc một con trỏ nằm ngoài phần cuối của mảng, thì con trỏ đến đối tượng có chỉ số con cao hơn sẽ so sánh cao hơn.- Các so sánh con trỏ khác là không xác định.
Vì vậy, nếu bạn có:
int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined
Cũng được:
struct X { int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined
Nhưng nó phụ thuộc vào something
câu hỏi của bạn:
int g;
int main()
{
int h;
int i;
int *a = &g;
int *b = &h; // can't compare a <=> b
int *c = &i; // can't compare b <=> c, or a <=> c etc.
// but a==b, b!=c, a!=c etc. are supported just fine
}
§ 20.8.5 / 8 : "Đối với các mẫu greater
, less
, greater_equal
, và less_equal
, các chuyên ngành cho bất kỳ loại con trỏ mang lại một trật tự tổng, thậm chí nếu được xây dựng trong các nhà khai thác <
, >
, <=
, >=
không có."
Vì vậy, bạn có thể đặt hàng toàn cầu bất kỳ số lẻ nào void*
miễn là bạn sử dụng std::less<>
và bạn bè, không phải để trần operator<
.
int *a = arr;
lợi ích dòng từ bao gồm một tham chiếu đến stackoverflow.com/questions/8412694/address-of-array ? Tôi không chắc chắn nếu nó là đủ liên quan đến câu hỏi hỏi mặc dù ...
<functional>
. Thêm.
Các ==
nhà điều hành trên con trỏ sẽ so sánh địa chỉ số của họ và do đó xác định xem họ trỏ đến cùng một đối tượng.
Tóm lại. Nếu chúng ta muốn xem liệu hai con trỏ trỏ đến cùng một vị trí bộ nhớ, chúng ta có thể làm điều đó. Ngoài ra, nếu chúng ta muốn so sánh nội dung của bộ nhớ được trỏ đến bởi hai con trỏ, chúng ta cũng có thể làm điều đó, chỉ cần nhớ tham khảo chúng trước.
Nếu chúng ta có
int *a = something;
int *b = something;
là hai con trỏ cùng loại, chúng ta có thể:
So sánh địa chỉ bộ nhớ:
a==b
và so sánh nội dung:
*a==*b
Mã đơn giản để kiểm tra răng cưa con trỏ:
int main () {
int a = 10, b = 20;
int *p1, *p2, *p3, *p4;
p1 = &a;
p2 = &a;
if(p1 == p2){
std::cout<<"p1 and p2 alias each other"<<std::endl;
}
else{
std::cout<<"p1 and p2 do not alias each other"<<std::endl;
}
//------------------------
p3 = &a;
p4 = &b;
if(p3 == p4){
std::cout<<"p3 and p4 alias each other"<<std::endl;
}
else{
std::cout<<"p3 and p4 do not alias each other"<<std::endl;
}
return 0;
}
Đầu ra:
p1 and p2 alias each other
p3 and p4 do not alias each other
So sánh các con trỏ không phải là di động, ví dụ: trong DOS các giá trị con trỏ khác nhau trỏ đến cùng một vị trí, so sánh các con trỏ trả về false.
/*--{++:main.c}--------------------------------------------------*/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int val_a = 123;
int * ptr_0 = &val_a;
int * ptr_1 = MK_FP(FP_SEG(&val_a) + 1, FP_OFF(&val_a) - 16);
printf(" val_a = %d -> @%p\n", val_a, (void *)(&val_a));
printf("*ptr_0 = %d -> @%p\n", *ptr_0, (void *)ptr_0);
printf("*ptr_1 = %d -> @%p\n", *ptr_1, (void *)ptr_1);
/* Check what returns the pointers comparison: */
printf("&val_a == ptr_0 ====> %d\n", &val_a == ptr_0);
printf("&val_a == ptr_1 ====> %d\n", &val_a == ptr_1);
printf(" ptr_0 == ptr_1 ====> %d\n", ptr_0 == ptr_1);
printf("val_a = %d\n", val_a);
printf(">> *ptr_0 += 100;\n");
*ptr_0 += 100;
printf("val_a = %d\n", val_a);
printf(">> *ptr_1 += 500;\n");
*ptr_1 += 500;
printf("val_a = %d\n", val_a);
return EXIT_SUCCESS;
}
/*--{--:main.c}--------------------------------------------------*/
Biên dịch nó theo Borland C 5.0, đây là kết quả:
/*--{++:result}--------------------------------------------------*/
val_a = 123 -> @167A:0FFE
*ptr_0 = 123 -> @167A:0FFE
*ptr_1 = 123 -> @167B:0FEE
&val_a == ptr_0 ====> 1
&val_a == ptr_1 ====> 0
ptr_0 == ptr_1 ====> 0
val_a = 123
>> *ptr_0 += 100;
val_a = 223
>> *ptr_1 += 500;
val_a = 723
/*--{--:result}--------------------------------------------------*/