[C++] Misc.

CS/C/C++ 2009. 1. 18. 17:50
Size
1 ≡ sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤sizeof(long)
1 ≤ sizeof(bool) ≤ sizeof(long)
sizeof(char) ≤ sizeof(wchar_t) ≤ sizeof(long)
sizeof(float) ≤ sizeof(double) ≤ sizeof(long double)
sizeof(N) ≡ sizeof(signed N) ≡ sizeof(unsigned N)

cf) limit 확인
  
#include <limits>
// ...
numeric_limits<float>::max();
// ...

Declator
* pointer  prefix
*const constant pointer  prefix 
reference  prefix 
[] array  postfix 
()  function  postfix 
postfix 선언자는 prefix 보다 더 강하게 결합한다. *kings[]는 포인터의 벡터.


전역 변수 접근
지역 변수는 접근할 수 없지만, 숨겨진 전역 변수는 다음과 같이 접근 가능하다.
  
int x;

void f2()
{
	int x = 1; // hide global x
	::x = 2; // assign to global x
	x = 2; // assign to local x
	// ...
}

초기화
초기화값이 지정되지 않은 global, namespace, local static은 적당한 타입의 0으로 초기화된다.


wide character prefix
L"angst"와 같이 L prefix는 wide character를 나타낸다.


constant variable
const 키워드는 객체를 상수로 선언하기 위해 객체의 선언에 추가될 수 있다.
const int x = 10;
extern const int x;
를 헤더파일에 선언할 수 있음. (const 가 아닌경우 중복 정의)


pointing constant pointer
constant가 아닌 pointer로 constant인 pointer를 pointing할 수 없다.

 
void f()
{
	int a = 1;
	const int c = 2;
	const int* p1 = &c; 	// ok
	const int* p2 = &a; 	// ok
	int* p3 = &c; 		// error
}

참조형 초기화
일반 T&의 초기값 T형의 lvalue여야 하지만, 
const T&의 초기값은 다음과 같은 경우에 T형의 lvalue를 필요로 하지 않는다.
[1] 묵시적으로 T형으로의 형변환이 일어난 후
[2] T 형의 임시 변수에 결과값이 대입되고
[3] 임시 변수가 초기값으로 사용된다.

double& dr = 1; // error : lvalue needed
const double& cdr = 1; // ok

두번째 초기화는 다음과 같은 해석이 일어날 것이다.
double temp = double(1);
const double& cdr = temp;

임시로 생성된 값은 참조 범위가 끝날때까지 영속한다.


형변환
  
void f()
{
	void* pv = pi; 	// ok: implicit conversion of int* to void*
	*pv; 			// error : can't dereference void*
	pv++; 		// error : cna't increment void*
	
	int* pv2 = static_cast<int*>(pv); 		// explicit conversion back to int*
	
	double* pd1 = pv; 					// error
	double* pd2 = pi; 					// error
	double* pd3 = static_cast<double*>(pv); 	// unsafe
}
다른 type의 객체를 가리키는 포인터를 "cast"하는 것은 안전하지 못하다.
int형을 double로 cast 하는 경우, 일반적으로 int형은 4바이트 경계, double형은 8바이트 경계를 갖기 때문에 잘못된 결과를 가지게 된다.


구조체 맴버에서의 구조체 이름 사용
구조체의 type은 선언한 후 바로 사용 가능하지만, 새로운 객체의 생성은 그 구조체의 선언이 완전히 끝난 후에야 가능하다.

  
struct Link {
	Link* prev;	// ok
	Link* next;	// ok
	Link member;	// error: recursive definition
}
: