책의 원형큐예제를 따라해봤는데 배열의 크기에 따라 오류의 유무가 있습니다. 도와주세요.

조회수 1133회

안녕하세요.

현재 천인국 저자의 "C언어로 쉽게풀어쓴 자료구조"라는 책을 보고 있습니다.


항상 예제를 직접 옮겨가며 작동방식을 꼼꼼히 살펴보고 직접 실행해보는 게 좋다고 생각하여

원형큐 예제를 만나 직접 옮겨보고 실행하던 와중 오류가 발생하더군요.

아래 소스코드에서 매크로로 지정해놓은 배열의 크기 MAX_QUEUE_SIZE를 3으로 지정하면 정상작동하고, 4이상의 정수로 지정하면 삭제단계출력부분에서 무한루프를 돌더군요;;😱

코드는 다음과 같습니다.


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

// ==== 원형큐 코드 시작 ====
#define MAX_QUEUE_SIZE 5
typedef int element;
typedef struct {    // 큐 타입
    element data[MAX_QUEUE_SIZE];
    int front, rear;
} QueueType;

// 오류 함수
void error(char *message) {
    fprintf(stderr, "%s\n", message);
    exit(1);
}

// 원형큐 초기화 함수
void init_queue(QueueType *q) {
    q->front = q->rear = 0;
}

// 공백 상태 검출 함수
int is_empty(QueueType *q) {
    return (q->front == q->rear);       

}

// 포화 상태 검출 함수
int is_full(QueueType *q) {
    return ((q->rear + 1) % MAX_QUEUE_SIZE == q->front);    
}

// 원형큐 출력 함수
void queue_print(QueueType *q) {
    printf("QUEUE(front=%d rear=%d) = ", q->front, q->rear);
    if (!is_empty(q)) { 
        int i = q->front;
        do {
            i = (i + 1) % (MAX_QUEUE_SIZE); 
            printf("%d | ", q->data[i]);
            if (i == q->rear)
                break;
        } while (i != q->front);
    }
    printf("\n");
}

// 삽입 함수
void enqueue(QueueType *q, element item) {
    if (is_full(q))
        error("큐가 포화상태입니다");
    q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
    q->data[q->rear] = item;
}

// 삭제 함수
element dequeque(QueueType *q) {
    if (is_empty(q))
        error("큐가 공백상태입니다");
    q->front = (q->front + 1)&MAX_QUEUE_SIZE;
    return q->data[q->front];
}

// 피크 함수
element peek(QueueType *q) {
    if (is_empty(q))
        error("큐가 공백상태입니다");
    return q->data[(q->front + 1) % MAX_QUEUE_SIZE];
}
// ===== 원형큐 코드 끝 =====

int main() {
    QueueType queue;
    int element;

    init_queue(&queue);
    printf("--데이터 추가 단계--\n");
    while (!is_full(&queue)) {
        printf("정수를 입력하시오 : ");
        scanf_s("%d", &element);
        enqueue(&queue, element);
        queue_print(&queue);
    }

    printf("큐는 포화상태입니다.\n\n");

    printf("--데이터 삭제 단계--\n");
    while (!is_empty(&queue)) {
        element = dequeque(&queue);
        printf("꺼내진 정수 : %d\n", element);
        queue_print(&queue);
    }
    printf("큐는 공백상태입니다.\n");
    return 0;
}

솔직히 읽기도 귀찮고 버거우실 수 있는 소스코드라 생각됩니다만

  • 철자라도 하나 틀렸었나 5번씩 검토하고

  • 배열의 크기가 작으면 또 실행이 되니 어이가 없고

  • 책의 저자께서 발행하시기 전에 돌려보시지 않으셨을리가 없다 생각이 되어

이렇게 질문 드리게됬습니다!

어째서 배열의 크기가 4를 넘어가면 무한루프를 돌게 되는 것인지 알려주실 수 있으신가요?

부탁드립니다!! 백날백년을 기다리겠습니다! 답변만 주십시오!

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    오타 같습니다.

    q->front = (q->front + 1)&MAX_QUEUE_SIZE;
    

    삭제 함수 내의 위 코드를 아래와 같이 바꾸어 보세요.

    q->front = (q->front + 1) % MAX_QUEUE_SIZE;
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 삭제함수 과정에서 오타가 발생했군요 ㅠㅠ 이런 오타들은 눈으로 디버깅하는 방법 말고는 없나요?? 임지훈 2021.4.14 08:36
    • 위의 코드처럼 컴파일은 되지만 오동작하는 오류를 실행시간 오류라고 합니다. 컴파일 오류는 컴파일할 때 오류가 표시되기 때문에 고치기 쉽지만, 실행시간 오류는 찾기 힘듭니다. 보통 실행시간 오류가 발생되는 코드를 작성하지 않기 위해서 직관적이고 짧은 코드를 작성하는 것이 좋고, 어쩔수 없이 코드가 복잡하다면 주석을 달아 주어야 합니다. 알 수 없는 사용자 2021.4.14 09:58
    • @임지훈 : 기본적으로 매의 눈을 가지고 있으면 좋은데, 사실 사람은 실수의 동물이라서요. 나의 확신에 빠지는 것이 가장 나쁩니다. ide의 디버깅모드로 실행하면서 찾아보는 방법을 배워야 합니다. nowp 2021.4.15 09:40

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)