[C] 구조체
자바에 클래스가 있다면, C에는 구조체가 있다. (struct)
물론 모든 부분이 같지는 않고, C의 구조체의 마지막에는 세미콜론을 붙여야 하고, C의 구조체의 멤버로는 메서드가 포함될 수 없는 등 다른 부분이 있다.
구조체의 메모리 모양, 선언, 접근 방법은 자바에서 배운 내용과 비슷하다.
이 부분에서 잠깐 "배열의 이름은 포인터다"를 떠올릴 수 있는데, 구조체의 이름도 구조체의 첫 번째 멤버의 주소라고 생각할 수 있다. (구조체에서 메모리는 연속적으로 구성되어있다.)
구조체를 선언하면서 동시에 그 구조체 타입의 변수도 선언할 수 있음을 기억해 두자.
따로 따로 선언하는 것과 같은 효과를 낸다.
선언과 초기화를 동시에 진행할 수도 있다.
위의 두 가지를 한 번에 사용할 수도 있다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct e{
int a;
int b;
} man1 = {
1,2
};
int main() {
printf("%d", man1.a);
// 1
}
변수 여러 개를 한 번에 선언하고 초기화 하는 것도 가능하다.
구조체의 배열도 존재한다.
자바에서 사용자가 지정한 클래스 타입의 배열을 사용할 수 있는 것과 같다.
초기화도 위에서 선언과 초기화를 동시에 수행하는 예시와 비슷하게 할 수 있고, 일단은 배열이기 때문에 포인터와 연관되는 부분이 많다.
구조체와 포인터에 대해서도 살펴보자.
메모리를 어떤 단위로 읽어야 하는지 나타내기 위해 struct point * pptr와 같이 구조체 타입을 지정해준다.
즉, pptr+1을 수행하면 해당 구조체 메모리의 크기만큼 건너뛴다. (구조체 배열 사용 시.)
C에서는 구조체의 포인터를 자주 사용하는 편이라, 새로운 연산자가 정의되어있다.
-> 연산자인데, 이 연산자를 사용해 구조체의 포인터를 통해 구조체의 변수에 쉽게 접근할 수 있다.
구조체의 멤버로 다른 구조체를 가질 수 있다.
이 때 자기 자신은 구조체의 멤버가 될 수 없음에 유의하자.
구조체 a가 구조체 a의 멤버로 들어와있다고 생각해보자.
컴파일 시 구조체의 메모리 크기를 알아야 하는데, 구조체 a의 메모리 크기를 알기 위해 멤버를 살펴보는 중 다시 구조체 a가 있고 이 구조체의 메모리 크기를 알기 위해 멤버를 봤더니 다시 구조체 a가 있고.....
이렇게 무한 재귀가 발생하기 때문에 메모리의 크기 확인을 위해 자기 자신은 구조체의 멤버로 들어올 수 없다.
하지만, 그럼에도 불구하고 자기 자신을 구조체의 멤버로 사용하고 싶다면 자기 자신의 포인터 타입을 사용하면 된다.
포인터의 크기는 굳이 포인터가 참조하는 메모리의 크기를 찾을 필요가 없으니..
구조체 내부에 다른 구조체가 멤버로 들어오는 경우를 정리하자.
구조체의 크기가 커지는것을 방지하기 위해 구조체 내부에 다른 구조체가 들어오는 경우에 구조체의 포인터를 사용하는 경우가 많다.
구조체를 함수 인자로 넘길 때는 Call By Value방식으로 전달되고, 구조체의 값들이 통으로 복사돼 전달된다,
그래서 구조체의 크기가 클수록 복사하는데에 리소스를 많이 사용하기 때문에 구조체의 크기를 줄이는 편이 합리적이다.
일단 구조체 안에 있는 멤버들은 매개변수로 전달 시 싹다 복사되기 때문에 구조체 안의 배열도 함께 복사할 수 있다.
'Programming Language > C' 카테고리의 다른 글
[C] 정리 (2) (0) | 2022.06.14 |
---|---|
[C] typedef / Union (0) | 2022.05.26 |
[C] 동적 메모리 (0) | 2022.05.23 |
[C] Stack / Heap (0) | 2022.05.23 |
[C] 배열 포인터 / 포인터 배열 정리 (0) | 2022.05.11 |
댓글
이 글 공유하기
다른 글
-
[C] 정리 (2)
[C] 정리 (2)
2022.06.14 -
[C] typedef / Union
[C] typedef / Union
2022.05.26 -
[C] 동적 메모리
[C] 동적 메모리
2022.05.23 -
[C] Stack / Heap
[C] Stack / Heap
2022.05.23