C++ Primer

표현식

kang057 2024. 6. 26. 21:58

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