본문 바로가기

TIPS/C언어

[TIPS] 6th 20160721_(1)

6

여섯번째 강좌 정리입니다.

 


1. 구조체

- 서로 다른 데이터 형을 하나의 데이터로 군집화하여 사용할 수 있도록 하는 사용자 정의 데이터 형을 구조체(structure)라 한다.


중복해서 자주 사용하는 명령어는 함수로 구조하였다. 이처럼 중복해서 자주 사용하는 변수는 (즉, 데이터) 구조체로 구조한다. 배열과 달리 구조체는 서로 다른 데이터끼리 그룹지을 수 있다. 대표적인 예로 성적처리시 학생 개개인별로 성적을 그룹지어 관리하는 것이 있다.

 

- 구조체의 정의

struct 키워드와 사용할 구조체 명을 명시하여 구조체를 정의한다.

구조체 내부를 구성하는 데이터는 미리 정의된 데이터 형으로 선언해야 한다.

구조체 내부의 각 데이터는 분리자(;)로 구분해야 한다.

struct 구조체명{

데이터 형 변수명1;

데이터 형 변수명2;

....

};

구조체명에는 int, char 등 기존에 있는 데이터 타입을 적으면 안된다. 구조체는 기존의 데이터형들을 묶어 새로운 데이터형을 만드는 방식이다.

구조체는 위와 같이 정의하고, 구조체 정의는 새로운 구조체를 만들뿐, 메모리를 할당하는 것이 아니다. 구조체 변수 선언은 아래 예제에서 살펴보자.

 

 

<22바이트의 People이라는 구조체 정의>


<구조체를 정의하면서 변수도 함께 선언>

☞ 보통 구조체를 한번만 사용하는 경우에 이렇게 적는다.


 

2. typedef

-기존의 데이터 형을 새로운 이름으로 재정의하는 사용자 정의 데이터

typedef 기존의 데이터형 새로운 데이터형.

 

typedef를 빼면 변수 선언과 같다.


<typedef의 예시>


typedef는 단순히 줄여쓰기 위한 문법이 아니다.

예를 들어 한 프로그램에서 '나이'에 관한 변수를 모두 char로 선언했다. 하지만 나이에 관련된 char형을 int로 모두 바꿔야 하는 상황이 올 때, 프로그램상에 다양한 char형 변수 중 어떤 것이 나이에 관한 변수인지 헷갈리고 힘들게 된다. 이런 상황을 예방하고자 사용하는 것이 typedef이다.


 

3. typedef VS define

 

다음 예시를 살펴보자.

#define MY_PTR int*

typedef int* INTPTR;


void main()

{

int a =2, b = 3;

MY_PTR p1, p2;    //int*p1,p2;

INTPTR p3, p4;    //int*p3, *p4;


p1=&a;

p2=&b;     //컴파일에러발생..

p3 = &a;

p4 = &b;

}

위의 예시에서 MY_PTR p1, p2; 같은 경우에는 int*p1,p2;와 같은 뜻이다. 즉, p1은 int*형으로 선언한 것이지만 p2는 int로 선언한 것이다. 따라서 아래 p2=&b;는 에러가 나게 된 것이다.

 

typedef는 데이터타입을 정의(치환)하는 것. 상수치환은 불가능.

#define은 일반 변수, 상수 등을 치환(글자 그대로를 치환함.)


4. 구조체 사용하기

-정의된 구조체는 struct키워드와 구조체명을 이용하여 기본 데이터형 변수를 선언하듯이 선언한다.

앞서 정의한 People 구조체의 변수는 다음과 같이 선언한다.


-c언어에서는 매번 구조체를 선언할 때마다 struct키워드를 명시해야 하므로 typedef 명령어를 사용하여 데이터 형을 재정의할 수 있다.

이렇게 typedef를 이용하면 struct를 변수를 선언할 때마나 사용해줄 필요가 없다.


그림6


이처럼 typedef를 구조체 정의 자체에 사용해주어도 된다.


-구조체 또한 데이터 형이기 때문에 변수 선언 시 배열, 포인터 문법을 그대로사용할 수 있다.

그림7


-구조체의 각 요소에는 '.'을 이용하여 접근할 수 있다.

그림8,그림9

 

5. 구조체 동적할당

-구조체 크기의 메모리를 동적 할당하여 선언하고 사용하기


PEOPLE *p = (PEOPLE*)malloc(sizeof(PEOPLE));

strcpy((*p).name,"홍길동");

(*p).age=20;

(*p).height=175.0;


그림10


위의 코드에서, 포인터'*'보다 '.'의 우선순위가 더 높기 때문에 괄호를 반드시 해주어야 한다. 구조체에 포인터를 사용하면 괄호를 계속해서 적어주어야 하는데, 이의 불편함을 없애기 위해 다음과 같이 표현한다.


strcpy(p->name"홍길동");

p->age = 20;

p->height = 175.0;


6. 구조체 크기와 메모리 배열

-구조체 크기는 일반적으로 구조체를 구성하는 요소들의 데이터 형의 크기를 합산한 값이다.

-비쥬얼C/C++에서는 처리의 수행능력을 높이기 위해 ‘Structure Member Alignment’를 사용하기 때문에 구조체 선언 시에 데이터 형을 어떻게 배열했는지에 따라 구조체의 크기가 달라질 수 있다.


struct MyData{

             char a;

             int b;

             short int c;

             int d;

};


1바이트 정렬시 = 11바이트

2바이트 정렬시 = 12바이트



4바이트 정렬 시 = 16바이트


비쥬얼 C/C++에서는 최대 데이터형을 따라 aliment를 정하기 때문에 구조체 정의시 생각없이 그냥 하게 되면 크기가 엄청나게 뻥튀기가 되므로 항상 염두해두어야 한다!


-구조체를 효과적으로 선언하려면 동일한 데이터형을 가진 변수끼리 모으고 작은 크기의 데이터 형이 위쪽에 오도록 선언하면 메모리 낭비를 줄일 수 있다.


struct MyData{

char a;

short int c;

int b;

int d;

}

이 경우에는 구조체의 크기는 12바이트가 된다.

배열의 경우는 한번에 들어간다. 끝부분만 영향을 받는다.

항상 구조체를 정의한 후에는 sizeof를 통해 크기를 확인하는 것이 좋다.



7. 공용체

공용체는 구조체와 외형적으로 같다.

-공용체는 union 이라는 키워드를 사용하며 구조체와 매우 유사한 형식을 가지고 있다.

-구조체는 구조체 내에 선언된 변수들이 별도로 메모리를 차지하지만, 공용체는 가장 큰 변수의 크기로 메모리가 할당된다.

-공용체에 선언된 모든 변수들이 가장 큰 하나의 메모리 영역을 공한다.

-공용체 내에 선언된 모든 변수들은 할당된 메모리를 각자의 데이터형 으로 접근하여 사용한다.


union Friend{

char a;

short int b;

int c;

}; 


여기서 Freind의 크기는 4바이트!!


8. 공용체의 사용

-공용체는 각 변수들이 동일한 메모리에 접근하기 때문에 한 변수의 값을 변경하게 되면 다른 변수의 값도 변하게 된다.


union Type{

int i;

short int s[2];

char c[4];

};


void main()

{

union Type data;

data.i=0x12345678

data.s[1]=0xABCD;

data.c[0]=0x11;

}


위와 같은 예시에서는 4바이트의 공간을 세가지 방식으로 사용할 수 있도록 한다.

i값을 변화시키면 4바이트의 값을 한번에 바꿀 수 있고, s는 2바이트, c는 1바이트만 바꿀 수 있다. 이러한 유니언은 보통 메모리를 극도로 아낄 때 사용한다.


 


본 포스트는 TIPSSOFT의 무료 지식나눔 강좌를 듣고 직접 정리한 글입니다.

자세한 사항은 아래 링크에서 확인하실 수 있습니다.


www.tipssoft.com

 


'TIPS > C언어' 카테고리의 다른 글

[TIPS] 8th 20160728_(1)  (0) 2016.08.06
[TIPS] 4th 20160714  (0) 2016.07.23