본문 바로가기

무언가 만들기 위한 지식/C,C++,Embedded C

[C,C++,Embedded C] About "Typedef"

typedef는 C코드에서 흔히 볼수 있는 말 그대로 타입선언이다.
하지만 이 Typedef를 제대로 활용하기 위해서는 이해가 필요하다. (별건 아니지만..)

typedef는 전처리기가 아니라 명령어 이기 때문에 반드시 문장 끝에 세미콜론(;)을 붙여 주어야 하며 모든 변수 타입을 지칭할 수 있다.
이는 가독성의 증대와 변수타입을 효율적으로 관리하도록 한다.
왠만한 하나의 모듈, 자체에는 사실상 엄청난 수의 typedef문이 들어있다.
각 회사마다 프로그램 내 규정에 맞도록 자료형을 정해놓는다.
(그래서 어떻게 보면 처음 보는 사람은 찾는데 더 힘들지만 나중에 코드짜기에는 더 편한 듯 하다.)

typedef의 의미는
"변수명을 타입이름으로 변경하는 기능"
이라고 말할 수 있다.
필자는 예전에
 typedef A B;
라는 문장은 B를 A로 표시한다로고 해석하였으나
그런 식으로 해석할 경우에는 해석 불가능한 복잡한 문장들을 접할 수 있다.
그렇기 때문에
typedef A B;
가 존재할때는 B는 변수명이고 A를 B의 타입이라고 생각하고, 변수 B를 이제부터는 자료형(type)으로 취급한다고 보면 된다.
예를 들면 배열이나 함수도 typedef로 선언이 가능하다.
그러나 시각상 배열이나 함수는 후위우선에 의해 변수 뒤에서 변수를 꾸며주기 때문에 A B로 해석이 되지 않는다.
즉 typedef다음에 자료형과 변수명이 선언되어 있다면, 변수명은 앞으로 그 변수의 타입으로 쓰인다고 해석하여야 한다.
즉 더이상 변수가 아닌 자료형으로서 사용된다는 것이다.

쉽게 기억할려면 [typedef 변수명] 으로 생각하고,
변수명은 이제부터 선언된 자료형으로 사용된다고 보면 된다.

다음코드를 통해 사용예를 보자.
코드중에는 함수를 인자로 받고 함수를 return하는 함수를 예로 보이기 위해 조금 코드가 지저분해졌고,
배열간 포인터 연결때문에 한번에 읽어내기는 힘들지도 모른다.^^

[작성환경
: Window XP  작성툴 : Visual Studio 6.0   컴파일러 : Visual Studio 6.0   사용언어 : C]


2~6 Line은 사용할 typedef를 선언한 것이다.
2,3  Line의 경우 함수 포인터를 선언.
4 Line은 2차원 배열, 5 Line은 1차원 배열을 7 Line은 Integer Pointer를 선언하였다.
10~18 Line은 심플한 함수로 호출되면 출력하는 함수이다.
19 Line은 함수 포인터로 함수의 주소들이 저장되어 있는 3칸의 배열이다. 나중에 함수를 가져오기 위해 함수테이블이 이용된다.
20 Line은 바로 함수를 인자로 받아, 함수를 리턴하는 함수이다.
가독성을 위해 위에서 선언된 typedef pf로 이미 함수형이 선언되어 있는 모습을 볼 수 있다.
21 Line에서 리턴하는 값이 바로 테이블에 가져오는 함수의 주소, 즉 함수 포인터이다.

이제 메인에서는 각 값들을 연결해 준다. 이를 이해하기 위해서는 좌측의 l-value와 우측의 r-value를 잘 비교해 보아야 한다.
24~25 Line에서는 기존의 많은 방식처럼 포인터와 변수의 주소를 연결해준다.
27 Line은 2차원 배열로 typedef 선언된 ary_2로 선언된 val2에 기존에 메모리에 할당된 9개 요소를 갖고 있는 2차원 배열을 연결해 주는 모습이다.
(연결한다는 의미는 첫번째 주소값을 넘겨주어 offset으로 접근이 가능하도록 한다는 말이다.)
28 Line에서는 세칸짜리 temp3배열 내부에 ary_1(한칸짜리 배열)을 넣어준 것이다.
즉 메모리는 2차원 배열처럼 배열요소 내부에 배열이 있는 구조가 된다.
이 상태는 temp3라는 이름으로 int형 9칸의 공간이 메모리에 할당된 구조이다. 즉 그냥 포인터가 아닌 메모리영역에 할당된 것이다.
29 Line에서는 배열의 포인터로 사용된 iP변수 temp4에 temp2(2차원 배열)의 [0]번째 요소 값을 전해 준다.
temp2의 0번째 요소라 함은 temp2[0]에 존재하는 하나의 배열(행)의 첫번째 값을 말한다.  
30 Line은 포인터(주소값)로 연결된 temp4에서 temp2 내용으로의 접근을 확인한 출력부분이다.
그리고 31 Line에서는 
func라는 함수에 returnInt라는 함수를 인자로 놓고, 함수 테이블에 존재하는 값을 리턴하여 바로 사용하는 예를 보였다.