구조체 사용하기
하나의 이름으로 서로 다른 데이터 타입을 묶어서 관리해주는 구조체에 대해서 살펴보겠습니다.
> // 구조체(Struct): 하나의 이름으로 서로 다른 데이터들을 묶어 관리하는 데이터 구조
C 언어에서의 구조체 사용하기: Point 예제
"구조체(structure)"는 여러 개의 변수를 하나의 새로운 타입으로 묶어 사용할 수 있는 데이터 구조입니다. 구조체를 사용하면 관련된 데이터를 그룹으로 묶어 저장하고 관리하기 편리해집니다.
구조체를 선언하려면, 먼저 구조체 타입을 정의한 후에 구조체 변수를 선언해야 합니다. 구조체 타입은 struct
키워드를 사용하여 정의하며, 구조체 변수는 구조체 타입의 이름을 사용하여 선언할 수 있습니다.
구조체는 다음과 같이 정의합니다.
struct structure_name
{
type member1;
type member2;
.
.
type member_n;
};
위와 같이 구조체를 정의하면, structure_name
이라는 새로운 자료형이 생성됩니다. 구조체의 각 멤버는 member1
, member2
, ... 입니다. 구조체 안의 각각의 변수들을 멤버 변수라고 합니다.
예를 들어, Point
구조체를 정의해보겠습니다:
struct Point
{
int x; // x 좌표 값
int y; // y 좌표 값
};
Point 구조체는 다음 그림과 같은 형태를 가지고 있습니다.
Point 구조체
┌─────────────────┐
│ x │
├─────────────────┤
│ y │
└─────────────────┘
새로운 자료형으로 정의된 구조체는 다음과 같이 변수를 선언하여 사용할 수 있습니다.
struct Point p1;
구조체의 멤버에 접근하려면 점(.) 연산자를 사용합니다.
p1.x = 10;
p1.y = 20;
다음은 구조체를 사용한 예제입니다.
코드: point_example.c
#include <stdio.h>
struct Point
{
int x;
int y;
};
int main(void)
{
struct Point p1;
p1.x = 10;
p1.y = 20;
printf("(%d, %d)\n", p1.x, p1.y);
return 0;
}
(10, 20)
위의 예제에서는 구조체 Point
를 정의하였으며, 구조체 변수 p1
을 선언하여 사용했습니다. 구조체의 멤버 변수에 접근하려면 구조체 변수의 이름과 멤버 변수의 이름을 점(.) 연산자로 연결하여 사용할 수 있습니다. 예를 들어, p1.x
와 p1.y
는 구조체 변수 p1
의 x
, y
멤버 변수에 접근하는 것입니다.
구조체 변수를 선언할 때, 구조체 내부의 멤버 변수에 값을 할당할 수도 있습니다. 예를 들어, 다음과 같이 구조체 변수를 선언할 수 있습니다:
struct Point p2 = {30, 40};
구조체는 함수의 매개변수로 전달하거나, 함수의 반환 값으로 사용할 수도 있습니다.
구조체는 유연한 데이터 구조를 제공하여, 복잡한 데이터 관리에 매우 유용한 기능입니다. 여러 개의 데이터 항목을 관리하는데 효율적으로 사용할 수 있습니다.
구조체 정의, 변수 선언 및 별칭 사용
이번에는 구조체를 정의하고 변수를 선언하는 방법에 대해 다룹니다. 또한, typedef 키워드를 사용하여 구조체의 별칭을 지정하는 방법과 익명 구조체를 정의하는 방법을 살펴봅니다.
구조체 정의와 변수 선언
앞서 살펴본 것처럼 구조체를 선언하는 가장 기본적인 방법은 다음과 같습니다.
struct Point
{
int x;
int y;
};
이렇게 정의한 후에, 구조체 변수를 선언할 수 있습니다.
struct Point p1;
하지만, 구조체 선언과 구조체 변수 선언을 한 번에 할 수도 있습니다.
struct Point
{
int x;
int y;
} p1;
구조체의 멤버 변수를 한 줄에 선언할 수도 있지만, 권장되지는 않습니다.
struct Point
{
int x, y;
};
변수를 선언하고 초기화하는 방법에는 여러 가지가 있습니다.
struct Point p1; // 구조체 변수 선언
struct Point p1 = {3, 10}; // 초기화 가능
struct Point p1 = {.y = 10, .x = 3}; // C99 도입, 순서 없이 멤버 지정으로 초기화 가능
struct Point p2 = {.x = 10}; // C99, 부분 초기화도 가능. C++에서는 동작 안 함.
typedef 키워드와 구조체 별칭
typedef 키워드를 사용하는 간단한 예제는 다음과 같습니다.
코드: integer_example.c
#include <stdio.h>
// int 타입의 별칭으로 integer를 정의합니다.
typedef int integer;
int main(void)
{
// integer 타입의 변수 a를 선언하고 10으로 초기화합니다.
integer a = 10;
// 변수 a의 값을 출력합니다.
printf("a = %d\n", a); // a = 10
return 0;
}
a = 10
위의 코드에서 typedef int integer;
는 integer
타입을 int
타입으로 정의합니다. 이렇게 정의한 후, integer
타입으로 변수를 선언할 수 있습니다. 예제에서는 integer a = 10;
처럼 integer
타입의 변수 a
를 선언하였습니다.
C 언어에서 구조체를 별칭으로 정의하는 간단한 예제는 다음과 같습니다:
코드: point_example_typedef.c
#include <stdio.h>
// point 구조체 선언
struct point
{
int x; // x 좌표를 저장하는 정수형 변수
int y; // y 좌표를 저장하는 정수형 변수
};
// struct point를 Point로 별칭(alias) 지정
typedef struct point Point;
int main(void)
{
Point p1; // Point 구조체 변수 p1 선언
p1.x = 10; // p1의 x 좌표에 10 할당
p1.y = 20; // p1의 y 좌표에 20 할당
// p1의 x, y 좌표 출력
printf("(%d, %d)\n", p1.x, p1.y);
return 0;
}
(10, 20)
위 예제에서는 구조체 point
를 정의한 후, typedef
키워드와 struct
키워드를 사용하여 구조체 point
의 별칭인 Point
를 정의하였습니다. 이제 Point
타입을 사용하여 구조체 변수를 선언할 수 있습니다.
별칭을 정의하면 구조체 이름이 길거나 복잡할 때, 코드의 가독성을 높일 수 있습니다.
typedef를 사용한 익명 구조체
typedef를 사용하여 익명 구조체를 정의하면, 구조체의 이름을 명시하지 않고도 구조체를 사용할 수 있습니다. 이를 통해 코드가 간결해지며 가독성이 향상됩니다. 아래 예제는 typedef를 사용한 익명 구조체를 정의하고 사용하는 방법을 보여줍니다.
코드: anonymous_structure.c
#define _CRT_SECURE_NO_WARNINGS // Visual Studio의 보안 경고를 무시하기 위한 매크로 정의
#include <stdio.h>
#include <string.h> // 문자열 관련 함수를 사용하기 위해 string.h 헤더 파일 포함
// Person 구조체 정의
typedef struct
{
char name[100]; // 이름을 저장할 문자 배열
int age; // 나이를 저장할 정수형 변수
} Person;
int main(void)
{
Person person; // Person 구조체 변수 person 선언
// person의 이름 필드에 "John Doe"를 복사
strcpy(person.name, "John Doe");
person.age = 30; // person의 나이 필드에 30 할당
// person의 이름과 나이 출력
printf("Name: %s\n", person.name);
printf("Age: %d\n", person.age);
return 0;
}
Name: John Doe
Age: 30
위의 코드에서 typedef struct {...} Person;
부분이 익명 구조체를 정의하고, 이를 Person
이라는 별칭으로 사용할 수 있게 합니다. 이후 Person
타입의 변수를 선언하고 멤버에 접근할 수 있습니다.
구조체와 scanf 함수 사용하기
아래 코드는 구조체를 사용하여 이름과 나이를 입력받고 출력하는 예제입니다.
코드: person_info.c
#define _CRT_SECURE_NO_WARNINGS // Visual Studio의 보안 경고를 무시
#include <stdio.h>
// person 구조체 정의
struct person
{
char name[20]; // 이름을 저장할 문자 배열
int age; // 나이를 저장할 정수형 변수
};
int main(void)
{
struct person p1; // person 구조체 변수 p1 선언
// 이름 입력 받기
printf("이름을 입력하세요: ");
scanf("%s", p1.name);
// 나이 입력 받기
printf("나이를 입력하세요: ");
scanf("%d", &p1.age);
// 입력받은 이름과 나이 출력하기
printf("이름: %s\n", p1.name);
printf("나이: %d\n", p1.age);
return 0;
}
이름을 입력하세요: Lisa
나이를 입력하세요: 21
이름: Lisa
나이: 21
+--------------+
| person 구조체 |
+--------------+
| |
| name: "Lisa" |
| |
| age: 21 |
| |
+--------------+
이 예제에서는 person
이라는 구조체를 정의하고, 구조체 변수 p1
을 선언하여 구조체 내부의 멤버 변수인 name
과 age
에 값을 입력받습니다.
구조체 멤버에 값을 저장할 때도 scanf
를 사용할 수 있습니다.
예제에서는 문자열을 입력받기 위해 %s
서식 지정자를 사용하며, p1.name
이 배열이기 때문에 &
를 사용하지 않고 그대로 scanf
함수의 인자로 전달합니다.
정수를 입력받기 위해 %d
형식 지정자를 사용하고, p1.age
는 정수형 변수이므로 주소를 전달하기 위해 &
를 사용합니다.
scanf 함수를 통해 구조체 멤버에 값을 쉽게 저장할 수 있어 사용자 입력을 효과적으로 관리할 수 있습니다.
C# 교과서 22장 구조체 사용하기 동영상 강의
C 언어 강의가 완료되면 C# 강의에서 C 언어 강의로 대체됩니다. 다만, 개념은 동일하기에 C 언어를 학습하고 있어도 맛보기로 보는 걸 추천합니다.
구조체 소개
구조체(Struct)는 하나의 데이터 묶음을 하는 레코드 역할을 합니다.
앞서 배운 변수는 하나의 이름으로 하나의 공간을 갖고, 배열은 하나의 이름으로 동일한 데이터 타입을 갖는 여러 개의 공간을 갖습니다.
변수와 배열을 확장하여 하나의 이름으로 여러 개의 데이터 타입을 한 개 또는 여러 개 보관하는 그릇 역할을 하는 것이 바로 구조체(Struct)입니다.
구조체는 int
, char[]
등의 서로 다른 자료를 하나의 집단으로 정의하여 하나의 이름으로 지정할 수 있는 여러 항목들의 모임으로, 데이터베이스에서 말하는 레코드(Record) 개념으로 볼 수 있습니다.
구조체 변수란 하나의 이름으로 하나 이상의 데이터 타입을 하나 보관해 놓는 그릇 역할이고, 구조체 배열은 하나의 이름으로 하나 이상의 데이터 타입을 여러 개 보관해 놓는 그릇 역할을 하는 것으로 볼 수 있습니다.
구조체 만들기
구조체를 만드는 방법은 다음과 같습니다. 구조체를 의미하는 struct
키워드를 사용하여 구조체를 만들고 중괄호 안에 구조체의 멤버들을 생성할 수 있습니다.
struct 구조체명
{
데이터타입 변수1;
데이터타입 변수2;
데이터타입 변수3;
};
위에서 구조체명은 새로운 데이터 타입이 되며, 변수를 선언할 때 구조체 이름을 사용할 수 있습니다. 구조체를 가리켜 사용자 정의 데이터 타입
으로 부르기도 합니다.
구조체를 사용하여 하나 이상의 변수 또는 배열을 묶어서 관리
구조체를 사용하여 하나 이상의 변수를 묶어서 사용하는 방법에 대해서 예제로 먼저 살펴보겠습니다.
다음 예제 코드는 Point 이름으로 X와 Y를 담을 수 있는 구조체를 만들고 값을 저장 후 이를 다시 출력하는 내용입니다.
코드: StructDemo.c, struct_demo.c
//[?] 구조체: 하나 이상의 변수 또는 배열을 묶어서 관리
#include <stdio.h>
struct Point
{
int X;
int Y;
};
int main(void)
{
struct Point point; // Point 구조체 형식의 변수 선언
point.X = 100; // 점을 구분해서 X 변수에 값을 할당
point.Y = 200; // 점을 구분해서 Y 변수에 값을 할당
printf("X: %d, Y: %d\n", point.X, point.Y); // X: 100, Y: 200
return 0;
}
X: 100, Y: 200
구조체를 선언할 때에는 struct
키워드를 사용합니다. struct Point {};
형태로 Point
이름의 구조체를 만듭니다.
만들어진 구조체는 int
, char
형식의 변수 선언과 동일한 방법으로 선언 후 사용할 수 있습니다.
다만, 변수와의 차이점은 변수는 하나의 값만 저장하는 대신에 구조체는 점(.
)을 구분으로 구조체 선언 시 사용한 여러 개의 변수를 하나의 이름(point
)으로 묶어서 사용할 수 있는 장점을 가집니다.
이처럼 구조체를 사용하면 하나의 이름으로 여러 데이터를 저장하여 사용할 수 있습니다.
구조체 사용하기
아래는 구조체를 사용한 간단한 예제입니다:
#include <stdio.h>
struct person {
char name[20];
int age;
};
int main() {
struct person p1;
printf("이름을 입력하세요: ");
scanf("%s", p1.name);
printf("나이를 입력하세요: ");
scanf("%d", &p1.age);
printf("이름: %s\n", p1.name);
printf("나이: %d\n", p1.age);
return 0;
}
위 예제에서는 구조체 person을 정의하였으며, 구조체 변수 p1을 선언하여 구조체 내부의 멤버 변수인 name과 age에 값을 입력받습니다. 그리고 입력받은 값을 출력합니다.
변수, 배열, 구조체 비교
코드: struct_description.c, StructDescription.c
// 구조체(Structure;Struct): 하나의 이름으로 서로 다른 데이터 타입을 묶어서 관리
#include <stdio.h>
//[!] 구조체 선언: 회원 관리
struct Member
{
char* Name; // 이름
int Age; // 나이
double Weight; // 몸무게
};
int main(void)
{
//[1] 변수(Variable): 하나의 이름으로 하나의 데이터 타입을 하나만 보관해 놓는 그릇
int num = 10;
//[2] 배열(Array): 하나의 이름으로 동일한 데이터 타입을 하나 이상 보관
int data[5] = { 10, 20, 30, 40, 50 };
//[3] 구조체(Struct)
struct Member objMember; //[a] 구조체 형식의 변수 선언
objMember.Name = "홍길동"; //[b] 구조체 각각의 멤버 변수(Member)를 초기화
objMember.Age = 21;
objMember.Weight = 100.05;
printf("이름: %s, 나이: %d, 몸무게: %.2f\n",
objMember.Name, objMember.Age, objMember.Weight); //[c] 구조체 참조
return 0;
}
이름: 홍길동, 나이: 21, 몸무게: 100.05
구조체 선언, 초기화, 참조
코드: 구조체_member.c
// 구조체 : 서로 다른 데이터형식을 하나의 이름으로 묶어서 관리
#include <stdio.h>
// 구조체 선언 : 새로운 데이터 형식인 member 형을 선언
struct member
{
char* name; // 이름
int age; // 나이
long money; // 연봉
};
int main(void)
{
// 구조체 형 변수 선언 : 개체의 인스턴스 생성(C#/C++)
struct member m;
// 구조체의 각각의 멤버를 초기화
m.name = "박용준";
m.age = 21;
m.money = 2100000000; // 21억
// 구조체 참조
printf("이름 : %s, 나이 : %d, 연봉 : %ld원\n", m.name, m.age, m.money);
}
이름 : 박용준, 나이 : 21, 연봉 : 2100000000원
구조체 선언과 동시에 초기화
코드: StructInitializer.c
#include <stdio.h>
//[?] 구조체 선언: 회원 관리
struct Member
{
char* Name; // 이름
int Age; // 나이
double Weight; // 몸무게
} objMember = { "백두산", 100, 70.05 };
int main(void)
{
//[!] 구조체(Struct) 참조
printf("이름: %s, 나이: %d, 몸무게: %.2f\n",
objMember.Name, objMember.Age, objMember.Weight);
return 0;
}
이름: 백두산, 나이: 100, 몸무게: 70.05
typedef
키워드
C 언어에서 typedef 키워드를 사용하는 간단한 예제는 다음과 같습니다.
#include <stdio.h>
typedef int integer;
int main() {
integer a = 10;
printf("a = %d\n", a);
return 0;
}
위의 코드에서 typedef int integer;
는 integer
타입을 int
타입으로 정의합니다. 이렇게 정의한 후, integer
타입으로 변수를 선언할 수 있습니다. 예제에서는 integer a = 10;
처럼 integer
타입의 변수 a
를 선언하였습니다.
구조체 별칭
C 언어에서 구조체를 별칭으로 정의하는 간단한 예제는 다음과 같습니다:
#include <stdio.h>
struct point {
int x;
int y;
};
typedef struct point Point;
int main() {
Point p1;
p1.x = 10;
p1.y = 20;
printf("(%d, %d)\n", p1.x, p1.y);
return 0;
}
위 예제에서는 구조체 point를 정의한 후, typedef 키워드와 struct 키워드를 사용하여 구조체 point의 별칭인 Point를 정의하였습니다. 이제 Point 타입을 사용하여 구조체 변수를 선언할 수 있습니다.
별칭을 정의하면 구조체 이름이 길거나 복잡할 때, 코드의 가독성을 높일 수 있습니다.
typedef
를 사용한 익명 구조체
C 언어에서 typedef
를 사용한 익명 구조체를 정의하고 사용하는 예제는 다음과 같습니다.
#include <stdio.h>
#include <string.h>
typedef struct {
char name[100];
int age;
} Person;
int main() {
Person person;
strcpy(person.name, "John Doe");
person.age = 30;
printf("Name: %s\n", person.name);
printf("Age: %d\n", person.age);
return 0;
}
위의 코드에서 typedef struct {...} Person;
은 Person
타입의 익명 구조체를 정의합니다. 이렇게 정의한 후, Person
타입으로 변수를 선언할 수 있습니다. 예제에서는 Person person;
처럼 Person
타입의 변수 person
을 선언하였습니다.
C 언어에서 구조체를 사용한 회원 정보 표시
이 글에서는 C 언어에서 구조체를 사용해 회원 정보를 저장하고 표시하는 방법을 보여드립니다. 예제 프로그램의 이름은 member_info_struct.c
입니다.
소스 코드: member_info_struct.c
예제 프로그램의 전체 소스 코드는 다음과 같습니다:
/*
구조체를 사용한 회원 정보 : member_info_struct.c
*/
#include <stdio.h>
// 구조체 선언
typedef struct member
{
char *name;
char *addr;
char *birth;
char *tel;
} Member;
int main()
{
// 구조체 형 변수 선언
Member objMember;
// 구조체 초기화
objMember.name = "지호";
objMember.addr = "서울";
objMember.birth = "050527";
objMember.tel = "114";
// 구조체 참조
printf("이름: %s\n", objMember.name);
printf("주소: %s\n", objMember.addr);
printf("생년월일: %s\n", objMember.birth);
printf("전화번호: %s\n", objMember.tel);
return 0;
}
이름: 지호
주소: 서울
생년월일: 050505
전화번호: 114
코드 설명
typedef struct member
를 사용하여 회원 정보를 저장할 구조체를 정의합니다. 이 구조체에는 이름, 주소, 생년월일, 전화번호를 저장하는 문자열 포인터 변수가 포함되어 있습니다.main()
함수에서Member
타입의 변수objMember
를 선언합니다.objMember
변수의 각 필드를 초기화합니다. 문자열은 이 예제에서 직접 대입되지만, 실제 상황에서는 사용자로부터 입력을 받거나 파일에서 읽어올 수 있습니다.printf()
함수를 사용하여objMember
의 각 필드를 출력합니다.
이 프로그램은 구조체를 사용하여 회원 정보를 저장하고 출력하는 간단한 예제입니다. 구조체를 사용하면 관련 데이터를 그룹화하여 코드를 더 직관적이고 관리하기 쉽게 만들 수 있습니다.
구조체 배열
구조체에도 배열을 사용할 수 있습니다. 다음과 같이 구조체 배열을 사용하여 1000개의 명함구조체를 만들 수 있습니다.
명함구조체 명함배열[1000];
만들어진 구조체 배열은 다음과 같이 0번째 인덱스부터 999번째 인덱스까지 배열을 사용하여 이름, 주소, 전화번호 멤버에 접근해서 값을 할당하거나 값을 참조해서 사용할 수 있습니다.
이름 | 주소 | 전화번호 |
---|---|---|
명함배열[0].이름 | 명함배열[0].주소 | 명함배열[0].전화번호 |
... | ... | ... |
... | ... | ... |
... | ... | ... |
명함배열[999].이름 | 명함배열[999].주소 | 명함배열[999].전화번호 |
구조체 배열 선언하기
C 언어에서 구조체 배열을 선언하는 예제는 다음과 같습니다.
#include <stdio.h>
typedef struct {
char name[100];
int age;
} Person;
int main() {
Person people[3];
strcpy(people[0].name, "John Doe");
people[0].age = 30;
strcpy(people[1].name, "Jane Doe");
people[1].age = 25;
strcpy(people[2].name, "Jim Doe");
people[2].age = 40;
for (int i = 0; i < 3; i++) {
printf("Name: %s\n", people[i].name);
printf("Age: %d\n", people[i].age);
}
return 0;
}
위의 코드에서 Person people[3];
은 Person
타입의 배열 people
을 정의합니다. 그리고 각 요소에 접근할 때는 [i]
연산자를 사용합니다. for
루프를 사용하여 배열의 각 요소에 접근하여 값을 설정하고 출력할 수 있습니다.
구조체 배열을 사용해서 데이터 대입 및 출력하기
이번에는 변수와 배열을 사용할 때 이미 알고 있는 데이터 타입을 사용하지 않고 새롭게 만든 데이터 타입, 즉 구조체를 만들어 그 구조체 형식 변수 및 배열을 사용하는 방법을 알아보겠습니다.
코드: StructArray.c
#include <stdio.h>
//[!] 구조체 선언: 회원 관리
struct Member
{
char* Name; // 이름
int Age; // 나이
double Weight; // 몸무게
};
int main(void)
{
int i;
//[1] 구조체 배열 선언
struct Member m[3]; // Member 형식이 3개가 준비
//[2] 초기화
m[0].Name = "홍길동";
m[0].Age = 21;
m[0].Weight = 100.05;
m[1].Name = "백두산";
m[1].Age = 100;
m[1].Weight = 70.05;
m[2].Name = "임꺽정";
m[2].Age = 40;
m[2].Weight = 150.05;
//[3] 참조
for (i = 0; i < 3; i++)
{
printf("%s, %3d, %6.2f\n", m[i].Name, m[i].Age, m[i].Weight);
}
return 0;
}
홍길동, 21, 100.05
백두산, 100, 70.05
임꺽정, 40, 150.05
Member
구조체를 사용하여 변수와 배열을 만들어 보았습니다.
구조체 배열 선언과 동시에 초기화
코드: StructArrayInitializer.c
#include <stdio.h>
//[!] 구조체 선언: 회원 관리
struct Member
{
char* Name; // 이름
int Age; // 나이
double Weight; // 몸무게
};
int main(void)
{
//[1][2] 구조체 배열 선언과 동시에 초기화
struct Member m[] =
{
{"홍길동", 21, 100.05}, {"백두산", 100, 70.05}, {"임꺽정", 40, 150.00}
};
//[3] 참조
for (int i = 0; i < 3; i++)
{
printf("%s, %3d, %6.2f\n", m[i].Name, m[i].Age, m[i].Weight);
}
return 0;
}
홍길동, 21, 100.05
백두산, 100, 70.05
임꺽정, 40, 150.00
코드: 구조체_구조체배열.c
#include <stdio.h>
// 구조체 선언
struct member
{
char* name; // 이름
int age; // 나이
long money; // 연봉
};
int main(void)
{
int i;
//// 구조체 배열 선언
//struct member objMembers[3];
//// 구조체 배열 초기화
//objMembers[0].name = "홍길동";
//objMembers[0].age = 21;
//objMembers[0].money = 1000;;
//objMembers[1].name = "백두산";
//objMembers[1].age = 31;
//objMembers[1].money = 2000;;
//objMembers[2].name = "임꺽정";
//objMembers[2].age = 41;
//objMembers[2].money = 3000;;
// 구조체 배열 선언과 동시에 초기화
struct member objMembers[] = {
{"홍길동", 21, 1000}, {"백두산", 31, 2000}, {"임꺽정", 41, 3000}
};
// 출력
for (i = 0; i < 3; i++)
{
printf("%8s %2d %4ld\n", objMembers[i].name, objMembers[i].age, objMembers[i].money);
}
}
홍길동 21 1000
백두산 31 2000
임꺽정 41 3000
[!INCLUDE 중첩 구조체 사용하기)]
중첩 구조체를 사용하여 성적 리스트 출력
이 글에서는 C 언어에서 중첩 구조체를 사용하여 성적 리스트를 출력하는 방법을 소개합니다. 아래 코드는 struct_practice.c
또는 StructPractice.c
파일로 작성됩니다.
코드: struct_practice.c, StructPractice.c
#include <stdio.h>
// 점수 구조체 선언
struct score {
int kor; int eng;
};
// 학생 구조체 선언
struct student {
int num;
struct score scores;
};
int main(void)
{
// 구조체 배열 선언과 동시에 초기화
struct student s[3] = { {1, {100, 90}}, {2, {90, 80}}, {3, {80, 70}} };
// for 문으로 구조체 배열 참조
for (int i = 0; i < 3; i++)
{
printf("%d: %3d, %3d\n", s[i].num, s[i].scores.kor, s[i].scores.eng);
}
return 0;
}
이 코드를 실행하면 다음과 같은 출력 결과가 나옵니다.
1: 100, 90
2: 90, 80
3: 80, 70
본 예제에서는 점수 구조체를 선언하여 국어와 영어 성적을 저장하고, 학생 구조체를 선언하여 학생 번호와 점수 구조체를 포함시켰습니다.
s[i].num
, s[i].scores.kor
, 그리고 s[i].scores.eng
코드를 사용하여 구조체 배열의 각 요소를 참조합니다. s[i].num
은 학생 구조체의 학생 번호를 가져오는 데 사용되며, s[i].scores.kor
는 국어 성적, 그리고 s[i].scores.eng
는 영어 성적을 가져옵니다. 이렇게 각 구조체 요소를 참조하면서 for
문을 사용해 성적 리스트를 출력합니다. 이를 통해 중첩 구조체를 사용하여 데이터를 효율적으로 관리할 수 있습니다.
C 언어에서 중첩 구조체 사용하기
이 글에서는 C 언어에서 중첩 구조체를 사용해 회원 정보와 점수 정보를 저장하고 출력하는 방법을 보여드립니다. 예제 프로그램의 이름은 nested_struct_example.c
입니다.
소스 코드: nested_struct_example.c
예제 프로그램의 전체 소스 코드는 다음과 같습니다:
/*
중첩 구조체 : nested_struct_example.c
*/
#include <stdio.h>
typedef struct Subject
{
int Kor;
int Eng;
} Subject;
typedef struct Member
{
int Num;
char Name[25];
Subject Score;
} Member;
int main()
{
Member objMember = { 1, "홍길동", {100, 80} };
Member* p;
p = &objMember;
printf("번호: %d\n", objMember.Num);
printf("이름: %s\n", objMember.Name);
printf("국어점수: %d\n", objMember.Score.Kor);
printf("영어점수: %d\n", p->Score.Eng);
return 0;
}
번호: 1
이름: 홍길동
국어점수: 100
영어점수: 80
코드 설명
Subject
구조체는 국어 점수와 영어 점수를 저장하기 위한 두 개의 정수형 변수를 포함합니다. Member
구조체는 회원 번호, 이름, 그리고 Subject
구조체를 이용한 점수 정보를 담습니다. 이렇게 중첩 구조체를 활용하면 관련 정보를 그룹화하여 코드를 더 명확하고 관리가 쉬워집니다.
main()
함수에서는 Member
타입의 변수 objMember
를 선언하고 초기화합니다. 또한, Member
구조체 포인터 p
를 선언한 후 objMember
의 주소를 대입합니다. printf()
함수를 사용하여 objMember
의 각 필드를 출력하며, 영어 점수는 포인터 p
를 이용해 출력합니다.
이 프로그램은 중첩 구조체를 사용하여 회원 정보와 점수 정보를 저장하고 출력하는 간단한 예제를 보여줍니다. 중첩 구조체를 사용함으로써 코드의 가독성과 유지 보수성이 향상됩니다.
구조체 비트 필드
코드: 구조체비트필드.c
#include <stdio.h>
struct A
{
int a : 8; // 0~255 : 2^8 = 256
int b : 4; // 0~3 : 2^2 = 4
};
int main(void)
{
struct A a;
a.a = 100;
a.b = 3;
printf("%d %d \n", a.a, a.b);
printf("Size : %d\n", sizeof(a));//8Byte : 64Bit
system("pause");
}
100 3
Size : 4
코드: 구조체_구조체비트필드.c
#include <stdio.h>
// 멤버(필드)의 데이터 저장 범위
// i: 0~255
// j: 0~3
struct A
{
int i;
int j;
};
// 구조체 비트필드를 적용한 구조체.
struct B
{
int i : 8;//2^8=256
int j : 4;//2^4=8
};
void main()
{
struct A a; struct B b;
a.i = 100; a.j = 3; b.i = 100; b.j = 3;
printf("%d %d\n", a.i, a.j);
printf("%d\n", sizeof(a));//8Byte
printf("%d %d\n", b.i, b.j);
printf("%d\n", sizeof(b));//4Byte
system("pause");
}
100 3
8
100 3
4
typedef 키워드와 함께 사용 - 구조체.c
코드: 구조체.c
#include <stdio.h>
struct _BizCard
{
char* name;//문자열
int age;//정수
};
typedef struct _BizCard BizCard;
int main(void)
{
BizCard a;
a.name = "홍길동";
a.age = 21;
printf("%s %d\n", a.name, a.age);
}
홍길동 21
C# 참고 - 구조체 매개 변수 - 함수의 매개 변수에 구조체 사용하기
이번에는 함수의 매개 변수로 구조체를 전달하는 구조체 매개 변수를 사용해보겠습니다.
코드: StructParameter.cs
using System;
// Member 구조체 선언
struct Member
{
public string Name;
public int Age;
}
class StructParameter
{
static void Main()
{
//[1] 변수 사용
string name = "홍길동";
int age = 21;
Print(name, age); // 매개 변수를 따로 선언
//[2] 구조체 사용
Member m;
m.Name = "백두산";
m.Age = 100;
Print(m); // 구조체 매개 변수를 사용하여 전달
}
static void Print(string name, int age) =>
Console.WriteLine($"이름: {name}, 나이: {age}");
static void Print(Member member) =>
Console.WriteLine($"이름: {member.Name}, 나이: {member.Age}");
}
이름: 홍길동, 나이: 21
이름: 백두산, 나이: 100
변수를 사용하여 Print
함수에 name
과 age
를 전달하는 모양과 구조체를 사용하여 Print
함수에 구조체 변수인 member
를 전달하는 2가지 모양을 확인할 수 있습니다.
만약, 한번에 함수에 전달해야 하는 매개 변수가 많을 경우에는 이처럼 구조체에 묶어서 구조체 변수 하나로 전달해서 사용하면 복잡하지 않고 편리하게 매개 변수를 전달 할 수 있습니다.
장 요약
C 언어에서 구조체는 사용자 정의 데이터 타입을 만들어 내는 최상위 문법입니다. 기본 사용법을 간단히 익혔으니 또 다른 문법을 학습해 나가도록 하겠습니다.
포인터 배우고 나서(아직 안 배운 내용)
구조체를 포인터로 접근하기
C 언어에서 구조체를 포인터로 접근하는 예제는 다음과 같습니다:
#include <stdio.h>
struct point {
int x;
int y;
};
int main() {
struct point p1 = { 10, 20 };
struct point *p2 = &p1;
printf("x: %d\n", p2->x);
printf("y: %d\n", p2->y);
return 0;
}
위 예제에서는 구조체 변수 p1을 선언하고, 구조체 포인터 변수 p2를 선언하여 구조체 변수 p1의 주소를 가리키게 합니다. 그리고 포인터 p2를 사용하여 구조체 변수 p1의 멤버 변수인 x와 y에 접근합니다. 포인터를 사용하여 구조체 멤버에 접근할 때는 화살표 연산자(->
)를 사용합니다.
구조체 포인터를 선언 및 동적으로 메모리 할당하기
구조체 포인터를 선언하고 동적으로 메모리 할당하는 예제는 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[100];
int age;
} Person;
int main() {
Person *person = (Person *)malloc(sizeof(Person));
strcpy(person->name, "John Doe");
person->age = 30;
printf("Name: %s\n", person->name);
printf("Age: %d\n", person->age);
free(person);
return 0;
}
위의 코드에서 Person *person = (Person *)malloc(sizeof(Person));
는 Person
타입의 구조체를 가리키는 포인터 person
을 만들고, malloc
함수를 사용하여 Person
타입의 메모리를 할당합니다. 그리고 구조체 포인터의 필드에 접근할 때는 ->
연산자를 사용합니다. 예제에서는 person->name
, person->age
처럼 접근하였습니다. 마지막으로 free
함수를 사용하여 할당한 메모리를 해제합니다.
구조체 별칭으로 포인터 선언 및 메모리 할당
C 언어에서 구조체 별칭으로 포인터 선언 및 메모리 할당하는 예제는 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[100];
int age;
} Person;
int main() {
typedef Person* PPerson;
PPerson person = (PPerson)malloc(sizeof(Person));
strcpy(person->name, "John Doe");
person->age = 30;
printf("Name: %s\n", person->name);
printf("Age: %d\n", person->age);
free(person);
return 0;
}
위의 코드에서 typedef Person* PPerson;
은 Person
타입의 포인터를 가리키는 별칭 PPerson
을 정의합니다. 이렇게 정의한 후, PPerson
타입으로 포인터 변수를 선언할 수 있습니다. 예제에서는 PPerson person = (PPerson)malloc(sizeof(Person));
처럼 PPerson
타입의 포인터 변수 person
을 선언하였습니다. 그리고 구조체 포인터의 필드에 접근할 때는 ->
연산자를 사용합니다. 마지막으로 free
함수를 사용하여 할당한 메모리를 해제합니다.
구조체 포인터 배열 선언하기
C 언어에서 구조체 포인터 배열을 선언하는 예제는 다음과 같습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[100];
int age;
} Person;
int main() {
Person *people[3];
for (int i = 0; i < 3; i++) {
people[i] = (Person *) malloc(sizeof(Person));
}
strcpy(people[0]->name, "John Doe");
people[0]->age = 30;
strcpy(people[1]->name, "Jane Doe");
people[1]->age = 25;
strcpy(people[2]->name, "Jim Doe");
people[2]->age = 40;
for (int i = 0; i < 3; i++) {
printf("Name: %s\n", people[i]->name);
printf("Age: %d\n", people[i]->age);
free(people[i]);
}
return 0;
}
위의 코드에서 Person *people[3];은 Person 타입의 포인터 배열 people을 정의합니다. for 루프를 사용하여 각 요소에 대해 메모리를 할당합니다. 각 요소에 접근할 때는 -> 연산자를 사용합니다. for 루프를 사용하여 각 요소에 접근하여 값을 설정하고 출력할 수 있습니다. 그리고 free 함수를 사용하여 할당한 메모리를 해제합니다.
구조체 사용 성적 처리 프로그램 작성
이번 강좌에서는 C언어의 구조체를 사용하여 성적 처리 프로그램을 작성하는 방법을 배워보겠습니다.
구조체란?
구조체(Structure)는 C언어에서 여러 개의 변수를 묶어서 하나의 데이터 형식으로 정의할 수 있는 기능입니다. 이를 통해 복잡한 데이터를 효율적으로 관리할 수 있습니다.
구조체는 struct
키워드와 함께 선언할 수 있습니다. 예를 들어, 아래와 같이 이름과 나이를 저장하는 구조체를 선언할 수 있습니다.
struct Person {
char name[20];
int age;
};
이 구조체를 사용하여 여러 개의 사람 정보를 저장할 수 있습니다.
struct Person p1 = {"Alice", 25};
struct Person p2 = {"Bob", 30};
구조체를 사용한 성적 처리 프로그램
이제 구조체를 사용하여 성적 처리 프로그램을 작성해보겠습니다. 먼저, 학생의 이름과 국어 점수, 영어 점수를 저장하는 구조체를 정의합니다.
typedef struct Score {
char name[10]; // *name : 이름
int kor;
int eng;
} Score;
이 구조체는 학생의 이름과 국어 점수, 영어 점수를 저장할 수 있는 멤버 변수를 가지고 있습니다.
다음으로, main()
함수에서는 Score
구조체 형 배열을 선언합니다. 이 배열은 두 명의 학생에 대한 성적을 저장합니다.
int main() {
int i = 0;
Score objScore[2];
// ...
}
for 루프를 사용하여 scanf()
함수를 통해 학생의 이름, 국어 점수, 영어 점수를 입력받습니다.
for (i = 0; i < 2; i++) {
printf("\n%d번째 이름 : ", i + 1);
scanf("%9s", objScore[i].name);
printf("\n국어점수 : ");
scanf("%d", &objScore[i].kor);
printf("\n영어점수 : ");
scanf("%d", &objScore[i].eng);
}
이때 %9s
를 사용하여 이름을 입력받습니다. %9s
는 문자열의 길이를 9로 제한하는 서식지정자입니다.
다음으로, for
루프를 사용하여 Score
배열의 각 요소에 대해 총점과 평균을 계산합니다. 총점은 kor
와 eng
멤버 변수의 합으로 계산되며, 평균은 tot
멤버 변수를 2.0으로 나눈 결과입니다.
// Process : 총점과 평균 구하기.
for (i = 0; i < 2; i++) {
// 총점
objScore[i].tot = objScore[i].kor + objScore[i].eng;
// 평균
objScore[i].avg = objScore[i].tot / 2.0;
}
마지막으로, for
루프를 사용하여 각 학생의 이름, 국어 점수, 영어 점수, 총점, 평균을 출력합니다.
printf("이름\t국어\t영어\t총점\t평균\t\n");
for (i = 0; i < 2; i++) {
printf("%6s %4d %4d %4d %4.1f\n",
objScore[i].name,
objScore[i].kor,
objScore[i].eng,
objScore[i].tot,
objScore[i].avg);
}
이렇게 구현된 성적 처리 프로그램은 두 명의 학생에 대한 성적을 입력받아 총점과 평균을 계산하고, 이를 출력합니다.
전체 소스는 다음과 같습니다.
코드: struct_score.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 구조체 설계.
typedef struct Score
{
char name[10]; // *name : 이름
int kor;
int eng;
int tot;
double avg;
} Score;
int main(void)
{
int i = 0;
Score score[2];
// 구조체 형 배열 초기화 : scanf()
for (i = 0; i < 2; i++)
{
printf("%d번째 이름: ", i + 1);
scanf("%9s", score[i].name);
printf("국어점수: ");
scanf("%d", &score[i].kor);
printf("영어점수: ");
scanf("%d", &score[i].eng);
}
// Process : 총점과 평균 구하기.
for (i = 0; i < 2; i++)
{
// 총점
score[i].tot = score[i].kor + score[i].eng;
// 평균
score[i].avg = score[i].tot / 2.0;
}
// Output : 결과 출력
printf("\n 이름 국어 영어 총점 평균\n");
for (i = 0; i < 2; i++)
{
printf("%5s %5d %5d %5d %5.1f\n",
score[i].name,
score[i].kor,
score[i].eng,
score[i].tot,
score[i].avg);
}
return 0;
}
1번째 이름: AAA
국어점수: 100
영어점수: 90
2번째 이름: BBB
국어점수: 95
영어점수: 85
이름 국어 영어 총점 평균
AAA 100 90 190 95.0
BBB 95 85 180 90.0
마무리
이번 강좌에서는 C언어의 구조체를 사용하여 성적 처리 프로그램을 작성하는 방법을 배워보았습니다. 구조체는 여러 개의 변수를 묶어서 하나의 자료형으로 정의할 수 있는 기능으로, 복잡한 데이터를 효율적으로 관리할 수 있습니다. 구조체를 사용하여 성적 처리 프로그램을 구현하면, 입력한 학생의 성적을 효율적으로 저장하고 처리할 수 있습니다.
면접 및 코딩 테스트 준비
- 구조체란 무엇인가요?
- 구조체는 어떻게 선언하나요?
- 구조체 멤버의 데이터 타입은 무엇이 될 수 있나요?
- 구조체 멤버의 이름은 어떻게 지정하나요?
- 구조체 변수는 어떻게 선언하나요?
- 구조체 변수에 값을 할당하는 방법은 무엇인가요?
- 구조체 변수의 멤버에 접근하는 방법은 무엇인가요?
- 구조체 변수를 함수의 인자로 전달하는 방법은 무엇인가요?
- 구조체 변수를 반환하는 함수를 만들 때 주의할 점은 무엇인가요?
- 구조체를 배열로 선언하는 방법은 무엇인가요?
- 구조체 배열의 멤버에 접근하는 방법은 무엇인가요?
- 구조체 포인터는 무엇이고 어떻게 선언하나요?
- 구조체 포인터를 사용하여 구조체 멤버에 접근하는 방법은 무엇인가요?
- 구조체 포인터를 사용하여 구조체 배열에 접근하는 방법은 무엇인가요?
- 구조체를 함수의 인자로 전달할 때 구조체 포인터를 사용하는 이유는 무엇인가요?
- 구조체를 함수의 인자로 전달할 때 구조체를 직접 전달하는 방법은 무엇인가요?
- 구조체 배열을 함수의 인자로 전달할 때는 어떻게 해야 하나요?
- 구조체를 파일에 쓰고 읽는 방법은 무엇인가요?
- 구조체를 동적 할당하는 방법은 무엇인가요?
- 구조체를 사용하여 연결 리스트를 구현하는 방법은 무엇인가요?
- 구조체를 사용하여 이중 연결 리스트를 구현하는 방법은 무엇인가요?
- 구조체를 사용하여 스택을 구현하는 방법은 무엇인가요?
- 구조체를 사용하여 큐를 구현하는 방법은 무엇인가요?
- 구조체를 사용하여 트리를 구현하는 방법은 무엇인가요?
- typedef를 사용하여 구조체를 새로운 데이터 타입으로 정의하는 방법은 무엇인가요?
- 구조체를 포인터 배열로 정의하는 방법은 무엇인가요?
- 구조체의 멤버가 배열인 경우의 접근 방법은 무엇인가요?
- 구조체의 멤버가 함수 포인터인 경우의 접근 방법은 무엇인가요?
- 구조체 멤버에 대한 비트 필드를 사용하는 방법은 무엇인가요?
- 구조체를 사용하여 union을 구현하는 방법은 무엇인가요?
- 구조체 내부에 구조체를 정의하는 방법은 무엇인가요?
- 구조체의 크기를 계산하는 방법은 무엇인가요?
- 구조체의 정렬 방식을 변경하는 방법은 무엇인가요?
- 구조체 내부에 padding이 발생하는 이유는 무엇인가요?
- 구조체 멤버의 크기와 정렬에 영향을 주는 데이터 타입이 무엇인가요?
- attribute ((packed))를 사용하여 구조체의 패딩을 없애는 방법은 무엇인가요?
- 구조체에서 임의의 메모리 위치에 데이터를 저장하는 방법은 무엇인가요?
- 비트 필드를 사용하여 구조체의 크기를 최소화하는 방법은 무엇인가요?
- 비트 필드를 사용하여 여러 개의 데이터를 저장하는 방법은 무엇인가요?
- 비트 필드를 사용하여 상태 정보를 저장하는 방법은 무엇인가요?
- 구조체의 멤버에 대한 메모리 접근 방식은 무엇인가요?
- 구조체의 멤버에 대한 메모리 접근 방식을 변경하는 방법은 무엇인가요?
- 구조체를 사용하여 전체적인 메모리 구조를 설계하는 방법은 무엇인가요?
- 구조체의 멤버를 초기화하는 방법은 무엇인가요?
- 구조체에서 문자열을 저장하는 방법은 무엇인가요?
- 구조체에서 문자열을 복사하는 방법은 무엇인가요?
- 구조체에서 문자열을 비교하는 방법은 무엇인가요?
- 구조체에서 동적으로 메모리를 할당하는 방법은 무엇인가요?
- 구조체에서 메모리를 해제하는 방법은 무엇인가요?
- 구조체에서 메모리 관리를 위한 도구로서 메모리 풀을 사용하는 방법은 무엇인가요?
문제 풀이
정보처리기능사 실기 문제: 구조체 배열 초기화 및 멤버 값의 합 계산
이 문제에서는 C 언어를 사용하여 구조체 배열을 초기화하고, 특정 구조체 멤버들의 값을 계산하여 출력하는 프로그램을 작성하는 것이 목표입니다. 이 과정에서 구조체 배열의 정의, 초기화 방법, 그리고 구조체 멤버에 접근하여 연산을 수행하는 방법에 대해 이해해야 합니다.
문제: A
라는 구조체가 있습니다. 이 구조체는 두 개의 정수 멤버 n
과 g
를 가집니다. 구조체 타입 A
의 배열 st
를 선언하고, 배열의 각 요소에 대해 n
멤버에는 배열의 인덱스 값을, g
멤버에는 인덱스 값에 1을 더한 값을 할당합니다. 이후, 배열의 첫 번째 요소의 n
값과 두 번째 요소의 g
값을 더한 결과를 출력하는 C 프로그램을 작성하시오.
#include <stdio.h>
struct A {
int n;
int g;
};
main() {
struct A st[2]; // 구조체 A 타입의 배열 선언
// 배열의 각 요소에 대해 n과 g를 초기화
for (int i = 0; i < 2; i++) {
st[i].n = i;
st[i].g = i + 1;
}
// 첫 번째 요소의 n 값과 두 번째 요소의 g 값을 더하여 출력
printf("%d", st[0].n + st[1].g);
}
해결 방법:
#include <stdio.h>
를 사용하여 표준 입출력 라이브러리를 포함합니다.A
라는 이름의 구조체를 정의합니다. 이 구조체는 두 개의 정수 멤버n
과g
를 포함합니다.A
타입의 구조체 배열st
를 크기 2로 선언합니다.for
반복문을 사용하여 배열st
의 각 요소에 대해, 멤버n
에는 반복 변수i
의 값을, 멤버g
에는i + 1
의 값을 할당합니다.- 배열
st
의 첫 번째 요소의n
멤버 값과 두 번째 요소의g
멤버 값을 더한 결과를printf
함수를 사용하여 출력합니다.
이 문제는 구조체 배열의 사용법과 각 요소의 멤버에 값을 할당하는 방법을 이해하는 데 중점을 둡니다. 또한, 구조체 멤버 값을 사용하여 간단한 수학 연산을 수행하고 그 결과를 출력하는 기본적인 프로그래밍 능력을 평가합니다.