[C language] Geany편집기 -13. Structure(구조체, 구조체 연결, 구조체 배열)
#정리
#struct - 1.basic
//구조체(사용자 정의 자료형) : 사용자가 자료형을 만들어서 쓸 수 있다.
- 자바의 클래스선언, 객체(오브젝트)사용과 비슷하다. >> struct 선언, struct 변수 사용
//구조체 선언 (**블록 뒤에 ;을 꼭 붙여줘야한다.**)
- struct Test{ int x; char c2; double d; char name[10]; char *pt_name; };
//구조체 원소 초기화 방법 2가지
- 1. 배열로 구조체 원소 초기화 : struct Test2 t2 = {33,3.141592};- 2. 개별 원소 초기화 : t2.x = 22; / t2.d = 33.3;
//4byte를 기준으로, 용량이 부족하면 4byte 만큼씩 추가하면서 영역을 확보한다.
// 남는 공간(padding byte)제거 명령(Byte Alignment)
- #pragma pack(1) // Byte Alignment를 한다 라고도 한다.
//printf("x start index: %d\n", offsetof(struct Test, x));//x의 인덱스를 알려줌.
- #include <stddef.h>선언 필요
//문자열 배열은 바로 값을 넣지 못한다.-strcpy(t.name,"kim");
#struct_typedef - 2.타입 정의 활용
//구조체 타입을 사용자가 정의한 형태로 변경하는 방법 2가지
<1. (score)구조체 선언과 함께 typedef를 이용하여 사용자가 정의한 이름으로 구조체 타입명을 변경.>
- typedef struct Score{ 원소 }SS; >> SS sc = {"kim",77,88,99,0,0,'F'}; //struct Score 타입을 SS 타입으로 변경
<2. (board)구조체 선언 후, 메인 실행문에서 typedef를 이용하여 사용자가 정의한 이름으로 구조체 타입명을 변경.>
- typedef struct Board SB; //하지만, 메인 코드에서 이렇게 다 작성하게 되면 오히려 줄만 늘어나고 의미가 없다.
//(member) 구조체 타입 이름 없이, 변수 (mb) 선언까지 한 번에 할 수도 있다.
- 단, 이경우 변수 초기화를 배열로 할 수 없고, 일일히 값을 넣어줘야한다.
#struct_inner - 3. 구조체를 구조체의 원소로 사용
//struct inner : 다른 구조체를 구조체의 원소로 초기화
- typedef struct student{ ~ Contact ctt; Score sc; }Student; //구조체를 원소로 하는 구조체 선언- st.ctt = ctt; //student st 구조체의 원소 Contact ctt에 ctt의 값을 할당.
- printf("tel: %s\n",st.ctt.tel); //구조체 안의 구조체 값 출력.
#struct_array - 4.구조체 배열 다루기
//구조체 배열도정수 배열 생성과 동일한 형태로 생성한다.
- Student sts[2] ={st, st2}; // (정수 배열 생성) int sus[2] = {su1,su2};//특정 인덱스[i]가 가지는 원소(구조체 sc)의 안에 있는 값을 꺼낸다.
- printf("total: %d, avg: %.2lf, grade: %c\n",sts[i].sc.total, sts[i].sc.avg, sts[i].sc.grade);
#struct - 1.basic
//구조체(사용자 정의 자료형) : 사용자가 자료형을 만들어서 쓸 수 있다.
- 자바의 클래스선언, 객체(오브젝트)사용과 비슷하다. >> struct 선언, struct 변수 사용
//구조체 선언 (**블록 뒤에 ;을 꼭 붙여줘야한다.**)
- struct Test{ int x; char c2; double d; char name[10]; char *pt_name; };
//구조체 원소 초기화 방법 2가지
- 1. 배열로 구조체 원소 초기화 : struct Test2 t2 = {33,3.141592};
- 2. 개별 원소 초기화 : t2.x = 22; / t2.d = 33.3;
//4byte를 기준으로, 용량이 부족하면 4byte 만큼씩 추가하면서 영역을 확보한다.
// 남는 공간(padding byte)제거 명령(Byte Alignment)
- #pragma pack(1) // Byte Alignment를 한다 라고도 한다.
//printf("x start index: %d\n", offsetof(struct Test, x));//x의 인덱스를 알려줌.
- #include <stddef.h>선언 필요
//문자열 배열은 바로 값을 넣지 못한다.
-strcpy(t.name,"kim");
---------------------------------------
#mission : score /member /board
//board - 시스템에 내장된 시간 구조체 사용하여 시간 값을 받아옴.
- localtime( );
--예문 코드 보기--
#include <stdio.h>
#include <time.h>
#pragma pack(1) //padding byte remove
struct Score{
char *pt_name;
int kor;
int eng;
int math;
int total;
double avg;
char grade;
};
struct Member{
int num;
char *id;
char *pw;
char *name;
char *tel;
};
struct Board{
int num;
char *title;
char *content;
char *writer;
char *wdate;
};
char* local_time();
int main(int argc, char **argv)
{
printf("structure score...\n");
printf("--- score ---\n");
struct Score sc = {"kim",77,88,99,0,0,'F'};
sc.total = sc.kor + sc.eng + sc.math;
sc.avg = sc.total/3;
if(sc.avg>=90){
sc.grade = 'A';
}else if(sc.avg>=80){
sc.grade = 'B';
}else if(sc.avg>=70){
sc.grade = 'C';
}else if(sc.avg>=60){
sc.grade = 'D';
}else{
sc.grade = 'F';
}
printf("name: %s\n",sc.pt_name);
printf("kor: %d, eng: %d, math: %d\n",sc.kor, sc.eng, sc.math);
printf("total: %d, avg: %.2lf, grade: %c\n",sc.total, sc.avg, sc.grade);
printf("--- member ---\n");
struct Member mb = {1,"admin","hi123456","kim","010-111"};
printf("num:%d, id:%s, pw:%s, name:%s, tel:%s\n",mb.num,mb.id,mb.pw,mb.name,mb.tel);
printf("--- board ---\n");
struct Board bd = {1,"title1","content1","lee",local_time()};
printf("num:%d, title:%s, content:%s, writer:%s, wdate:%s\n",bd.num, bd.title, bd.content, bd.writer, bd.wdate);
return 0;
}
char* local_time(){
struct tm *pt_time; //시스템에 내장된 구조체 사용
time_t time_now;
time(&time_now);
printf("time_now:%ld\n",time_now);
pt_time = localtime(&time_now);
printf("time:%s\n",asctime(pt_time));//long타입의 시간을 문자열로 변환
char *wdate = asctime(pt_time);
printf("wdate:%s\n",wdate);
return wdate;
}
#struct_typedef - 2.타입 정의 활용
//구조체 타입을 사용자가 정의한 형태로 변경하는 방법 2가지
<1. (score)구조체 선언과 함께 typedef를 이용하여 사용자가 정의한 이름으로 구조체 타입명을 변경.>
- typedef struct Score{ 원소 }SS; >> SS sc = {"kim",77,88,99,0,0,'F'}; //struct Score 타입을 SS 타입으로 변경
<2. (board)구조체 선언 후, 메인 실행문에서 typedef를 이용하여 사용자가 정의한 이름으로 구조체 타입명을 변경.>
- typedef struct Board SB; //하지만, 메인 코드에서 이렇게 다 작성하게 되면 오히려 줄만 늘어나고 의미가 없다.
//(member) 구조체 타입 이름 없이, 변수 (mb) 선언까지 한 번에 할 수도 있다.
- 단, 이경우 변수 초기화를 배열로 할 수 없고, 일일히 값을 넣어줘야한다.
--예문 코드 보기--
#include <stdio.h>
#include <time.h>
#pragma pack(1) //padding byte remove
typedef struct Score{
char *pt_name;
int kor;
int eng;
int math;
int total;
double avg;
char grade;
}SS;//새로운 타입으로 정의 : struct Score >> SS
struct{
int num;
char *id;
char *pw;
char *name;
char *tel;
}mb;//변수 선언 : struct (이름 없음) 타입의 변수 "mb"
struct Board{
int num;
char *title;
char *content;
char *writer;
char *wdate;
};
char* local_time();
int main(int argc, char **argv)
{
printf("structure score...\n");
printf("--- score ---\n");
SS sc = {"kim",77,88,99,0,0,'F'};
sc.total = sc.kor + sc.eng + sc.math;
sc.avg = sc.total/3;
if(sc.avg>=90){
sc.grade = 'A';
}else if(sc.avg>=80){
sc.grade = 'B';
}else if(sc.avg>=70){
sc.grade = 'C';
}else if(sc.avg>=60){
sc.grade = 'D';
}else{
sc.grade = 'F';
}
printf("name: %s\n",sc.pt_name);
printf("kor: %d, eng: %d, math: %d\n",sc.kor, sc.eng, sc.math);
printf("total: %d, avg: %.2lf, grade: %c\n",sc.total, sc.avg, sc.grade);
printf("--- member ---\n");
//mb = {1,"admin","hi123456","kim","010-111"};
//배열로 값을 초기할 수 없고, 하드 코딩으로 하나씩 넣어야한다.
mb.num =1;
mb.id="admin";
mb.pw="hi123456";
mb.name="kim";
mb.tel="010-111";
printf("num:%d, id:%s, pw:%s, name:%s, tel:%s\n",
mb.num,mb.id,mb.pw,mb.name,mb.tel);
printf("--- board ---\n");
//타입 변환과 변수 선언을 모두 메인 함수에서.
typedef struct Board SB;
SB bd = {1,"title1","content1","lee",local_time()};
printf("num:%d, title:%s, content:%s, writer:%s, wdate:%s\n",
bd.num, bd.title, bd.content, bd.writer, bd.wdate);
return 0;
}
char* local_time(){
struct tm *pt_time; //시스템에 내장된 구조체 사용
time_t time_now;
time(&time_now);
printf("time_now:%ld\n",time_now);
pt_time = localtime(&time_now);
printf("time:%s\n",asctime(pt_time));//long타입의 시간을 문자열로 변환
char *wdate = asctime(pt_time);
printf("wdate:%s\n",wdate);
return wdate;
}
#struct_inner - 3. 구조체를 구조체의 원소로 사용
//struct inner : 다른 구조체를 구조체의 원소로 초기화
- typedef struct student{ ~ Contact ctt; Score sc; }Student; //구조체를 원소로 하는 구조체 선언
- st.ctt = ctt; //student st 구조체의 원소 Contact ctt에 ctt의 값을 할당.
- printf("tel: %s\n",st.ctt.tel); //구조체 안의 구조체 값 출력.
--예문 코드 보기--
#include <stdio.h>
typedef struct contact{
char *tel, *email, *addr; //동일 타입 변수 동시 선언
}Contact;
typedef struct score{
int kor, eng, math, total;
double avg;
char grade;
}Score;//타입을 새롭게 정의
//struct inner : 다른 구조체를 구조체의 원소로 초기화
typedef struct student{
char *pt_name;
Contact ctt;
Score sc;
}Student;
int main(int argc, char **argv)
{
printf("struct inner ...\n");
printf("--- contact ---\n");
Contact ctt;
ctt.tel = "010";
ctt.email = "aaa@aaa.com";
ctt.addr = "seoul";
printf("ctt.tel: %s, ctt.email: %s, ctt.addr: %s \n",ctt.tel,ctt.email,ctt.addr);
printf("--- score ---\n");
Score sc = {77,88,99,0,0,'F'};
sc.total = sc.kor + sc.eng + sc.math;
sc.avg = sc.total/3;
if(sc.avg>=90){
sc.grade = 'A';
}else if(sc.avg>=80){
sc.grade = 'B';
}else if(sc.avg>=70){
sc.grade = 'C';
}else if(sc.avg>=60){
sc.grade = 'D';
}else{
sc.grade = 'F';
}
printf("kor: %d, eng: %d, math: %d\n",sc.kor, sc.eng, sc.math);
printf("total: %d, avg: %.2lf, grade: %c\n",sc.total, sc.avg, sc.grade);
printf("--- student ---\n");
Student st;
st.pt_name = "kim";
st.ctt = ctt;//student st 구조체의 원소 Contact ctt에 ctt의 값을 할당.
st.sc = sc;
printf("name: %s\n",st.pt_name);
printf("tel: %s\n",st.ctt.tel);
printf("email: %s\n",st.ctt.email);
printf("addr: %s\n",st.ctt.addr);
printf("kor: %d, eng: %d, math: %d\n",st.sc.kor, st.sc.eng, st.sc.math);
printf("total: %d, avg: %.2lf, grade: %c\n",st.sc.total, st.sc.avg, st.sc.grade);
return 0;
}
#struct_array - 4.구조체 배열 다루기
//구조체 배열도정수 배열 생성과 동일한 형태로 생성한다.
- Student sts[2] ={st, st2}; // (정수 배열 생성) int sus[2] = {su1,su2};
//특정 인덱스[i]가 가지는 원소(구조체 sc)의 안에 있는 값을 꺼낸다.
- printf("total: %d, avg: %.2lf, grade: %c\n",sts[i].sc.total, sts[i].sc.avg, sts[i].sc.grade);
--예문 코드 보기--
#include <stdio.h>
typedef struct contact{
char *tel, *email, *addr; //동일 타입 변수 동시 선언
}Contact;
typedef struct score{
int kor, eng, math, total;
double avg;
char grade;
}Score;//타입을 새롭게 정의
typedef struct student{
char *pt_name;
Contact ctt;
Score sc;
}Student;
int main(int argc, char **argv)
{
printf("struct inner ...\n");
//이렇게 배열 생성 하던 것처럼 구조체 배열도 생성한다.
//int su1 = 10;
//int su2 = 20;
//int sus[2] = {su1,su2};
printf("==== contact[] ====\n");
Contact ctt;
ctt.tel = "010";
ctt.email = "aaa@aaa.com";
ctt.addr = "seoul";
Contact ctt2;
ctt2.tel = "011";
ctt2.email = "bbb@bbb.com";
ctt2.addr = "pusan";
Contact ctts[2] = {ctt,ctt2};
for(int i=0;i<2;i++){
printf("%s ",ctts[i].tel);
printf("%s ",ctts[i].email);
printf("%s \n",ctts[i].addr);
}
printf("==== score[] ====\n");
Score sc = {77,88,99,0,0,'F'};
Score sc2 = {55,66,77,0,0,'F'};
Score scs[2] = {sc,sc2};
for(int i=0;i<2;i++){
scs[i].total = scs[i].kor + scs[i].eng + scs[i].math;
scs[i].avg = scs[i].total/3;
if(scs[i].avg>=90){
scs[i].grade = 'A';
}else if(scs[i].avg>=80){
scs[i].grade = 'B';
}else if(scs[i].avg>=70){
scs[i].grade = 'C';
}else if(scs[i].avg>=60){
scs[i].grade = 'D';
}else{
scs[i].grade = 'F';
}
printf("kor: %d, eng: %d, math: %d\n",scs[i].kor, scs[i].eng, scs[i].math);
printf("total: %d, avg: %.2lf, grade: %c\n",scs[i].total, scs[i].avg, scs[i].grade);
}
printf("==== student[] ====\n");
Student st;
st.pt_name = "kim";
st.ctt = ctt;
st.sc = sc;
Student st2 = {"lee",ctt2,sc2};
Student sts[2] ={st, st2};
for(int i=0;i<2;i++){
printf("---student %d---\n",i+1);
printf("name: %s, tel: %s, mail: %s, addr: %s\n",
sts[i].pt_name,sts[i].ctt.tel,sts[i].ctt.email,sts[i].ctt.addr);
printf("kor: %d, eng: %d, math: %d\n",sts[i].sc.kor, sts[i].sc.eng, sts[i].sc.math);
sts[i].sc.total = sts[i].sc.kor + sts[i].sc.eng + sts[i].sc.math;
sts[i].sc.avg = sts[i].sc.total/3;
if(sts[i].sc.avg>=90){
sts[i].sc.grade = 'A';
}else if(sts[i].sc.avg>=80){
sts[i].sc.grade = 'B';
}else if(sts[i].sc.avg>=70){
sts[i].sc.grade = 'C';
}else if(sts[i].sc.avg>=60){
sts[i].sc.grade = 'D';
}else{
sts[i].sc.grade = 'F';
}
//특정 인덱스[i]가 가지는 원소(구조체 sc)의 안에 있는 값을 꺼낸다.
printf("total: %d, avg: %.2lf, grade: %c\n",sts[i].sc.total, sts[i].sc.avg, sts[i].sc.grade);
}
return 0;
}