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;
눈에 안띄어서 보기 힘듦