[KOCW 한국산업기술대학교 박정민 교수님] C 프로그래밍 15강

MinWoo Park·2021년 8월 26일
0

KOCW

목록 보기
15/19
post-thumbnail

Part15 구조체와 공용체란 무엇인가

15.1 구조체란

관련 있는 데이터를 묶어서 하나의 자료형으로 그룹화하면 관리가 쉽고 코드의 가독성과 간결성이 한결 높아지는 장점을 지님

구조체 정의

  • 하나 이상의 변수를 묶어 그룹화하는 사용자 정의 자료형
  • 같은 자료형, 다른 자료형 모두 묶을 수 있다
  • 구조체 이름과 구조체 멤버 변수를 만들어 구조체를 정의함
    ex)
struct point // 구조체 키워드/구조체 이름
{
	int x; // 구조체 멤버변수
   	int y; 
};
  • 구조체 키워드: 구조체의 시작을 알리는 struct 키워드
  • 구조체 이름: 구조체를 구분하는 이름
  • 멤버 변수: 구조체를 구성하는 구조체 멤버 변수의 이름

구조체 변수

  • 구조체 변수란 구조체 멤버 변수에 접근하게 해주는 변수를 뜻함
  • 구조체 정의와 구조체 변수 선언을 동시에 하는 방법
    ex)
struct point 
{
	int x;
	int y;
} p1, p2, p3; // 구조체 변수들
  • 구조체 정의와 구조체 변수 선언을 따로 하는 방법
    ex)
#include <stdio.h>

struct point
{
	int x;
    int y;
};

int main(void)
{
	struct point p1, p2, p3; // 구조체 변수를 개별적으로 선언
    ...
    return 0;
}

구조체 변수로 멤버 변수에 접근하기

  • 접근(.) 연산자를 사용
    ex)
#include <stdio.h>

struct group
{
    int a;
    double b;
};

int main(void)
{
    struct group g1;

    g1.a = 10;
    g1.b = 1.234;

    printf("g1.a의 값: %d \n", g1.a);
    printf("g1.b의 값: %lf \n", g1.b);

    return 0;
}
g1.a;
구조체 변수/접근 연산자(.)/멤버 변수
  • 구조체 변수: 멤버 변수에 접근하게 해주는 구조체 변수 이름
  • 접근 연산자: 구조체 변수로 멤버 변수에 접근하기 위한 연산자
  • 멤버 변수: 접근하려는 멤버 변수 이름을 지정

구조체 변수의 초기화

ex)

#include <stdio.h>

struct point
{
    int x;
    int y;
};

int main(void)
{
    struct point p1 = {10, 20}; // 구조체 변수의 초기화
 
    pritnf("%d %d \n", p1.x, p1.y);

    return 0;
}
  • 주의할 점은 구조체 변수 선언과 구조체 변수의 초기화를 따로하면 에러 발생
    ex)
struct point p1;
p1={10, 20}; // error

15.2 중첩 구조체

  • 구조체 내에 구조체가 포함되어 있다는 의미
  • 멤버 변수로 구조체 변수를 사용

ex)

#include <stdio.h>

struct score
{
    double math;
    double english;
    double total;
};

struct student
{
    int no;
    struct score s;
};

int main(void)
{
    struct student stu = {20101323, {90, 80, 0}};
    // struct student stu = {20101323, 90, 80, 0}; // 중괄호 생략해도 데이터는 순서대로 저장됨

    stu.s.total = stu.s.math + stu.s.english;
    printf("class of %d \n", stu.no);
    printf("total score %lf \n", stu.s.total);

    return 0;
}

typedef를 이용한 구조체의 재정의

  • typedef를 이용해 자료형 재정의를 했던 것처럼 구조체에도 typedef를 이용해 새 이름을 부여할 수 있음
  • 구조체 정의와 동시에 typedef를 선언
    ex)
typedef struct score 
{
	...
} SCORE;

/// 일반화 

typedef struct 구조체 이름
{
	...
} 새 구조체 이름
  • 구조체 정의와 개별적으로 typedef를 선언
    ex)
struct score 
{
	...
};
typedef struct score SCORE;

/// 일반화

struct 구조체 이름 
{
	...
}
typedef struct 구조체 이름 새로운 구조체 이름; 
    

15.3 구조체와 배열

멤버 변수로 배열을 사용할 때 주의 사항

  • 구조체 멤버 변수로 문자열 배열을 사용하는 경우 선언과 동시에 초기화하지 않으면, 함수를 사용해서 문자열 저장해야 함.
    그 때 사용하는 함수가 <string.h> 파일에 있는 strcpy()함수

15.4 구조체와 포인터

멤버 변수로 포인터 사용하기

ex) point 이름의 구조체에 멤버 변수로 포인터를 사용

struct point 
{
	int* x; // 멤버 변수로 1차원 포인터 선언
	int** y; // 멤버 변수로 다차원 포인터 선언 
};

구조체 변수로 포인터 사용하기

  • 구조체 변수로 포인터를 사용한다는 의미는 구조체 변수에 간접 접근할 수 있다는 의미
    ex)
#include <stdio.h>

struct student 
{
    char no[10];
    char name[20];
    double total;
};

int main(void)
{
    struct student stu = {"20101323", "Park", 160};
    struct student *p = NULL; // 구조체 변수로 1차원 포인터 선언

    p = &stu; // struct student의 주소를 저장
    printf("%s %s %lf \n", stu.no, stu.name, stu.total);
    printf("%s %s %lf \n", (*p).no, (*p).name, (*p).total); // 1차원 포인터를 이용한 접근, *p == *&stu  == stu
    printf("%s %s %lf \n", p->no, p->name, p->total); // 1차원 포인터를 이용한 접근, -> 연산자는 포인터 변수에만 사용. -> 연산자는 포인터 변수만으로 구조체의 멤버 변수에 접근 가능, 위 보다 더 많이 사용 

    return 0;
}

자기 참조 구조체와 외부 참조 구조체

  • 구조체의 멤버 변수로 구조체 포인터 변수를 사용하는 것
  • 자기 참조 구조체란 구조체 내에서 자기 자신을 참조하는 것
    ex)
struct developer
{
	char name[20];
	int age;
	struct developer* p;
};
  • 외부 참조 구조체란 구조체 내에서 다른 구조체를 참조하는 것
    ex)
struct developer
{
	char name[20];
	int age;
	struct language* p;
};

15.5 구조체와 함수

구조체를 함수의 인자로 전달하기 - 값에 의한 호출과 주소에 의한 호출

  • 값에 의한 호출
    ex)
void function(struct point a)
{
	...
}
  • 주소에 의한 호출
    ex)
void function(struct point* a)
{
	...
}

구조체를 함수의 반환형으로 전달하기 - 값 반환과 주소 반환

  • 값 반환
    ex)
struct point function()
{
	struct point p = {10, 20};
	return p;
}
  • 주소 반환
    ex)
struct point* function()
{
	static struct point p = {10, 20};
	return &p;
}

15.6 공용체와 열거형

공용체

ex)

union date
{
	int i;
	char c;
	double d;
}

  • 멤버 변수들 중 가장 큰 메모리 공간을 '공유'해서 사용
    double이 가장 큰 8바이트를 갖으니 이를 공유해서 사용

열거형

enum week {ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN};
열거형 키워드/ 열거형 이름 / {상수 이름}
  • 열거형 키워드: 열거형 상수를 선언하기 위해 enum 키워드를 지정
  • 열거형 이름: 열거형을 대표하는 열거형 이름
  • 상수 이름: 열거형 데이터로 사용할 상수 이름을 지정
  • 컴파일러는 열거형 멤버들을 정수형 상수로 인식함

Reference
강의: 박정민, 『C 프로그래밍』, KOCW 한국산업기술대학교, 15강
교재: 박정민, 『열혈강의 C 언어 본색 명강의가 일으키는 C 언어 기적』, 프리렉 (2011), p472-531.

profile
물음표를 느낌표로 바꾸는 순간을 사랑하는 개발자입니다.

0개의 댓글