본문 바로가기
[알고리즘 + 자료구조]/[Do it 자료구조와 함께 배우는 알고리즘]

[알고리즘] Do it 자료구조와 알고리즘 2장 정리

by Hevton 2020. 10. 9.
반응형

연습문제_Q1 > 키의 최솟값을 구하는 함수 minof

#include <stdio.h>
#include <stdlib.h>

int minof(const int a[], int n)
{
    int min = a[0];
    
    for(int i=1; i<n; i++)
    {
        if(min>a[i])
            min = a[i];
    }
    return min;
}

int main()
{
    int i;
    int *height;
    int number;
    
    printf("사람 수 : ");
    scanf("%d", &number);
    
    height = (int*)calloc(number, sizeof(int));
    printf("%d 사람의 키를 입력하세요.\n", number);
    
    for(int i=0; i<number; i++)
    {
        printf("height[%d] : ", i);
        scanf("%d", &height[i]);
    }
    printf("최솟값은 %d입니다.\n", minof(height, number));
    free(height);
    
    return 0;
}

 

연습문제_Q2 > 키의 합계를 구하는 함수 sumof

#include <stdio.h>
#include <stdlib.h>

int sumof(const int a[], int n)
{
    int sum=0;
    
    for(int i=0; i<n; i++)
    sum+=a[i];
    
    return sum;
    
}

int main()
{
    int i;
    int *height;
    int number;
    
    printf("사람 수 : ");
    scanf("%d", &number);
    
    height = (int*)calloc(number, sizeof(int));
    printf("%d 사람의 키를 입력하세요.\n", number);
    
    for(int i=0; i<number; i++)
    {
        printf("height[%d] : ", i);
        scanf("%d", &height[i]);
    }
    printf("합계는 %d입니다.\n", sumof(height, number));
    free(height);
    
    return 0;
}

 

연습문제_Q3 > 키의 평균을 구하는 함수 aveof

#include <stdio.h>
#include <stdlib.h>

double aveof(const int a[], int n)
{
    double sum=0;
    
    for(int i=0; i<n; i++)
    sum+=a[i];
    
    return sum/(double)n;
}

int main()
{
    int i;
    int *height;
    int number;
    
    printf("사람 수 : ");
    scanf("%d", &number);
    
    height = (int*)calloc(number, sizeof(int));
    printf("%d 사람의 키를 입력하세요.\n", number);
    
    for(int i=0; i<number; i++)
    {
        printf("height[%d] : ", i);
        scanf("%d", &height[i]);
    }
    printf("평균은 %f입니다.\n", aveof(height, number));
    free(height);
    
    return 0;
}

 

연습문제_Q4 > 키와 사람 수를 난수로 생성하여 키의 최댓값을 구하는 프로그램 작성

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int maxof(const int a[], int n)
{
    int i;
    int max = a[0];
    
    for(i=1; i<n; i++)
    {
        if(a[i] > max) max=a[i];
    }
    
    return max;
}

int main()
{
    int i;
    int* height;
    int number;
    srand(time(NULL));
    
    number = rand()%16+5;
    
    height = (int *)calloc(number, sizeof(int));
    
    for(int i=0; i<number; i++)
    {
        height[i] = 100+rand()%90;
        printf("height[%d] = %d\n", i, height[i]);
    }
    
    printf("최댓값은 %d입니다.\n", maxof(height, number));
    free(height);
    
    return 0;
}

 

연습문제_Q5 > 배열 요소를 역순으로 정렬하는 과정을 일일이 출력하는 프로그램

#include <stdio.h>
#include <stdlib.h>

#define swap(type, x, y) do { type t = x; x = y; y = t; } while(0)

void ary_reverse(int a[], int n)
{
    int i;
    for(i=0; i<n/2; i++)
    {
        printf("a[%d]와 a[%d]를 교환합니다.\n", i, n-i-1);
        swap(int, a[i], a[n-i-1]);
        for(int j=0; j<n; j++)
        printf("%d ", a[j]);
        putchar('\n');
    }
    printf("역순 정렬을 종료합니다.");
}

int main()
{
    int i;
    int *x;
    int nx;
    
    printf("요소 개수 : ");
    scanf("%d", &nx);
    x = (int *)calloc(nx, sizeof(int));
    
    for(i=0; i<nx; i++)
    {
        scanf("%d", &x[i]);
    }
    
    ary_reverse(x, nx);
    free(x);
    
    return 0;
}

 

연습문제_Q6 > card_convr 함수를 수정하여 배열의 맨 앞쪽에 아랫자리가 아닌 윗자리를 저장하는 card_conv 함수 작성

//Q5의 ary_reverse를 변형하여 사용해주면 됨.
#include <stdio.h>
#include <stdlib.h>
#define swap(type, x, y) do { type t = x; x = y; y = t; } while(0)

void ary_reverse(char a[], int n)
{
    int i;
    for(i=0; i<n/2; i++)
    swap(char, a[i], a[n-i-1]);
}
int card_convr(unsigned x, int n, char d[])
{
    char dchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int digits=0;
    
    if(x==0)
        d[digits++] = dchar[0];
    else{
        while(x)
        {
            d[digits++] = dchar[x%n];
            x/=n;
        }}
    return digits;
}

int main()
{
    int i;
    unsigned no;
    int cd;
    int dno;
    char cno[512];
    int retry;
    
    puts("10진수를 기수 변환합니다.");
    do {
        printf("변환하는 음이 아닌 정수 : ");
        scanf("%u", &no);
        do{
            printf("어떤 진수로 변환할까요?(2-36) : ");
            scanf("%d", &cd);
        } while(cd < 2 || cd >36);
        dno = card_convr(no, cd, cno);
        ary_reverse(cno, dno);
        printf("%d진수로는", cd);
        for(i=0; i<dno; i++)
        {
            printf("%c", cno[i]);
        }
        printf("입니다.\n");
        printf("한번 더 할까요?(1 예/0 아니오) : ");
        scanf("%d", &retry);
    } while(retry==1);
    
    return 0;
}

 

연습문제_Q7 > 기수 변환 과정을 상세히 출력하는 프로그램 작성

//Q5의 ary_reverse를 변형하여 사용해주면 됨.
#include <stdio.h>
#include <stdlib.h>
#define swap(type, x, y) do { type t = x; x = y; y = t; } while(0)

void ary_reverse(char a[], int n)
{
    int i;
    for(i=0; i<n/2; i++)
    swap(char, a[i], a[n-i-1]);
}
int card_convr(unsigned x, int n, char d[])
{
    char dchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int digits=0;
    
    if(x==0)
        d[digits++] = dchar[0];
    else{
        while(x)
        {
            printf("%d|%10d ••• %c\n", n, x, dchar[x%n]);
            d[digits++] = dchar[x%n];
            x/=n;
            printf(" + ---------\n");
        }}
    printf("%12d\n", x);
    return digits;
}

int main()
{
    int i;
    unsigned no;
    int cd;
    int dno;
    char cno[512];
    int retry;
    
    puts("10진수를 기수 변환합니다.");
    do {
        printf("변환하는 음이 아닌 정수 : ");
        scanf("%u", &no);
        do{
            printf("어떤 진수로 변환할까요?(2-36) : ");
            scanf("%d", &cd);
        } while(cd < 2 || cd >36);
        dno = card_convr(no, cd, cno);
        ary_reverse(cno, dno);
        printf("%d진수로는", cd);
        for(i=0; i<dno; i++)
        {
            printf("%c", cno[i]);
        }
        printf("입니다.\n");
        printf("한번 더 할까요?(1 예/0 아니오) : ");
        scanf("%d", &retry);
    } while(retry==1);
    
    return 0;
}

 

연습문제_Q8 > 배열 b의 모든 요소를 배열 a에 복사하는 함수를 작성하세요.

 #include <stdio.h>
 #include <stdlib.h>

 void ary_copy(int a[], const int b[], int n) {
     for(int i =0; i < n ; i++) {
         a[i] = b[i];
     }
 }

 int main()
 {
     int N;
     int *ori, *ori_copy;
     
     printf("요소 갯수 : ");
     scanf("%d", &N);
     
     ori = calloc(N, sizeof(int));
     ori_copy = calloc(N, sizeof(int));
     
     printf("값 입력 : ");
     
     for(int i=0; i<N; i++) {
         scanf("%d", &ori[i]);
     }
     
     ary_copy(ori_copy, ori, N);
     
     for(int i =0; i < N; i++) {
         printf("%d ", ori_copy[i]);
     }
    free(ori);
    free(ori_copy);
     
     
     return 0;
 }

 

연습문제_Q9 > 배열 b의 모든 요소를 배열 a에 역순으로 복사하는 함수를 작성하세요.

 #include <stdio.h>
 #include <stdlib.h>

 void rary_copy(int a[], const int b[], int n) {
     for(int i =0; i < n ; i++) {
         a[i] = b[n-i-1];
     }
 }

 int main()
 {
     int N;
     int *ori, *ori_copy;
     
     printf("요소 갯수 : ");
     scanf("%d", &N);
     
     ori = calloc(N, sizeof(int));
     ori_copy = calloc(N, sizeof(int));
     
     printf("값 입력 : ");
     
     for(int i=0; i<N; i++) {
         scanf("%d", &ori[i]);
     }
     
     rary_copy(ori_copy, ori, N);
     
     for(int i =0; i < N; i++) {
         printf("%d ", ori_copy[i]);
     }
 
    free(ori);
    free(ori_copy);

     
     return 0;
 }

 

연습문제_Q10 > 배열 a의 모든 요소의 순서를 뒤섞는 shuffle 함수를 작성하세요.

 //포문 카운트값 i로 배열 요소 0부터 n보다 작을 때 까지 돌면서,
 //rand 함수로 0~n-1 까지의 랜덤 수를 뽑아서
 //현재 i와 랜덤으로 뽑은 요소 인덱스를 서로 바꿔치기.
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>

 void shuffle(int a[], int n) {
     srand(time(NULL));
     for(int i =0; i < n ; i++) {
         int temp = rand()%n;
         int value = a[i];
         a[i] = a[temp];
         a[temp] = value;
     }
 }

 int main()
 {
     int N;
     int *ori;
     
     printf("요소 갯수 : ");
     scanf("%d", &N);
     
     ori = calloc(N, sizeof(int));
     
     printf("값 입력 : ");
     
     for(int i=0; i<N; i++) {
         scanf("%d", &ori[i]);
     }
     
     shuffle(ori, N);
     
     for(int i =0; i < N; i++) {
         printf("%d ", ori[i]);
     }
     free(ori);
     
     return 0;
 }

 

연습문제_Q11 > dayofyear 함수를 변수 i와 days를 사용하지 않고 동시에 for문이 아닌 while문으로 구현해보세요.

 #include <stdio.h>

 int mdays[][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};

 int isleap(int year)
 {
     return year % 4 ==0 && year % 100 !=0 || year % 400 ==0;
 }

 int dayofyear(int y, int m, int d) {
     int *p = mdays[isleap(y)];
     while(m-1) {
         d+= *p;
         p=p+1;
         m--;
     }
     return d;
 }

 int main()
 {
     int year, month, day;
     int retry;
     do{
         printf("년 : "); scanf("%d", &year);
         printf("월 : "); scanf("%d", &month);
         printf("일 : "); scanf("%d", &day);
         printf("%d년의 %d일째입니다.\n", year, dayofyear(year, month, day));
         printf("다시 할까요?( 1 예/ 0 아니오) : ");
         scanf("%d", &retry);
     } while(retry == 1);
     
     return 0;
 }

// 문제에서 주어지는 정답
///*--- y년 m월 d일의 그 해의 지난 날의 수를 구합니다. ---*/
//int dayofyear(int y, int m, int d)
//{
//	while (--m)
//		d += mdays[isleap(y)][m - 1];
//	return (d);
//}

 

연습문제_Q12 > 시력 분포를 그래프 모양으로 출력하도록 프로그램 작성

 #include <stdio.h>
 #define VMAX 21

 typedef struct {
     char name[20];
     int height;
     double vision;
 } PhysCheck;

 double ave_height(const PhysCheck dat[], int n) {
     int i;
     double sum = 0;
     for(i=0; i<n; i++) {
         sum +=dat[i].height;
     }
     return sum;
 }

 void dist_vision(const PhysCheck dat[], int n, int dist[]) {
     int i;
     for(i=0; i< VMAX; i++) {
         dist[i] = 0;
     }
     for(i=0; i<n; i++) {
         if(dat[i].vision>=0.0 && dat[i].vision <= VMAX/10.0)
             dist[(int)(dat[i].vision*10)]++;
     }
 }

 int main() {
     int i;
     PhysCheck x[] = { {"박현규", 162, 0.3}, {"함진아", 173, 0.7}, {"최윤미", 175, 2.0}, {"홍연의", 171, 1.5}, {"이수진", 168, 0.4}, {"김영준", 174, 1.2}, {"박용규", 169, 0.8}};
     
     int nx = sizeof(x) / sizeof(x[0]);
     int vdist[VMAX];
     puts("신체 검사표");
     puts("   이름   키   시력");
     puts("-----------------");
     for(i=0; i<nx; i++) {
         printf("%-5s%5d%5.1f\n", x[i].name, x[i].height, x[i].vision);
     }
     printf("\n평균 키 : %5.1f cm\n", ave_height(x, nx));
     dist_vision(x, nx, vdist);
     printf("\n시력 분포\n");
     for(i=0; i < VMAX; i++) {
         printf("%.1f ~ : ", i/10.0);
         for(int j = 0; j < vdist[i]; j++) {
             printf("*");
         }
         putchar('\n');
     }
     return 0;
 }

 

연습문제_Q13 > 날짜를 나타내는 구조체가 아래와 같을 때, 각 함수들을 작성하세요.

typedef struct {
	int y;
    int m;
    int d;
} Date;

1. y년 m월 d일을 나타내는 구조체를 반환하는 함수 DateOf

2. 날짜 x의 n일 뒤의 날짜를 반환하는 함수 After

3. 날짜 x의 n일 앞의 날짜를 반환하는 함수 Before

 

 #include <stdio.h>

 typedef struct {
     int y;
     int m;
     int d;
 } Date;

 int mdays[][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};


 int isleaf(int y) {
     return y % 4 == 0 && y % 100 != 0 ||y % 400==0;
 }


 Date DateOf(int y, int m, int d) {
     Date z = {y, m, d};
     return z;
 }

 //하나씩 증가하며 더해주며 체크하는 방법 / 뭉탱이로 체크하여 계산하는 방법
 Date After(Date x, int n) {
     while(n) {
         int up = mdays[isleaf(x.y)][x.m-1] - x.d + 1; //다음달이 되기 위해 더해야 할 숫자
         if(up>n) {
             x.d += n;
             break;
         } else {
             x.d = 1;
             if((x.m)+1>12) {
                 x.y++; x.m=1;
             } else
                 x.m++;
             n -= up;
         }
     }
     return x;
 }

 Date Before(Date x, int n) {
     while(n){
         int down = x.d; // 이전 달로 내려가기 위한 조건
         
         if(down>n) {
             x.d-=n;
             break;
         } else {
             if(x.m==1) {
                 x.y--; x.m=12;
             } else
                 x.m--;
             x.d = mdays[isleaf(x.y)][x.m-1];
             n-=down;
         }
     }
     return x;
 }



 int main()
 {
     Date d = {2027, 8, 14};
     d = Before(d, 2500);
     printf("%d 년 %d 월 %d 일", d.y, d.m, d.d);
 }
 
 
// 문제에서 주어진 정답 After, Before. 내 코드보다 훨씬 간결함. ㅜㅜ
// 다 더해놓고, 또는 다 빼놓고 시작.

///*--- 날짜 x의 n 일 뒤의 날짜를 반환 ---*/
//Date After(Date x, int n)
//{
//	if (n < 0)
//		return Before(x, -n);
// 다 더해놓음
//	x.d += n;
//
//	while (x.d > mdays[isleap(x.y)][x.m - 1]) {
//		x.d -= mdays[isleap(x.y)][x.m - 1]; //x.m -1은 데이터 검출 작업(인덱스0부터시작하기떄문)
//		if (++x.m > 12) { //'월'의 실제움직임
//			x.y++;
//			x.m = 1;
//		}
//	}
//	return x;
//}
//
///*--- 날짜 x의 n일 앞의 날짜를 반환 ---*/
//Date Before(Date x, int n)
//{
//	if (n < 0)
//		return After(x, -n);
// 다 빼놓음
//	x.d -= n;
// x.m 값 변화가 '월'의 실제 움직임이고, x.m-1은 배열이 0부터 인덱스가 시작되기 때문에 n월은 n-1인덱스에 있으므로 데이터 검출작업
//	while (x.d < 1) {
//		if (--x.m < 1) { 
//			x.y--;
//			x.m = 12;
//		}
//		x.d += mdays[isleap(x.y)][x.m - 1];
//	}
//
//	return x;
//}

 

 

공부 내용 정리

▶︎ 배열과 포인터

 

∙ 일반적으로 자료형이 Type이고 요소 개수가 n인 배열의 자료형은 Type[N]으로 나타낸다.
->
int a[5];에서 배열 a의 자료형은 int[5]형이라고 말함.
또는 포인터적인 접근으로 int * 형이라고도 함.

 

∙ 배열의 요소 개수를 구하는 팁.
배열 이름이 a일때, int count = sizeof(a) / sizeof(a[0]);



∙ 절차지향인 C언어에선 배열 선언 시 객체지향 언어들과는 다르게 배열 요소값을 변수로 넣어 초기화 할 수 없다. 이때 상수값을 넣어줘야 하며, 상수는 실행 시점이 아닌 컴파일 시점에 계산되어 준비된다.

int n;
printf("요소 개수 : ");
scanf("%d", &n);
int a[n]; //컴파일 오류 : n은 상수식이 아닙니다.


대신 동적할당을 사용한다.

int n;
int *a;
printf("요소 개수 : ");
scanf("%d", &n);
a = calloc(n, sizeof(int));

 

▶︎ 동적할당 함수

• calloc 함수

헤더 : #include <stdlib.h>
형식 : void *calloc(size_t nmemb, size_t size);
설명 : 크기가 size인 자료가 nmemb개만큼 들어갈 메모리를 할당합니다. 할당한 메모리 영역은 모든 비트가 0으로 초기화됩니다.
반환값 : 메모리 할당에 성공하면 할당한 영역의 첫 번째 포인터를 반환하고, 실패하면 NULL 포인터를 반환합니다.

• malloc 함수

헤더 : #include <stdlib.h>
형식 : voud *malloc(size_t size);
설명 : 크기가 size인 메모리를 할당합니다. 할당한 메모리의 값은 정의되지 않습니다.
반환값 : 메모리 할당에 성공하면 할당한 영역의 첫 번째 포인터를 반환하고, 실패하면 NULL 포인터를 반환합니다.

 

• free 함수

헤더 : #include <stdlib.h>
형식 : void free(void *ptr)
설명 : ptr이 가리키는 메모리를 해제한다.
반환값 : 없음

 

+ NULL = ((void *)0)



▶︎ C언어 프로그램 메모리 구조

프로그램을 실행하면 운영체제는 프로그램이 사용할 메모리 영역을 할당한다. 할당하는 메모리 영역은 데이터/스택/힙 영역으로 나뉜다.

• 데이터 영역

- 전역 변수와 정적(static) 변수가 할당되는 영역
- 프로그램을 시작하면 할당하고, 종료하면 메모리에서 해제한다.

• 스택 영역

- 함수 호출 시 생성되는 지역변수와 매개변수가 저장되는 영역
- 함수 호출이 완료되면 사라짐

• 힙 영역

- 필요에 따라 동적으로 메모리 할당
- 런타임동안 메모리 결정해야 하는 경우 사용됨


+ calloc, malloc 함수는 힙 영역 메모리를 차지한다.
+ 사용이 끝나면 해제해줘야하는데 이때 사용하는 함수가 free함수다.



▶︎ void 포인터

calloc 함수, malloc 함수, free 함수는 char형 객체, int형 객체, 나아가 배열이나 구조체 객체 등 모든 자료형의 메모리 확보 또는 해제에 사용합니다.

이때 특정한 자료형의 포인터를 주고받을 때 자료형이 서로 맞지 않으면 문제가 발생하므로 void 포인터를 반환하거나 받는 데 사용합니다. void 포인터는 모든 형의 객체를 가리킬 수 있습니다. void 포인터를 모든 자료형의 포인터에 대입할 수 있고, 거꾸로 모든 자료형의 포인터를 void 포인터에 대입할 수 있습니다.

+ 값을 사용할 때 (역참조 *연산을 사용할 때)에는 그 전에 먼저 void *형이 아닌 다른 명확한 자료형에 대한 포인터로 형변환을 해준 뒤 사용해주어야한다. void *인 상태에서 역참조(*)연산을 사용하면 에러가 나온다.

 

▶︎ 포인터와 배열 활용


포인터 p가 배열의 요소 e를 가리킬 때
p+i는 요소 e의 i개만큼 뒤쪽의 요소를 가리키는 포인터가 되고,
p-i는 요소 e의 i개만큼 앞쪽의 요소를 가리키는 포인터가 됩니다.

Q. 옛날엔 int면 4바이트 더해주고, char이면 1바이트만 더해주며 계산해줬던거같은데 그냥 1이면 자동 형변환이 되는듯?

(따라서 포인터 a와 b가 같은 배열의 요소를 가리킨다면 b - a에 의해 두 요소의 인덱스 차이를 얻을 수 있대. 배열 x의 어느 한 요소를 가리키는 포인터 p가 있을 때, 그 요소의 인덱스는 p - x로 얻을 수 있다는 것..!)

▶︎ NULL 포인터 

정의는 '값 0을 갖는 상수식을 void *로 형 변환한 식'이다.
정수값 0은 모든 포인터형으로 형 변환이 가능하고 그 결과는 NULL 포인터입니다.



▶︎ 주사 

배열의 요소같은 데이터를 하나씩 차례로 살펴보는 과정.


▶︎ 함수 형식의 매크로

정의
#define func(type, x) do { type t = x; } while(0)

호출
func(int, 5);

함수 형식 매크로는 프로그램을 컴파일 하는 과정에서 그대로 치환됩니다. 따라서 위의 함수 func(int, 5) 부분이 위에 func(type, x)와 매칭되어 그 다음 do부터의 문장이 그대로 치환됩니다.

do { type t = x; } while(0);

명백히 한번만 실행되는 구문인데도 do while을 쓰는 이유는

#define func(type, x) { type t = x; }

그냥 이렇게 정의할 경우 치환 시에

{ type t = x; } ; 처럼 마지막에 불필요한 세미콜론이 남고, 괄호도 의미없이 생길수도 있으며 이런것들이 여러 오류로 이어질 수 있기 때문에 do while로 하는것이 낫습니다.

참고로 do while문은 do 부터 while 마지막의 세미콜론까지가 하나의 구문입니다.


▶︎ 기수

수를 나타내는데 기초가 되는 수로, 10진법에서는 0부터 9까지의 정수를 말한다.

 

+ 10진수의 2진수, 8진수, 16진수로의 변환을 통해 각 진수의 기수들로 수를 표현하는 방법.

10진수를 2진수, 8진수, 16진수로 표현하는 방법




▶︎ N진수 표현

0x로 시작하면 16진수값
0으로 시작하면 8진수값

0x1C // 10진수 28에 대한 16진수 표기
034 // 10진수 28에 대한 8진수 표기


▶︎ 소수찾기

2부터 n-1 까지의 어떤정수로도 나누어떨어지지 않음

2부터 n-1 까지의 어떤소수로도 나누어떨어지지 않음

2부터 n의 제곱근까지의 어떤소수로도 나누어떨어지지 않음

이외에 범위안의 소수를 구할때 좋은 알고리즘은 '에라토스테네스의 체' 알고리즘( 제곱근이하의수까지 다 나눠주고 그 범위안에서 체크안된것들 모두 소수)


▶︎ 배열 초기화 팁

 

배열 초기화에 없는 요소는 0으로 초기화된다.
int mc[2][3] = {{1, 2}, {4}};
=
int mc[2][3] =  {{1, 2, 0}, {4, 0, 0}};


▶︎ 구조체


임의의 자료형 요소를 조합하여 만든 자료구조

// 구조체 xyz
struct xyz {
int x;
long y;
double z;
};


xyz를 구조체 태그라고 한다.
x, y, z 변수들을 구조체 멤버라고 한다.

struct xyz a //struct xyz형 a 정의
struct xyz *p = &a // a를 가리키는 포인터

구조체 객체 안 멤버는 .연산자를 사용하여 다음과 같은 형식으로 접근
a.x // 객체이름.멤버이름(객체 a안의 멤버 x)

p가 struct xyz형에 대한 포인터일 때 p가 가리키는 객체의 멤버에 접근하는 형식은 -> 연산자를 사용합니다.
p->x // 포인터 이름 -> 멤버 이름(p가 가리키는 객체 안의 멤버 x)


∙ 구조체 선언 간결화

구조체를 선언할땐 구조체의 태그이름만으로 구조체 자료형의 이름으로 지정할 수 없다. 다시말해
xyz a; 가 아니라 struct xyz a; 이런식으로 항상 struct를 붙여줘야한다. 이때 typedef 선언을 사용해 짧게 만들어 줄 수 있다.

typedef struct xyz XYZ; // struct xyz와 동의어인 XYZ 선언
이렇게되면 이제 하나의 단어 XYZ만으로 구조체 자료형의 이름을 나타낼 수 있다.

XYZ a; //XYZ형(즉, struct xyz형) a

이런 typedef와 구조체 정의를 한번에 하는 방법

typedef struct {
int x;
long y;
double z;
}XYZ;

 

 

출처 - 'do it 자료구조와 함께 배우는 알고리즘 입문 C언어편' 도서

반응형