본문 바로가기
College Computer Science/C Language

[C 프로그래밍 실습] 동적 메모리와 전처리 1 (Lab 13)

by 2den 2021. 1. 8.
728x90

<Lab 13 문제 유형 요약>

 

  • Program 1 : 구조체, 동적 메모리 할당
  • Program 2 : 이차원 배열, 동적 메모리 할당
  • Program 3 : 파일 입력, 구조체, 동적 메모리 할당, 연결리스트
  • Program 4 : 동적 메모리 할당, 연결리스트, 출력
  • Program 5 : 배열, 연결리스트, 삽입, 삭제, 정렬

 

 


 

Program 1

 

다음 결과를 참고로 구조체 point circle을 정의하고 구조체 circle을 저장할 공간을 동적으로 할당하여 다음 자료를 저장하고 출력하는 프로그램을 작성하시오.

  • 구조체 point : 실수 멤버 x, y 이차원 평면의 좌표로 구성
  • 구조체 circle : 원의 중심 좌표인 point와 반지름인 실수 radius멤버로 구성
  • 원 중심좌표(x,y) 와 반지름을 실수로 차례로 입력

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define PI 3.141592

typedef struct _point {
  double x;
  double y;
} point;

typedef struct _circle {
  point p;
  double r;
} circle;

int main(void)
{
  point *p = malloc(sizeof(point));
  circle *c = malloc(sizeof(circle));

  while (1)
  {
      printf("원의 중심 좌표(x,y), 반지름을 입력하시오 : ");
      scanf(" %lf %lf %lf", &(p->x), &(p->y), &(c->r));
      if (isdigit(p->x) != 0 || isdigit(p->y) != 0 || isdigit(c->r) != 0)
      {
          printf("error\n");
          continue;
      }
      break;
  }

  printf("원중심좌표 (%.2lf, %.2lf)\n", p->x, p->y);
  printf("원반지름: %.2lf\n", c->r);
  printf("원면적: %.2lf\n", PI*(c->r)*(c->r));

  free(p); free(c);

  return 0;
}

 

 

Program 2

 

2차원 배열의 메모리를 동적으로 할당하는 함수(make2dArray)를 만들고, 2차원 배열 x의 원소를 y에 복사한후 xy의 배열값을 출력하는 프로그램을 쓰시오.

  • 자료형과 함수 설명

int x[2][3] = { 1, 3, 5, 2, 4, 6 };

int **y;

int **make2dArray(int rows, int cols);  // rowcol 크기의 2차원 배열을 동적 할당

void copyarray(int x[][3], int **y, int rowsize, int colsize);  // x에서 y로 복사

void printarray1(int x[][3], int rowsize, int colsize);  // 이차원 배열 출력

void printarray2(int **y, int rowsize, int colsize);  // 이중 포인터 배열 출력

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

int **make2dArray(int rows, int cols)
{
  int **y = (int**)malloc(sizeof(int*)*cols);

  for(int i=0; i<cols; i++)
  {
    y[i] = (int*)malloc(sizeof(int)*rows );
  }

  return y;
}

void copyarray(int x[][3], int **y, int rowsize, int colsize)
{
  for (int i=0; i<rowsize; i++)
  {
    for( int j=0; j<colsize; j++)
    {
      y[i][j] = x[i][j];
    }
  }
}

void printarray1(int x[][3], int rowsize, int colsize)
{
  for (int i=0; i<rowsize; i++)
  {
    for( int j=0; j<colsize; j++)
    {
      printf("%d ", x[i][j]);
    }
    printf("\n");
  }
}

void printarray2 (int **y, int rowsize, int colsize)
{
  for (int i=0; i<rowsize; i++)
  {
    for( int j=0; j<colsize; j++)
    {
      printf("%d ", y[i][j]);
    }
    printf("\n");
  }
}

int main(void)
{
  int x[2][3] = { 1,3,5,2,4,6 };
  int **y = make2dArray(2,3);

  copyarray(x, y, 2, 3);
  printf("이차원 배열 x\n");
  printarray1(x, 2, 3);
  printf("\n이차원 배열 y\n");
  printarray2(y, 2, 3);

  free(y);

  return 0;
}

 

 

Program 3

 

다음 파일(in.txt) 내용을 참고하여 구조체를 정의하고, 그 내용을 읽어 동적으로 자료를 만들어 연결리스트를 구성하시오. 각 학생의 점수의 합을 구하여 아래와 같이 연결리스트를 출력하는 프로그램을 작성하시오.

  • 입력파일(in.txt)

1    강동구    30.3    40.5
2    강혜진    28.3    37.5
3    김다영    32.5    77.3
4    김민지    67.2    39.9
5    김소연    77.8    67.4
6    안태용    22.4    37.5

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

typedef struct _student {
    int no;
    char name[10];
    float sub1;
    float sub2;
} student;

typedef struct linked_list {
    student* sstruct;
    struct linked_list* next;
} node;

typedef node* link;

link createNode(student* step)
{
    link cur;
    cur = (node*)malloc(sizeof(node));
    cur->sstruct = (student*)malloc(sizeof(student));

    cur->sstruct->no = step->no;
    strcpy(cur->sstruct->name, step->name);
    cur->sstruct->sub1 = step->sub1;
    cur->sstruct->sub2 = step->sub2;
    cur->next = NULL;

    return cur;
}

link appendNode(link head, link cur)
{
    link nextNode = head;

    if (head == NULL)
    {
        head = cur;
        return head;
    }

    while (nextNode->next != NULL)
    {
        nextNode = nextNode->next;
    }

    nextNode->next = cur;

    return head;
}


int printNode(link head)
{
    link nextNode = head;

    while (nextNode != NULL)
    {
        printf("%5d%10s%8.1f%8.1f%8.1f\n", nextNode->sstruct->no, nextNode->sstruct->name, nextNode->sstruct->sub1, nextNode->sstruct->sub2, nextNode->sstruct->sub1 + nextNode->sstruct->sub2);
        nextNode = nextNode->next;
    }

    return 0;
}

int main()
{
    FILE* fp;
    char fn[] = "in.txt";

    student s;
    student* sptr = &s;

    link head = NULL;
    link cur;

    if ((fp = fopen(fn, "r")) == NULL)
    {
        printf("파일을 열 수 없습니다.\n");
        exit(1);
    }

    while (!feof(fp))
    {
        fscanf(fp, "%d%s%f%f\n", &sptr->no, sptr->name, &sptr->sub1, &sptr->sub2);
        cur = createNode(sptr);
        head = appendNode(head, cur);
    }

    printNode(head);
    fclose(fp);

    return 0;
}

 

 

Program 4

 

동적 메모리 할당을 이용하여 이름이 포함된 노드들의 연결 리스트를 만들면서, 리스트의 처음부터 마지막까지 반복문으로 출력하는 함수 printList()를 만들어서 아래와 같이 출력하는 프로그램을 작성하시오.(강의자료 유사 문제)

  • 데이터와 함수 설명

link createNode(char *name);   //create node

link appendNode(link head,link cur); //append

void printList(link head); 

 

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

typedef struct linked_list {
  char* name;
  struct linked_list* next;
} node;
typedef node* link;


link createNode (char* name)
{
  link cur;
  cur = (link)malloc(sizeof(node));
  
  if (cur==NULL)
  {
    printf("노드 생성을 위한 메모리 할당에 문제가 있습니다.\n");
    return NULL;
  }

  cur->name = (char*)malloc(sizeof(char)*(strlen(name)+1));
  strcpy(cur->name, name);

  cur->next = NULL;

  return cur;
}

link appendNode(link head, link cur)
{
  link nextNode = head;

  if (head==NULL)
  {
    head = cur;
    return head;
  }

  while (nextNode->next != NULL)
  {
    nextNode = nextNode->next;
  }

  nextNode->next = cur;

  return head;
}

void printList(link head)
{
  int cnt = 0;
  link nextNode = head;

  while(nextNode != NULL)
  {
    printf("%3d번째 노드는 %s\n", ++cnt, nextNode->name);
    nextNode = nextNode->next;
  }

  return;
}

int main()
{
  char name[30];
  link head = NULL;
  link cur;

  printf("이름을 입력하고 enter를 누르세요. >> ");

  while(gets(name)!=NULL)
  {
    cur = createNode(name);
    if (cur==NULL)
    {
      printf("동적메모리 할당에 문제가 있습니다.\n");
      exit(1);
    }
    head = appendNode(head, cur);
    printList(head);
    printf("이름을 입력하고 enter를 누르세요. >> ");
  }

  return 0;
}

 

 

Program 5

 

다음과 같은 정수형 배열을 이용하여 연결리스트로 만들어서 출력하고, 삽입과, 삭제 기능을 하는 프로그램을 쓰시오.

  • 데이터와 함수 설명

int data[] = {10, 30, 40, 70, 90 };

createList() 함수: 배열 data를 이용하여 연결 리스트를 생성

insertNode() 함수: 입력한 정수의 노드를 생성하여 순서에 맞도록 삽입

deleteNode() 함수: 입력한 정수를 가지는 노드를 찾아 삭제

printList() 함수: 리스트의 링크를 따라가면서 처음부터 마지막까지 data 필드를 출력

 

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

typedef struct linked_list {
  int name;
  struct linked_list* next;
} node;
typedef node* link;


link createList()
{
  int data[] = {10, 20, 40, 70, 90};
  
  link head, cur;
  head = (link)malloc(sizeof(node));
  cur = (link)malloc(sizeof(node));

  head->next = cur;
  
  if (head==NULL || cur==NULL)
  {
    printf("노드 생성을 위한 메모리 할당에 문제가 있습니다.\n");
    return NULL;
  }

  for(int i=0; i<5-1; i++)
  {
    cur->name = data[i];
    link temp = (link)malloc(sizeof(node));
    cur->next = temp;
    cur = temp;
  }

  cur->name = data[4];
  cur->next = NULL;

  return head;
}

void insertNode(link head, int insertval)
{
  link pre = head;
  link cur = head->next;
  link temp = (link)malloc(sizeof(node));
  temp->name = insertval;

  for(int i=0; i<5; i++)
  {
    if (cur->name > temp->name)
    {
      pre->next = temp;
      temp->next = cur;
      break;
    }

    pre = cur;
    cur = cur->next;
  }

  return;
}

void deleteNode(link head, int deleteval)
{
  link pre = head;
  link cur = head->next;

  for(int i=0; i<5; i++)
  {
    if (cur->name == deleteval)
    {
      pre->next = cur->next;
      free(cur);
      break;
    }

    pre = cur;
    cur = cur->next;
  }

  return;
}

void printList(link head)
{
  link nextNode = head->next;

  while(nextNode != NULL)
  {
    printf("%d -> ", nextNode->name);
    nextNode = nextNode->next;
  }
  printf("NULL\n");

  return;
}

int main()
{
  int insertval, deleteval;
  link head = createList();
  printf("Original List\n");
  printList(head);

  printf("\n삽입할 노드의 숫자를 입력하시오 => ");
  scanf("%d", &insertval);
  printf("Updated List after insert %d\n", insertval);
  insertNode(head, insertval);
  printList(head);

  printf("\n제거할 노드의 숫자를 입력하시오 => ");
  scanf("%d", &deleteval);
  printf("Updated List after delete %d\n", deleteval);
  deleteNode(head, deleteval);
  printList(head);
  
  return 0;
}

 

728x90

댓글