4.1 기초
4.1.1 기본 개념
● 연산자 종류 : 단항 연산자 , 이항 연산자
● 연산자와 피연산자를 하나로 묶기
○ 우선 순위와 결합 법칙
● 피연산자 변환
○ 정수 타입 피연산자는 보통 더 큰 정수 타입을 승격한다.
○ 정수 -> 부동소수점 O / 포인터 타입 -> 부동소수점 X
● 다중 정의한 연산자
○ 정의 : 이미 존재하고 있는 연산자 기호에 이런 식으로 다른 의미를 부여하는 것
● 좌변 값과 우변 값
○ 대입에서 왼쪽 피연산자로 (const가 아닌) 좌변 값을 쓰고 왼쪽 피연산자를 좌변 값으로 변환한다.
○ 주소 연산자에서느 좌변 값 피연산자를 쓰고 피연산자에 대한 포인터를 우변 값으로 반환한다.
○ 내장 역참조와 첨자 연산자, 반복자 역참조, string과 vector 첨자 연산자에서는 모두 좌변 값을 반환한다.
○ 내장/반복자 증가, 감소 연산자에서는 좌변 값을 피연산자를 쓰고, 이 연산자와 전위 버전 모든 좌변 값을 반환한다.
4.1.2 우선순위와 결합법칙
● 복합 표현식 : 연산자가 둘 이상인 표현식
● 복합 표현식을 평가할 때는 피연산를 연산자와 묶게 된다. 피연산자를 묶는 방법은 우선순위와 결합법칙을 따른다.
● 괄호로 우선순위와 결합법칙 재정의하기
4.1.3 평가 순서
● 연산자에 평가 순서를 지정하지 않고 표현식에서 같은 객체를 참조하면서 변경하면 오류이다.
● 평가 순서, 우선순위, 결합법칙
○ 피연산자의 평가 순서는 우선순위, 결합칙과 관계 없다.
4.2 산술 연산자
● 단항 산술 연산자는 곱셈과 나눗셈 연산자보다 우선순위가 높으며 차례로 이항 덧셈과 뺄셈 연산자 순이다.
4.3 논리와 관계 연산자
● 관계 연산자에서는 산술 또는 포인터 타입을 피연산자로 취하고 논리 연산자에서는 bool로 변환할 수 있는 모든 타입을 피연산자로 취한다.
● 논리 AND 와 OR 연산자
○ && 연산자에서는 왼편이 true일 때만 오른편을 평가함
○ || 연산자에서는 왼편이 false일 때만 오른편을 평가함
● 논리 NOT 연산자
○ 논리 NOT 연산자에서는 해당 피연산자에 대한 진리 값의 역을 반환한다.
● 관계 연산자
○ 관계 연산자는 일반적으로 사용하는 의미 그대로 이며 bool 값을 반환한다.
● 상등 비교와 bool 상수
○ 산술 또는 포인터 객체의 진리 값을 확인할 떄 가장 직접적인 방법은 그 값을 조건으로 사용하는 것이다.
4.4 대입 연산자
● 대입 연산자에서 왼쪽 피연산자는 반드시 변경할 수 있는 좌변 값이어야 한다.
● 대입은 오른쪽 결합이고 우선 순위가 낮다.
● 상등과 대입 연산자를 헷갈리지 말자
● 복합 대입 연산자
4.5 증가와 감소 연산자
● 증가와 감소 연산자를 사용하면 객체에 1을 더하거나 뺄 때 간편하게 단축해 표기 가능
● 표현식 하나에서 역참조와 증가 결합하기
*(pbeg++);
● 피연산자 평가 순서는 정해져 있지 않음을 기억한다.
4.6 멤버 접근 연산자
● 점과 화살표 연산자를 사용해 멤버에 접근할 수 있다.
● 점 연산자는 클래스 타입 객체에서 멤버를 가져오고 화살표에서는 ptr -> men을 (*ptr).men에 대한 동의어로 정의한다.
string s1 = "a string", *p = &s1;
auto n = s1.size(); // string s1의 size 멤버를 실행한다
n = (*p).size(); // p로 가리키는 객체에 대한 size를 실행한다.
n = p -> size(); // (*p).size()와 같다.
*p.size() // 오류 : p는 포인터이며 size멤버가 없음
4.7 조건 연산자
● 조건 연산자(?)를 사용하면 표현식 안에 간단한 if-else 논리를 넣을 수 있다.
● 조건 연산자는 우선순위가 꽤 낮으므로 큰 표현식에 조건 표현식을 넣을 때는 일반적으로 조건을 나타내는 하위 표현식을 괄호로 둘러싸야 한다.
4.8 비트 연산자
● 비트 연산자에서는 비트 모음으로 사용할 정수 타입을 피연산자로 취한다.
● 비트 이동 연산자
○ 왼쪽 이동 연산자(<<)에서는 오른쪽에 값이 0인 비트를 채운다.
○ 오른쪽 이동 연산자(>>) 동작은 왼쪽 피연산자 타입에 따라 다르다.
● 비트 NOT 연산자
○ 비트 NOT 연산자 (~)에서는 피연산자의 비트를 반전한 새로운 값을 생성한다.
● 비트 AND, OR, XOR 연산자
● 이동 연산자는 왼쪽 결합이다.
4.9 sizeof 연산자
● sizeof 연산자에서는 표현식이나 타입 이름의 크기를 바이트 단위로 반환한다.
● 지정한 표현식에서 반환하는 타입의 크기를 반환한다. sizeof 연산자는 다른 것과 달리 피연산자를 평가하지 않는다.
○ sizeof char 또는 char 타입 표현식은 1임을 보장한다.
○ sizeof 참조자 타입은 참조하는 타입의 객체 크기를 반환한다.
○ sizeof 포인터는 포인터를 담을 수 있는 크기를 반환한다.
○ sizeof 역참조한 포인터는 포인터에서 가리키는 타입의 객체 크기를 반환하는데 그 포인터는 유효하지 않아도 된다.
○ sizeof 배열은 전체 배열 크기이며 이는 sizeof 요소 타입을 얻어 배열 요소 수를 곱한 것과 같다. sizeof에서는 배열을 포인터로 변환하지 않음에 주의한다.
○ sizeof string 또는 vector 타입은 이 타입의 고정 부분에 대한 크기만을 반환하며 해당 객체의 요소에서 사용한 크기는 반환하지 않는다.
4.10 쉼표 연산자
● 쉼표 연산자에서는 피연산자 둘을 취하고 왼쪽에서 오른쪽으로 평가한다.
4.11 타입 변환
● 두 타입이 서로 관련이 있으면, 어떤 타입이 객체 또는 값을 관련 있는 타입인 피연산자를 대신해 쓸 수 있다. 두 타입 사이에 변환이 있으면 그 둘은 관련이 있다.
● 암시적 변환이 일어날때
○ 표현식 대부분에서 int보다 작은 정수 타입 값은 먼저 적합한 더 큰 정수 타입으로 승격한다.
○ 조건에서 bool이 아닌 표현식은 bool로 변환한다.
○ 초기화에서 초기 값은 해당 변수 타입으로 변환한다. 대입에서 오른쪽 피연산자는 왼쪽 피연산자 타입으로 변환한다.
○ 피연산자 타입이 여러 가지인 산술과 관계 표현식에서 각 타입은 공통 타입으로 변환한다.
○ 변환은 함수 호출 과장에서도 일어난다.
4.11.1 산술 변환
● 산술 변환은 어떤 사눗ㄹ 타입을 다른 타입으로 변환한다.
● 정수 승격
○ 정수 승격은 작은 정수 타입을 더 큰 정수 타입으로 변환한다.
● 부호 없는 타입 피연산자
○ 연산자의 피연산자 타입이 서로 다르면 일반적으로 피연산자를 공통 타입으로 변환한다.
○ 부호속성이 다르고 부호 없는 피연산자의 타입이 부호 있는 피연산자의 타입과 같거나 더 크면 부호 있는 피연산자를 부호 없는 타입으로 변환한다.
4.11.2 다른 암시적 변환
● 배열을 포인터로 변환 : 표현식 대부분에서 배열을 사용하면 이 배열은 자동으로 해당 배열의 첫 요소에 대한 포인터로 변환한다.
int arr[10];
int* p = arr;
● 포인터 변환 :
○ 상수 정수 값 0과 상수 nullptr은 어떤 포인터 타입으로도 변환할 수 있다.
○ const가 아닌 타입에 대한 포인터는 void*로 변환할 수 있으며 가리키는 타입에 관계없이 포인터는 const void*로 변환 할 수 있다.
○ 상속과 관계있는 타입에 적용하는 포인터 변환도 있다.
● bool로 변환 : 산술 또는 포인터 타입을 자동으로 bool로 변환한다.
● const로 변환 : const가 아닌 타입에 대한 포인터를 const인 해당 타입에 대한 포인터로 변환할 수 있으며 참조자일 경우에도 비슷하다.
● 클래스 타입에서 정의한 변환 : 클래스 타입에서는 컴파일러에서 자동을 적용할 변환을 정의할 수 있다. 컴파일러에서는 클래스 타입 변환을 한 번에 단 하나만 적용한다.
4.11.3 명시적 변환
● 명시적 변환은 캐스트로 요청한다.
● 명명한 캐스트의 형식
캐스트 - 이름<타입>(표현식);
● static_cast
○ 하위 const를 포함한 변환을 제외하고 모든 명확한 타입 변환은 static_cast를 사용해 요청할 수 있다.
○ static_cast는 흔히 더 큰 산술 타입을 더 작은 타입에 대입할 떄 유용하다.
○ static_cast는 컴파일러에서 자동으로 하지 않는 변환 할 때도 유용하다.
● const_cast
○ const_cast에서는 피연산자의 하위 const만을 변경한다.
○ const_cast는 표현식에서 상수 속성을 변경할 때만 사용할 수 있다.
● reinterpret_cast
○ reinterpret_cast에서는 일반적으로 피연산자 비트 구성 형식을 저수준에서 재해석 한다.
○ reinterpret_cast는 근본적으로 시스템 의존적이다.
'C++ Primer' 카테고리의 다른 글
함수 (0) | 2024.07.02 |
---|---|
문장 (0) | 2024.06.29 |
문자열, 벡터와 배열 (0) | 2024.06.26 |
변수와 기본 타입 (0) | 2024.06.25 |
서론 (0) | 2024.06.24 |