cCcode

C Language [핵심정리] - 34 본문

C Language Basic

C Language [핵심정리] - 34

cCcode 2021. 7. 1. 19:47

1. 자료형 변환하기

C언어에서는 표현 범위가 넓은 부분으로 저장하면 자동으로 변환된다고 전에 잠깐 언급한 적 있는데요

이번에는 포인터끼리 변환하는 방법입니다. 단순히 괄호 안에 넣어주었던 자료형 대신 포인터 즉, *(Asterisk)를 사용하면 되는 간단한 개념입니다. ◇ (자료형 *) 포인터

포인터 변환 후 할당
결과

numPtr에 저장된 값을 char 포인터로 받아서 해당 포인터의 크기(1byte)만큼 값을 가져옵니다. (이 때, numPtr의 주소를 가져오는 것이기 때문에 역참조가 아닌 상태로 할당을 합니다.) 즉, 자료형에 따라 역참조에 의해 가져오는 값의 크기가 달라집니다. 결과로 0x78이 나온 이유는 리틀엔디언 때문입니다. 

그럼 반대로 작은 크기 메모리에서 메모리 크기보다 큰 값을 가져온다면 어떻게 될까요?

포인터 변환 후 할당
결과

출력해보면 해당 값 앞에 의미모를 값들이 붙어서 출력되었습니다. 이처럼 크기가 작은 메모리할당한 뒤 큰 자료형의 포인터역참조하면 옆의 공간을 침범해 값을 가져오게 됩니다.

메모리 공간 침범

참고로 할당되지 않은 공간에는 쓰레기 값이 들어있기 때문에 의도치 않은 결과가 나올 수 있습니다.

여기서 한 가지 의문 "포인터는 값이 아니라 주소가 저장되는 데 굳이 변형이 필요한건가?" 하는 의문이 들 수도 있습니다. 하지만 메모리 주소가 무엇을 가리키고 있는지 생각하면 간단히 해결되는 의문이죠.

형식 호환 X
경고

 

포인터를 다른 자료형으로 변환하면서 역참조하려면 ◆ *(자료형 *)포인터 를 사용하면 됩니다.

char 포인터 변환 후 출력
결과

정상적으로 char 포인터 전환 되었기에 1byte만큼의 메모리를 가져왔습니다.  만약 정상적으로 변환되지 않았거나 변환하지 않았다면 0x12345678 이라는 결과값이 나왔겠죠?

 

혹시 예전에 void 포인터를 배울 때 void 포인터는 자료형이 정해지지 않아서 모든 포인터를 대체할 수 있다고 말씀드린거 기억하시나요? 그 때는 void 포인터역참조 연산을 할 수 없다고 했는데요. 저희는 방금 배운 *(자료형 *)포인터를 통해서 역참조 연산을 수행할 수 있습니다.

void 포인터 형변환 역참조
결과

 

자료형 변환은 구조체 포인터변환할 때 자주 사용합니다. 일반 변수 때문에 변환하는 경우는 생각보다 드물고요. 이 때는 struct와 구조체 명 뒤에 *(Asterisk)를 붙여준 뒤 괄호로 묶어주면 됩니다.

○ (struct 구조체 명 *)포인터 ○ ((struct 구조체명 *) 포인터)->멤버

구조체 포인터 사용 - 1
구조체 포인터 사용 - 2
결과

저 코드에서 Ptr을 구조체 포인터로 변환 해준 이유는 Ptr은 void 포인터구조체의 형태를 알지 못한다면 멤버에 접근할 수 없습니다. 그래서 구조체 포인터변환을 해준 후 멤버에 접근하는 겁니다. 여기서 조금 거슬리는 게 있죠. 바로 Ptr을 묶어 주고 있는 괄호입니다. 사실 괄호가 의미가 없어보여 없어도 되는거 아니냐?라고 하실 수 있는데 만약 제가 (struct data*)Ptr 같은 형식으로 사용한다면 이 Ptr(void 포인터)로는 멤버에 접근할 수 없습니다.

멤버에 접근 불가
이유

 

그럼 이 (struct data)Ptr 은 어디에 쓸 수 있냐면 바로 

다른 포인터에 메모리 주소 저장
결과

다른 포인터에 메모리 주소저장할 때만 쓸 수 있습니다. 따라서 멤버에 접근하고 싶다면 자료형 변환포인터 전체를 괄호로 묶어줘야 합니다. 

 

+ typedef 를 사용해서 구조체 별칭 뿐 아니라 포인터의 별칭 또한 함께 선언할 수 있습니다.

구조체 포인터 별칭 선언

그리고 이렇게 선언한 구조체를 ▲(구조체 별칭 *)포인터 or ▲((구조체 별칭 *)포인터)->멤버 and △(구조체 포인터 별칭)포인터 or △ ((구조체 포인터 별칭)포인터)->멤버 이용해서 변환할 수 있습니다.

구조체 포인터 별칭 사용 - 1
구조체 포인터 별칭 사용 - 2

 

'C Language Basic' 카테고리의 다른 글

C Language [핵심정리] - 36  (0) 2021.07.09
C Language [핵심정리] - 35  (0) 2021.07.04
C Language [핵심정리] - 33  (0) 2021.06.29
C Language [핵심정리] - 32  (0) 2021.06.27
C Language [핵심정리] - 31  (1) 2021.06.21
Comments