본문 바로가기
교육관련/한화비전 VEDA 수강일지

[VEDA 1기 수강일지] 4일차 - C언어 기초 (4) : 구조체 포인터, 연결 리스트

by 김수효 2024. 7. 18.
수강한 개념

 

구조체 포인터
- 화살표 (->) 연산자 : 구조체 포인터의 멤버에게 접근할때 사용하는 연산자
- 자기참조 구조체

struct link {
	int id;
	char Bookname[30];
	struct link* prev; //이전 노드 주소
	struct link* next; //다음 노드 주소
};


- 링크드리스트 구현
- 이중 링크드리스트 구현

구조체 비트 필드
- 임베디드에서 가끔 사용됨. 알아보기
- 비트단위로 메모리 할당을 할 수도 있다

다양한 자료형

- union 공용체
- enum 열거형
 ㄴ 코드의 가독성 상승

- typedef 
 ㄴ 타입 재정의
 ㄴ 구조체에 많이 쓴다

문제 구현 / 개선방안

 

1. 이중 연결 리스트 구현

 

1) DLLfx.h

#pragma once

struct link {
	int id;
	char Bookname[30];
	struct link* prev; //이전 노드 주소
	struct link* next; //다음 노드 주소
};

void nodeEnter(struct link** HEAD, struct link** TAIL);
void nodePrint(struct link** HEAD, struct link** TAIL);
void nodeSearch(struct link** HEAD, struct link** TAIL);
void nodeDelet(struct link** HEAD, struct link** TAIL);
void nodeReset(struct link** HEAD);

 

2) DLLfx.c 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "DLLfx.h"

void nodeEnter(struct link** HEAD, struct link** TAIL)
{
	while (1)
	{
		struct link* temp = (struct link*)malloc(sizeof(struct link));
		if (temp == NULL)//메모리 할당 실패
		{
			printf("할당 실패\n");
			exit(1);
		}
		printf("ID : ");
		scanf("%d", &temp->id);
		if (temp->id == -1) break; //루프 종료
		printf("NAME : "); getchar();
		fgets(temp->Bookname, 30, stdin);
		temp->Bookname[strlen(temp->Bookname) - 1] = '\0';
		temp->prev = NULL;
		temp->next = NULL;

		if (*HEAD == NULL) //첫번째 노드 
		{
			*HEAD = *TAIL = temp;
		}
		else  //첫번째 노드가 아닌경우
		{
			temp->prev = *TAIL;
			(*TAIL)->next = temp;
			*TAIL = (*TAIL)->next; 
		}

	} getchar();
}

void nodePrint(struct link** HEAD, struct link** TAIL)
{
	//출력
	struct link* temp = (struct link*)malloc(sizeof(struct link));
	if (temp == NULL)//메모리 할당 실패
	{
		printf("할당 실패\n");
		exit(1);
	}

	temp = *HEAD;
	while (temp != NULL)
	{
		printf("%d, %s\n", temp->id, temp->Bookname);
		temp = temp->next;
	}
}

void nodeSearch(struct link** HEAD, struct link** TAIL)
{
	//검색 : 이름기준
	struct link* temp = (struct link*)malloc(sizeof(struct link));
	if (temp == NULL)//메모리 할당 실패
	{
		printf("할당 실패\n");
		exit(1);
	}

	temp = *HEAD;
	int sinx = 0; //이름유무 체크
	char sname[20];
	printf("이름검색 : ");
	fgets(sname, 20, stdin);
	sname[strlen(sname) - 1] = '\0';

	while (temp != NULL)
	{
		if (!strcmp(sname, temp->Bookname))
		{
			printf("%d, %s\n", temp->id, temp->Bookname);
			sinx = 1; break;
		}
		else temp = temp->next;
	}
	if (sinx == 0) printf("검색 결과 없음\n");
}

void nodeDelet(struct link** HEAD, struct link** TAIL)
{
	//삭제
	struct link* temp = (struct link*)malloc(sizeof(struct link));
	if (temp == NULL)//메모리 할당 실패
	{
		printf("할당 실패\n");
		exit(1);
	}

	temp = *HEAD;
	int cinx = 0; //이름유무 체크
	char sname[20];
	printf("이름검색(삭제) : ");
	fgets(sname, 20, stdin);
	sname[strlen(sname) - 1] = '\0';
	struct link* btemp = *HEAD; //이전 노드 주소

	while (temp != NULL)
	{
		//btemp = 이전노드, temp = 현재노드
		if (!strcmp(sname, temp->Bookname))
		{
			//HEAD
			if (temp == *HEAD)
			{
				*HEAD = temp->next;
				free(temp);
				(*HEAD)->prev = NULL;
				cinx = 1; break;
			}
			//TAIL
			if (temp == *TAIL)
			{
				*TAIL = btemp;
				free(temp);
				cinx = 1; break;
			}

			//middle
			else
			{
				temp = temp->next;
				temp->prev = btemp;
				temp = btemp->next;
				btemp->next = temp->next;
				
				free(temp);
				cinx = 1; break;
			}
		}
		else
		{
			btemp = temp;
			temp = temp->next;
		}
	}
	if (cinx == 0) printf("검색 결과 없음\n");

	//삭제확인
	printf("\n[삭제 후 재출력]\n");
	temp = *HEAD;
	while (temp != NULL)
	{
		printf("%d, %s\n", temp->id, temp->Bookname);
		temp = temp->next;
	}
}

void nodeReset(struct link** HEAD)
{
	struct link* temp = (struct link*)malloc(sizeof(struct link));
	if (temp == NULL)//메모리 할당 실패
	{
		printf("할당 실패\n");
		exit(1);
	}

	temp = *HEAD;
	while (temp != NULL)
	{
		*HEAD = temp->next;
		free(temp);
		temp = *HEAD;
	}
	printf("삭제가 완료되었습니다.\n");
}

 

3) Menu.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "DLLfx.h"

int main() {
	//do-while 입력/출력/검색 메뉴 프로그램

	int menuNo;

	struct link* HEAD, * TAIL;
	HEAD = TAIL = NULL;


	do {
		printf("\n----메뉴----\n");
		printf("1. 입력\n");
		printf("2. 출력\n");
		printf("3. 검색\n");
		printf("4. 삭제\n");
		printf("\n");
		printf("9. 종료\n");
		printf("------------\n");
		printf("선택 ---> ");

		scanf("%d", &menuNo); getchar();

		switch (menuNo) {
		case 1:
			printf("입력 선택하였습니다\n");
			nodeEnter(&HEAD, &TAIL);
			break;
		case 2:
			printf("출력 선택하였습니다\n");
			nodePrint(&HEAD, &TAIL);
			break;
		case 3:
			printf("검색 선택하였습니다\n");
			nodeSearch(&HEAD, &TAIL);
			break;
		case 4:
			printf("삭제 선택하였습니다\n");
			nodeDelet(&HEAD, &TAIL);
			break;
		case 9:
			printf("이중연결리스트를 해제합니다\n");
			nodeReset(&HEAD);
			break;
		default:
			printf("잘못 선택하였습니다\n");
			break;
		}

	} while (menuNo != 9);
}
기타 사항

 

- 메모리맵
- 비트연산과 매크로 함수 
- 엔디언

 ㄴ 메모리 등에 대상을 배열하는 방법

 ㄴ 방법에 따라 빅 엔디언, 리틀 엔디언, 미들 엔디언 등으로 나뉜다

 


VEDA 바로가기 : www.vedacademy.co.kr

VEDA(한화비전 아카데미) 영상으로 확인하기 : https://url.kr/zy9afd

본 후기는 VEDA(한화비전 아카데미) 1기 학습 기록으로 작성되었습니다.

댓글