typedef
형을 정의하는 것을 의미한다.
예를 들어 int n=20; 이 있는데 이게 32비트인것을 알려줄 때 typedef를 사용한다.
1
2
3
4
5
6
7
8
|
#include <stdio.h>
int main() {
typedef int Int32;
Int32 n = 20;
printf("%d\n", n);
printf("%d\n", sizeof(Int32));
}
|
cs |
typedef int Int32; --> 이게 자료형이라고 선언한 것이다.
Int32 n = 20; --> 자료형을 Int32로 선언함으로써 n이 32비트라는 것을 가시적으로 확인할 수 있다.
그러면 궁금증이 생기는데 Int32 가 int인지 즉 4바이트인지 궁금해진다.
이걸 확인하기 위해 7번째 줄에printf("%d\n", sizeof(Int32)); 를 써줬는데 이렇게 하면 4가 출력되므로 Int32도 4바이트라는 것을 알 수 있다.
배열이나 포인터에도 typedef를 써줄 수 있다. 먼저 배열부터 보자.
x,y좌표 순서쌍을 담는 배열을 만들어봤다.
point2[0]은 x좌표, point2[1]은 y좌표를 의미한다.
이렇게 point2라는 이름으로 만들어주면 이게 순서쌍을 담는건가? 그냥 점2개를 의미하는건가? 긴가민가하니까
typedef를 이용해서 순서쌍을 담는 자료형을 만들어줄 것이다.
1
2
3
4
5
6
7
8
9
|
#include <stdio.h>
int main(){
typedef int Pair[2];
Pair point = { 3,4 };//int point[2]={3,4} 로 인식 Pair자체가 2개짜리 int형 배열
printf("(%d, %d)\n", point[0], point[1]);
}
|
cs |
이렇게 하면
Pair point = { 3,4 }; <-- 이 코드를 컴퓨터는 int point[2]={3,4};로 인식한다.
포인터의 경우도 살펴보자
char name2[]를 char *name2로 사용할 수 있다. char형은 배열 형태로 선언하던, 포인터 형태로 선언하던 문자열을 담을 수 있다.
1
2
3
4
5
6
7
8
9
|
#include <stdio.h>
int main(){
typedef char *String;
String name = "Meaning";
printf("이름:%s\n", name2);
}
|
cs |
String name = "Meaning"; <-- 이 부분을 컴퓨터는 char *name="Meaning";으로 인식한다.
구조체 만들기
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h>
int main(){
typedef int Pair[2];
Pair p;//int p[2];와 같은 의미
p[0] = 3; //x좌표
p[1] = 4;//y좌표
}
|
cs |
순서쌍을 알려주는 자료형을 선언했는데 주석을 달지 않았다면 x,y좌표라는 것이 직관적으로 보이지 않는다.
이때 해결책이 구조체이다.
1
2
3
4
5
6
7
8
9
10
|
#include <stdio.h>
int main(){
typedef struct{int x,int y;}Pair;
Pair p;
p.x=3;
p.y=4;
}
|
cs |
구조체를 이용해 써주면 p의 x좌표가 3이고 y좌표가 4인것을 직관적으로 알 수 있다.
구조체는
typedef struct{int x,int y;}Pair; 이 코드처럼
여러개의 변수(x,y)를 하나의 이름(Pair)으로 묶는 역할을 한다.
하지만 구조체를 선언할때 typedef를 굳이 써주지 않고
struct Pair{ int x,y;}; <-- 이런식으로 선언하고
구조체는 보통 전역변수로 선언하는 편이다.
그래서 종합해보면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
struct Pair { int x, y; };
//typedef 생략하고 쓰는 방식
//typedef struct {int x,y;} Pair
//구조체는 대부분 전역변수로 선언
int main() {
Pair p;
p.x = 3;
p.y = 4;
printf("(%d,%d)", p.x, p.y);
}
|
cs |
뭔가 객체지향언어에서 클래스랑 비슷한 느낌도 나는 것 같다!
구조체를 하나 선언하면, 메모리에서 아무일도 일어나지 않는다. 그냥 컴파일러에 이런 구조체가 있다는걸 알려준다.
10번째 줄에 Pair p; 를 하면 메모리에 새로운 용량이 생긴다. Pair는 두개의 변수를 묶은 형태이기에 두개의 정수를 보관할 수 있는 8바이트의 공간이 생성돼서 거기에 p.x,p.y가 각각 저장된다.
그래서 sizeof(p)를 하면 8바이트가 나오게 된다.
p의 사이즈를 구하면
8바이트가 나오는 것을 알 수 있다!
구조체와 메모리
상품의 고유번호, 상품의 이름, 상품의 가격을 저장하는 구조체를 만들어보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
struct ProductInfo {
int num;
char name[100];
int cost;
};
int main() {
ProductInfo myProduct = { 47900,"제주 한라봉",19900 };
printf("상품번호=%d\n", myProduct.num);
printf("상품이름=%s\n", myProduct.name);
printf("가격=%d", myProduct.cost);
}
|
cs |
ProductInfo myProduct = { 47900,"제주 한라봉",19900 };
--> 위 코드처럼 굳이 myProduct.num=47900; 이렇게 일일이 써주지 않아도 배열로 선언하는 방법이 있다.
sizeof(myProduct)를 했을때 108바이트가 나오는데, 이는 num에서 4바이트, name에서 100바이트, cost에서 4바이트를 썼기때문이다.
그렇다면 메모리가 어떤식으로 이루어져 있을까?
임의로 주소값을 출력해봤다.
이걸 그림으로 나타내보면
myProduct의 주소값은 결국 첫번째 주소값이기 때문에 상품번호인 myProduct.num의 주소값과 같다는 것을 알 수 있다
'C > 기초(두들낙서)' 카테고리의 다른 글
[C기초] 구조체 포인터, 구조체에 함수 집어넣기 (0) | 2022.01.11 |
---|---|
[C기초] 함수 재귀,배열을 매개변수로 넘기기 + 배열을 매개변수 넘기기 활용하여 문자열 공백없이 출력하기 (0) | 2022.01.10 |
[C기초] 함수 반환/호출/프로토타입 (0) | 2022.01.09 |
[C기초] 포인터와 배열 연습문제 (0) | 2022.01.08 |
[C기초] 포인터 배열 (0) | 2022.01.04 |
댓글