c++

C++ Primer CH4. Expressions

big whale 2024. 1. 21. 16:11

Lvalues and Rvalues

  • 모든 표현식은 rvalue거나 lvalue이다.
  • lvalue: 주소를 나타내는 표현식. 
  • rvalue: 값을 나타내는 표현식. 

object를 lvalue로 쓰면 memory 위치를 사용하는 것과 같고, rvalue로 쓰면 값(내용물)을 사용하는 것과 같다.

decltype과 lvalue, rvalue간의 관계

 

할당은 오른쪽 결합이다(right associative)

int ival, jval;
ival = jval = 0; //ok

int *pval;
ival = pval = 0; // error, pval이 포인터라서 ival에 할당 안됨.

 

전위 증가와 후위 증가

int i = 0, j = 0;
j = ++i; // i를 증가시키고 그 자체 반환, 반환값lvalue
j = i++; // i값을 반환하고 i 증가. 반환값rvalue

 

연산자는 아무 순서대로 평가된다

*beg = toupper(*beg++) // beg를 대문자로 바꾸고 ++ 하고 beg을 역참조해서 할당하는데 이 순서가
// 정해져 있지 않다. undefined behavior

4.8 Bitwise 연산자

~ : NOT
<< : left shift
>>: right shift
&: AND
^: XOR // 두 비트 중 하나만 1인 경우 1
|: OR

bitwise 연산자 사용할 땐 unsigned 값일 때만 사용한다

 

shift 연산은 왼쪽 결합이다

cout << 42 << 10;

 

operators

  • sizeof
  • comma

4.11 Type Conversions

Implicit conversion(묵시적 형변환)

  • 프로그래머의 의도와는 상관없이 c++이 자동으로 공통 타입으로 변환해주는 것
  • 가능하다면 정확도를 보존하는 방향으로 변환됨
  • 초기화하려는 오브젝트의 타입이 절대적이다.
int ival = 3.541 + 3; // 6
  • int보다 작은 정수 타입은 int로 바뀐다.
  • int보다 큰 정수 타입 있으면 그걸로 바뀐다.
  • 정수타입, 소수타입 있으면 소수타입으로 변한다.

pointer conversion

  • 0 → nullptr

등등

 

Explicit Conversions(명시적 형변환)

명시적으로 오브젝트의 타입을 다른 타입으로 전환하는 것.

언제 하는지

int i, j;
double slope = i/j; // 둘 다 int라서 int 결과가 반환되어 slope에 할당된다.

double slope = (double)i/j; // 소수점까지 살린다.

Named Casts

  • cast-name<type>(expression);

static_cast

  • 특정 타입을 사용하는 것을 강제하고 싶을 때
  • 큰 타입의 수를 작은 타입으로 변환하고 싶을 때 사용하면, 컴파일러가 경고 메시지 안띄운다.
  • 컴파일러가 자동으로 형변환 안해줄 때 사용하면 좋다.
double slope = static_cast<double>(j) // 특정 타입으로 강제
void* p = &d;
double *dp = static_cast<double*>(p); // 컴파일러가 안해줄 때. 실제 포인터 타입과 같아야 함.

 

const_cast

  • const를 떼버리는 named cast
  • 오직 low-level const만 바꾼다.
  • const 뗀 다음 write하면 undefined behavior이다.
  • 표현식의 constness를 제거하기 위한 목적으로 사용한다.
  • overloaded 함수 context에서 사용하면 유용하다.
const char *cp;
char *q = static_cast<char*>(cp); // error: static_cast는 const 못뗀다.
static_cast<string>(cp); // ok: string 리터럴을 string으로 바꾸기 가능.
const_cast<string>(cp); // error: constness만 변경 가능.

 

reinterpret_cast

  • 저수준 메모리 조작 필요할 경우.
  • 서로 다른 타입인데도 변경이 가능함.
  • 안전성 검사가 없는 강력한 캐스트
  • 포인터간 변화에 사용
int *ip;
char *pc = reinterpret_cast<char*>(ip);
string str(pc); // 아무 에러 안일어남. -> 심각한 런타임 에러 발생 가능

 

old-style cast

char *pc = (char*) ip;

눈에 안띄어서 보기 힘듦