U E D R , A S I H C RSS

새싹교실/2012/start Line


1. 새싹교실/startLine

  • 모임시간 : 가변
  • 가르치는 사람 : 서민관
  • 배우는 사람 : 박환희, 이성훈, 최재현, 서민관

2. 수업

2.1. 1회차-환희, 성훈 (2012-03-21)

2.1.1. 수업내용

  • 전체적인 수업 일정.
  • wiki 사용법.
  • 0과 1으로 어떻게 글자를 표현하는가(ASCII code).
  • 컴파일러가 하는 일.
  • 변수의 개념과 타입.
  • 입, 출력 함수(printf, scanf)와 테스트 함수(assert).
  • 왜 테스트 함수를 써야 하는가.

2.1.2. 과제

  • 변수 선언과 사칙연산만 한 시점에서 어떤 과제를 내야 할지 딱히 떠오르는 것이 없어서 이번에는 패스.

2.1.3. 후기

  • 처음이라 간단하게 하려고 변수와 연산에 대해서만 말을 했는데, 간단하게 하려고 하니까 너무 내용이 간단해져서 뭔지 모르는 사이에 내용이 다 끝나버렸습니다. 그렇다고 잘 했느냐고 하면 그것도 딱히 아닌 느낌이네요. 앞으로는 실습 위주로 하면서 조금 더 자세하게 진행을 해야 하지 않을까 싶습니다. 경우에 따라서는 완전히 다른 방법을 써야 할지도 모르겠지만... 어쨌든 아는 것과 가르치는 것은 다르다는 것을 새삼 느낀 시간이었습니다. - 서민관
  • 매주가 기다려져서 좋네요 ㅋㅋㅋㅋㅋ - 이성훈
  • 앞으로가 기대대요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ - 박환희

2.2. 1회차-재현 (2012-03-22)

2.2.1. 수업내용

  • 전체적인 수업 일정.
  • 재현이가 기존에 아는 부분들(변수, 제어문) 확인.
  • 정확하게 알지 못 하는 부분들(함수, call by value, call by reference, 구조체, 포인터)

2.2.2. 과제

  • 일단 재현이가 기존에 C를 어느 정도 공부했는지를 확인하기 위한 시간이라 따로 과제를 준비하지 못 했음.

2.2.3. 후기

  • 서민관 - 간단하게 재현이가 C문법 알고있는 부분 알아보기, 함수 만들어보기, 전체적인 계획 설명, gcc 사용법. 일단 제어문과 간단한 함수 문법까지도 알고 있는 것 같다. 어제 일도 있어서 긴장을 많이 했는데 그래도 생각보다 어렵지는 않았다. 앞으로는 좀 더 예제등을 준비해야겠다.
  • 최재현 - 아는 범위를 확인하고 앞으로의 방향에 대해 얘기 했습니다. 다음에는 모르는 것들에 대해 배우고 아는 것은 확실히 배워야겠습니다.

2.3. 2회차-환희 (2012-03-26)

2.3.1. 수업내용

  • 1회차 내용의 복습.
  • 제어문의 의의.
  • 제어문(조건문, 반복문)의 문법과 몇몇 주의해야 될 부분들(switch문의 break 사용, 반복문에서의 종료 조건 등).
  • 간단한 제어문 실습.

2.3.2. 과제

  • 중첩된 반복문으로 별 찍기 - 상당히 특이하게 반복문을 사용했다. 생각이 좀 좋은듯 -_-

int main()
{
   int num1 , num2 = 1, num3, num4 = 2;

   printf("별을 위해서 숫자를 입력해주세요\n");
   scanf("%d", &num1);

   num3 = num1 - 1;

   while(num2 <= num1){
      while(num3 < num1){
         printf("*");
         num3++;
      }
      printf("\n");
      num3 = num3 - num4;
      num2 = num2 + 1;
      num4++;
   }

   return 0;
}
  • 윤년 달력

2.3.3. 후기

  • 박환희 - 오늘은 제어문에 대한 내용을 배웠고 느낌은 마음이 편하였고 제어문에는 이러한 종류가 있다는것을 알았고 앞으로 문법을 좀더 익혀야겠다는것을 생각했습니다.
  • 서민관 - 제어문의 사용에 대한 수업(if문법, switch.. for...) 몇몇 제어문에서 주의해야 할 점들(switch에서의 break, 반복문의 종료조건등..) 그리고 중간중간에 쉬면서 환희가 약간 관심을 보인 부분들에 대해서 설명(윈도우 프로그래밍, python, 다른 c함수들) 저번에 생각보다 진행이 매끄럽지 않아서 이번에도 진행에 대한 걱정을 했는데 1:1이라 그런지 비교적 진행이 편했다. 그리고 환희가 생각보다 다양한 부분에 관심을 가지고 질문을 하는 것 같아서 보기 좋았다. 새내기들이 C를 배우기가 꽤 힘들지 않을까 했는데 의외로 if문이나 for문에서 문법의 이해가 빠른 것 같아서 좀 놀랐다. printf, scanf나 기타 헷갈리기 쉬운 c의 기본문법을 잘 알고 있어서 간단한 실습을 하기에 편했다.

2.4. 3회차-환희 (2012-3-28)

2.4.1. 수업내용

  • 배열의 사용법.
  • 함수의 역할과 인자/리턴 타입에 따른 함수의 종류.
  • 함수의 사용.
  • 간단한 예제.
  • swap 함수를 통해서 알아본 현재 시점에서 함수의 문제.

2.4.2. 과제

  • 숫자를 세 개 받아서 정렬하기.

2.4.3. 후기

  • 간단한 이전 시간(if문, 반복문)의 복습과 배열의 사용에 대해 알아보았다. 그리고 이번 시간에 주로 한 내용은 함수가 왜 필요한지와 함수를 만드는 법, 함수를 사용하는 법 등이었다. 개인적으로는 함수를 꽤 중요하게 생각하는 만큼 함수의 필요성을 잘 캐치해 줬으면 좋겠다. 그리고 새삼 드는 생각이지만 환희의 질문이 중요한 부분을 잘 찌른다는 생각이 든다. 별다른 언급도 없었는데 함수 내에서 변수의 scope나 함수 내부의 이름 겹침 등에 대한 질문이 있었다. 그리고 중간에 함수 사용의 예제로 printf문을 약간 이상하게 쓴 코드를 보여줬는데 의외로 감을 잘 잡은 것 같았다. 현재 진행상황으로는 다음에 포인터를 다뤄야 할텐데 함수를 쓰는 것을 조금 더 연습을 시킬지 바로 포인터를 나갈지 고민이다. 당장 포인터를 했다가 어려워하지 않을까 모르겠다. - 서민관
  • 경험했던 것
    - 배열, 배열을 쓸 때 자주하는 실수
    - 함수란? 함수의 정의, 만드는 예제
    - 숫자를 받아 큰 수대로 정렬
    - 해봐야 할 것 ......? - 환희

2.5. 3회차-성훈, 재현 (2012-3-28)

2.5.1. 수업내용

  • 재현, 성훈이의 함수에 대한 지식 확인.
  • swap 함수를 만들어보고 문제점 확인.
  • 포인터의 개념, 프로그램 실행시 메모리의 구조.
  • malloc 함수를 이용한 메모리 할당.
  • 배열과 포인터의 관계.

2.5.2. 과제

2.5.3. 후기

  • 처음에 간단하게 재현, 성훈이의 함수에 대한 지식을 확인했다. 그 후에 swap 함수를 만들어 보고 실행시의 문제점에 대해서 이야기를 했다. 함수가 실제로 인자를 그대로 전달하지 않고 값을 복사한다는 것을 이야기 한 후에 포인터에 대한 이야기로 들어갔다. 개인적으로 새싹을 시작하기 전에 가장 고민했던 부분이 포인터를 어떤 타이밍에 넣는가였는데, 아무래도 call-by-value의 문제점에 대해서 이야기를 하면서 포인터를 꺼내는 것이 가장 효과적이지 않을까 싶다. 그 후에는 주로 그림을 통해서 프로그램 실행시 메모리 구조가 어떻게 되는지에 대해서 설명을 하고 포인터 변수를 통해 주소값을 넘기는 방법(call-by-reference)을 이야기했다. 그리고 malloc을 이용해서 메모리를 할당하는 것과 배열과 포인터의 관계에 대해서도 다루었다. 개인적인 느낌으로는 재현이는 약간 표현이 소극적인 것 같아서 정확히 어느 정도 내용을 이해했는지 알기가 어려운 느낌이 있다. 최대한 메모리 구조를 그림으로 알기 쉽게 표현했다고 생각하는데, 그래도 정확한 이해도를 알기 위해서는 연습문제 등이 필요하지 않을까 싶다. 성훈이는 C언어 자체 외에도 이런저런 부분에서 질문이 많았는데 아무래도 C언어 아래 부분쪽에 흥미가 좀 있는 것 같다. 그리고 아무래도 예제를 좀 더 구해야 하지 않을까 하는 생각이 든다. - 서민관
  • 포인터의 기초와 포인터를 이용한 swap 함수 구현, 값 변환. 그리고 malloc의 형태 기초와 좀 더 쉽게 쓰는 법 익힘. 다음엔 malloc을 이용한 응용프로그램 구현을 해보고 싶다. - 재현
  • 포인터의 정의, 포인터 변수의 정의, malloc 함수, fflush() 함수, getchar() 함수, 메모리의 heap과 stack 영역, (int)a와 *(*(int a))의 차이, 포인터의 OS별 크기(DWORD 크기를 따라간다. 32bit/64bit),
    해봐야 할 것 - 디버깅, 가변인자함수 조사, 복습. - 성훈

2.6. 4회차-환희 (2012-4-2)

2.6.1. 수업내용

  • swap 함수에 대해서 복습.
  • 함수의 호출과 값 복사(call-by-value).
  • 포인터의 개념, 프로그램 실행시 메모리의 구조.
  • 추가적으로 환희의 질문들에 대한 대답과 기타.

2.6.2. 과제

  • 개인적으로 현재 시점에서 과제를 낸다면 C의 문법을 익히기 위한 과제를 준비할 것 같은데 환희가 현재 시점에서 C 문법을 나름대로 잘 쓰는 만큼 그렇게까지 무리해서 과제를 낼 필요는 없지 않을까 싶다. 사실 언제쯤부터 어떤 과제들을 내야 할지 정확히 감이 안 잡히는 것도 있지만... - 서민관

2.6.3. 후기

  • 저번시간에 했던 swap 함수에 대해서 간단하게 복습을 하고 swap 함수의 문제점에 대해서 짚어보았다. 그리고 포인터의 개념과 함수에서 포인터를 사용하는 방법 순으로 진행을 해 나갔다. 새삼 느끼는 거지만 call-by-value의 문제점을 처리하기 위해서 포인터를 들고 나오는 것이 가장 직접적으로 포인터의 필요성을 느끼게 되는 것 같다. 그리고 개념의 설명을 하기에도 편한 것 같고. 그 후에는 포인터에 대한 부분이 일단락되고 성훈이나 재현이처럼 malloc이나 추가적인 부분을 진행할 예정이었는데 환희가 함수의 사용에 대해서 질문을 좀 해 오고 그 외에도 약간 다른 부분을 다루다 보니 진도가 약간 늦어졌다. 그래도 포인터에서는 이해가 가장 중요하다고 생각하는 만큼 조금 천천히 나가는 것도 괜찮다고 본다. 그리고 앞으로의 목표는 일단 처음에 잡아둔 목표까지 무사히 완주하는 것이다. 원래 첫 진도 예정에 다양한 것들이 담겨있는 만큼 목표만 이루어도 충분히 괜찮은 C 실력이 길러지지 않을까 싶다. - 서민관
  • 포인터에 대한 대략적인 개념 - 복잡하지만 숙달되면 나아질듯 합니다.
    약간의 잡지식.
    메모리 구조 + 주소 - 변수 선언시 그 변수의 주소 + 값의 이야기...인데 그림으로 설명해주셔서 쉽게 이해했습니다. - 환희

2.7. 4회차-성훈 (2012-4-3)

2.7.1. 수업내용

2.7.2. 후기

포인터에 대해 잘 배웠네요 ㅎ
포인터변수가 가지는 값과 *, &연산자의 사용법을 잘(은 익혔는데 아직도 긴가민가하고..) 배웠구요..
malloc과 fflush 함수에 대해 다시 정확하게 짚을 수 있어서 좋았구요
특히 heap과 stack에 대한 깊은 이해를 할 수 있었네요.
그래도 역시 개념만 충실한 상태라 좀 많은 예제를 다뤄볼 수 있었으면 좋겠네요
그리고 밑의 과제... 이중 포인터라뉰ㅋㅋㅋㅋㅋㅋㅋㅋㅋ - 성훈

2.7.3. 과제

  • 배열 받아서 뒤집기 - 배열의 주소값을 인자로 받아서 뒤집는 함수.

// 함수 선언
void reverseArr(int **arr, int arrLen);

// 함수 사용시
int arr[10];
reverseArr(&arr, 10);

2.8. 5회차-환희 (2012-4-4)

2.8.1. 수업내용

  • 포인터 변수와 malloc 함수.
  • 배열과 포인터의 관계.
  • 포인터 변수를 인자로 받는 함수.

2.8.2. 후기

  • 포인터 변수에 값을 주어 초기화 하려면 어떻게 해야 하는가(malloc 함수의 사용)와 메모리 해제(free 함수)에 대한 이야기를 했다. 그리고 배열과 포인터에 대한 이야기를 했는데, 배열도 결국 연속된 메모리를 잡는다는 점에서 포인터와 같고 값의 참조도 포인터 변수와 똑같이 할 수 있다는 것을 다뤘다. 그 후에는 포인터 변수(배열)를 인자로 받는 함수를 만드는 법을 배우고, 배열을 인자로 받을 때는 반드시 길이를 관리해줘야 한다는 이야기를 했다. - 서민관
  • malloc 함수 = 힙에 배당되는 메모리, 변수 타입에 따라 할당된 값에 따라 생기는 메모리(변수?)
    Pointer와 배열 = 둘은 결국 같다.
    배열(포인터)을 인자로 받는 함수 = 주소값, 거울 | 거울
    오늘은 다소 힘든 개념들이었습니다. - 환희

2.9. 5회차-성훈 (2012-4-5)

2.9.1. 수업내용

  • 포인터 변수에 대해 리뷰.
  • 구조체의 의미, 구조체의 문법(struct 키워드, .연산자, typedef 키워드).
  • 구조체를 인자로 받는 함수와 구조체 포인터(changeAge()함수를 통해서 접근함).
  • 이중 포인터.

2.9.2. 후기

  • 포인터 2회차. 포인터 변수에 대해서 잠깐 리뷰를 하고 그 후에 구조체와 typedef에 대해서 다루었다. 그리고 구조체를 인자로 받는 함수에 대해서도 다루었다. 그 후에 typedef int* SOMETHING이라는 표현을 써서 이중 포인터에 대해서 이야기를 해 봤는데, 이쪽은 역시 약간 난이도가 있는 것 같다. 특히 int **twoDim에서 twoDim0에 다시 malloc을 해 줘야 한다는 부분이 어려운 것 같다. 차근차근 해보자. 개인적으로 성훈이가 가르친 부분들을 잘 따라오려고 한다는 것을 (*s).age에서 느꼈다. ->연산자가 아니라 *연산자 후에 .연산자로 내용물을 참조한다는 것은 나름대로 메모리의 구조를 생각하려고 애를 썼다는 얘기다. 좀 고마웠다. - 서민관
  • 포인터 변수와 이중 포인터, 구조체에 대해 알게 되었고, 자신이 만든 헤더는 "#"로 전처리함을 알았다. 또한 typedef에 대해서도 익혔다.
※ 감상.
  • 함수까지 독학하는데 1달이었다. 당연히 혼자하는 거니까 농떙이치면서 했지만... 그렇기에 누군가의 가르침을 받으면서 해보니 무지막지한 속도로 C를 정복할 수 있게 된 것 같다. 이런 기회에 그저 감ㅋ사ㅋ하다. - 성훈

2.10. 4회차-재현 (2012-4-5)

2.10.1. 수업내용

  • 포인터 변수와 malloc 함수.
  • 구조체, 구조체 포인터, typedef 키워드.
  • 구조체를 인자로 받는 함수.

2.10.2. 후기

  • 구조체에 초점을 맞춰서 진도를 나갔다. 원래 목표는 성훈이랑 같은 정도(이중 포인터)까지 나가는 것이었는데, 시간이 약간 모자랐다. 사실 다중 포인터에 대해서는 한 번쯤 더 다루어야지 싶으니까 다음에 애들을 다 모아서 좀 더 자세히 다루는 시간을 마련할 생각이다. - 서민관
  • 오늘은 동적할당(malloc)과 구조체, 구조체 포인터, typedef에 대해 개념정리를 하고 그에 대한 간단한 예제와 메모리 그림을 통해서 쉽게 접근을 했다. 또, 구조체와 구조체 포인터의 접근 방법에 대해 숙지하고 함수에 대해 자세히 다뤄서 많은 이해를 했다. 다음엔 다차원 배열과 포인터를 해보고 그에 대한 이해를 해야 할 것 같다. - 재현

2.11. 6회차-환희 (2012-4-9) + 7회차-환희 (2012-4-9)

2.11.1. 수업내용

  • 구조체 문법.
  • 왜 구조체를 써야 하는가.
  • 추상화의 측면에서 보는 타입과 연산(operation).
  • 구조체를 인자로 받는 함수.
  • fopen() 함수 등에 대한 간단한 언급.

2.11.2. 후기

  • 시험기간에 환희 후기를 적어둔 종이를 파일 째로 잃어버렸습니다. ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
  • 정모 전에 두 시간, 정모 끝나고 두 시간이 걸린 정말 긴 새싹이었습니다. ;;;; 처음 계획으로는 재현이나 성훈이랑 비슷하게 구조체 문법과 사용에 대해서 간단하게 다룰 생각이었는데 환희가 왜 구조체가 필요한지에 대한 이야기를 하면서 이야기가 많이 다른 방향으로 흘러갔네요. 일단 구조체가 필요한 이유를 추상화의 관점에서 추상화 한 타입(구조체)과 타입에 관한 연산(함수)을 제공하기 위해서라고 말을 했는데 그래도 직접 피부에 와 닿았을지 어떨지는 좀 걱정입니다. 역시 이런 부분은 직접적으로 경험을 해 보지 않으면 안 될 것 같네요. 한 시스템(도서관 관리 프로그램이나 은행 시스템 등)을 재현이, 성훈이랑 셋이서 쪼개서 만들어 보게 하거나 하는 게 좀 괜찮지 않을까 싶습니다. 나중에 시켜봐야지. - 서민관

2.12. 8회차 (2012-5-1) - 성훈, 환희

2.12.1. 수업내용

  • 함수와 구조체 문법 복습.
  • 프로그래밍 패러다임 - 함수형 프로그래밍.
  • 프로그램을 의미단위(함수)로 쪼개기.
  • 의사코드 적기.
  • 함수 만들기 실습(isPrime, isPalindromePrime 등).

2.12.2. 후기

  • 경험했던 일 : 함수를 만드는 이유. 슈도 코드의 편리성. 포인터와 구조체 복습.
    해 봐야 할 것 : reverse(number) 정의 - 수 배열을 뒤집는 함수
    좋았던 점 : 시험 때문에 희...미...했던 기억이 되살아서 좋았고, 함수에 대한 이해도가 높아진 듯해서 좋았다. 오늘은 C스러움이 많이 느껴져서 흡족하다. 컴공다운 걸 해서 보람이 느껴진다. - 성훈
  • 함수와 구조체 문법에 대한 복습과 '함수형 프로그래밍'에 대해서 다루었다. 복습은 시험이 끝나고 잊어버렸을 테니까 한 것이고 중요한 것은 뒤쪽에서 했던 함수형 프로그래밍 부분이다. 전체적인 내용은 프로그램을 의미단위(함수)로 쪼개는 의사코드를 적고 함수의 껍데기를 만든 후에 내용물을 채워 나가는 방식이었다. 개인적으로 내 새싹에서 꼭 다루고 싶었던 내용의 절반에 해당하는 부분이라 고민을 많이 했는데, 그래도 전하기는 잘 전한 것 같다. 다음으로는 가르쳐야 할 나머지 절반인 설계에 대한 실습을 좀 해 봐야 할 것 같다. - 서민관

2.12.3. 과제

  • 아래와 같은 함수를 만듭니다.
  • 꼭 reverse 함수 하나로 만들 필요는 없습니다.
    오늘 했던 내용을 생각하면서 함수를 만드는 도중에 자신이 필요하다고 생각하는 부분은
    추가적으로 함수를 만들어서 써도 좋습니다. 오히려 좀 더 작은 함수들로 나누는 편을 추천합니다.

// 정수를 인자로 주면 숫자를 뒤집어서 돌려준다.
// 123을 넣으면 321을 리턴. 100을 넣으면 1을 리턴. 120을 넣으면 21을 리턴.
int reverse(int number);

2.13. 9회차(2012-5-9) - 성훈, 환희

2.13.1. 수업내용

  • callback, event driven과 관련된 간단한 이야기.
  • 문자열(char *)에 대한 이야기.
  • 문자열을 다루기 위한 함수들(str...).
  • winapi.co.kr

2.13.2. 후기

  • Callback(winapi 이야기하면서) + winapi.co.kr
    문자열과 관련된 함수 5가지. + 실습.
    오늘은 함수를 봐서 그냥 아... 그렇구나 그런 느낌.
    배운다는 것 보다는 암기에 가까운 느낌이었다. - 환희
  • 문자열과 관련된 유용한 함수들과 CallBack의 개념과 구조체 활용을 배웠다.
    어려운 느낌이 들기는 하지만 아직도 해 볼 만 하다.
    점점 C언어가 function 위주의 프로그래밍이라는 걸 더 깊이 이해하게 된다.
    구조체 예제가 좀 있으면 좋겠다. - 성훈
  • 전체적으로 문자열과 문자열을 다루는 함수만에 초점을 맞춰서 수업을 진행했습니다. 그런데 아무래도 첫 시간에 못지 않게 진행이 늘어졌던 시간이 아니었나 싶습니다. 사실 문자열 함수들은 단순 함수니만큼 인자들을 보고 쓰는 것에 익숙하다면 알아서도 보고 쓸 수준이긴 한데, 그래도 다들 그런 것을 찾아서 써 보거나 한 경험이 별로 없는 만큼 한 번쯤 그런 함수들을 찾아서 쓰는 시간을 가지는 것도 나쁘지 않지 않을까 싶었는데 생각보다 좀 진행이 늘어졌군요. 단순히 설명만 이어졌기 때문인가. 그래도 이번 시간에 굳이 문자열과 관련 함수를 다룬 것은 C언어에서 문자열을 단순한 char의 *가 아닌 하나의 타입으로 보고 그와 관련된 연산(함수)을 제공했다는 것을 한 번쯤 생각해봤으면 합니다. - 서민관

2.13.3. 과제 - 캘린더 만들기

  • Calender.h 파일 - 만들어야 할 함수들. 더 늘려도 상관 없습니다.

// 한 달의 달력을 출력하는 함수입니다.
void printCalender(int nameOfDay, int year, int month);
// 달의 첫 날의 요일(nameOfDay)과 마지막 날의 수를 받아서 1~endDayOfMonth까지 출력합니다.
void printDate(int nameOfDay, int endDayOfMonth);
// 달의 1일 앞의 부분에 빈 요일 수만큼 탭('\t')을 넣습니다.
void printFirstTab(int nameOfDay);
// 달력 첫 머리 부분(월, 년도, 한 줄, 요일 표시)을 출력합니다.
void printHeader(int year, int month);
// 다음 달의 첫 날의 요일을 반환합니다.
int calculateNameOfNextMonthFirstDay(int nameOfDay, int year, int month);
// 해당 달의 마지막 날의 요일을 반환합니다.
int calculateNameOfLastDay(int nameOfDay, int year, int month);
// 윤달 체크.
bool isLeapYear(int year);
// 각 달의 마지막 날 수를 반환합니다.
// 단순한 switch-case문으로 이루어져 있으며, 2월에 대해서는 윤달 체크를 합니다.
int endDayOfMonth(int year, int month);
// 각 요일의 숫자를 받아서 문자열 값을 반환합니다. (ex. 0-"Sun", 1-"Mon" ...)
// 단순한 switch-case문으로 이루어져 있습니다.
char *printMonthName(int i);
  • main.cpp 파일

#include <stdio.h>
#include "Calender.h"

int main(int argc, char *args[]) {
	// year와 요일(nameOfDay)을 입력받는 부분.
	int year = 0, nameOfDay = 0;
	printf("Enter the year : ");
	scanf("%d", &year);
	printf("Enter the name of day(0:sun ~ 6:sat) : ");
	scanf("%d", &nameOfDay);

	// 1~12월을 출력하는 부분.
	for ( int month = 1; month <= 12; month++ ) {
		printCalender(nameOfDay, year, month);
		nameOfDay = calculateNameOfNextMonthFirstDay(nameOfDay, year, month);
	}

	return 0;
}
  • sample output - 1월부터 12월까지. 출력을 예쁘게 하고 싶으면 탭('\t')을 쓰면 됩니다.

                 January, 2012
-------------------------------------------------
  Sun    Mon    Tue    Wed    Thu    Fri    Sat
   1      2      3      4      5      6      7
   8      9     10     11     12     13     14
  15     16     17     18     19     20     21
  22     23     24     25     26     27     28
  29     30     31

2.13.4. 기타

  • 왜 strcat(str1, str2)를 한 후에 str1을 프린트했는데 이상한 출력이 나오는가.
    People p;와 strcat의 사용에 문제가 있습니다. p를 초기화(People p = {0};) 하지 않고 사용하면
    p.name이 쓰레기 값으로 채워지는 것 같습니다. 그래서 strcat을 사용하면 p.name의 뒷부분(p.name99의 뒷부분)에 "홍길동" 내용이 붙습니다.
    이런 상황을 피하기 위해서는 처음에 p를 초기화 하고 사용하거나 memset(p.name, 0, sizeof(char)*100);을 하는 방법이 있습니다.


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

typedef struct People{
	char gender;
	int age;
	char name[100];
	char real_name[100];
} People;

int main()
{
	char str1[100] = "abc";
	char str2[100] = "aaa";

	People p;
	strcat(p.name, "홍길동");

	strcat(str1, str2);

	printf("%s", str1);

	getchar();
	return 0;
}

2.14. 10회차(2012-5-22) - 성훈, 환희

2.14.1. 수업내용

  • 예제를 조금 더 다루어 봤으면 하는 얘기와 구조체를 써 보고 싶다는 얘기가 있어서
    아예 구조체를 쓸 만한 예제를 만들어 봤습니다.
  • 전체적으로 제대로 완성하는 프로그램을 만들어 본다는 점에 의의가 있을 것 같습니다.
    그리고 addAccount()와 deleteAccount()는 이 이후 수업을 위한 하나의 포인트가 될 것입니다.

Account.h
#include <stdio.h>

typedef struct Account {
	char *name;
	int money;
} Account;

typedef struct AccountArray {
	struct Account **accounts;
	int currentAccountNumber;
	int maxLength; // 배열을 사용할 때는 길이를 관리하는 구조체를 만들어서 쓰면 편하다.
} AccountArray;

Account *createAccount(char *name); // Account에 깔끔하게 이름을 할당하기 위해서는 문자열 함수가 필요할 것이다.
AccountArray *createAccountArray(int maxLength);
void addAccount(AccountArray *accountArray, char *name);
bool isFull(AccountArray *accountArray); // 배열이 다 차면 어떻게 하면 좋을까??????
AccountArray *extendArray(AccountArray *before); // 다 찬 배열은 새로 확장을 해 주어야 합니다.
void deleteAccount(AccountArray *accountArray, char *name); // 배열의 중간 원소 삭제? 중간에 구멍만 뻥 뚫어두면 되나?
void deposit(AccountArray *accountArray, char *name, int money); // accountArray 내부에서 이름으로 비교할 필요가 있겠지.
void withdraw(AccountArray *accountArray, char *name, int money);

void addAccountMenu();
void deleteAccountMenu();
void depositMenu();
void withdrawMenu();

main.cpp
#include <stdio.h>

#include "Account.h"

int main(int argc, char *argv[]) {
    int select = 0;
	// 추가적인 변수들이 필요할 것으로 예상.

    while ( true ) {
        printf("select menu : ");
		printf("1: 계좌 추가\n");
		printf("2: 계좌 삭제\n");
		printf("3: 입금\n");
		printf("4: 출금\n");
        scanf("%d", &select);

        switch ( select ) {
		case 1:
			addAccountMenu();
			break;
		case 2:
			deleteAccountMenu();
			break;
		case 3:
			depositMenu();			
			break;
		case 4:
			withdrawMenu();
			break;
                default:
                        break;
		}
    }

	return 0;
}

2.14.2. 후기

2.15. 11회차(2012-5-23) - 성훈, 환희

2.15.1. 수업내용

////////////////////////////////////// 기본 타입, 기본 타입 + 포인터
char a; // a의 타입? 1. 메모리에 a 그려보기.
a = ?? // 적절한 값으로 초기화 해 보기.
int b; // b의 타입? 1. 메모리에 b 그려보기.
b = ?? // 적절한 값으로 초기화 해 보기.

char c[10]; // c의 타입?, 1. 선언과 동시에 0으로 초기화 해 보기., 2. 반복문을 이용해서 원소마다 초기화 해 보기., 3. c[0]의 타입?
char *d; // d의 타입? char 10개 분량의 배열로 선언과 동시에 초기화 해 보기.

// c와 d를 각각 메모리에 그려보기. 중요.


??? // []를 이용해서 c의 세 번째 원소에 접근해 보기.
??? // 가능한 방법으로 d의 세 번째 원소에 접근해 보기.
??? // 가능한 방법으로 c의 세 번째 원소에 접근해 보기.
// array[0] == *(array + 0) 배열이나 포인터나 해당 주소에 대한 접근이라는 점에서는 동일하게 접근할 수 있다.



//////////////////////////////////////// 사용자 정의 타입, 사용자 정의 타입 + 포인터
Person p; // p의 타입? 1. 메모리에 p의 모양 그려보기.
??? // p의 내용물에 접근해보기.

Person pArr[10]; // pArr의 타입? 1. 메모리에 pArr의 모양 그려보기.
??? // pArr의 0번째 내용물에 접근해보기

Person *p2; // p2의 타입? 1. 메모리에 p2의 모양 그려보기.
??? // p2 초기화 해 보기.
??? // p2의 내용물에 접근해보기.



Person *ppa[10] // ppa의 타입? 1. 메모리에 ppa의 모양 그려보기., 2. ppa[0]의 타입? 3. ppa[0] 초기화 해 보기. 4. ppa[0]의 내용물에 접근해 보기.

Person **ppb // ppb의 타입? 1. 메모리에 ppb의 모양 그려보기., 2. ppb[0]의 타입? 3. ppb[0] 초기화 해 보기., 4. ppb[0]의 내용물에 접근해 보기.

2.15.2. 후기

2.16. 12회차(2012-7-19)

2.16.1. 수업내용

  • AccountArray와 관련된 함수들 만들기.
  • 왜 createAccount(char *name)은 Account의 *를 반환하는가.

Account makeAccount(char *name) {
	Account account;
	account.money = 0;
	account.name = (char *)malloc(sizeof(char) * (strlen(name)+1));
	strcpy(account.name, name);

	return account;
}

void addMoney(Account account, int money) {
	account.money += money;
}
그냥 Account를 반환하게 만든 다음 함수들을 써 보면 차이를 알 수 있습니다.
Account를 그냥 넘겨주게 되면 call-by-value로 Account의 복사본을 가지고 money를 증가시키기 때문에
원본 Account에는 아무런 변화가 없습니다.
  • extendArray 등의 함수 사용의 불편함.

2.17. 13회차(2012-7-20)

2.17.1. 수업내용


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

typedef int Data;

typedef struct Node {
    Data data;
    Node *nextNode;
} Node;

typedef struct LinkedList {
    int length;
    Node *headNode;
} LinkedList;

LinkedList *createList();
Node *createNode(Data data);
void deleteList(LinkedList *linkedList); // LinkedList까지 삭제.
void addData(LinkedList *linkedList, Data data); // LinkedList의 맨 뒤에 Data를 가진 Node 추가.
void removeData(LinkedList *linkedList, Data data); // 해당하는 Data를 가진 Node 삭제.
Node *getData(LinkedList *linkedList, int position); // 해당하는 index를 가진 Node를 반환.
void clearList(LinkedList *linkedList); // LinkedList의 Node들 삭제.
void printList(LinkedLIst *linkedList);

2.17.2. 코드들

  • 환희


  • 성훈

#include "LL.h"

LinkedList *createList(){
	LinkedList *res;
	res = (LinkedList *)malloc( sizeof(LinkedList) );
	(*res).headNode = NULL;
	(*res).length = 0;	
	return res;
}
Node *createNode(Data data){
	Node *res;
	res = (Node *)malloc( sizeof(Node) );
	(*res).data = 0;
	(*res).nextNode = NULL;
	return res;
}
void deleteList(LinkedList *linkedList){
	clearList(linkedList);
	free(linkedList);
}
void addData(LinkedList *linkedList, Data data){
	Node *node = createNode( data );
	Node *temp = linkedList->headNode;
	for(;temp->nextNode != NULL;){
		temp = temp->nextNode;
	}
	temp->nextNode = node;
}
void removeData(LinkedList *linkedList, Data data){
	int onoff = 0;																		//for duty of switch
	Node *remove = linkedList->headNode;
	if( remove->data == data ){
		free( remove );																	//If the object is headNode
		onoff = 1;
	}
	if( onoff == 0 && remove->nextNode->data == data ){
		free( remove->nextNode );														//If the object is the nextNode of headNode
		onoff = 1;
	}
	for(; onoff == 0 && remove->nextNode->data != data;){								//...
		remove = remove->nextNode;
	}
	remove->nextNode = remove->nextNode->nextNode;										//	remove   remove-n   remove-n-n
	free(remove->nextNode);																//	remove ~ remove-n-n , free remove-n
}
Node *getData(LinkedList *linkedList, int position){
	Node *get = linkedList->headNode;
	for( int i = 0 ; i < position ; i++ ){
		get = get->nextNode;
	}
	return get;
}
void clearList(LinkedList *linkedList) {
	Node *now = (*linkedList).headNode;
	Node *next;
	for( ; (*now).nextNode != NULL ; ){	//now의 다음이 있는동안 반복
		next = (*now).nextNode;			//next는 now의 다음
		free( now );					//now를 free
		now = next;						//next를 now로 당김
	}
	free( now );						//now를 free
}
int lengthOf(LinkedList *linkedList){
	int length = 0;
	Node *temp = linkedList->headNode;
	for( ; temp->nextNode != NULL ; length++ ){
		temp = temp->nextNode;
	}
	return length;
}
void printList(LinkedList *linkedList){
	Node *temp = linkedList->headNode;
	for( ; temp->nextNode != NULL ; ){
		printf("%d\t", temp->data);
		temp = temp->nextNode;
	}
	printf("\n");
}

2.17.3. 질문

  • 더미 노드의 사용 이유, 예시.

2.18. 2012-7-30

2.18.1. 코드

int main() {
	Stack *stack = createStack();
	assert(stack->elementNumber == 0);
	assert(stack->head == NULL);

	push(stack, 10);
	assert(stack->elementNumber == 1);
	assert(peek(stack)->data == 10);

	push(stack, 20);
	assert(stack->elementNumber == 2);
	assert(peek(stack)->data == 20);

	assert(pop(stack)->data == 20);
	assert(stack->elementNumber == 1);

	Node *result = pop(stack);
	assert(result->data == 10);
	assert(isEmpty(stack));

	return 0;
}

2.19. 2012-8-2

2.19.1. 코드

  • Map in C - 어떻게든 클래스 흉내를 내 보려고 정말 별 짓을 다 했다. 코드를 보고 싶으면 서민관에 가서 볼 것.


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2012-08-01 18:25:48
Processing time 0.2989 sec