프로그램은 잘 도는데 경고가 너무 많이 떠서요;;

yangam의 이미지

FUNDAMENTALS OF DATA STRUCTURES IN C 133페이지 2번 문제를 나름대로 풀어봤습니다.

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

#define	EACH_TIME	100		// 단위 시간만큼 돌아감

#define	USED	1		// 활주로가 단위 시간에 이미 사용되었을 경우 
#define	NOTUSED	0		// 활주로가 단위 시간에 아직 사용되지 않았을 경우

#define SPECIAL 2		// Runway 2 에 Landing 했을 경우
#define LANDING	1		// 함수에서 Landing 인지 Takeoff 인지 구분하기 위해서 사용
#define TAKEOFF	0

// Queue Structure 
typedef struct {
	int	planeid;			// plane's ID
	int landing_wt;			// landing waiting time
	int left_ft;			// left fly time
	int takeoff_wt;			// takeoff waiting time
	struct queue *link;
} queue;

// f - head of queue, r - tail of queue 
void initq(queue **f, queue **r);

// f - head of queue, r - tail of queue, flag - Distinguish Landing or Takeoff, planenum - number of plane will create
void createq(queue **f, queue **r, int flag);

// f - head of queue
void deleteq(queue **f);

// df - Destination head of queue, dr - Destination tail of queue, sf - Source head of queue, flag - Distinguish Landing or Takeoff
void addq(queue **df, queue **dr, queue **sf, int flag);

int main()
{
	int usedrunway0, usedrunway1, usedrunway2;		// 활주로의 사용 여부를 확인하는 변수
	
	int crashed;				// 사고가 난 비행기의 수

	int decide_runway;			// 활주로를 결정하는 변수
	int decide_planenum;		// 단위 시간에 처리될 이륙 및 착륙 비행기의 수를 결정하는 변수

	int total_takeoff_time;	
	int total_landing_time;
	int total_takeoff_plane_count;
	int total_landing_plane_count;

	int each_time;		// EACH_TIME 단위 시간 만큼 loop 이 실행됨
	
	int i;		// for loop statement 을 위한 임시 변수
	queue *t;	// for loop statement 을 위한 임시 큐			

	queue *lqf0, *lqf1, *lqf2, *lqf3;		// 4개의 Landing Queue 의 Front
	queue *lqr0, *lqr1, *lqr2, *lqr3;		// 4개의 Landing Queue 의 Rear
	queue *tqf0, *tqf1, *tqf2;				// 3개의 Takeoff Queue 의 Front
	queue *tqr0, *tqr1, *tqr2;				// 3개의 Takeoff Queue 의 Rear

	queue *wlqf, *wlqr;		// Landing 될 비행기가 들어있는 Queue
	queue *wtqf, *wtqr;		// Takeoff 될 비행기가 들어있는 Queue

	// 각각의 Landing Queue 를 초기화
	initq(&lqf0, &lqr0);
	initq(&lqf1, &lqr1);
	initq(&lqf2, &lqr2);
	initq(&lqf3, &lqr3);

	// 각각의 Takeoff Queue 를 초기화
	initq(&tqf0, &tqr0);
	initq(&tqf1, &tqr1);
	initq(&tqf2, &tqr2);

	// Landing 될 비행기가 들어있는 Queue 와 Takeoff 될 비행기가 들어있는 Queue 초기화
	initq(&wlqf, &wlqr);
	initq(&wtqf, &wtqr);

	// 설정된 단위 시간 만큼 loop 이 실행됨
	each_time = EACH_TIME;
	crashed = 0;

	srand((unsigned)time(NULL));
	while (each_time-- >= 0) {
		usedrunway0 = usedrunway1 = usedrunway2 = 0;

		puts("\n========================================");
		printf("프로그램 종료까지 %d 단위 시간 남음\n", each_time);
		puts("========================================");

		// 한 번에 최소한 0 - 3 대는 착륙하게끔 해준다.
		decide_planenum = rand() % 4;
		for (i = 0; i < decide_planenum; i++)
			createq(&wlqf, &wlqr, LANDING);

		// 한 번에 0 - 3 대는 이륙하게끔 해준다.
		decide_planenum = rand() % 4;
		for (i = 0; i < decide_planenum; i++)
			createq(&wtqf, &wtqr, TAKEOFF);

		// Landing 될 비행기와 Takeoff 될 비행기들의 정보를 출력
		puts("\n==========================");
		puts("Landing 될 비행기들의 정보");
		puts("==========================");
		for (t = wlqf; t; t = t->link)
			printf("Plane ID: %-3d Left fly time: %-3d Landing waiting time: %-3d\n", t->planeid, t->left_ft, t->landing_wt);

		puts("\n==========================");
		puts("Takeoff 될 비행기들의 정보");
		puts("==========================");
		for (t = wtqf; t; t = t->link)
			printf("Plane ID: %-3d Takeoff waiting time: %-3d\n", t->planeid, t->takeoff_wt);

		/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */		
		/* Takeoff 보다 Landing 이 더 중요하므로 Takeoff 부터 처리한다. (Takeoff 는 시간만 지연될 뿐, Landing 처럼 인명 피해가 일어나지는 않는다.) <- 왜냐하면, 단위 시간에 각 활주로는 Landing 또는 Takeoff 할 수 있다. */
		/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */		

		// 만약 Landing 될 비행기의 체공 시간이 0 이라면 Runway 2(tqf2) 에 비상 착륙 시킨다.
		if (wlqf && wlqf->left_ft == 0) {
			// Runway 2 에 비상 착륙 시킴
			addq(&tqf2, &tqr2, &wlqf, SPECIAL);

			// Landing 될 비행기 Queue 에서 삭제
			deleteq(&wlqf);

			// 이로써, Runway 2 는 현재 단위 시간에 사용되었다.
			usedrunway2 = 1;
		}

		// 한 번에 0 - 3 대씩 착륙하게끔 해준다.
		decide_planenum = rand() % 4;

		for (i = 0; i < decide_planenum; i++) {
			decide_runway = i;

			if (decide_runway == 0)
				decide_runway = rand() % 2;

			if (decide_runway == 2)
				decide_runway = rand() % 2 + 2;


			switch (decide_runway) {
				case 0: 
					if (wlqf && usedrunway0 == 0) {
						addq(&lqf0, &lqr0, &wlqf, LANDING);
						deleteq(&wlqf);
						usedrunway0 = 1;
					}
					break;

				case 1:
					if (wlqf && usedrunway0 == 0) {
						addq(&lqf1, &lqr1, &wlqf, LANDING);
						deleteq(&wlqf);
						usedrunway0 = 1;
					}
					break;

				case 2:
					if (wlqf && usedrunway1 == 0) {
						addq(&lqf2, &lqr2, &wlqf, LANDING);
						deleteq(&wlqf);
						usedrunway1 = 1;
					}
					break;

				case 3:
					if (wlqf && usedrunway1 == 0) {
						addq(&lqf3, &lqr3, &wlqf, LANDING);
						deleteq(&wlqf);
						usedrunway1 = 1;
					}
					break;
			}
		}

		// 한 번에 0 - 3 대씩 이륙하게끔 해준다.
		decide_planenum = rand() % 4;

		for (i = 0; i < decide_planenum; i++) {
			decide_runway = i ;

			switch (decide_runway) {
				case 0:
					if (wtqf && usedrunway0 == 0) {
						addq(&tqf0, &tqr0, &wtqf, TAKEOFF);
						deleteq(&wtqf);
						usedrunway0 = 1;
					}
					break;

				case 1: 
					if (wtqf && usedrunway1 == 0) {
						addq(&tqf1, &tqr1, &wtqf, TAKEOFF);
						deleteq(&wtqf);
						usedrunway1 = 1;
					}
					break;

				case 2:
					if (wtqf && usedrunway2 == 0) {
						addq(&tqf2, &tqr2, &wtqf, TAKEOFF);
						deleteq(&wtqf);
						usedrunway2 = 1;
					}
					break;
			}
		}

		// Landing 될 Queue 에 있는 비행기의 Left fly time 을 1 만큼 줄이고, Landing waiting time 을 1 만큼 증가시킨다.
		for (t = wlqf; t; t = t->link) {
			t->landing_wt++;
			t->left_ft--;
		}

		// Takeoff 될 Queue 에 있는 비행기의 Takeoff waiting time 을 1 만큼 증가시킨다.
		for (t = wtqf; t; t = t->link)
			t->takeoff_wt++;

		// 만약 체공 시간이 0 미만이라면 사고가 난 것임
		if (wlqf && wlqf->left_ft < 0) {
			puts("\n========================================================================");
			printf("ID 가 %d 인 비행기가 체공 시간이 다 되어서 추락하였습니다ㅠOㅠ;\n", wlqf->planeid);
			puts("========================================================================");

			deleteq(&wlqf);
			crashed++;
		}

		// Runway 0 의 Takeoff Queue 를 출력한다.
		puts("\n================================");
		puts("Runway 0 의 Takeoff Queue 내용");
		puts("================================");
		for (t = tqf0; t; t = t->link)
			printf("Plane ID: %-3d Takeoff waiting time: %-3d\n", t->planeid, t->takeoff_wt);

		// Runway 1 의 Takeoff Queue 를 출력한다.
		puts("\n================================");
		puts("Runway 1 의 Takeoff Queue 내용");
		puts("================================");
		for (t = tqf1; t; t = t->link)
			printf("Plane ID: %-3d Takeoff waiting time: %-3d\n", t->planeid, t->takeoff_wt);

		// Runway 2 의 Takeoff Queue 를 출력한다.
		puts("\n================================");
		puts("Runway 2 의 Takeoff Queue 내용");
		puts("================================");
		for (t = tqf2; t; t = t->link) {
			if ((t->planeid % 2) == 0)
				printf("Plane ID: %-3d Takeoff waiting time: %-3d\n", t->planeid, t->takeoff_wt);

			else
				printf("Plane ID: %-3d Left fly time: %-3d Landing waiting time: %-3d\n", t->planeid, t->left_ft, t->landing_wt);
		}

		// Runway 0 의 Landing Queue A 를 출력한다.
		puts("\n==================================");
		puts("Runway 0 의 Landing Queue A의 내용");
		puts("==================================");
		for (t = lqf0; t; t = t->link)
			printf("Plane ID: %-3d Left fly time: %-3d Landing waiting time: %-3d\n", t->planeid, t->left_ft, t->landing_wt);

		// Runway 0 의 Landing Queue B 를 출력한다.
		puts("\n==================================");
		puts("Runway 0 의 Landing Queue B의 내용");
		puts("==================================");
		for (t = lqf1; t; t = t->link)
			printf("Plane ID: %-3d Left fly time: %-3d Landing waiting time: %-3d\n", t->planeid, t->left_ft, t->landing_wt);

		// Runway 1 의 Landing Queue A 를 출력한다.
		puts("\n==================================");
		puts("Runway 1 의 Landing Queue A의 내용");
		puts("==================================");
		for (t = lqf2; t; t = t->link)
			printf("Plane ID: %-3d Left fly time: %-3d Landing waiting time: %-3d\n", t->planeid, t->left_ft, t->landing_wt);

		// Runway 1 의 Landing Queue B 를 출력한다.
		puts("\n==================================");
		puts("Runway 1 의 Landing Queue B의 내용");
		puts("==================================");
		for (t = lqf3; t; t = t->link)
			printf("Plane ID: %-3d Left fly time: %-3d Landing waiting time: %-3d\n", t->planeid, t->left_ft, t->landing_wt);
	}

	total_landing_time = 0;
	total_landing_plane_count = 0;
	for (t = lqf0; t; t = t->link) {
		total_landing_time += t->landing_wt;
		total_landing_plane_count++;
	}
	for (t = lqf1; t; t = t->link) {
		total_landing_time += t->landing_wt;
		total_landing_plane_count++;
	}
	for (t = lqf2; t; t = t->link) {
		total_landing_time += t->landing_wt;
		total_landing_plane_count++;
	}
	for (t = lqf3; t; t = t->link) {
		total_landing_time += t->landing_wt;
		total_landing_plane_count++;
	}

	total_takeoff_time = 0;
	total_takeoff_plane_count = 0;
	for (t = tqf0; t; t = t->link) {
		total_takeoff_time += t->takeoff_wt; 
		total_takeoff_plane_count++;
	}
	for (t = tqf1; t; t = t->link) {
		total_takeoff_time += t->takeoff_wt; 
		total_takeoff_plane_count++;
	}
	for (t = tqf2; t; t = t->link) {
		if ((t->planeid % 2) == 0) {
			total_takeoff_time += t->takeoff_wt; 
			total_takeoff_plane_count++;
		}

		else {
			total_landing_time += t->landing_wt;
			total_landing_plane_count++;
		}
	}

	puts("\n===================================================");
	printf("총 %d 대의 비행기가 착륙하였습니다.\n", total_landing_plane_count);
	printf("총 %d 대의 비행기가 이륙하였습니다.\n", total_takeoff_plane_count);
	printf("총 %d 대의 비행기가 추락하였습니다.\n\n", crashed);
	printf("평균 %.2f 단위 시간만에 착륙하였습니다.\n", (float)total_landing_time / total_landing_plane_count);
	printf("평균 %.2f 단위 시간만에 이륙하였습니다.\n", (float)total_takeoff_time / total_takeoff_plane_count);
	puts("===================================================");

	return 0;
}

void initq(queue **f, queue **r)
{
	*f = NULL;
	*r = NULL;
}

void createq(queue **f, queue **r, int flag)
{
	static int landing_id = 1;		// Landing 은 Odd number
	static int takeoff_id = 2;		// Takeoff 는 Even number

	queue *temp;

	// 메모리 할당을 실패할 경우에 Error Message 를 출력한 후 프로그램 종료
	if ((temp = (queue *)malloc(sizeof(queue))) == NULL) {
		fprintf(stderr, "Out ot memory! Can't create Queue!\n");
		exit(0);
	}

	// Landing 할 비행기라면 아래의 if 문 실행
	if (flag == LANDING) {
		temp->planeid = landing_id;				// 비행기 ID 저장
		temp->left_ft = rand() % EACH_TIME;		// 체공 가능 시간
		temp->landing_wt = 0;					// Landing waiting time 은 우선 0 으로 설정

		landing_id++;
		landing_id++;
	}

	// Takeoff 할 비행기라면 아래의 else-if 문 실행
	else if (flag == TAKEOFF) {
		temp->planeid = takeoff_id;			// 비행기 ID 저장
		temp->takeoff_wt = 0;				// Takeoff waiting time 은 우선 0 으로 설정
		
		takeoff_id++;
		takeoff_id++;
	}

	temp->link = NULL;

	if (*f)
		(*r)->link = temp;

	else
		*f = temp;

	*r = temp;
}

void deleteq(queue **f)
{
	queue *temp = *f;

	if (*f == NULL) {
		fprintf(stderr, "The queue is empty! Can't delete queue\n");
		exit(0);
	}

	*f = temp->link;
	
	free(temp);
}

void addq(queue **df, queue **dr, queue **sf, int flag)
{
	queue *temp;

	// 메모리 할당을 실패할 경우에 Error Message 를 출력한 후 프로그램 종료
	if ((temp = (queue *)malloc(sizeof(queue))) == NULL) {
		fprintf(stderr, "Out ot memory! Can't create Queue!\n");
		exit(0);
	}
	
	if (flag == LANDING) {
		temp->left_ft = (*sf)->left_ft;		
		temp->landing_wt = (*sf)->landing_wt;
	}

	else if (flag == TAKEOFF)
		temp->takeoff_wt = (*sf)->takeoff_wt;

	else if (flag == SPECIAL) {
		temp->left_ft = (*sf)->left_ft;		
		temp->landing_wt = (*sf)->landing_wt;
	}

	temp->planeid = (*sf)->planeid;
	temp->link = NULL;

	if (*df)
		(*dr)->link = temp;

	else
		*df = temp;

	*dr = temp;
}

Compile 해보면 아시겠지만, 경고가 20개이상이 뜨는데.
제가 보기에는 전혀 문제 없는 부분인데.. 경고가 뜨네요.

주로, for(t = lqf0; t; t = t->link) 이런 부분에서 나더군요.

구조체 포인터 t 와 lqf0 모두 같은 queue * 형 인데
왜 타입이 다르다는건지 이해가 가지 않아서요;

올바른 답변 부탁드립니다^-^;;;

cdpark의 이미지

// Queue Structure
typedef struct {
   int   planeid;         // plane's ID
   int landing_wt;         // landing waiting time
   int left_ft;         // left fly time
   int takeoff_wt;         // takeoff waiting time
   struct queue *link;
} queue;

이 부분은 C 언어도 아니고 C++ 언어도 아니네요. 어느 언어로 짜셨나요? :(

alsong의 이미지

typedef struct _queue{
    int planeid; // plane's ID
    int landing_wt; // landing waiting time
    int left_ft; // left fly time
    int takeoff_wt; // takeoff waiting time
    struct _queue *link;
} queue;

위와 같이 고치세요.

queue = struct _queue와 같습니다.
struct queue != queue
경고가 발생하는것 같네요.

참고로 typedef인 경우 queue_t와 같에 정의하는것도 괜찮습니다.

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

yangam의 이미지

음.. C언어 맞구요~ ㅎ_ㅎ;; (혹시 농담하신건가요? ;;;)

typedef struct {
....
struct queue *link;
} queue;

라고 해주면 문제가 있는거군요.
그러고보니..

struct 구조체-TAG { ... } 선언자-리스트;

이런식으로 정의하는게 완전한 정의인걸로 아는데
맨 위의 정의에서는 구조체-TAG 가 없어서 문제가 되는것 같네요;

답변 주셔서 정말 감사합니다^0^

작은 것들, 사소한 것들을 소중히 여기고,
항상 최선을 다하는 멋진 사람이 되고 싶다.
그들이 나에게 일깨워준 것처럼,
그들 자신이 얼마나 소중한 존재인지 알 수 있도록
도와주는 그런 좋은 사람이 되고 싶다

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.