Home C언어 공부 정리(9/10)-연습문제
Post
Cancel

C언어 공부 정리(9/10)-연습문제

22/01/11

단어리스트 입력받아 거꾸로 리스트 출력하기

  • 단어리스트 struct node 생성
    • 1
      2
      3
      4
      
      struct node {
          char *name;
          struct node *link; // struct node를 참조하는 포인터변수 link
      };
      
  • 단어 입력받기(함수 getname())
    • getchar()로 입력받기
  • getname()을 node에 추가(함수 addlist(), namecopy())
    • (node *)가 비어있으면 메모리 할당, node.name에 namecopy()로 단어 추가
    • node.link에 다음 단어 연결(재귀함수)
  • ★역순환 리스트 생성(invert())★
  • 역순환 리스트 출력(listprint())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct node {
    char *name;
    struct node *link;
};

int getname(char *);
struct node *addlist(struct node *, char *); // addlist함수는 struct node 참조
char *namecopy(char *);

// invert함수 선언
// malloc 사용 x, 주어진 연결 리스트에서 직접 link 변경시킬 것

void listprint(struct node *);

int main() {
    struct node *root;
    char name[80];
    root = NULL; // NULL pointer

    while(getname(name) != EOF) // EOF : End Of File, `ctrl-z`누르면 실행
        root = addlist(root, name);
    
    listprint(root);

    root = invert(root);
    printf("----- invert -----\n");
    listprint(root);

    return 0;
}

int getname(char *pname) {
    int i = 0;
    char c;

    while(((c=getchar()) != '\n') && c != EOF)
        *(pname + i++) = c;
    
    if (c == '\n')
        *(pname + i) = '\0';
    if (c == EOF)
        *pname = EOF;
    return *pname;
}

struct node *addlist(struct node *p, char *w) {
    if (p == NULL) { // null값인지 확인 후
        p = (struct node *)malloc(sizeof(struct)); // 메모리 할당 >> 융통성은 있지만 속도는 떨어짐
        p -> name = namecopy(w);
        p -> link = null;
    } else
        p -> link = addlist(p->link, w);
    
    return p;
}

char *namecopy(char *s) {
    char *p;
    int i = 0;

    p = (char *)malloc(strlen(s) + 1);
    while((*(p+1) = *(s+i)) != '\0')
        i++;

    return p;
}

void listprint(struct node *p) {
    while(p != NULL) {
        printf("%s\n", p -> name);
        p = p -> link;
    }
}

// invert 정의



소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct node {
    char *name;
    struct node *link;
};

int getname(char *);
struct node *addlist(struct node *, char *);
char *namecopy(char *);

// invert함수 선언
struct node *invert(struct node *);

void listprint(struct node *);

int main() {
    struct node *root;
    char name[80];
    root = NULL; // NULL pointer

    while(getname(name) != EOF) // EOF : End Of File, `ctrl-z`누르면 실행
        root = addlist(root, name);
    
    listprint(root);

    root = invert(root);
    printf("----- invert -----\n");
    listprint(root);

    return 0;
}

int getname(char *pname) {
    int i = 0;
    char c;

    while(((c=getchar()) != '\n') && c != EOF)
        *(pname + i++) = c;
    
    if (c == '\n')
        *(pname + i) = '\0';
    if (c == EOF)
        *pname = EOF;
    return *pname;
}

struct node *addlist(struct node *p, char *w) {
    if (p == NULL) {
        p = (struct node *)malloc(sizeof(struct));
        p -> name = namecopy(w);
        p -> link = null;
    } else
        p -> link = addlist(p->link, w);
    
    return p;
}

char *namecopy(char *s) {
    char *p;
    int i = 0;

    p = (char *)malloc(strlen(s) + 1);
    while((*(p+1) = *(s+i)) != '\0')
        i++;

    return p;
}

void listprint(struct node *p) {
    while(p != NULL) {
        printf("%s\n", p -> name);
        p = p -> link;
    }
}

// invert 정의
struct node *invert(struct node *lead) {
    struct node *trail, *middle;
    middle = NULL;
    while(lead) { // lead가 NULL이 아닐 동안
        trail = middle;
        middle = lead;
        lead = lead -> link;
        middle -> link = trail;
    }
    return middle;
}

실행 순서

  • apple
    banana
    candy
    danger
    EOF (입력)

  • getname(name)
    • char c = apple
    • *p = c
  • root = addlist(root, name)
    • p값*p->name*p->link*w 
      NULLNULLNULLapple 
      메모리할당namecopy(w)NULL  
        appleNULL 
  • 01

  • getname(name)
    • char c = banana
    • *p = c
  • root = addlist(root, name)
    • p값*p->name*p->link*w 
      not nullappleNULLbanana 
         addlist(p->link,w) 
      NULLNULLNULLbanana 
      메모리할당namecopy(w)NULL  
        bananaNULL 
  • 02

  • getname(name)
    • char c = candy
    • *p = c
  • root = addlist(root, name)
    • p값*p->name*p->link*w 
      not nullbananaNULLcandy 
         addlist(p->link,w) 
      NULLNULLNULLcandy 
      메모리할당namecopy(w)NULL  
        candyNULL 
  • 03

  • getname(name)
    • char c = danger
    • *p = c
  • root = addlist(root, name)
    • p값*p->name*p->link*w 
      not nullcandyNULLdanger 
         addlist(p->link,w) 
      NULLNULLNULLdanger 
      메모리할당namecopy(w)NULL  
        dangerNULL 
  • 04

  • listprint(root);
  • apple
    banana
    candy
    danger

  • ----- invert -----
  • invert(root)
    • 05

    • invert 실행순서
    • 06
    • Noleadmiddletrail
      1,2apple|banana…NULLNULL
      3 apple|banana… 
      4,5banana…apple|NULL 
    • 07
    • Noleadmiddletrail
      1,2banana… apple|NULL
      3 banana… 
      4,5candy…banana|apple… 
    • 08
    • Noleadmiddletrail
      1,2candy… banana|apple…
      3 candy… 
      4,5danger…candy|banana… 
    • 09
    • Noleadmiddletrail
      1,2danger|NULL candy|banana…
      3 danger|NULL 
      4,5\0danger|candy… 
  • listprint(root)
  • danger
    candy
    banana
    apple

결과

apple
banana
candy
danger
----- invert -----
danger
candy
banana
apple

This post is licensed under CC BY 4.0 by the author.

C언어 공부 정리(9/10)-typedef, 비트 필드

C언어 공부 정리(9/10)-FILE I/O

Comments powered by Disqus.