16 - Struct 1

<학습하기>

배열
성격이 같은 데이터들은 모아서 한꺼번에 관리할 수 있는 자료구조.
데이터형이 같은 많은 자료들을 모아서 한번에 관리할 수 있다.
학생들 성적, 일일 매출액 , ...

구조체(struct)
성격이 다른 데이터들은 모아서 한꺼번에 관리할 수 있는 자료구조.
공통점을 가지고 있는 여러 데이터들을 모아서 하나로 묶어 관리할 수 있다.

구조체 정의
실제로 구조체변수를 만드는 것이 아니라,
앞으로 이런 구조체변수를 만들겠다고 알려주는 것.

형식
struct 구조체이름
{
자료형 변수이름;
자료형 변수이름;
:
:
};

ex)
struct PersonInfo                        PersonInfo라는 구조체는
{
char name[30];                          name이라는 30개짜리 문자배열
int age; age라는 정수형 변수
double height; height라는 실수형 변수
:     를 갖고 있다.
                                          앞으로 이런 모양의 구조체 변수를 만들 것이다.
};
이때, 이 구조체에 포함되어 있는 변수들 (name, age, height, ...)은
멤버변수 (member variable)이라 부른다.

구조체변수 생성
앞에서 만든 구조체 정의를 이용해 실제 데이터를 저장할 수 있는 구조체 변수를 만든다.

형식
struct 구조체 이름 변수이름;

ex)
struct PersonInfo person;
//위에서 정의된 PersonInfo와 같은 모습의 구조체 변수 person을 만들었다.
//person안에는 name이라는 문자배열, age라는 정수변수, height라는 실수변수가 포함된다.

구조체를 한번 정의해 놓으면 그 구조체를 이용하여 수많은 구조체 변수를 만들 수 있다.
struct PersnoInfo student;
struct PersonInfo best;
struct PersonInfo students[10];

구조체 정의와 구조체 변수간의 사이는 붕어빵틀과 붕어빵의 관계와 비슷하다.

  붕어빵                                              구조체
우리가 필요한 것은 붕어빵.       우리가 필요한 것은 실제로 데이터를
            저장할 수 있는 구조체 변수.

하지만 처음부터 붕어빵을 만들 수      하지만 처음부터 구조체 변수를 만들 수
없으며, 붕어빵틀을 먼저 만들어야 한다.  없으며, 구조체 선언을 먼저 해야한다.

붕어빵 틀을 하나 만들어 놓으면    구조체 선언을 한번 해 놓으면
붕어빵을 얼마든지 찍어낼 수 있다.    구조체 변수를 얼마든지 찍어낼 수 있다.

같은 붕어빵 틀에서 찍어낸 붕어빵틀은  같은 구조체 선언에서 만들어진 구조체 변수들은
모두 같은 모습을 하고 있다.      모두 같은 모습을 하고 있다.

다른 붕어빵 틀을 이용해서      다른 구조체선언을 이용해서
다른 모습의 붕어빵을 찍어낼 수 있다.  다른 모습의 구조체변수를 찍어낼 수 있다.

구조체 초기화
구조체를 만든 후 멤버 변수들을 초기화시키는 방법
ex)
struct PersonInfo person = {"홍길동", 20, 173.2};
//person 이라는 구조체의 첫번째 멤버변수로부터 순서대로 초기값이 들어간다.
//각 순서의 멤버변수 데이터형과 초기값의 데이터형이 일치해야 한다.
//초기값이 없는 멤버변수는 0으로 채워진다.

구조체의 멤버변수에 접근하는 방법.
배열의 경우 배열의 내부변수에 접근하기 위해서는 첨자를 사용한다.
구조체의 경우 구조체 멤버변수에 접근하기 위해서는, 마침표(.)를 사용한다.

형식
구조체변수.멤버변수
ex)
int age = person.age; //person이란 구조체변수의 age라는 멤버변수 꺼내기.
person.height = 165;  //person의 키를 165로 세팅.

[구조체변수. 멤버변수]를 하나의 변수로 취급할 수 있다.

일반 변수와 마찬가지로 구조체 변수 역시 & 또는 *연산자로서 주소를 조작할 수 있다.
ex)
struct PersonInfo *personPnt;
//personPnt라는 포인터변수 만들기.
//이때 personPnt가 가리키는 곳에는 PersonInfo의 구조체 변수가 존재.
personPnt = &person;   
//구조체 변수 person의 주소를 personPnt에 저장.

포인터 변수는 *를 사용함으로써 포인터가 가리키는 곳의 변수를 찾을 수 있다.
구조체 포인터의 경우에도 *personPnt는 바로 person이란 변수를 의미한다.
그러므로 (*personPnt) . age는 person . age)와 같은 의미가 된다.
참고로 *personPnt . age는 *(personPnt . age)와 같은 의미이므로 오류가 일어난다.
이때 (*personPnt) . age 형식을 간략화시킨 것이 -> 로서,
구조체 포인터의 경우 ->를 사용함으로써 멤버변수에 접근 가능.
ex)
personPnt -> age = 20;  >>> person. age - 20; 과 동일.

<실습하기>
#include <stdio.h>
#include <string.h>

// 학생들의 이름, 나이, 주소, 키, 몸무게, 평균성적 등을 받아오는 함수를 만들고
// 출력하는 프로그램을 만들어라.

// 구조체 정의
struct StudentInfo       // 학생들의 정보를 저장하는 구조체
{
char name[30]; // 학생 이름
int age; // 나이
char *address; // 주소
double height; // 키
double weight; // 몸무게
double avg; // 평균성적
};

void ReadStudentInfo(struct StudentInfo *stdInfo);

void PrintStudentInfo(struct StudentInfo stdInfo);  // StudentInfo 형태의 구조체를 받아서 출력

main()
{
// 구조체 생성
/* 초기화와 함께 구조체 변수 만들기
struct StudentInfo student =  // student라는 구조체가 만들어짐.
  //구조는 StudentInfo에서 정의된 것처럼 6개의 멤버변수 존재
{
"홍길동",
20, // 나이
"서울시 강남구",
173.2, // 키
73, // 몸무게
80 // 평균성적
};
*/

struct StudentInfo student;  // 초기화 안함

// 학생의 데이터를 읽어오는 함수
ReadStudentInfo(&student); // 학생의 데이터를 읽어오는 함수


// 이 데이터를 출력하는 함수
PrintStudentInfo(student);  // student라는 구조체 안의 모든 멤버변수 데이터들을 한번에 전달
}

void ReadStudentInfo(struct StudentInfo *stdInfo)
{
strcpy(stdInfo->name, "홍길동");  // stdInfo.name은 문자배열이므로 strcpy로 복사해야 함
stdInfo->age = 20;
stdInfo->address = "서울시 강남구";
stdInfo->height = 173.2;
stdInfo->weight = 73;
stdInfo->avg = 80;
}

/*
char name[] = "홍길동";
int age = 20;
char address[] = "서울시 강남구";
double height = 176.3;
double weight = 68;
double avg = 87.5;

// 이 데이터를 출력하는 함수
PrintStudentInfo(name, age, address, height, weight, avg);



void PrintStudentInfo(char *name, int age, char *address, double height, double weight, double avg);
//이런 식으로 데이터가 많아지면 쓰기 힘듦..

*/

void PrintStudentInfo(struct StudentInfo stdInfo)
// StudentInfo 형태의 구조체를 받아서 출력
// 구조체가 인수로 전달될 때는 stdInfo라는 새로운 구조체가 만들어진 후
// 호출하는 측의 인수(student)의 각 멤버변수가 하나씩 그대로 복사된다.
{
printf("%s 학생의 정보\n", stdInfo.name);
printf("나이 : %d\n", stdInfo.age);
printf("키 : %f\n", stdInfo.height);
printf("몸무게 : %f\n", stdInfo.weight);
printf("주소 : %s\n", stdInfo.address);
printf("평균성적 : %f\n", stdInfo.avg);

}

















댓글

이 블로그의 인기 게시물

11 - Scanf

JAVA - Day3 - Scanner, if, if else

JAVA - Day5 - Array,Random