반응형
#11.4 구조체 포인터
구조체 포인터
- 구조체 변수를 가리키는 포인터
- 즉, 구조체 변수의 시작 주소가 저장된다.
- 기본적인 사용법은 일반적인 포인터와 동일하지만 구조체 포인터에서만 사용하는 문법이 있다.
※ 구조체 멤버로 포인터를 사용하는 것과 구분해야 함. 그 경우는 아래의 코드.
struct student {
char *name;
};
구조체 포인터 변수 선언 및 연결
- 일반 포인터 선언과 동일: * 사용
- 주소 연산자(&): 구조체 변수의 시작 주소
struct student st1 = {10, "Tom", 3.2};
struct student *pst; // 구조체 포인터 변수 선언
pst = &st1; // 연결
간접 연산자(*)를 이용한 구조체 변수 접근
st2 = *pst;
간접 참조를 이용한 구조체 변수의 멤버 접근
방법 1: *과 . 사용
- 포인터가 가리키는 변수에 접근하기 위해 간접연산자 * 사용
- 구조체의 멤버에 접근하기 위해 멤버 연산자 . 사용
struct student st1, *pst = &st1;
(*pst).id = 20; // pst가 가리키는 구조체의 멤버 id에 20 대입
※ * 보다 .의 우선순위가 높기 때문에 괄호 반드시 필요하다.
방법 2: 구조체 포인터에서만 사용하는 전용 연산자 (->)
pst -> id = 20; // pst가 가리키는 구조체의 멤버 id에 20 대입
// (*pst).id = 20; 위와 동일한 뜻
구조체 포인터 배열 (구조체 + 포인터 + 배열)
구조체 포인터가 원소인 배열
struct student st1 = {10, "Tom", 3.2}, st2;
struct student *past[3] = { &st1, &st2 } // 구조체 포인터 배열
past[2] = past[1]; // 주소 값 대입: past[2]도 st2를 가리킴
*past[2] = *past[0]; // past[2]가 가리키는 구조체에 past[0]이 가리키는 구조체 대입
학습 정리
- 구조체 포인터는 구조체를 가리키는 포인터
- 구조체 포인터를 사용하여 멤버에 간접 접근하기 위해서는 구조체 포인터 전용 참조 연산자 -> 사용
- 구조체 포인터 배열은 구조체 포인터가 원소인 배열
#11.5 구조체와 함수
구조체를 함수의 인자로 사용
실인자의 값이 형식인자에 대입됨 -> 일반 변수와 같음
void print(struct student st) {
printf("id: %d\n", st.id);
printf("name: %s\n", st.name);
printf("grade: %.2f\n", st.grade);
}
int main() {
struct student st1 = {10, "Tom", 3.2};
print(st1);
return 0;
}
구조체를 함수의 반환형로 사용
구조체 전체 값이 통째로 호출함수에게 전달됨
struct student init() {
struct student st = {0, "", 0};
return st; // 구조체 변수 st의 값 반환
}
int main() {
struct student st1 = {10, "Tom", 3.2};
printf("%d, %s, %.2f\n", st1.id, st1.name, st1.grade);
st1 = init(); // init()의 반환값 대입
printf("%d, %s, %.2f\n", st1.id, st1.name, st1.grade);
return 0;
}
예제11.6)
두 복소수를 입력 받아, 두 복소수의 합을 출력하는 프로그램을 작성하시오.
- 구조체 complex 사용
- add_complex() 함수 정의해 사용
- 구조체 complex형 변수 두 개를 인자로 받아, 두 복소수의 덧셈 결과(구조체 complex형)를 반환
- main() 함수
- 사용ㅈ라ㅗ부터 복소수의 정보를 입력받아 구조체 변수에 저장
- add_complex 함수를 호출하여 덧셈 결과 얻기
- 덧셈 결과 출력
struct complex {
double real, imag;
};
struct complex add_complex(struct complex a, struct complex b) {
struct complex c;
c.real = a.real+b.real;
c.imag = a.imag+b.imag;
return c;
}
int main() {
struct complex c1, c2, c3;
scanf("%lf%lf", &c1.real, &c1.imag);
scanf("%lf%lf", &c2.real, &c2.imag);
c3 = add_complex(c1,c2);
}
구조체 포인터 변수를 함수 인자로 사용
실인자의 값(주소)이 형식인자에 대입된다.
void init_p(struct student *pst) {
pst->id = 0;
pst->name[0] = '\0';
pst->grade = 0.0;
}
int main() {
struct student st1 = {10, "Tom", 3.2};
init_p(&st1);
return 0;
}
구조체 주소를 반환하는 함수
일반 변수의 주소 반환과 동일
struct student *next_addr(struct student *pst) {
return pst+1;
}
int main() {
struct student st[2] = {{10, "Tom", 3.2}, {20,"Ann",3.5"}};
struct student *p;
p = next_addr(st); // 배열의 이름(주소) 전달
return 0;
}
함수 호출(총 정리)
- 함수 인자나 반환 값의 자료형에 관계없이 함수 호출 과정은 동일
- 함수 호출 시에는 전달된 값을 형식인자에 대입
- 차이가 나는 이유는 전달된 값이 정수, 문자를 나타내느냐, 주소를 나타내느냐에 따른 부수적인 효과일 뿐이다.
- 함수 종료 시에는 리턴 값이 통쨰로 호출함수에 전달된다.
-> 자료형(int, 포인터, 구조체, 배열)마다 따로 외우려고 하지 말고 원리를 이해하자!
#11.6 중첩 구조체 및 자기참조 구조체(1)
중첩 구조체(nested structure)
다른 구조체가 구조체의 멤버로 사용
자신과 동일한 구조체 자료형은 멤버로 사용될 수 없다. 왜냐하면, 자기 자신을 정의하기 위해 자기 자신이 필요하므로 순환 오류에 빠진다.
학습 정리
- 구조체 또는 구조체 포인터를 함수에 인자로 전달하고 반환하는 과정은 일반 변수와 동일하다.
- 함수 인자나 반환 값의 자료형에 관계없이 함수 호출 과정은 동일
- 중첩 구조체는 구조체가 멤버로 사용된 구조체
- 자신과 동일한 구조체 자료형은 멤버로 사용될 수 없다.
반응형
'Algorithm > C프로그래밍' 카테고리의 다른 글
[6주차] 구조체 (0) | 2021.11.09 |
---|---|
[10주차] 동적 할당 (4) | 2021.11.05 |
[9주차] 동적 할당 (0) | 2021.11.05 |
[5주차] 문자열 (0) | 2021.09.29 |
[4주차] 문자열 (0) | 2021.09.27 |