엉망인 제 코드 좀 봐주시길 바랍니다

csh7213의 이미지
세벌의 이미지

for (int i = 0; i < MAX_STACK; i++) {
	printf("학번과 이름을 입력하세요\n");
	printf("1\n");
 
	scanf_s("%d %c ", st[i].no, st[i].name);
	printf("2\n");
 
	push(s, st[i]);
	printf("3\n");
 
	enqueue(q, st[i]); Queue_print;
	printf("4\n");
}
이런 식으로 의심스러운 곳에 printf 써 보셔요.
제대로 하려면 디버거 사용법도 공부해 보시고요.

컴파일 할 때 에러 메시지 뿐 아니라 경고 메시지도 보시고요.

scanf_s 함수를 꼭 써야 하나요? MS 전용인 거 같은데...
http://www.cplusplus.com/forum/beginner/2300/

익명 사용자의 이미지

범용큐, 범용스택을 구현할 줄 알아야 되는데.. 흠..
큐는 FIFO 이고, 스택은 LIFO 입니다.
링크드 리스트로 구현하면 realloc 필요없습니다.
큐는 자료를 tail(rear) 에 삽입하고, head(front) 에서 빼옵니다.
뒤에서 넣고 앞으로 나오는 빨대(대롱)같은거죠.
반면 스택은 통 같은 겁니다. 통에 넣고 빼면 맨 마지막에 넣은게 먼저 빠지죠.
그러면 큐를 수정하여 스택을 만들 수 있는데,
자료를 tail(rear) 에 넣고, tail(rear) 에서 꺼내면 스택이 되겠죠?
스택 자료구조는 제가 아직 필요하지 않아서 만들지를 않았습니다. 님께서 함 만들어보세요.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
 
typedef struct _TianNode TianNode;
struct _TianNode {
  TianNode *next;
  void     *data;
};
 
typedef struct _TianQueue TianQueue;
struct _TianQueue {
  TianNode *head;
  TianNode *tail;
  unsigned int count;
  void (* free_func) (void *);
};
 
TianQueue *tian_queue_new (void (* free_func) (void *));
void       tian_queue_free   (TianQueue *q);
void       tian_queue_add    (TianQueue *q, void *data);
bool       tian_queue_remove (TianQueue *q);
void      *tian_queue_peek   (TianQueue *q, unsigned int i);
 
TianQueue *tian_queue_new (void (* free_func) (void *))
{
  TianQueue *q;
 
  q = calloc (1, sizeof (TianQueue));
  q->free_func = free_func;
 
  return q;
}
 
void tian_queue_free (TianQueue *q)
{
  TianNode *p = q->head;
 
  while (p)
  {
    if (q->free_func && p->data)
      q->free_func (p->data);
 
    TianNode *next = p->next;
    free (p);
    p = next;
  }
 
  free (q);
}
 
void tian_queue_add (TianQueue *q, void *data)
{
  TianNode *node = malloc (sizeof (TianNode));
  node->next = NULL;
  node->data = data;
 
  if (!q->count)
    q->head = node;
  else
    q->tail->next = node;
 
  q->tail = node;
  q->count++;
}
 
bool tian_queue_remove (TianQueue *q)
{
  if (!q->count)
    return false;
 
  TianNode *node;
 
  node = q->head;
  q->head = q->head->next;
  q->count--;
 
  if (q->free_func)
    q->free_func (node->data);
 
  free (node);
 
  return true;
}
 
void *tian_queue_peek (TianQueue *q, unsigned int i)
{
  if (!q->count)
    return NULL;
 
  TianNode *p;
 
  for (p = q->head; i > 0 && p; i--)
    p = p->next;
 
  return p->data;
}
 
typedef struct {
  char name[20];
  char id[20];
} Student;
 
Student *student_new ()
{
  return malloc (sizeof (Student));
}
 
void student_free (Student *student)
{
  free (student);
}
 
int main (int argc, char **argv)
{
  TianQueue *queue;
  Student   *student;
 
  queue = tian_queue_new ((void (*)(void *)) student_free);
 
  for (int i = 0; i < 5; i++)
  {
    Student *person;
    person = student_new ();
    printf ("이름: ");
    scanf ("%s", person->name);
    printf ("학번: ");
    scanf ("%s", person->id);
    tian_queue_add (queue, person);
  }
 
  for (int i = 0; i < queue->count; i++)
  {
    student = tian_queue_peek (queue, i);
    printf ("%s: %s\n", student->name, student->id);
  }
 
  tian_queue_remove (queue);
 
  for (int i = 0; i < queue->count; i++)
  {
    student = tian_queue_peek (queue, i);
    printf ("%s: %s\n", student->name, student->id);
  }
 
  tian_queue_free (queue);
 
  return 0;
}
cogniti3의 이미지

그리고 위 질문자님, return 에서 포인터를 넘겨주고, 함수 return 형이 포인터가 되어야 하는데... 포인터에 대한 이해가 없으신거 같네요. c 책에서 포인터 부분 펴서 보세요. 포인터 모르면 위에 TianQueue 가 뭐하는 건지 아예 이해 안 되요

익명 사용자의 이미지

위에 stack 설명이 잘못된 부분이 있습니다.
위키 문서를 보니 tail 에 넣고 tail 에서 빼는게 아니라,
head 에 넣고 head 에서 뺍니다.

https://en.wikipedia.org/wiki/Stack_(abstract_data_type)

structure frame:
    data : item
    next : frame or nil
 
이것은 TianNode 에 해당하는 부분입니다.

structure stack:
    head : frame or nil
    size : integer
 
이것은 struct TianStack ... 이런 구조체를 만들면 되겠고,

procedure initialize(stk : stack):
    stk.head ← nil
    stk.size ← 0
 
이것은 TianStack *tian_stack_new () 함수를 만들면 되고,
대응되는 void tian_stack_free (TianStack *stack) 함수도 만들어주면 좋겠죠?

procedure push(stk : stack, x : item):
    newhead ← new frame
    newhead.data ← x
    newhead.next ← stk.head
    stk.head ← newhead
    stk.size ← stk.size + 1
 
void tian_stack_push (TianStack *stack, void *data) 이런 함수를 만들어야겠고,

procedure pop(stk : stack):
    if stk.head = nil:
        report underflow error
    r ← stk.head.data
    stk.head ← stk.head.next
    stk.size ← stk.size - 1
    return r
 
void *tian_stack_pop (TianStack *stack) 이런 함수를 만들면 되겠죠.
void * 자료형은 모든 자료형을 다룰 있습니다.
익명 사용자의 이미지

스택을 구현하면 다음과 같습니다.

typedef struct _TianStack TianStack;
struct _TianStack {
  TianNode *head;
  unsigned int count;
  void (* free_func) (void *);
};
 
TianStack *tian_stack_new (void (* free_func) (void *));
void       tian_stack_free (TianStack *stack);
void       tian_stack_push (TianStack *stack, void *data);
void      *tian_stack_pop  (TianStack *stack);
 
TianStack *tian_stack_new (void (* free_func) (void *))
{
  TianStack *stack;
 
  stack = calloc (1, sizeof (TianStack));
  stack->free_func = free_func;
 
  return stack;
}
 
void tian_stack_free (TianStack *stack)
{
  TianNode *p = stack->head;
 
  while (p)
  {
    if (stack->free_func && p->data)
      stack->free_func (p->data);
 
    TianNode *next = p->next;
    free (p);
    p = next;
  }
 
  free (stack);
}
 
void tian_stack_push (TianStack *stack, void *data)
{
  TianNode *node = malloc (sizeof (TianNode));
  node->data = data;
  node->next = stack->head;
  stack->head = node;
  stack->count++;
 
}
 
void *tian_stack_pop  (TianStack *stack)
{
  if (!stack->head)
    return NULL;
 
  TianNode *node;
 
  node = stack->head;
  stack->head = stack->head->next;
  stack->count--;
 
  return node->data;
}
 
void *tian_stack_peek (TianStack *stack, unsigned int i)
{
  if (!stack->count)
    return NULL;
 
  TianNode *p;
 
  for (p = stack->head; i > 0 && p; i--)
    p = p->next;
 
  return p->data;
}

아래 코드는 TianQueue, TianStack 를 포함한 소스코드입니다.
main() 함수에 TianStack 을 활용한 예가 있습니다.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
 
typedef struct _TianNode TianNode;
struct _TianNode {
  TianNode *next;
  void     *data;
};
 
typedef struct _TianQueue TianQueue;
struct _TianQueue {
  TianNode *head;
  TianNode *tail;
  unsigned int count;
  void (* free_func) (void *);
};
 
TianQueue *tian_queue_new (void (* free_func) (void *));
void       tian_queue_free   (TianQueue *q);
void       tian_queue_add    (TianQueue *q, void *data);
bool       tian_queue_remove (TianQueue *q);
void      *tian_queue_peek   (TianQueue *q, unsigned int i);
 
TianQueue *tian_queue_new (void (* free_func) (void *))
{
  TianQueue *q;
 
  q = calloc (1, sizeof (TianQueue));
  q->free_func = free_func;
 
  return q;
}
 
void tian_queue_free (TianQueue *q)
{
  TianNode *p = q->head;
 
  while (p)
  {
    if (q->free_func && p->data)
      q->free_func (p->data);
 
    TianNode *next = p->next;
    free (p);
    p = next;
  }
 
  free (q);
}
 
void tian_queue_add (TianQueue *q, void *data)
{
  TianNode *node = malloc (sizeof (TianNode));
  node->next = NULL;
  node->data = data;
 
  if (!q->count)
    q->head = node;
  else
    q->tail->next = node;
 
  q->tail = node;
  q->count++;
}
 
bool tian_queue_remove (TianQueue *q)
{
  if (!q->count)
    return false;
 
  TianNode *node;
 
  node = q->head;
  q->head = q->head->next;
  q->count--;
 
  if (q->free_func)
    q->free_func (node->data);
 
  free (node);
 
  return true;
}
 
void *tian_queue_peek (TianQueue *q, unsigned int i)
{
  if (!q->count)
    return NULL;
 
  TianNode *p;
 
  for (p = q->head; i > 0 && p; i--)
    p = p->next;
 
  return p->data;
}
 
typedef struct _TianStack TianStack;
struct _TianStack {
  TianNode *head;
  unsigned int count;
  void (* free_func) (void *);
};
 
TianStack *tian_stack_new (void (* free_func) (void *));
void       tian_stack_free (TianStack *stack);
void       tian_stack_push (TianStack *stack, void *data);
void      *tian_stack_pop  (TianStack *stack);
 
TianStack *tian_stack_new (void (* free_func) (void *))
{
  TianStack *stack;
 
  stack = calloc (1, sizeof (TianStack));
  stack->free_func = free_func;
 
  return stack;
}
 
void tian_stack_free (TianStack *stack)
{
  TianNode *p = stack->head;
 
  while (p)
  {
    if (stack->free_func && p->data)
      stack->free_func (p->data);
 
    TianNode *next = p->next;
    free (p);
    p = next;
  }
 
  free (stack);
}
 
void tian_stack_push (TianStack *stack, void *data)
{
  TianNode *node = malloc (sizeof (TianNode));
  node->data = data;
  node->next = stack->head;
  stack->head = node;
  stack->count++;
 
}
 
void *tian_stack_pop  (TianStack *stack)
{
  if (!stack->head)
    return NULL;
 
  TianNode *node;
 
  node = stack->head;
  stack->head = stack->head->next;
  stack->count--;
 
  return node->data;
}
 
void *tian_stack_peek (TianStack *stack, unsigned int i)
{
  if (!stack->count)
    return NULL;
 
  TianNode *p;
 
  for (p = stack->head; i > 0 && p; i--)
    p = p->next;
 
  return p->data;
}
 
typedef struct {
  char name[20];
  char id[20];
} Student;
 
Student *student_new ()
{
  return malloc (sizeof (Student));
}
 
void student_free (Student *student)
{
  free (student);
}
 
int main (int argc, char **argv)
{
  TianStack *stack;
  Student   *student;
 
  stack = tian_stack_new ((void (*)(void *)) student_free);
 
  for (int i = 0; i < 5; i++)
  {
    Student *person;
    person = student_new ();
    printf ("이름%d: ", i + 1);
    scanf ("%s", person->name);
    printf ("학번%d: ", i + 1);
    scanf ("%s", person->id);
    tian_stack_push (stack, person);
  }
 
  puts ("-- stack -------------------------------");
 
  for (int i = 0; i < stack->count; i++)
  {
    student = tian_stack_peek (stack, i);
    printf ("%s: %s\n", student->name, student->id);
  }
 
  tian_stack_pop (stack);
 
  puts ("-- stack after tian_stack_pop (stack) --");
 
  for (int i = 0; i < stack->count; i++)
  {
    student = tian_stack_peek (stack, i);
    printf ("%s: %s\n", student->name, student->id);
  }
 
  tian_stack_free (stack);
 
  return 0;
}

소스코드를 exam.c 라 저장하고 터미널에서 단순히 make exam 이라고 치면 exam 이라는 실행파일이 만들어집니다.
아래처럼 실행시킵니다. 귀찮아서 a, b, c, d, e 를 입력했습니다.
님께서는 TianQueue 소스코드 설명할 때 사용한 main() 함수와 TianStack 소스코드 설명할 때 사용한 main() 함수를 수정해야겠죠. main() 함수는 1개만 존재해야 합니다. 그리고
free_func 함수를 지정하도록 했는데, 그것 때문에 이중 free 문제가 발생할 수 있습니다.
그렇다고해서 free_func 를 지정하지 않으면 student item 을 일일이 메모리 해제(free)해줘야 하는 불편함이 따르겠습니다.

Student *student;
student = student_new ();
tian_queue_add (student);
tian_stack_push (student);
...
tian_queue_remove (queue);
...
tian_queue_free (queue);
tian_stack_free (stack);
...

이렇게 하면 어떤 문제가 발생할 것 같습니까?
이런 문제를 해결하는 방법으로 ref_count 를 두는 방법이 있습니다. 나중에 서서히 알아보시고,
초보자분께 그런것까지 바라기는 무리인 거 같고, 일단은, free_func 를 NULL 로 지정해서 사용하시되,
student 를 일일이 메모리 해제(free)해줘야 합니다. 공부용 예제 코드에서는 안 해도 별 문제가 안 됩니다만,
나중에 계속 c 공부하시면서 메모리 할당/해제에 대해 신경을 쓰셔야 됩니다.
포인터 모르시면 c 책에서 포인터 부분만 열심히 보세요. 봐서 이해 안 되면 도서관에 다른 c 책 펴서 포인터 부분을 열심히 보세요. 그렇게 포인터 익숙해진 후, c 포인터 예제 책이 있습니다. 그 책으로 포인터 열심히 보세요.
나중에 결국 컴퓨터 구조를 배우시게 될텐데... 아... 진작에 배울 걸.. 아하~~ 이 생각 들겁니다.

[hodong@nimfsoft ~]$ ./exam
이름1: a
학번1: a
이름2: b
학번2: b
이름3: c
학번3: c
이름4: d
학번4: d
이름5: e
학번5: e
-- stack -------------------------------
e: e
d: d
c: c
b: b
a: a
-- stack after tian_stack_pop (stack) --
d: d
c: c
b: b
a: a

열공하십쇼

익명 사용자의 이미지

만들고 보고 아래 함수에 메모리 누수 버그가 있네요. 어떻게 고쳐야 할까요?

void *tian_stack_pop  (TianStack *stack)
{
  if (!stack->head)
    return NULL;
 
  TianNode *node;
 
  node = stack->head;
  stack->head = stack->head->next;
  stack->count--;
 
  return node->data;
}

아래처럼 고쳐줍니다.
void *tian_stack_pop  (TianStack *stack)
{
  if (!stack->head)
    return NULL;
 
  TianNode *node;
  void *data;
 
  node = stack->head;
  data = stack->head->data;
  stack->head = stack->head->next;
  stack->count--;
 
  free (node);
 
  return data;
}

고친 후 테스트해보니 잘 되네요 ㅋㅋ

[hodong@nimfsoft ~]$ make exam
cc     exam.c   -o exam
[hodong@nimfsoft ~]$ ./exam
이름1: 아이린
학번1: 9284792542
이름2: 에이핑크
학번2: 2498729587
이름3: 태연
학번3: 92857492875
이름4: 블랙핑크
학번4: 29845792857
이름5: 트와이스
학번5: 02948502954
-- stack -------------------------------
트와이스: 02948502954
블랙핑크: 29845792857
태연: 92857492875
에이핑크: 2498729587
아이린: 9284792542
-- stack after tian_stack_pop (stack) --
블랙핑크: 29845792857
태연: 92857492875
에이핑크: 2498729587
아이린: 9284792542
익명 사용자의 이미지

scanf_s("%d %c ", st[i].no, st[i].name);
위 코드를 아래와 같이 수정하시고 실행해 보세요.

scanf_s("%d %s", &(st[i].no), st[i].name, sizeof(st[i].name));

익명 사용자의 이미지

아래 함수는 리턴값이 없는데 에러 안 나요?

Student dequeue(Queue* q)
{
	if (is_empty_q(q))
	{
		fprintf(stderr, "큐가 비어있습니다.\n");
		exit(1);
	}
	else {
		q->data[++(q->front)];
	}
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.