본문 바로가기

프로그래밍/C language

6. Structures


6.1 Basics of Structures

- Structure은 여러 variable이 묶어진 collection임
- 관련된 여러 변수들을 하나의 단위로 조작가능하게 해줌
- structure 내부 변수명은 바깥의 변수명과 겹쳐도 상관없음

ex) struct point{
int x;
int y;
}; //두가지 int형의 x,y 변수를 가지는 point라는 구조를 선언, 여기서 point를 structure tag라고 하고 안에 있는 변수를 member라고 함

struct point pt; // 앞서 정의한 struct point라는 구조를 틀로 하는 pt변수 선언
pt = {100, 200}; // pt의 member변수에 값 할당
print(%d, %d, pt.x, pt.y); // pt의 x와 y값 출력

6.2 Structures and Functions

- structure타입 변수는 function의 argument, return type으로 쓰일 수 있음
- argument로 들어갈때는, structure의 값이 복사되어 들어감. 따라서, structure를 가리키는 pointer를 생성하여 집어넣는 것이 효율적일 수 있음

ex1) struct point make point(int x, int y){
struct point temp;
temp.x = x; 
temp.y = y;
return temp;
} // struct point 형을 반환하는 문장

ex2) struct point *pp; //struct point형 값을 가리키는 포인터 변수 pp
printf("%d, %d", (*pp).x, pp->x); // 동일한 출력

ex3) ++p->len은 ++(p->len)과 같음, 즉 len을 1증가
*p->str++는 *(p->str)++와 같음, 즉 str이 가리키는 것을 1 증가
*p++->str은 *(p++->str)와 같음, 즉 p를 1 증가

6.3  Array of Structure

- Array내에 변수로 struct변수가 들어갈 수 있음

ex1) struct key{
char *word;
int count;
} keytab[NKEYS];
//struct key를 변수로 갖는 keytab배열 선언

ex2) struct key{
char *word;
int count;
} keytab[] = {
"good", 0,
"break", 0,
"case", 0
};
//struct key를 변수로 갖는 keytab배열 선언 및 값 할당
printf("%d", keytab[0].count); // 배열의 첫번째 요소에서 count멤버 값 출력

6.4 Pointers to Structures

- struct타입의 변수를 가리키는 pointer를 설정할 수 있고, function의 return type또한 지정가능

ex) struct key *binsearch(char* Word, struct key* tab, int n) 
// struct key 구조를 가리키는 포인터가 return값과 argument에 사용됨

6.5 Self-referential Structures

- struct member는 자신의 struct형을 가질 수 있으므로, recursive하게 자신을 참조할 수 있음

ex)
struct tnode{
char *word;
int count;
struct tnode *left;
struct tnode *right;
}
// binary tree구조에서 하나의 노드를 위와 같은 구조로 저장가능
// 구조체의 멤버가 자신의 구조를 가진 다른 노드를 가리키게 됨

6.6 Table Lookup

- #define문의 name, replacement_text은 install(name, replacement_text)를 통해 hash table에 저장됨 
- hash table의 각 값은 struct형의 node로 구성된 linked-list의 첫번째 node를 가리킴

ex) hash size =  100;
struct nlist *hashtab[100];

struct nlist{
struct nlist *next; // 다음 linked-list 가리킴
char *name; // name 가리킴
char *defn; // replacement_text 가리킴
}

6.7 Typedef

- Typedef문은 기존의 data type과 동일한 성질의, 새로운 이름의 data type을 생성하는 문장
- 새로운 data type의 이름은 첫문자를 대문자로 써서 data type임을 구분
- 문법적으로는 storage class인 static, extern과 같은 위치에 typedef를 작성
- #define과 동일한 기능을 하지만, preprocessor가 처리하는 #define과 달리 compiler에 의해 처리되므로 더 많은 것을 text substitution할 수 있음
- 두가지 이유로 사용됨
1. machine-dependent한 program에서 int, short등은 machine에 따라 bit_size등이 다른데,
typedef를 이용하여 작성된 프로그램은 typedef문에서만 상황에 맞게 변경함으로서 유연하게 대처가능
2. 더 이해하기 쉽게 문서화 할 수 있음

ex) typedef int Length; // int타입인 Length 
typedef struct tnode *Treeptr; //struct tnode *타입인 Treeptr
typedef int (*PFI)(char *, char *); // 두개의 char*을 입력받고, int를 반환하는 pointer to function인 PFI

Length len;
Treeptr node1;
PFI strcmp;  

6.8 Unions

- Union은 여러 다른 type의 변수를 하나의 저장공간에서 조작할 수 있게 하는 구조체 문법의 변수임
- 메모리 공간을 저장하기 위해 예전에 사용

ex) union u_tag{
int ival; //4byte 
double fval; //8byte
} u;

u.ival = 7; //u에 int형으로 7 저장
u.fval = 9; //u에 double형으로 9 저장

//u는 union u_tag형의 변수
//u는 double이 가장 크므로, 8byte만큼의 공간을 할당받음 
//union은 본질적으로 하나의 저장공간이므로, 하나의 값만을 저장함

6.9 Bit-fields

- 자료형에 맞게 값을 저장하는 것이 아닌, 비트수에 맞게 값을 저장하고 싶은 경우 사용
- bit-field가 실제로 할당되는 순서나, 숫자가 bit-field에 padding될 때 어떤 방식으로 될 지는 implement-dependent
- low-level의 프로그래밍에서, storage space가 부족할 경우사용. 예를 들어, c에서 가장 작은 자료형인 char은 8bit를 사용함
하지만, True/False를 나타내고 싶을 경우 1bit만 사용하면 되므로, bit-field사용

ex) struct{
unsigned int is_keyword : 1; //1비트 저장공간 할당
unsigned int is_extern : 2; //2비트 저장공간 할당
unsigned int is_static : 3; //3비트 저장공간 할당
} flags;
//들어가는 값이 unsigned int형임을 명시 

flags.is_keyword = 2; //1비트 공간에 할당 되므로 실제로는 11중 앞 또는 뒤의 1이 버려지고, 1만 저장됨
flags.is_extern = 2; //2비트 공간에 할당되므로 11이 저장
flags.is_static = 2; //3비트 공간에 할당되므로 11이 저장
//unsigned int형인 2가 공통적으로 할당되는 예시

'프로그래밍 > C language' 카테고리의 다른 글

8. The UNIX System Interface  (0) 2021.09.03
7. Input and Output  (0) 2021.08.19
5. Pointer and Arrays  (0) 2021.08.11
4. Function and Program Structure  (0) 2021.03.29
3. Control Flow  (0) 2021.03.29