[과제 소개]
들어온 인자를 타입별(char, int, float, double)로 변환하여 출력하는 프로그램을 작성한다.
받은 인자의 리터럴 타입을 감지할 수 있어야하며, 예시는 다음과 같다.
char
literal values: ‘c’, ‘a’…int
literal values: 0, -42, 42…float
literal values: 0.0f, -4.2f, 4.2f… -inff, +inff, nanfdouble
literal values: 0.0, -4.2, 4.2… -inf, +inf, naninf
, nan
이란?
inf
는 무한대값을 의미한다.
nan
(Not A Number) 은 "숫자가 아님"을 의미하며, 그 결과를 숫자로 표현할 수 없는 계산을 수행할 때 얻게 되는 float value 이다. NaN을 사용하여 수행하는 모든 계산도 NaN으로 귀결된다.
>>> 2*float("inf")
inf
>>> -2*float("inf")
-inf
>>> float("inf")-float("inf")
nan
/convert 0
char: Non displayable
int: 0
float: 0.0f
double: 0.0
./convert nan
char: impossible
int: impossible
float: nanf
double: nan
./convert 42.0f
char: '*'
int: 42
float: 42.0f
double: 42.0
허용 함수
stoi()
, stof()
, stod()
: 각각 string을 int, float, double로 변환한다.형변환의 의도를 더 잘 표현하기 위해 상황에 맞는 4가지 형변환이 존재한다. 요구한 형 변환이 적절한 경우에는 형 변환된 데이터를 반환하지만, 요구한 형 변환이 적절하지 않은 경우 컴파일시 에러가 발생한다.
<Type>
: 변환하고자 하는 자료형. 객체의 포인터
또는 참조형
이 와야한다.(expression)
: 변환의 대상static_cast<T>(expr)
기본 자료형 데이터간의 형변환에 사용한다.
암시적 형변환이 가능할 때 static_cast로 명시적 형변환을 시켜줄 수 있다.
포인터 타입(expr
)을 다른 것(<T>
)으로 변환하는 것은 허용하지 않지만 상속 관계에 있는 포인터끼리 변환은 가능하다.
static_cast<기초클래스>(파생클래스)
)시에는 안전하지 않게 동작할 수 있기 때문에, 이 경우에는 dynamic_cast를 사용한다.dynamic_cast<T>(expr)
class Truck : public Car 일 때
Truck * ptruck = new Truck();
Car * pcar = dynamic_cast<Car*>(ptruck);
const_cast<T>(expr)
void test(char *str){}
int main(void)
{
const char *name = "홍길동";
test(const_cast<char *>(name);
}
reinterpret_cast<T>(expr)
임의의 포인터 타입간의 형변환에 사용된다.
정수형을 포인터로 바꿀 수도 있다.
즉, 일반적으로 허용하지 않는 위험한 형 변환을 (무조건적인 형 변환) 할 때 사용한다.
int *
-> char
-> int *
로 이뤄지는 형변환이 있을 때, 주소값이 파괴되어 결국 nullptr을 가르키게 된다. char형은 1바이트 크기여서 주소 값을 다 표현하지 못하기 때문이다. 즉, 데이터를 옮기는 과정에서 dump가 되버려 원본 데이터가 파괴될 위험이 있다.(void *)
로도 전달이 가능하기 때문에 특수한 경우에 쓰인다.
[과제 소개]
void * serialize(void)
함수를 작성하시오Data * deserialize (void * raw)
함수를 작성합니다. ptr = new char[sizeof(std::string) * 2 + sizeof(int)];
ptr = new char[52];
sizeof(std::string)
는 왜 24byte인가?컴퓨터 시스템(window, linux, mac, compiler)마다 다르겠지만 libc++기준 문자열 클래스의 한 크기는 24byte이다. 그런데 std::string str = "hello"
일 때 str.size()
or str.length()
는 5가 나온다.
이는 문자열 클래스 24byte 안에 hello 외에 다른 값들이 존재한다는 것을 의미한다. 예를 들면 hello
가리키는 포인터가 존재한다. 24byte 안에 실제 문자열이 들어있는 것이 아닌 멤버 변수들(실제 문자열을 가르키는 포인터, 패딩 및 기타 ..)이 모여 24byte의 크기를 갖게 되는 것이다.
구조가 있는 객체의 내용물
을 바이트 배열로 저장하는 것을 직렬화(Serialization)이라고 하고, 반대로 바이트 배열로부터 내용물을 읽어와 객체에 채우는 것을 역직렬화(Deserialization)라고 합니다.
메모리안의 어떠한 (추상적) 데이터구조를 연속된 bit 로 외부에 보내기위해 정렬하는것.
그렇다면 이 문제에서는 string, int, string 구조체의 직렬화를 위해 몇 바이트 배열을 만들어야되냐가 문제인데, 총 52바이트(24 + 8 + 24) 인 것이다.
https://dojang.io/mod/page/view.php?id=495
reinterpret_cast<char *> 를 사용한다.
[과제 소개]
Base * generate (void)
함수 작성하시오 : A,B or C 무작위 인스턴스, 인스턴스 Base 포인터 반환<typeinfo>
사용금지<T>
와 다르면 NULL이 반환됨 -> 이를 이용해 안전하게 다운캐스트 가능.typeid(int) == typeid(double) ;