1. 구조체와 공용체
구조체 (structure) : 정수나 문자, 실수나 포인터 그리고 이들의 배열 등을 묶어 하나의 자료형으로 이용하는 것
// 구조체 예시
struct student
{
// field or memder
char name[20];
int age;
char student_number[20];
}
// 구조체를 이용하여 객체 생성
struct student Student1;
+ 구조체 정의는 변수의 선언과는 다른 것으로 변수 선언에서 이용될 새로운 구조체 자료형을 정의하는 구문
+ 구조체 멤버의 초기값을 대입할 수 없음
+ 한 구조체 내부에서 선언되는 구조체 멤버의 이름은 모두 유일해야 함
+ 구조체 멤버로는 일반 변수, 포인터 변수, 배열 등이 가능하며 다른 구조체 변수 및 구조체 포인터도 허용
구조체 변수 초기화
초기화 값은 중괄호 내부에서 구조체의 각 멤버 정의 순서대로 초기값을 쉼표로 구분하여 기술
배열과 같이 초기값에 기술되지 않은 멤버 값은 자료형에 따라 기본값인 0, 0.0, '\0' 등으로 저장
// 구조체 변수 선언 + 초기화
struct student Student1 = {"김철수", 22, "202047859"};
struct student Student2 = {"박지원", 25}; // student_number 멤버는 '\0'으로 저장
// 구조체 멤버 접근
Student1.age = 26;
#include <stdio.h>
#include <string.h>
// 은행 계좌 정보 구조체 정의
struct account
{
char name[12]; // 계좌주 이름
int actnum; // 계좌 번호
double balance; // 잔고
};
int main(void)
{
struct account mine = {"홍길동", 1001, 300000};
struct account yours; // 객체만 선언 초기화 X
struct account friend;
// 객체 yours 멤버 초기화 (멤버 각각 초기화)
strcpy(yours.name, "이동원");
// yours.name = "이동원"; => 오류
yours.actnum = 1002;
yours.balance = 200000;
// 객체 friend 멤버 초기화 (멤버 한번에 초기화)
friend = (struct account) { .name = "장규리", .actnum = 1003, .balance = 5000000};
// 구조체의 크기
printf("구조체의 크기 : %zu\n", sizeof(mine));
printf("[%s] %d 잔액 : %15.0f원\n", mine.name, mine.actnum, mine.balance);
printf("[%s] %d 잔액 : %15.0f원\n", yours.name, yours.actnum, yours.balance);
printf("[%s] %d 잔액 : %15.0f원\n", friend.name, friend.actnum, friend.balance);
return 0;
}
/*
구조체의 크기 : 24
[홍길동] 1001 잔액 : 300000원
[이동원] 1002 잔액 : 200000원
[장규리] 1003 잔액 : 5000000원
*/
구조체의 정의도 변수 선언 처럼 유효범위는 전역(global) 또는 지역(local)으로 모두 가능
동일한 구조체형 변수는 대입문이 가능하다.
mine = yours;
그러나 (mine == yours)와 같은 동등 비교는 할 수 없다.
만일 구조체를 비교하려면 구조체 멤버 하나하나를 비교해야 한다.
// 문자열을 처리하기 위한 포인터 char * 와 배열 char []
char *dept;
char name[12];
dept = "컴퓨터공학과";
// name = "컴퓨터공학과" => 오류발생
strcpy(name, "박지원"); // 올바른 사용
공용체(union) : 서로 다른 자료형의 값을 동일한 저장공간에 저장하는 자료형
=> 여러 멤버 변수 들을 동시에 저장하는 구조체와 달리 공용체는 하나의 변수 만을 유의미 하게 저장한다.
공용체 변수의 크기는 멤버 중 가장 큰 자료형의 크기로 정해진다.
union data
{
char ch;
int cnt;
double real;
} data1;
공용체의 멤버는 모든 멤버가 동일한 저장공간을 사용하므로 동시에 여러 멤버의 값을 동시에 저장하여 이용할 수 없으며, 마지막에 저장된 단 하나의 멤버 자료 값만을 저장
공용체의 초기화 값은 공용체 정의 시 처음 선언한 멤버의 초기값으로만 저장이 가능
#include <stdio.h>
union data
{
char ch;
int cnt;
double real;
} data1;
int main(void)
{
union data data2 = { 'A' };
union data data3 = {97.78};
union data data4;
data4.real = 3.78;
printf("공용체 크기 :%zu data3 크기 : %zu\n", sizeof(union data), sizeof(data3));
printf("%c %c %f\n\n", data2.ch, data3.ch, data4.real);
// 멤버에 ch 저장
data1.ch = 'a';
printf(" data1.ch : %c\n data1.cnt : %d\n data1.real : %f\n\n", data1.ch, data1.cnt, data1.real);
// 멤버에 cnt 저장
data1.cnt = 100;
printf(" data1.ch : %c\n data1.cnt : %d\n data1.real : %f\n\n", data1.ch, data1.cnt, data1.real);
// 멤버에 real 저장
data1.real = 3.156789;
printf(" data1.ch : %c\n data1.cnt : %d\n data1.real : %f\n", data1.ch, data1.cnt, data1.real);
return 0;
}
/*
공용체 크기 :8 data3 크기 : 8
A a 3.780000
data1.ch : a
data1.cnt : 97
data1.real : 0.000000
data1.ch : d
data1.cnt : 100
data1.real : 0.000000
data1.ch : ?
data1.cnt : -1755645192
data1.real : 3.156789
*/
2. 자료형 재정의
자료형 재정의 typedef
typedef는 이미 사용되는 자료 유형을 다른 새로운 자료형 이름으로 재정의할 수 있도록 하는 키워드
// typedef 기존자료유형이름 새로운자료형1, 새로운자료형2;
// => 여러이름으로도 재정의 가능
typedef int myint;
자료형을 재정의 하는 이유 : 프로그램의 시스템 간 호환성과 편의성을 위해 필요
문장 typedef도 일반 변수와 같이 그 사용 범위를 제한한다.
함수 내부에서 재정의 된다면, 그 함수에서만 이용이 가능하다.
#include <stdio.h>
struct date
{
int year;
int month;
int day;
};
// struct date 유형을 date 형으로 사용하기 위한 구문
typedef struct date date;
/*
typedef struct date
{
int year;
int month;
int day;
} date;
*/
// 위와 같이 사용하여도 무방
int main(void){
typedef struct
{
char title[50];
char company[30];
char kinds[30];
date release;
} software;
software vs = {"비주얼 스튜디오 커뮤니티", "MS", "통합개발환경", {2022, 7, 4} };
printf("제품명: %s\n", vs.title);
printf("회사 : %s\n", vs.company);
printf("종류 : %s\n", vs.kinds);
printf("출시일 : %d. %d. %d\n", vs.release.year, vs.release.month, vs.release.day);
return 0;
}
/*
제품명: 비주얼 스튜디오 커뮤니티
회사 : MS
종류 : 통합개발환경
출시일 : 2022. 7. 4
*/
3. 구조체와 공용체의 포인터 배열
구조체 포인터는 구조체의 주소값을저장하는 변수이다.
포인터 변수의 구조체 멤버 접근 연산자 ->
구조체 포인터 멤버 접근연산자 ->는 p->name과 같이 사용한다. 연산식 p->name은 포인터 p가 가리키는 구조체 변수의 멤버 name을 접근하는 연산식이다.
+ 연산식 p->name은 접근 연산자(.) 와 간접연산자(*)를 사용한 연산식 (*p).name으로도 사용 가능
(*p).name =! *p.name 임을 주의
+ 연산식 *p.name은 접근연산자(.)가 간접연산자(*)보다 우선순위가 빠르므로 *(p.name)과 같은 연산식
공용체 포인터도 동일
#include <stdio.h>
#include <string.h>
struct book
{
char title[50];
int book_id;
};
int main(void)
{
struct book c;
struct book* p;
p = &c;
strcpy(p->title, "C Programming");
p->book_id = 3429875;
printf("title : %s, id : %d\n", p->title, p->book_id); // 포인터 p가 가리키는 구조체 멤버 변수
printf("title : %s, id : %d\n", (*p).title, (*p).book_id);
printf("title : %s, id : %d\n", c.title, c.book_id); // 구조체 변수 c가 가리키는 멤버 변수
return 0;
}
/*
title : C Programming, id : 3429875
title : C Programming, id : 3429875
title : C Programming, id : 3429875
*/
#include <stdio.h>
#include <string.h>
struct book
{
char title[50];
int book_id;
};
int main(void)
{
struct book c[3];
struct book* p = c;
strcpy(p[0].title, "C Programming");
p[0].book_id = 3429872;
printf("p[0].title : %s, p[0].book_id : %d", p[0].title, p[0].book_id);
return 0;
}
// p[0].title : C Programming, p[0].book_id : 3429872
'C Programming' 카테고리의 다른 글
[C언어로 배우는 프로그래밍 기초 Perfect 3판] Chapter 14. 함수와 포인터 활용 (0) | 2022.07.04 |
---|---|
[C언어로 배우는 프로그래밍 기초 Perfect 3판] Chapter 13. 구조체와 공용체 - 프로그래밍 연습 (0) | 2022.07.04 |
[C언어로 배우는 프로그래밍 기초 Perfect 3판] Chapter 08 프로그래밍 연습 (0) | 2022.06.29 |
[C언어로 배우는 프로그래밍 기초 Perfect 3판] Chapter 07 프로그래밍 연습 (0) | 2022.06.29 |
[C언어로 배우는 프로그래밍 기초 Perfect 3판] Chapter 04 ~ 08 (0) | 2022.06.28 |