본문 바로가기

C lang

[C language] Geany편집기 -14. 구조체 포인터, 구조체 배열 포인터 , bubble sort(정렬), union(유니온), enum(나열형)

#정리

#struct_function - 구조체를 매개변수로 활용 

//{.변수명=값}형태로 순서에 상관없이 지정된 변수에 값을 할당 할 수 있다.
 - Member m = {.pw="hi123456",.id="admin",.num=1,.name="kim",.tel="011"};


#struct_sort - 값 크기 순으로 정렬하기 

** https://jinhyy.tistory.com/9 << sort 종류 및 방식 대한 설명

//사이즈를 비교하여 크기 순으로 정렬

 - bubble sort 공식 : for[0~2]{ for[x+1~2]{ if >> swap }} // swap을 사용한다.


#struct_pointer - 구조체를 가리키는 포인트 변수 1. main() >> Fn(struct_pt) 

//포인트 변수를 통해 구조체의 양과 상관없이 4byte로 값을 전달할 수 있다.

 - printf("sizeof(m):%d\n",sizeof(pt_m));//주소 값이기 때문에 4Byte의 크기를 가진다.
//구조체 포인트 변수의 값 접근 방식 두 가지
<1. (*pt_m).var 포인터 역참조 >
  - (*pt_m).num = 11;//역 참조를 통해 값 변경 가능.
  - printf("num:%d", (*pt_m).num);//.이 *보다 연산 우선순위가 높아 ( )를 해줘야 한다.
<2. pt_m->var  구조체 포인터 변수의 속성에 바로 접근하는 연산자 >
** ( )를 쓰는 것도 불편하다면 -> 연산자를 쓸 수 있다. **
 - pt_m->num = 11; //-> 구조체 포인터 변수의 속성에 바로 접근하는 연산자를 통해 값에 접근
 - printf("num:%d", pt_m->num);  //-> 연산자를 통해 출력도 가능하다.
//함수에 구조체를 값으로 넘겨줄 때는 두 가지 방식 모두 가능
 - test01(&m);//&m,pt_m 둘 다 가능
 - test01(pt_m);

//타입명 재정의와 함께 포인트 변수의 타입도 같이 정의할 수 있다.

 - typedef struct{ ~ }Contact,*Pt_contact; //*Pt_contact >> 포인터 타입 재정의

 >> Pt_contact p_con = &ctt;//*을 붙이지 않고 변수를 선한언다.



#struct_pointer - 구조체를 가리키는 포인트 변수 2. Fn() >> main(struct_pt) 

//앞에서 진행한 방식 모두 함수의 리턴 값으로 활용할 수 있다.


#struct_array - 구조체 배열을 가리키는 포인트 변수 

//구조체 배열에서 값에 접근하는 방법 두 가지

** 정수 배열 접근 방법 //*(pt_sus+0) == pt_sus[0] = sus[0] **
<1. pt_cs[i] : 인덱스 형태로 값에 접근>

 - printf("name:%s, model:%s, price: %d \n",pt_cs[i].name,pt_cs[i].model,pt_cs[i].price);
<2. *(pt_cs+i) : 포인터 형태로 값에 접근>

 - printf("name:%s, model:%s, price: %d \n",(pt_cs+i)->name,(pt_cs+i)->model,(pt_cs+i)->price);





#c66union & struct 

//공용체 : 사용자가 정의할 수 있는 자료형 중 하나로 구조체와 비슷하나, 메모리를 공유하여 사용된다는 것이 차이점이다. 

//공용체의 선언 방법

 - typedef union{ ~원소~ }타입명;

//공용체도 순서에 상관 없이, 변수를 지정하여 값을 할당할 수도 있다.
 - Test_u tu = {.avg=6.28,.num=22};

//구조체와 유니온의 차이**
 - 구조체 : 모든 변수를 담을 수 있게 메모리 영역을 확보한다.
 - 공용체 : 가장 큰 용량을 가진 변수 만큼의 공용 메모리 영역을 확보한다

   (변수가 단일 타입인지, 여러 개의 타입이 섞여있는지에 따라 용량 증가방식이 다르다 - 예문 코드 참조).
 >> 모든 변수가 동일 메모리를 공유하며, 최종적으로 할당(사용)한 변수만 가지고 있는다.




#enum(에넘) - 열거형

//에넘 : 열거 방식의 사용자 정의 자료형

 - 변수가 선언 된 순서대로 값이 자동으로 할당된다.

 - 할당되는 시작 값을 지정할 수 있다.   

 - 주로 계절과 날짜(요일, 월 등)을 만들 때 사용된다.

 

 

 

 

#struct_function - 구조체를 매개변수로 활용 

//{.변수명=값}형태로 순서에 상관없이 지정된 변수에 값을 할당 할 수 있다.
 - Member m = {.pw="hi123456",.id="admin",.num=1,.name="kim",.tel="011"};

 

--예문 코드 보기--

더보기
#include <stdio.h>
#pragma pack(1)//Byte Alignment

#define MEMBER_ARR_LEN 2
#define CAR_ARR_LEN 3

typedef struct{
	int num;
	char *id, *pw, *name, *tel;	
}Member;

typedef struct{
	char *name,*model;
	int price;
}Car;

void test01(Member m);
void test02(Car c);
void test03(Member ms[MEMBER_ARR_LEN]);
void test04(Car cs[CAR_ARR_LEN]);

int main(int argc, char **argv)
{
	printf("struct function...\n");
	//{.변수명=값}형태로 순서에 상관없이 지정된 변수에 값을 할당 할 수 있다.
	Member m = {.pw="hi123456",.id="admin",.num=1,.name="kim",.tel="011"};
	Member m2 = {2,"admin2","hi123456","lee","012"};
	test01(m);
	Car c = {"911GT","porche",2000};
	Car c2 = {"phanamera","porche",1500};
	Car c3 = {"911","porche",2500};
	test02(c);
	
	printf("------- member[] ------\n");
	Member ms[MEMBER_ARR_LEN] = {m,m2};
	test03(ms);
	printf("------- car[] ------\n");
	Car cs[CAR_ARR_LEN] = {c,c2,c3};
	test04(cs);
	
	return 0;
}
void test01(Member m){
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",m.num,m.id,m.pw,m.name,m.tel);
	printf("sizeof(m):%d\n",sizeof(m));
}
void test02(Car c){
	printf("name:%s, model:%s, price: %d \n",c.name,c.model,c.price);
	printf("sizeof(c):%d\n",sizeof(c));
}
void test03(Member ms[MEMBER_ARR_LEN]){
	for(int i=0;i<MEMBER_ARR_LEN;i++){
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",ms[i].num,ms[i].id,ms[i].pw,ms[i].name,ms[i].tel);
	}	
}
void test04(Car cs[CAR_ARR_LEN]){
	for(int i=0;i<CAR_ARR_LEN;i++){
	printf("name:%s, model:%s, price: %d \n",cs[i].name,cs[i].model,cs[i].price);
	}
}

 


 

#struct_sort - 값 크기 순으로 정렬하기 

** https://jinhyy.tistory.com/9 << sort 종류 및 방식 대한 설명

//사이즈를 비교하여 크기 순으로 정렬

 - bubble sort 공식 : for[0~2]{ for[x+1~2]{ if >> swap }} // swap을 사용한다.

 

--예문 코드 보기--

더보기
#include <stdio.h>

#define CAR_ARR_LEN 3
#pragma pack(1)//Byte Alignment

typedef struct{
	char *name,*model;
	int price;
}Car;

int main(int argc, char **argv)
{
	printf("struct sort...\n");
	//bubble sort 공식 : for[0~2]{ for[x+1~2]{ if >> swap }}
	int arr[3] = {88,22,55};
	
	for(int x=0;x<3;x++){
		for(int i=x+1;i<3;i++){
			if(arr[x]>arr[i]){
			int tmp;
			tmp = arr[x];
			arr[x] = arr[i];
			arr[i] = tmp;
			}
		}
	}

	for(int i=0;i<3;i++){
		printf("%d ",arr[i]);
	}
	printf("\n");
	printf("-------------\n");
	Car c1 = {"911","porche",2500};
	Car c2 = {"phanamera","porche",1500};
	Car c3 = {"911GT","porche",2000};
	Car cs[CAR_ARR_LEN] = {c1,c2,c3};
	
	for(int x=0;x<3;x++){
		for(int i=x+1;i<3;i++){
			if(cs[x].price > cs[i].price){
				Car tmp;
				tmp = cs[x];
				cs[x] = cs[i];
				cs[i] = tmp;
			}
		}
	}
		
	for(int i=0;i<CAR_ARR_LEN;i++){
	printf("name:%s, model:%s, price: %d \n",cs[i].name,cs[i].model,cs[i].price);
	}
	
	
	return 0;
}

 

#struct_pointer - 구조체를 가리키는 포인트 변수 1. main() >> Fn(struct_pt) 

//포인트 변수를 통해 구조체의 양과 상관없이 4byte로 값을 전달할 수 있다.

 - printf("sizeof(m):%d\n",sizeof(pt_m));//주소 값이기 때문에 4Byte의 크기를 가진다.
//구조체 포인트 변수의 값 접근 방식 두 가지
<1. (*pt_m).var 포인터 역참조 >
  - (*pt_m).num = 11;//역 참조를 통해 값 변경 가능.
  - printf("num:%d", (*pt_m).num);//.이 *보다 연산 우선순위가 높아 ( )를 해줘야 한다.
<2. pt_m->var  구조체 포인터 변수의 속성에 바로 접근하는 연산자 >
** ( )를 쓰는 것도 불편하다면 -> 연산자를 쓸 수 있다. **
 - pt_m->num = 11; //-> 구조체 포인터 변수의 속성에 바로 접근하는 연산자를 통해 값에 접근
 - printf("num:%d", pt_m->num);  //-> 연산자를 통해 출력도 가능하다.
//함수에 구조체를 값으로 넘겨줄 때는 두 가지 방식 모두 가능
 - test01(&m);//&m,pt_m 둘 다 가능
 - test01(pt_m);

//타입명 재정의와 함께 포인트 변수의 타입도 같이 정의할 수 있다.

 - typedef struct{ ~ }Contact,*Pt_contact; //*Pt_contact >> 포인터 타입 재정의

 >> Pt_contact p_con = &ctt;//*을 붙이지 않고 변수를 선한언다.

 

--예문 코드 보기--

더보기
#include <stdio.h>
#pragma pack(1)//Byte Alignment

#define MEMBER_ARR_LEN 2

typedef struct{
	int num;
	char *id, *pw, *name, *tel;	
}Member;

typedef struct{
	char *name,*model;
	int price;
}Car;

typedef struct{
	char *tel, *email, *addr; 
}Contact,*Pt_contact;//타입명 재정의와 함께 포인트 변수의 타입도 같이 정의할 수 있다.

void test01(Member *pt_m);
void test02(Car *pt_c);
void test03(Contact *pt_ctt);

int main(int argc, char **argv)
{
	printf("struct pointer...\n");
	printf("========member*=========\n");
	Member m = {1,"admin","hi123456","kim","011"};
	printf("sizeof(m):%d\n",sizeof(m));
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",m.num,m.id,m.pw,m.name,m.tel);

	printf("--------(*pt_m).var---------\n");
	Member *pt_m;
	pt_m = &m;//포인트 변수에 구조체 변수 m의 주소 할당.
	printf("sizeof(m):%d\n",sizeof(pt_m));//주소 값이기 때문에 4Byte의 크기를 가진다.
	(*pt_m).num = 11;//역 참조를 통해 값 변경 가능.
	(*pt_m).id = "admin3";
	(*pt_m).pw = "hi123";
	(*pt_m).name = "han";
	(*pt_m).tel = "013";
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",
	(*pt_m).num,(*pt_m).id,(*pt_m).pw,(*pt_m).name,(*pt_m).tel);//.이 *보다 연산 우선순위가 높아 ( )를 해줘야 한다.
	
	printf("--------pt_m->var---------\n");
	//( )를 쓰는 것도 불편하다면 -> 연산자를 쓸 수 있다.
	pt_m->num = 11;//-> 구조체 포인터 변수의 속성에 바로 접근하는 연산자
	pt_m->id = "admin4";
	pt_m->pw = "hi124";
	pt_m->name = "park";
	pt_m->tel = "014";
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",
	pt_m->num,pt_m->id,pt_m->pw,pt_m->name,pt_m->tel);//.이 *보다 연산 우선순위가 높아 ( )를 해줘야 한다.
	
	printf("--------test01 : (*pt_m).var---------\n");
	test01(&m);//&m,pt_m 둘 다 가능
	test01(pt_m);
	
	printf("========car*=========\n");
	Car c;
	Car *pt_c = &c;
	pt_c->name = "OOOO";
	pt_c->model = "A7";
	pt_c->price = 3500;
	
	test02(pt_c);
	
	printf("========contact*=========\n");
	Contact ctt;
	Contact *pt_ctt = &ctt;
	pt_ctt->tel = "010";
	pt_ctt->email = "aaa@bbb.com";
	pt_ctt->addr = "seoul";
	
	test03(&ctt);
	
	
	Pt_contact p_con = &ctt;//*을 붙이지 않고 변수를 선한언다.
	p_con->tel = "017";
	p_con->email = "ccc@ddd.com";
	p_con->addr = "pusan";
	
	test03(p_con);
	
	return 0;
}

void test01(Member *pt_m){
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",
	pt_m->num,pt_m->id,pt_m->pw,pt_m->name,pt_m->tel);
	
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",
	(*pt_m).num,(*pt_m).id,(*pt_m).pw,(*pt_m).name,(*pt_m).tel);
}
void test02(Car *pt_c){
	printf("name:%s, model:%s, price: %d \n",
	pt_c->name,pt_c->model,pt_c->price);
}
void test03(Contact *pt_ctt){
	printf("tel:%s, email:%s, addr:%s \n",
	(*pt_ctt).tel,(*pt_ctt).email,(*pt_ctt).addr);
}

 

 

#struct_pointer - 구조체를 가리키는 포인트 변수 2. Fn() >> main(struct_pt) 

//앞에서 진행한 방식 모두 함수의 리턴 값으로 활용할 수 있다.

 

--예문 코드 보기--

더보기
#include <stdio.h>
#pragma pack(1)//Byte Alignment

#define MEMBER_ARR_LEN 2

typedef struct{
	int num;
	char *id, *pw, *name, *tel;	
}Member;

typedef struct{
	char *name,*model;
	int price;
}Car;

typedef struct{
	char *tel, *email, *addr; 
}Contact,*Pt_contact;

Member *test01();
Car *test02();
Contact *test03();
Pt_contact test04();
int main(int argc, char **argv)
{
	printf("struct pointer...\n");
	printf("======== test01 member*=========\n");
	Member *pt_m = test01();
	printf("num:%d, id:%s, pw:%s, name:%s, tel:%s \n",
		pt_m->num,pt_m->id,pt_m->pw,pt_m->name,pt_m->tel);

	printf("======== test02 car*=========\n");
	Car *pt_c = test02();
	printf("name:%s, model:%s, price: %d \n",
		(*pt_c).name,(*pt_c).model,(*pt_c).price);
	
	printf("======== test03,04 contact*=========\n");
	Contact *pt_ctt = test03();
	printf("tel:%s, email:%s, addr:%s \n",
		pt_ctt->tel,pt_ctt->email,pt_ctt->addr);
	Pt_contact pt_ctt2 = test04();
	printf("tel:%s, email:%s, addr:%s \n",
		pt_ctt2->tel,pt_ctt2->email,pt_ctt2->addr);
	
	return 0;
}
Member *test01(){
	Member m = {1,"admin","hi123456","kim","011"};
	Member *pt_m;
	pt_m = &m;//포인트 변수에 구조체 변수 m의 주소 할당.
	(*pt_m).num = 11;//역 참조를 통해 값 변경 가능.
	(*pt_m).id = "admin3";
	(*pt_m).pw = "hi123";
	(*pt_m).name = "han";
	(*pt_m).tel = "013";
	
	return pt_m;
}
Car *test02(){
	Car c;
	Car *pt_c = &c;
	pt_c->name = "OOOO";
	pt_c->model = "A7";
	pt_c->price = 3500;
	
	return pt_c;
}
Contact *test03(){
	Contact ctt;
	Contact *ptr = &ctt;
	ptr->tel = "010";
	ptr->email = "aaa@bbb.com";
	ptr->addr = "seoul";
	
	return ptr;
}
Pt_contact test04(){
	Contact ctt;
	Pt_contact p_ctt = &ctt;
	p_ctt->tel = "011";
	p_ctt->email = "ccc@ddd.com";
	p_ctt->addr = "pusan";
	
	return p_ctt;
}

 

#struct_array - 구조체 배열을 가리키는 포인트 변수 

//구조체 배열에서 값에 접근하는 방법 두 가지

** 정수 배열 접근 방법 //*(pt_sus+0) == pt_sus[0] = sus[0] **
<1. pt_cs[i] : 인덱스 형태로 값에 접근>

 - printf("name:%s, model:%s, price: %d \n",pt_cs[i].name,pt_cs[i].model,pt_cs[i].price);
<2. *(pt_cs+i) : 포인터 형태로 값에 접근>

 - printf("name:%s, model:%s, price: %d \n",(pt_cs+i)->name,(pt_cs+i)->model,(pt_cs+i)->price);

 

--예문 코드 보기--

더보기
#include <stdio.h>
#pragma pack(1)//Byte Alignment

#define CAR_LENGTH 3
#define CONTACT_LENGTH 3

typedef struct{
	char *name,*model;
	int price;
}Car;

typedef struct{
	char *tel, *email, *addr; 
}Contact;

void test01(Contact *ptrs);

int main(int argc, char **argv)
{
	printf("struct array pointer...\n");
	
	Car cs[CAR_LENGTH] = {
		{"BMW2","520D2",5002},
		{"BMW3","520D3",5003},
		{"BMW4","520D4",5004}
		};
	
	Car *pt_cs = cs;
	
	//구조체 배열에서 값에 접근하는 방법 두 가지
	//int *ps_sus = sus;
	//*(pt_sus+0) == pt_sus[0] = sus[0]
	printf("--- pt_cs[i] ---\n");
	//1. pt_cs[i] 형태로 값에 접근.
	for(int i=0;i<CAR_LENGTH;i++){
		printf("name:%s, model:%s, price: %d \n",
			pt_cs[i].name,pt_cs[i].model,pt_cs[i].price);
	}
	
	printf("--- *(pt_cs+i) --\n");
	//2. *(pt_cs+i) 형태로 값에 접근.
	for(int i=0;i<CAR_LENGTH;i++){
		printf("name:%s, model:%s, price: %d \n",
			(pt_cs+i)->name,(pt_cs+i)->model,(pt_cs+i)->price);
	}
	
	printf("=== Contact mission ===\n");

	Contact ctts[CONTACT_LENGTH] = {
		{"011","aaa@bbb.com","seoul"}
		,{"012","bbb@ccc.com","pusan"}
		,{"013","ccc@ddd.com","daegu"}};
		
	Contact *pt_ctts = ctts;
	for(int i=0;i<CONTACT_LENGTH;i++){
		printf("tel:%s, email:%s, addr:%s \n",
			(pt_ctts+i)->tel,(pt_ctts+i)->email,(pt_ctts+i)->addr);
	}
	test01(pt_ctts);
	return 0;
}
void test01(Contact *ptrs){
		printf("--- test01 --\n");
		for(int i=0;i<CONTACT_LENGTH;i++){
		printf("tel:%s, email:%s, addr:%s \n",
			ptrs[i].tel,ptrs[i].email,ptrs[i].addr);
		}
		for(int i=0;i<CONTACT_LENGTH;i++){
		printf("tel:%s, email:%s, addr:%s \n",
			(ptrs+i)->tel,(ptrs+i)->email,(ptrs+i)->addr);
		}
}

 

#c66union & struct 

//공용체 : 사용자가 정의할 수 있는 자료형 중 하나로 구조체와 비슷하나, 메모리를 공유하여 사용된다는 것이 차이점이다. 

//공용체의 선언 방법

 - typedef union{ ~원소~ }타입명;

//공용체도 순서에 상관 없이, 변수를 지정하여 값을 할당할 수도 있다.
 - Test_u tu = {.avg=6.28,.num=22};

//구조체와 유니온의 차이**
 - 구조체 : 모든 변수를 담을 수 있게 메모리 영역을 확보한다.
 - 공용체 : 가장 큰 용량을 가진 변수 만큼의 공용 메모리 영역을 확보한다

   (변수가 단일 타입인지, 여러 개의 타입이 섞여있는지에 따라 용량 증가방식이 다르다 - 예문 코드 참조).
 >> 모든 변수가 동일 메모리를 공유하며, 최종적으로 할당(사용)한 변수만 가지고 있는다.

 

--예문 코드 보기--

더보기
#include <stdio.h>

typedef struct{
	int num;
	double avg;
}Test;
typedef union{
	int num;
	double avg;
}Test_u;

typedef union{
	//1개의 타입으로 이루어져있으면, 제일 큰 변수의 크기로 영역확보.
	//2개 이상의 타입으로 이루어져있으면, 제일 긴 타입을 기본 크기로 한 뒤 이후 4byte 씩 증가하면서 제일 큰 변수 사이즈에 맞춤.
	char name1[7];//4byte + 3byte(4byte) = 8byte
	char name2[8];//8byte
	char name3[9];//(long)8byte + 4byte
	char name4[10];//8byte + 4byte
	char name5[16];//8byte + 4byte + 4byte
	char name6[17];//8byte + 8byte + 4byte = 20byte
	double avg;//8byte
}Names;

int main(int argc, char **argv)
{
	printf("union...\n");//공용체
	
	//Test t = {11,3.14};
	Test t = {.avg=3.14,.num=11};//순서에 상관 없이, 변수를 지정하여 값을 할당할 수도 있다.
	printf("sizeof(t): %d byte\n",sizeof(t));//int(4)+double(8) = 12Byte : 모든 변수를 담을 수 있는 메모리 영역을 확보한다.
	printf("struct: %d %.2lf\n",t.num,t.avg);
	
	Test_u tu = {.avg=6.28,.num=22};
	//tu.num =22;
	//tu.avg =44.44;
	printf("sizeof(tu): %d byte\n",sizeof(tu));//가장 큰 용량을 가진 변수 만큼의 공용 메모리 영역을 확보한다.
	printf("union: %d %.2lf\n",tu.num,tu.avg);//모든 변수가 동일 메모리를 공유하며, 최종적으로 사용한 변수만 가지고 있는다.
											//>> num을 마지막에 할당하였기 때문에, num값만 잘 나온다.

	printf("--------------\n");
	
	Names ns;
	printf("sizeof(ns): %d byte\n",sizeof(ns));

	return 0;
}

 

#enum(에넘) - 열거형

//에넘 : 열거 방식의 사용자 정의 자료형

 - 변수가 선언 된 순서대로 값이 자동으로 할당된다.

 - 할당되는 시작 값을 지정할 수 있다.   

 - 주로 계절과 날짜(요일, 월 등)을 만들 때 사용된다.

 

--예문 코드 보기--

더보기
#include <stdio.h>
enum abc{//a=0,b=1,c=2 //자동으로 변수에 값이 할당 된다.
	a,b,c
};

enum boolean{//FALSE=0,TRUE=1
	FALSE, TRUE
};

enum day{//0,1,2,3,4,5,6
	sun=1, mon, tue, wed, thu, fri, sat
	//sun을 1로 변경하면 1부터 값이 매겨진다.
};

int main(int argc, char **argv)
{
	printf("enum...\n");
	
	//자동으로 할당 된 값을 확인 할 수있다.
	int x = a;
	int y = b;
	int z = c;
	printf("%d %d %d\n",x,y,z);
	
	printf("-------true/false-------\n");
	printf("%d %d\n",FALSE,TRUE);
	
	printf("----------------\n");
	
	printf("%d %d %d %d %d %d %d\n",sun,mon,tue,wed,thu,fri,sat);
	
	int dd = tue;
	switch(dd){
		case sun: case sat:
			printf("Good...\n");
		break;
		case mon: case tue: case wed: case thu: case fri: 
			printf("bad...\n");
		break;
	}	
	
	
	return 0;
}