- 구조체 메모리 최적화 -
#include <stdio.h> //데이터간 장치간 통신할때 사용하는 프로그래밍 해 볼 것
typedef struct _smart //최적화 전. 28바이트
{
int a;
char b;
short c;
int d;
char e;
short f;
char g;
int h;
char i;
char j;
short k;
}smart;
typedef struct _smart1 //메모리 최적화 구조체. 24바이트
{
int a;
char b;
short c;
int d;
char e;
char g;
short f;
int h;
char i;
char j;
short k;
}smart1;
#pragma pack(1)
typedef struct _smart2 //pragma 테스트 최적화 전.
{
int a;
char b;
short c;
int d;
char e;
short f;
char g;
int h;
char i;
char j;
short k;
}smart2;
#pragma pack(4) // 이 범위 안에는 최적화를 자동으로 시켜준다.
// 전처리어 중에 컴파일러한테 지시를 내리는 것이 있는데 그 중 하나다.
// 컴파일러 한테 셋팅을 바꾸라는 말이다.
// pack 은 packing 의 뜻. 어떤 단위로 싼다
// pack(1)을 하면 1바이트로 싼다.
// 즉, 다시 애기하면 원래는 pack(4) 4바이트로 최적화가 자동으로 되어있는 상태였고 그것을 임시적으로 (1) 1바이트로 최적화 시켜라.
// 라고 그 범위만 설정 해 논것이다.
#pragma pack(1)
typedef struct _smart3
{
int a;
char b;
short c;
int d;
char e;
char g;
short f;
int h;
char i;
char j;
short k;
}smart3;
#pragma pack(4) //왠만하면 구조체 사용시에만 사용하는 것이 좋다. 구조체는 4byte 와 2byte를 좋아하는 성질이 있기 때문에 메모리 최적화를 자기 스스로 시키지 못하기 때문이다.
pragma는 한마디로 진짜 포장한다라는 의미이다. 메모리를 어떤식으로 포장하여 사용할 것인가를 구분해준다.
int main(void)
{
printf("구조체 type smart의 크기는 ? : %d Byte\n",sizeof(smart));
printf("구조체 type smart1의 크기는 ? : %d Byte\n",sizeof(smart1));
printf("구조체 type smart2의 크기는 ? : %d Byte\n",sizeof(smart2));
printf("구조체 type smart3의 크기는 ? : %d Byte\n",sizeof(smart3));
return 0;
}
/* 스택 구조는 아래서 부터 변수가 선언 되는 것인데
20바이트를 차지하려면 밑에서부터 5칸을 차지 해야 한다.
★컴파일러가 32비트기에 4바이트에 맞추려고 노력중이다.
int 가 4바이트라 우선순위가 제일 높고 하나의 스텍을 쓰게된다.
허나, char 와 short는 1바이트와 끝에 2바이트를 생성하여 한바이트를 뛰어넘게 된다.
즉, int를(4바이트) 제일 좋아하고 그 다음을 short 형 (2바이트)를 그 다음으로 좋아하고
다시 정리하면 1 1 2 , 2 1 1 과 같다. 좋아하는 2바이트는 중간에 쓰게 되면 한칸 띄우고 한다.
ex) 5바이트를 보내려한다면 2바이트를 먼저 선언 후 , char 형을 세개 선언해줘야 순서가 맞다.
그리고 나서 8바이트 나머지를 선언하려 한다면 char형을 선언해준 다음 그 다음에 short를 선언해줘야
딱 맞는 8바이트 형태가 된다.
*/
- 구조체 변수 전달 예제 -
#include <stdio.h>
typedef struct _point
{
int xpos;
int ypos;
}point;
void showposition(point pos)
{
printf("[%d, %d]\n", pos.xpos, pos.ypos);
}
point getcurrentposition(void)
{
point cen;
printf("input current pos : ");
scanf("%d %d", &cen.xpos, &cen.ypos);
return cen;
}
int main(void)
{
point curpos = getcurrentposition();
showposition(curpos);
return 0;
}
- 구조체 변수 전달 예제 2-
#include <stdio.h>
typedef struct _person
{
char name[20];
char phonenum[20];
int age;
}person;
void showpersoninfo(person man)
{
printf("name : %s\n", man.name);
printf("phone : &s\n", man.phonenum);
printf("age : %d\n",man.age);
}
person readpersoninfo(void)
{
person man;
printf("name? "); scanf("%s", man.name);
printf("phone? "); scanf("%s", man.phonenum);
printf("age? "); scanf("%d", &man.age);
}
int main(void)
{
person man = readpersoninfo();
showpersoninfo(man);
return 0;
}
- 구조체 변수 전달 예제 3-
#include <stdio.h>
typedef struct _point
{
int xpos;
int ypos;
}point;
void orgsymtrans(point* ptr) //원점 대칭
{
ptr->xpos = (ptr->xpos) * -1;
ptr->ypos = (ptr->ypos) * -1;
}
void showposition(point pos)
{
printf("[%d, %d]\n", pos.xpos, pos.ypos);
}
int main(void)
{
point pos = {7, -5};
orgsymtrans(&pos);
showposition(pos);
orgsymtrans(&pos);
showposition(pos);
return 0;
}
- 구조체 변수 전달 예제 2 수정-
#include <stdio.h>
typedef struct _person
{
char name[20];
char phonenum[20];
int age;
}person;
void showpersoninfo(person* man)
{
printf("name : %s\n", man->name); // 같은 작업.
printf("phone : &s\n", man->phonenum);
printf("age : %d\n", man->age);
}
void readpersoninfo(person* man) // 주소를 받기에 4바이트.
{
;
printf("name? "); scanf("%s", man->name); //.을 지우고 -> 로 바꾼다.
printf("phone? "); scanf("%s", man->phonenum);
printf("age? "); scanf("%d", man->age);
return;
}
int main(void)
{
person man; //44바이트의 복사가 일어난다. 그렇기에 인자로 주소를 던져줘서 point 매개변수로 받아 그 값을 포인터로 수정하게끔 최적화.
readpersoninfo(&man);
showpersoninfo(&man);
return 0;
}
- 구조체 변수 전달 예제 4-
#include <stdio.h>
typedef struct _point
{
int xpos;
int ypos;
}point;
int main(void)
{
point pos1 = {1, 2};
point pos2;
pos2 = pos1;
printf("크기 : %d\n", sizeof(pos1));
printf("[%d, %d]\n", pos1.xpos, pos1.ypos);
printf("크기 : %d\n", sizeof(pos2));
printf("[%d, %d]", pos2.xpos, pos2.ypos);
return 0;
}
- 구조체 변수 전달 예제 5-
#include <stdio.h>
typedef struct _point
{
int xpos;
int ypos;
}point;
point addpoint(point pos1, point pos2)
{
point pos = {pos1.xpos + pos2.xpos, pos1.ypos + pos2.ypos};
return pos;
}
point minpoint(point pos1, point pos2)
{
point pos = {pos1.xpos - pos2.xpos, pos1.ypos - pos2.ypos};
return pos;
}
int main(void)
{
point pos1 = {5, 6};
point pos2 = {2, 9};
point result;
result = addpoint(pos1, pos2);
printf("[%d, %d]\n", result.xpos, result.ypos);
result = minpoint(pos1, pos2);
printf("[%d, %d]\n", result.xpos, result.ypos);
return 0;
}
- 구조체 안의 구조체 선언-
#include <stdio.h>
typedef struct _point
{
int xpos;
int ypos;
}point;
typedef struct _circle
{
point cen;
double rad;
}circle;
void showcircleinfo(circle* cptr)
{
printf("[%d, %d]\n", (cptr->cen).xpos, (cptr->cen).ypos);
printf("radius : %g\n\n", cptr->rad);
}
int main(void)
{
//circle c1 = { { 1, 2 }, 3.5 };
circle c1;
circle c2 = { 2, 4, 3.9 }; //구분 짓지 않으면 순서대로 초기화 한다. xpos 다음 ypos
c1.cen.xpos = 1; //계속해서 구조체를 생성 가능하고 그 구조체 안으로 계속 접근할때는 dot 연산자를 이용해서
c1.cen.ypos = 2; //계속해서 접근할 수 있다.
c1.rad = 3.5;
showcircleinfo(&c1);
showcircleinfo(&c2);
return 0;
}
- 공용체의 의미 -
#include <stdio.h>
typedef struct _T
{
unsigned int a;
unsigned short b;
unsigned char c;
}T;
typedef union _T1
{
unsigned int a; //78 56 34 12 의 형태로 저장 되어 반대로 12 34 56 78 로 출력되게 된다.
unsigned short b; //이러한 것으로 말미암아 쇼트 b는 덮어씌우는 형태로 78 56 부분에 저장하게 될 것이고
unsigned char c; //차 c는 78부분에 덮어씌우게 될 것이다.
}T1;
int main(void)
{
T obj1;
T1 obj2;
obj1.a = 0x12345678;
obj1.b = 0xABCD;
obj1.c = 0xEE; //8보다 크면 무조건 음수로 취급하기 때문에 양수 형태로 선언해야 한다. 그래서 현재 FFFFABCD , FFFFFFEE로 출력 되고 있다.
obj2.a = 0x12345678;
obj2.b = 0xABCD;
obj2.c = 0xEE;
printf("구조체 type T의 변수 obj1의 멤버 a의 16진수 값은 ? %X\n",obj1.a);
printf("구조체 type T의 변수 obj1의 멤버 b의 16진수 값은 ? %X\n",obj1.b);
printf("구조체 type T의 변수 obj1의 멤버 c의 16진수 값은 ? %X\n\n",obj1.c);
printf("공용체 type T1의 변수 obj2의 멤버 a의 16진수 값은 ? %X\n",obj2.a);
printf("공용체 type T1의 변수 obj2의 멤버 b의 16진수 값은 ? %X\n",obj2.b);
printf("공용체 type T1의 변수 obj2의 멤버 c의 16진수 값은 ? %X\n\n",obj2.c);
printf("구조체 type T의 크기는 ? %d\n",sizeof(T));
printf("유니온 type T1의 크기는 ? %d\n",sizeof(T1));
return 0;
}
- 공용체 예제 -
#include <stdio.h>
typedef struct _sbox
{
int mem1;
int mem2;
double mem3;
}sbox;
typedef union _ubox
{
int mem1;
int mem2;
double mem3;
}ubox;
int main(void)
{
sbox sbx;
ubox ubx;
printf("%p %p %p\n",&sbx.mem1, &sbx.mem2, &sbx.mem3);
printf("%p %p %p\n",&ubx.mem1, &ubx.mem2, &ubx.mem3);
printf("%d %d\n",sizeof(sbox), sizeof(ubox));
return 0;
}
- 공용체 예제 2 -
#include <stdio.h>
typedef union _ubox
{
int mem1;
int mem2;
double mem3;
}ubox;
int main(void)
{
ubox ubx;
ubx.mem1 = 20;
printf("%d\n", ubx.mem2);
ubx.mem3 = 7.15;
printf("%d\n", ubx.mem1);
printf("%d\n", ubx.mem2);
printf("%g\n", ubx.mem3);
return 0;
}
- 공용체 예제3 -
#include <stdio.h>
typedef struct _dbshort
{
unsigned short upper; //short를 제일 먼저 선언하게 되면 구조체는 오른쪽에다가 할당 해 준다. 그래서 상위 쇼트라고 이름 지었다.
unsigned short lower; //
}dbshort;
typedef union _rdbuf
{
int ibuf;
char bbuf[4];
dbshort sbuf;
}rdbuf;
int main(void)
{
rdbuf buf;
printf("정수 입력 : ");
scanf("%d", &(buf.ibuf));
printf("상위 2바이트 : %u\n",buf.sbuf.upper);
printf("하위 2바이트 : %u\n",buf.sbuf.upper);
printf("상위 1바이트 아스키 코드 : %c\n",buf.bbuf[0]);
printf("상위 1바이트 아스키 코드 : %c\n",buf.bbuf[3]);
return 0;
}
- 열거형 예제 -
#include <stdio.h>
typedef enum _syllable //typedef 선언이 추가된 열거형의 정의
{
Do = 1, re = 2, mi = 3, fa = 4, so = 5, la = 6, ti = 7
}syllable;
void sound(syllable sy)
{
switch (sy)
{
case Do:
puts("도는 하얀 도라지");
return;
case re:
puts("레는 하얀 도라지");
return;
case mi:
puts("미는 하얀 도라지");
return;
case fa:
puts("파는 하얀 도라지");
return;
case so:
puts("솔는 하얀 도라지");
return;
case la:
puts("라는 하얀 도라지");
return;
case ti:
puts("시는 하얀 도라지");
return;
}
puts("다 함께 부르세 ~ 도레미파 솔라시도 솔 도~");
}
int main(void)
{
syllable tone;
for (tone = Do; tone <= ti; tone += 1)
{
sound(tone);
}
return 0;
}
- 열거형 기본형 준비 -
#include <stdio.h>
typedef enum _smart //열거형 enumeratedv type, 이것은 보통 int 타입이라 생각하면 된다.
{
ZERO = -100, //이렇게 초기화 한 후 ONE 을 출력하면 1이 증가한 형태인
ONE, //보통 대문자로 선언.
TWO = 502, //이렇듯 중간에서도 바꿔서 그 다음부터 열거 식으로 넘버링이 가능하다.
THREE,
FOUR
}smart;
int main(void)
{
int e1;
e1 = ONE;
printf("%d",e1);
printf("%d",THREE);
return 0;
}
//일종의 디파인, 우리가 1,2,3,4 적을 필요 없이 순서대로 차례로 늘어나게끔 된다.
//넘버링 즉 번호 매길때 편리하게 쓰이는 열거형 타입이다.
//일종의 디파인 이라는 소리라는 것은 변수 형태로 따로 선언을 해주지 않고
//enum 으로 정의해주면 어디서든 불러서 쓸 수 있다.
//레지스터 주소 매기듯이 데이터를 열거해서 쓸 수 있다. (volatile 하듯이)
'개발자 > C 언어' 카테고리의 다른 글
C언어_다차원 배열 (0) | 2015.04.17 |
---|---|
C언어_교환법칙, (2,3)차원 배열, 더블 포인터의 이해 (0) | 2015.04.17 |
C언어_구조체의 활용(배열 통째로 옮기기, 구조체 메모리 저장 형태) (0) | 2015.04.17 |
C언어_펌웨어_인터럽트 사용법 (0) | 2015.04.17 |
C언어_펌웨어_주사위 인터럽트 사용. (0) | 2015.04.17 |