C언어에서는 상황에 따라서 필요에 따라서 자료형을 임의로 변환할 수 있는 형변환이란 작업을 할 수 있다.
예를 들어 정수형을 저장하는 num의 값의 10의 값을 실수로 바꾸고 싶다면 (float)num; 으로 10을 실수로 형변환하여 10.000...으로 변환 할 수 있다.
하지만 이것은 변수의 값을 변경하는 것이지 num이 저장하는 데이터 타입을 변경하는 것이 아니다.
c언어에서는 한번 선언된 변수의 타입은 바꿀 수 없기 때문에 새로운 변수를 선언해야 한다.
새로운 변수를 선언하는 방식
int num = 10;
float floatNum = (float)num; // 올바른 변환
해당 방식은 이전 설명했던 것 처럼 num = (float)num;에서 새로운 변수를 선언해서 값을 저장하는 것으로 크게 다른 점이 없다. 그렇다면 포인터를 사용해서 num의 주소값을 int 형을 저장하는 주소가 아닌 float형을 저장하는 주소로 변경하는 방법을 알아보자
포이터를 활용한 메모리의 재해석
#include <stdio.h>
int main() {
int num = 10;
float *intPtr = (float *)#
*intPtr = 10;
printf("Value at address nums: %f\n", *intPtr);
return 0;
}
위 코드와 같이 num의 주소 값을 포인터 변수 intptr로 받아 강제로 int 형의 주소를 float형의 주소로 해석하게 만들어버릴 수 있다 이 방식은 매우 위험하고 비효율적인 방법이다.
고정된 주소를 활용한 void 포인터 활용
#include <stdio.h>
int main() {
// 고정된 주소를 가리키는 포인터 선언 (예: 0x1000)
void *fixedAddress = (void *)0x1000;
// 고정된 주소를 float로 해석해서 값을 읽어오기
printf("Interpreted as float: %f\n", *(float *)fixedAddress);
// 고정된 주소를 int로 해석해서 값을 읽어오기
printf("Interpreted as int: %d\n", *(int *)fixedAddress);
return 0;
}
선언한 변수는 다시 자료형을 재정의 할 수 없기 때문에 고정된 주소 값이 있다면 이 주소로 여러 자료형을 저장할 수 있다.
자주 사용하지 않는 것 같지만 많이 사용하는 방식이다 예를 들자면 malloc이 존재한다.
stdlib.h에 정의된 malloc을 보면
void* malloc(size_t size);
void *를 반환 값으로 정의된 것을 볼 수 있다. 이는 반환 되는 주소 값이 어떤 자료형을 나타내는지 알 수 없기 때문에 void *로 선언한 것이다. 실제로 사용 예를 보자면
int *ptr = (int *)malloc(sizeof(int) * 10);
반환된 void * 형을 int *로 변환해 해당 주소 값이 int형의 주소를 저장하는 주소 값이라는 의미를 말한다.
'C 자료구조와 알고리즘' 카테고리의 다른 글
공용체 (3) | 2024.10.11 |
---|---|
전처리기 토큰 결합 연산자 (3) | 2024.10.10 |
자료구조와 알고리즘 (0) | 2024.07.15 |
댓글