C++에서 & 기호는 연산자로 사용되며, 크게 두 가지 상황에서 쓰입니다. 하나는 비트별 AND(Bitwise AND) 연산자이고, 다른 하나는 주소 연산자(Address-of Operator)입니다.
비트별 AND (Bitwise AND)
비트별 AND 연산자(&)는 첫 번째 피연산자의 각 비트를 두 번째 피연산자의 같은 자리 비트와 비교합니다. 두 비트가 모두 1이면 결과 비트는 1로 설정되고, 그렇지 않으면 0으로 설정됩니다. 이때 비트별 AND 연산자의 양쪽 피연산자는 반드시 정수 계열(integral type)이어야 합니다.
예제
#include <iostream>
using namespace std;
int main() {
unsigned short a = 0x5555; // 0101... 패턴
unsigned short b = 0xAAAA; // 1010... 패턴
cout << hex << (a & b) << endl;
}실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
0
0x5555(0101...)와 0xAAAA(1010...)는 서로 대응되는 모든 비트가 정반대이므로, AND 연산 시 겹치는 1비트가 없어 결과가 0이 됩니다.
주소 연산자 (Address Of Operator)
C++는 포인터 관련 연산자로 주소 연산자(&)와 역참조 연산자(간접 참조 연산자, *) 두 가지를 제공합니다.
포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 즉, 한 변수의 주소를 담고 있는 변수는 그 변수를 "가리킨다(point to)"고 표현합니다. 포인터가 가리키는 대상은 객체나 구조체, 심지어 포인터 자신을 포함해 어떤 데이터 타입이든 될 수 있습니다.
주소 연산자(&)는 *와 상반되는 역할을 하는 단항 연산자로, 피연산자로 지정된 변수의 메모리 주소를 반환합니다.
예제
#include <iostream>
using namespace std;
int main() {
int var;
int *ptr;
int val;
var = 3000;
// var의 주소를 ptr에 저장
ptr = &var;
// ptr이 가리키는 위치의 값을 읽어옴
val = *ptr;
cout << "var의 값 : " << var << endl;
cout << "ptr의 값 : " << ptr << endl;
cout << "val의 값 : " << val << endl;
return 0;
}실행 결과
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 출력됩니다.
var의 값 : 3000 ptr의 값 : 0xbff64494 val의 값 : 3000
ptr에는 var의 실제 메모리 주소가 저장되며, *ptr을 통해 그 주소에 들어 있는 값(3000)에 접근할 수 있습니다. 정리하면 &는 변수의 주소를 얻을 때, *는 해당 주소에 저장된 값을 읽을 때 사용됩니다.