본문 바로가기

Algorithm/C프로그래밍

[6주차] 구조체

반응형

#11.1 구조체 개요

구조체(structure)

의미상 관계가 있는 항목을 그룹으로 묶어 표현한 자료형

  • 구조체는 변수의 모양(type)이다.
  • 차이는 int, char은 기본적으로 정해져 있는 기본 자료형이고, 구조체는 사용자가 용도에 맞게 만들어서 사용하는 사용자 자료형이다.
  • 구조체 구성하는 변수들을 멤버라고 부른다.

※ 구조체의 개념과 문법적 성질은 배열(동일한 정보의 단순 모임)과 매우 다르다. 구조체는 자료형 다른 것도 묶을 수 있다. 비교하면 더 헷갈리니 분리해서 공부하자.

 

#11.2 구조체의 정의, 선언, 사용(1)

구조체 정의

  • 자료형(변수의 모양)을 정의하는 것 - 변수 선언과는 다른 개념
  • struct 키워드 사용
  •  
  • struct 구조체자료형이름 { 멤버자료형 멤버변수; 멤버자료형 멤버변수; }; // 세미콜론 필요하다.
  • 정의만 하는 걸로는 메모리에 공간이 할당 되지 않는다.

 

구조체 선언

  • 일반적인 변수 선언과 동일한 형태
  • 자료형 변수명;
    // ex. struct student st1, st2; // 자료형:struct student, 변수명: st1, st2
  • 변수 선언을 해야 메모리에 공간 할당된다.
  • 구조체 변수 자체는 메모리 공간을 따로 가지지 않고, 멤버들의 메모리로 구성된다.

 

구조체 변수 초기화

다른 초기화와 유사하게 중활호 안에 멤버 변수 순서대로 초기화 값 나열

struct student st1 = {10, "Tom", 3.2};

 

구조체 멤버 변수 사용

구조체 멤버 연산자(.) 사용: 구조체변수.멤버변수

 

 

프로그램 1: 구조체를 사용하는 전형적인 프로그램

struct student {	// 구조체 student 정의는 함수 밖에서 한다.
	int id;
    char name[8];
    double grade;
}

void main() {
	struct student st1 = {10, "Tom", 3.2};	// 변수 선언 및 초기화
    
    st1.id += 20;	// 구조체 멤버 참고
    strcpy(st1.name, "alice");	// 주의: st1.name = "alice" (x)
    st1.name[0] = 'A';
    
    printf("id: %d\n", st1.id);	// 정수 출력
    printf("name: %s\n", st1.name);	// 문자열 출력
    printf("grade: %.2f\n", st1.grade); 	// 부동소수 출력
}

 

예제11.1

주 메뉴 1개, 부 메뉴 3개, 음료 1개의 값을 입력 받고, 각 항목의 값과 총합을 출력하는 프로그램을 작성하시오.

주 메뉴, 부 메뉴, 음료가 하나의 런치 박스 안에 들어있는 것으로 간주해, 구조체를 선언해서 입력받고 출력하시오. (구조체 변수 box)

#include <stdio.h>

struct lunchbox {	// 구조체 lunchbox 정의
	int maindish, sidedish[3], beverage;
}

int main() {
	struct lunchbox box;	// 구조체 변수 선언
    int i, total = 0;
    
    scanf("%d", &box.maindish);
    
    for (i=0;i<3; ++i) {
    	scanf("%d", &box.sidedish[i]);
    }
    
    scanf("%d",&box.beverage);
    
    total = box.maindish;	// 총합 계산
    for (i=0;i<3;++i)
    	total += box.sidedish[i];
    total += box.beverage;
    
    printf("Total: %d + ... = %d", box.maindish, total);
    
    return 0;
}

 

구조체 정의와 선언의 다양한 형태 

1. 자료형 정의와 변수 선언을 따로 (가장 일반적인 형태)

struct student {	// 구조체 자료형 정의 (함수 밖에서)
	int id;
    char name[8];
}

void func() {
	struct student st1;	// 지역 변수 st1 선언
}

 

2. 자료형 정의와 변수 선언을 동시에

ex. student: 구조체 자료형 이름, st: 구조체 변수 이름

struct student{	// 구조체 자료형 정의
	int id;
    char name[8];
} st1; // 전역 변수 st1 선언

void func() {
	struct student st2;	// 지역 변수 st2 선언
}
// 총 2개의 변수 선언한 것이다.

정의, 선언과 동시에 초기화도 가능하다.

struct student{	// 구조체 자료형 정의
	int id;
    char name[8];
} st1 = {10, "Tom"}; // 전역 변수 선언 및 초기화

 

3. 구조체 자료형 이름 생략 가능

BUT, 자료형 이름이 없으므로, 다른 곳에서 선언 불가능

struct {	// 구조체 자료형 정의(이름 없음)
	int id;
    char name[8];
} st1;	// 구조체 변수 st1 선언(가능)

void func() {
	struct student st1;	// compile error
    struct st2; // compile error
}

typedef와 결합해 사용됨

 

4. 구조체 자료형을 함수 안에서 정의하면?

정의한 함수 안에서만 사용 가능하다.

void func1() {
	struct student{	// 구조체 자료형 정의(함수 안)
    	int id;
        char name[8];
    };
    struct student st1;	// 구조체 변수 선언
}

void func2() {
	struct student st2;	// compile error
}

 

학습 정리

  • 구조체는 의미상 연관 관계가 있는 항목을 그룹으로 묶어 표현한 자료형
  • 구조체를 구성하는 변수를 멤버 변수라고 부른다.
  • 구조체 정의는 자료형을 명시하는 것을 의미하고, 구조체 선언은 변수를 선언하는 것을 의미한다.
  • 구조체 변수는 중괄호 안에 멤버 변수의 값을 나열하여 초기화한다.
  • 멤버연산자(.)를 이용하여 구조체 변수의 멤버에 접근한다.

 


 

#11.2 구조체의 정의, 선언, 사용(2)

구조체에 사용 가능한 연산자

구조체는 사용자가 만든 자료형이므로 기본 자료형인 int, char, double에 비해 사용 가능한 연산자가 제한적이다.

-> 산술 연산(+,-), 비교 연산(<,>) 등 지원 안 된다.

구조체에 사용 가능한 연산자는 대입연산자(=), 주소연산자(&), 간접참조 연산자(*), sizeof 연산자 정도이다.

 

구조체 변수의 대입 연산

모든 멤버 변수에 대해, 대입 연산이 수행된다. 멤버끼리 단순 대입이 되는 것이다.

※ 배열의 경우에도 각 원소마다 단순 대입되는 것이지 strcpy가 호출되는 것이 아니다.

 

구조체에 할당되는 메모리 크기

구조체 크기는 구조체 멤버 크기의 합이 아닐 수도 있다.(시스템 마다의 차이 등의 이유로) 때문에 구조체의 크기가 필요한 경우, sizeof 연산자를 사용한다. 다른 자료형도 마찬가지다.

 

#11.3 구조체 배열

구조체가 배열, 포인터, 함수 등과 결합되어 확장될 수 있다.

 

구조체 (+) 배열

구조체가 원소로 사용된 배열이다. BUT, 같은 차원의 배열에서는 같은 구조체 모양끼리의 묶음만 허용된다.

선언, 접근, 초기화 등 구조체 배열에 대한 문법은 일반 배열과 동일하다.

 

구조체 배열 선언과 접근: [] 사용

struct student ast[3];	// 구조체 배열 선언

ast[0].id = 10;
strcpy(ast[0].name, "Tom");
ast[0].grade = 3.2;

ast[1] = ast[0];	// 구조체 대입
ast[1].name[0] = 'M';

 

구조체 배열 초기화: 중괄호{} 이용

int i;
struct student ast[3] = { {10, "Tom", 3.2}, {20, "Alice"} };	// 생략된 부분은 모두 0으로 초기화

for (i=0; i<3; ++i) 	// 반복문으로 배열 출력
	prinf("%d: %d, %s, %.2f\n", i ast[i].id, ast[i].name, ast[i].grade);

 

예제11.3) 복소수 구조체 배열

복소수를 구조체로 표현하고, 크기가 3인 복소수 구조체 배열을 선언한 후, 0번과 1번 복소수의 덧셈 결과를 2번 복소수에 대입하는 프로그램을 작성하시오.

  • 0번 복소수: 1.2 + 2.0i
  • 1번 복소수: -2.2 - 0.3i
struct complex {
	double real, imag;
}

struct complex x[3] = { {1.2, 2.0}, {-2.2, -0.3} };

x[2].real = x[0].real + x[1].real;
x[2].imag = x[0].imag + x[1].imag;

 

학습 정리

  • 구조체 변수의 대입 연산은 각 멤버 변수에 대한 대입 연산을 의미
  • 구조체의 크기가 필요한 경우 sizeof 연산자를 사용
  • 구조체 배열은 동일한 구조체 자료형의 변수를 묵은 배열
  • 선언, 접근, 초기화 등 구조체 배열에 대한 문법은 일반 배열과 동일
반응형

'Algorithm > C프로그래밍' 카테고리의 다른 글

[7주차] 구조체  (0) 2021.11.09
[10주차] 동적 할당  (4) 2021.11.05
[9주차] 동적 할당  (0) 2021.11.05
[5주차] 문자열  (0) 2021.09.29
[4주차] 문자열  (0) 2021.09.27