본문 바로가기

Algorithm/C프로그래밍

[7주차] 구조체

반응형

#11.4 구조체 포인터

구조체 포인터

  • 구조체 변수를 가리키는 포인터
  • 즉, 구조체 변수의 시작 주소가 저장된다.
  • 기본적인 사용법은 일반적인 포인터와 동일하지만 구조체 포인터에서만 사용하는 문법이 있다.

※ 구조체 멤버로 포인터를 사용하는 것과 구분해야 함. 그 경우는 아래의 코드.

struct student {
	char *name;
};

 

구조체 포인터 변수 선언 및 연결

  • 일반 포인터 선언과 동일: * 사용
  • 주소 연산자(&): 구조체 변수의 시작 주소
struct student st1 = {10, "Tom", 3.2};
struct student *pst;	// 구조체 포인터 변수 선언
pst = &st1;	// 연결

세종대학교 고C 강의자료

 

간접 연산자(*)를 이용한 구조체 변수 접근

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]이 가리키는 구조체 대입

세종대학교 고C 강의자료

 

학습 정리

  • 구조체 포인터는 구조체를 가리키는 포인터
  • 구조체 포인터를 사용하여 멤버에 간접 접근하기 위해서는 구조체 포인터 전용 참조 연산자 -> 사용
  • 구조체 포인터 배열은 구조체 포인터가 원소인 배열

 


 

#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;
}

세종대학교 고C 강의자료

 

구조체 주소를 반환하는 함수

일반 변수의 주소 반환과 동일

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)

다른 구조체가 구조체의 멤버로 사용

세종대학교 고C 강의자료
세종대학교 고C 강의자료

 

자신과 동일한 구조체 자료형은 멤버로 사용될 수 없다. 왜냐하면, 자기 자신을 정의하기 위해 자기 자신이 필요하므로 순환 오류에 빠진다.

 

학습 정리

  • 구조체 또는 구조체 포인터를 함수에 인자로 전달하고 반환하는 과정은 일반 변수와 동일하다.
  • 함수 인자나 반환 값의 자료형에 관계없이 함수 호출 과정은 동일
  • 중첩 구조체는 구조체가 멤버로 사용된 구조체
  • 자신과 동일한 구조체 자료형은 멤버로 사용될 수 없다.
반응형

'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