2 개의 포인터가 있다고 가정합니다.
int *a = something;
int *b = something;
내가 그들을 비교하고 그들이 같은 장소를 가리키는 지 확인하고 싶다면 (a == b) 작동합니까?
답변:
예, 이것이 포인터 동등성의 정의입니다. 둘 다 동일한 위치를 가리 킵니다 (또는 포인터 별칭 임).
여기에 약간의 사실 은 사양의 관련 텍스트입니다.
동일한 유형의 객체에 대한 포인터는 '직관적 인'예상 결과와 동일한 지 비교할 수 있습니다.
에서 § 5.10 은 C ++ 11 표준 :
동일한 유형의 포인터 (포인터 변환 후)가 동일한 지 비교할 수 있습니다. 동일한 유형의 두 포인터는 둘 다 null이거나 둘 다 동일한 함수를 가리 키거나 둘 다 동일한 주소 ( 3.9.2 )를 나타내는 경우에만 동일하게 비교됩니다 .
(멤버 및 또는 널 포인터 상수에 대한 포인터 비교에 대한 세부 정보는 제외- '내가 의미하는 바를 수행'의 동일한 행 아래로 계속됩니다.)
- [...] 두 피연산자가 모두 null이면 동일하게 비교됩니다. 그렇지 않으면 하나만 null이면 같지 않음을 비교합니다. [...]
가장 '눈에 띄는'경고는 가상과 관련이 있으며 예상 할 수있는 논리적 인 것 같습니다.
- [...] 둘 중 하나가 가상 멤버 함수에 대한 포인터이면 결과는 지정되지 않습니다. 그렇지 않으면, 가장 많이 파생 된 동일한 객체 (1.8)의 동일한 멤버를 참조하는 경우에만 동일하게 비교하거나 연관된 클래스 유형의 가상 객체로 역 참조 된 경우 동일한 하위 객체를 참조하는 경우에만 동일하게 비교합니다. [...]
에서 § 5.9 은 C ++ 11 표준 :
동일한 유형의 객체 또는 함수에 대한 포인터 (포인터 변환 후)를 다음과 같이 정의 된 결과와 비교할 수 있습니다.
- 두 개의 포인터 (P)과 같은 물체 또는 함수 또는 동일한 어레이의 끝을지나 두 지점 중 하나에 동일한 유형 점 Q 또는 그 둘 NULL의 경우
p<=q와p>=q모두 참 수율p<q및p>q양 수율 거짓.- 동일한 유형의 두 포인터 p와 q가 동일한 객체의 구성원이 아닌 다른 객체 나 동일한 배열의 요소 또는 다른 함수를 가리 키 거나 둘 중 하나만 null 인 경우
p<q,p>q,p<=q,및 의 결과p>=q는 지정되지 않습니다 .- 두 개의 포인터가 동일한 객체의 비 정적 데이터 멤버 나 해당 멤버의 하위 객체 또는 배열 요소를 재귀 적으로 가리키면 나중에 선언 된 멤버에 대한 포인터는 두 멤버가 동일한 액세스 제어를 갖는 경우 더 크게 비교됩니다 (11 절). 그들의 클래스가 노조가 아니라면.
- 두 포인터가 액세스 제어가 다른 동일한 객체의 비 정적 데이터 멤버를 가리키는 경우 (Clause 11) 결과는 지정되지 않습니다.
- 두 포인터가 동일한 공용체 객체의 비 정적 데이터 멤버를 가리키는 경우 동일하게 비교합니다 (
void*필요한 경우로 변환 한 후 ). 두 포인터가 동일한 배열의 요소를 가리 키거나 배열의 끝을 벗어난 요소를 가리키면 아래 첨자가 더 높은 개체에 대한 포인터가 더 높게 비교됩니다.- 다른 포인터 비교는 지정되지 않습니다.
따라서 다음과 같은 경우 :
int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined
또한 확인 :
struct X { int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined
그러나 something귀하의 질문 에 따라 다릅니다 .
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 "템플리트 greater, less, greater_equal, 그리고 less_equal, 어떤 포인터 유형에 대한 전문 내장 사업자 짝수 경우, 전체 순서를 얻을 <, >, <=, >=하지 않습니다."
그래서, 당신은 맨손이 아닌 친구와 사용 하는 한 전 세계적으로 이상한 것을 주문할 수 있습니다 .void*std::less<>operator<
int *a = arr;라인에 stackoverflow.com/questions/8412694/address-of-array에 대한 참조를 포함하면 이점이 있습니까? 나는 아니에요 확인은 관련 충분한 질문에 경우는 ...하지만 질문
<functional>. 추가되었습니다.
포인터 앨리어싱을 확인하는 간단한 코드 :
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;
}
산출:
p1 and p2 alias each other
p3 and p4 do not alias each other
포인터를 비교하는 것은 이식 가능하지 않습니다. 예를 들어 DOS에서 다른 포인터 값이 같은 위치를 가리키고 포인터를 비교하면 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}--------------------------------------------------*/
Borland C 5.0에서 컴파일하면 결과는 다음과 같습니다.
/*--{++: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}--------------------------------------------------*/