이번 글에서는 구조체 배열, 구조체 포인터, ->연산자,구조체와 함수에 대해서 알아 볼 것이다.
1.구조체 배열
구조체 배열은 같은 구조체를 여러 개 모은것이다.
그냥 일반 배열이랑 다를게 없다. .연산자로 멤버들 접근하는 것만 빼면 그냥 배열과 똑같다. 예시를 보자면
![](https://blog.kakaocdn.net/dn/cNJESf/btszCplzbYI/O3NZHZx1qvxGQAEtayk4Hk/img.jpg)
struct student list[100]; 처럼 구조체형 list 변수에다가 []로 크기를 표시해주면 된다. 배열과 마찬가지로 구조체 배열도 초기화를 해줄 수 있다.
![](https://blog.kakaocdn.net/dn/NndWb/btszDUE43Kz/Gwr07mfQTufalH8DWhJdkk/img.jpg)
바로 이렇게!
2.구조체를 가리키는 포인터
구조체를 가리키는 포인터도 일반 변수에서의 포인터와 똑같다. 그냥 포인터가 그 구조체의 주소를 가리키고 있는 것이다.
![](https://blog.kakaocdn.net/dn/b7DksQ/btszCpePVHI/qdOkZzqCDaU4UvRoRqOrlk/img.jpg)
이렇게 구조체 포인터 변수를 선언해주고 포인터 변수p에 구조체 변수s의 주소를 넣어주면 포인터변수 p는 s의 주소를 가리키게 되고 *p는 변수 s를 가리키게 된다.
또 . 연산자가 *연산자보다 우선순위가 높으므로 *p에 ()를 쳐줘야한다.
3.->연산자
여기서 (*p). 으로 멤버에 접근하지 않고 p->로 접근 할 수 있다.
즉, ->연산자는 구조체 포인터로 구조체 멤버를 접근할 때 사용한다.
변수를 이용해 멤버 접근 = . 연산자
포인터를 이용해 멤버 접근 = -> 연산자
![](https://blog.kakaocdn.net/dn/bWP5AX/btszD0rQEJw/7lJ4NwZrwZ6jP2kxaBVyX0/img.jpg)
출력 결과를 보면 결과는 다 똑같다.
+ 포인터를 멤버로 가지는 구조체
![](https://blog.kakaocdn.net/dn/ZpT7a/btszCEpm1mu/cz9K9HNtD5sOkcgXwMHk40/img.jpg)
이 코드를 보면 구조체 date와 구조체 student가 있다.
main함수를 보면 struct date형 변수 d가 {3,29,1990}으로 초기화 되어있고, struct student형 변수 s가 {20190001,”Kim”,4.3}으로 초기화 되어있다.
//여기서 student의 멤버 dob의 값이 초기화설정되지 않았기때문에 dob의 값은 0을,dob는 포인터이므로 NULL값을 갖게 된다.//
그리고 s.dob는 d의 주소값을 가지게 되고(*dob는 d의 변수값을 받음)
그림으로 표현하면
![](https://blog.kakaocdn.net/dn/sDbEm/btszGR12dLk/m9cgVJ68cBnVbhNL9A2Gq1/img.jpg)
이렇게 된다. s.dob는 포인터변수이므로 ->연산자를 통해 date d에 접근가능하다.
4.구조체와 함수
구조체도 함수의 인수가 될 수 있다. 마찬가지로 값에 의한 호출과 주소에 의한 호출로 나뉜다.
값에 의한 호출은 구조체 변수를 함수의 인수로 전달하는 경우이다.
![](https://blog.kakaocdn.net/dn/x8ogZ/btszI0quEAt/0QcT44QmkKwBO81UPlLBMk/img.jpg)
이렇게 equal함수에 main함수에 있는 구조체 a,b변수의 메모리를 그대로 복사한다. 따라서 equal함수에 32byte의 구조체 두개와 그 멤버가 복사되는 것이다. 그러므로 구조체의 크기가 크면 클수록 그만큼 시간과 메모리가 소요된다. equal함수가 끝나면 그 안에있는 메모리는 삭제된다.
주소에 의한 호출은 구조체 포인터를 함수의 인수로 전달하는 경우이다.
![](https://blog.kakaocdn.net/dn/cp1EUB/btszCKXxu4X/hyuegF9KkKcmqdHu4oRLJ1/img.jpg)
이 경우 구조체의 주소가 전달이 된다. 따라서 equal함수에서는 main함수에 있는 구조체 변수a,b의 주소를 받는 4byte짜리 포인터변수 p1,p2가 생성된다. 그러므로 값에의한 호출보다 시간과 공간을 절약할 수 있다. 그리고 equal함수에서 main함수에 있는 구조체 a,b를 수정할 수 있다.
5.구조체를 반환하는 경우
복사본이 반환되는 경우
![](https://blog.kakaocdn.net/dn/bRFppT/btszHRtNqW3/991rlO5fwf0ehLpFVRM5z0/img.jpg)
struct student형 create 함수를 만들었고 인자값은 없다. 반환값은 struct student 형 변수 s를 받게된다. 즉, 구조체 변수 s가 main함수의 구조체변수 a에 복사된 것이다.
주소가 반환되는 경우
![](https://blog.kakaocdn.net/dn/3bKj7/btszCGHwRAH/GEferIUL7moMkeiJ8bNRQ0/img.jpg)
void형 create함수를 만들었고 인자값은 struct student *p를 받는다. void형이기 때문에 리턴값은 없다. main함수를 보면 struct student 형 변수 a를 선언했고 create함수의 인자로 a의 주소를 보냈다. 그러면 create함수에서는 인자로 struct student *p값에 struct student a의 값이 들어가고, p에는 a의 주소값이 들어가게 된다. 그리고는 create함수에서 ->연산자를 이용해 p를 통해서 a의 값에 접근할 수 있게 되었다. 아래 그림을 보면서 글을 읽으면 아마 이해가 될 것이다.(나만 그럴수도…)
이상입니다.
저 혼자 공부하는 것이므로, 만약 틀린것이 있다면 댓글로 지적해주시면 감사하겠습니다!
'Language > C & C++' 카테고리의 다른 글
[C++] fill 함수에 대해 알아보자 (0) | 2024.02.22 |
---|---|
포인터배열과 배열포인터 예제,이중포인터 예제 배열과 포인터[C프로그래밍] (2) | 2023.11.18 |
포인터의 활용(1)[C프로그래밍] (0) | 2023.11.17 |
union,enum,typedef[C프로그래밍] (0) | 2023.11.14 |
구조체(1)[C프로그래밍] (0) | 2023.11.02 |