Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C/C++ 포인터 비교 방법 – 관계 연산자 활용법과 주의사항

C/C++ 포인터 비교의 기본 원리

두 포인터가 같은 배열을 가리키고 있다면 서로 비교할 수 있습니다. 이때 관계 연산자(<, >, <=, >=)를 사용해 두 포인터의 상대적인 위치를 판단합니다. 반면, 포인터는 메모리 주소를 다루는 특수한 변수이기 때문에 일반 숫자처럼 곱셈이나 나눗셈을 수행할 수는 없습니다.

C 언어에서의 포인터 비교

예제 코드

#include <stdio.h>

int main() {
    int *p1;
    int *p2;

    p1 = (int *)200;
    p2 = (int *)300;

    if (p1 > p2) {
        printf("P1 is greater than p2");
    } else {
        printf("P2 is greater than p1");
    }

    return 0;
}

실행 결과

P2 is greater than p1

p1은 200, p2는 300이라는 주소값을 가지므로 'p1 > p2' 조건은 거짓이 되어 else 블록이 실행됩니다.

C++에서의 포인터 비교

예제 코드

#include <iostream>
using namespace std;

int main() {
    int *p1;
    int *p2;

    p1 = (int *)200;
    p2 = (int *)300;

    if (p1 > p2) {
        cout << "P1 is greater than p2";
    } else {
        cout << "P2 is greater than p1";
    }

    return 0;
}

실행 결과

P2 is greater than p1

포인터 비교 시 알아두어야 할 핵심 사항

  • 비교 결과가 확정되는 경우: 같은 타입의 두 포인터 p1과 p2가 같은 객체나 함수를 가리키거나, 같은 배열의 마지막 요소 바로 다음 위치(one past the end)를 가리키거나, 둘 다 null 포인터라면 p1<=p2와 p1>=p2는 모두 참(true)이 되고, p1<p2와 p1>p2는 모두 거짓(false)이 됩니다.
  • 비교 결과가 정의되지 않는 경우: 같은 타입의 두 포인터가 서로 다른 객체(같은 객체의 멤버나 같은 배열의 요소가 아닌 경우)나 서로 다른 함수를 가리키거나, 둘 중 하나만 null이라면 p1<p2, p1>p2, p1<=p2, p1>=p2의 결과는 정의되지 않습니다(unspecified).
  • 멤버 포인터 비교: 두 포인터가 같은 객체의 non-static 데이터 멤버 또는 그 멤버의 하위 객체(subobject)나 배열 요소를 가리키면서 접근 제어(access control) 수준이 동일하다면 비교 결과가 명확하게 정의됩니다.
  • 접근 제어가 다른 경우: 두 포인터가 같은 객체의 non-static 데이터 멤버를 가리키더라도 접근 제어 수준이 서로 다르면 비교 결과는 정의되지 않습니다.

참고로 위 예제는 임의의 정수를 주소로 강제 형변환하여 사용한 학습용 코드입니다. 실제 프로그램에서 유효하지 않은 임의의 주소에 접근하면 정의되지 않은 동작(undefined behavior)이 발생할 수 있으므로 주의해야 합니다.