C 자료형 형변환 - sonkoni/Koni-Wiki GitHub Wiki
컴파일러에게 자료형을 변환한다는 의도를 명확하게 밝혀주는 것이 명시적 형변환, 즉, 타입 캐스팅이다.
== 명시적 형변환 ==
(자료형)변수
(자료형)값
== 특정 자료형 포인터로 변환 ==
(자료형 *)포인터
== 특정 자료형 포인터로 변환 후 역참조
*(자료형 *)포인터
int a = 32; int b = 7; float num;
num = a / b; // 정수 ÷ 정수 = 정수가 된다. 소숫점을 다 짤라먹은 다음 num 에 할당된다.
printf("=> %f\n", num);
// => 4.000000int a = 32; int b = 7; float num;
num = (float)a / b; // 타입캐스팅. 실수 ÷ 정수 = 실수가 된다.
printf("=> %f\n", num);
// => 4.571429작은 자료형의 자릿수에 맞는 수만 출력된다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int *numPtr = malloc(sizeof(int));
char *cPtr;
*numPtr = 0x12345678;
cPtr = (char *)numPtr; // int 포인터롤 char 포인터로 변환하여 저장
printf("%p: 0x%x\n", cPtr, *cPtr); // 메모리 주소는 동일하며, 자신의 자료형에 따라 읽어오는 크기만 달라진다.
printf("%p: 0x%x\n", numPtr, *numPtr);
free(numPtr);
return 0;
}
// 0x600001878030: 0x78
// 0x600001878030: 0x12345678캐스팅이라는 것은, 자료는 동일한데 읽어오는 범위가 다른 것이다. 이 부분 관련해서는 공용체와 엔디언 참고하기.
int [12] [34] [56] [78] ─┐─┐ Little Endian int |78||56||34||12|
short x x [56] [78] ▼ │ Little Endian short |78||56|
char x x x [78] ▼ Little Endian char |78|
기본 자료형에서는 이렇게 읽어온 데이터 자체가 해당 변수의 스토리지에 직접 저장되기 때문에 본래 자료로 되돌아갈 수 없다. 하지만 포인터의 경우 스토리지의 주소를 동일하게 저장하고 읽어오는 범위를 달리 하겠다는 것이므로, 다시 본래의 자료로 캐스팅했을 경우 손실이 발생하지 않고 되돌릴 수 있다.
int *other = (int *)cPtr;
printf("%p: 0x%x\n", other, *other);
// 0x6000024f8030: 0x12345678메모리 침범이 일어나기 때문에 이렇게 하지 않는다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
short *numPtr = malloc(sizeof(short));
*numPtr = 0x5678;
printf("%p: 0x%x\n", numPtr, *numPtr);
// 쓰레기값 채워보기
numPtr[1] = 0x1020;
// 캐스팅하면 메모리 침범이 발생
int *sPtr = (int *)numPtr;
printf("%p: 0x%x\n", sPtr, *sPtr);
free(numPtr);
return 0;
}
// 0x10520c4a0: 0x5678
// 0x10520c4a0: 0x10205678
// ---- 쓰레기값short [56] [78] ─┐ Little Endian short |78||56|
int [10] [20] [56] [78] ▼ Little Endian int |78||56||20||10|
--------- --------
쓰레기값 쓰레기값
포인터를 자료형 * 로 캐스팅 한 뒤 역참조한다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int *numPtr = malloc(sizeof(int));
*numPtr = 0x12345678;
printf("=> 0x%x\n", *(char *)numPtr);
// =============== numPtr 을 char * 로 캐스팅한 후 역참조했다.
free(numPtr);
return 0;
}
// => 0x78