SICP 연습문제 1.8

 참으로 허무한 문제다.

 분명 나의 계산에는 이상이 없었다.

 보고 또 보고, 계속 봐도 나는 틀린게 없었다.

 뭐가 문제지?

 답은 책이 잘못된 것이었다…..

 관련 링크 : http://www.buggymind.com/72

 한참을 끙끙대다가 인터넷의 도움을 받기로 하고 검색한 결과 어이없는 내용없다…(하하…)

 문제인즉, 세제곱을 구하는 공식이 틀렸던 것이다.

 아래의 공식이 정확한 공식이다.

사용자 삽입 이미지
 아래는 바뀐 코드 내용이다.

사용자 삽입 이미지

SICP 연습문제 1.7

 앞서만든 제곱근 구하기 프로그램의 개량된 버전을 만드는 내용이다.

 좀더 정확한 근사치를 구할 수 있도록 하는 프로그램인데…..

 결과적으로 못풀었다.

 알고리즘은 머리에 있는데….자세한 문법을 몰라 못풀었다.(…라고 말하고 싶다.)

 앞으로의 숙제이다.

 언제고 문제를 해결한다면 다시 이 포스팅을 다시 할 것이다. : )

 아래에 미처 못 푼 코드를 남겨둔다.

 사용자 삽입 이미지

SICP 연습문제 1.6

 제곱근을 구하는 식에서 사용한 if 라는 특별문을 임의의 프로시져로 바꾸어서 사용하는 문제이다.

 즉,

(Language : text)
  1. (define (sqrt-iter guess x)
  2.     (if (good-enough? guess x)
  3.         guess
  4.         (sqrt-iter (improve guess x)
  5.                 x)))

를 다음과 같이 바꾸어서 실행했을 때 어떤 결과 값이 나오겠느냐….이다.

(Language : text)
  1. (define (new-if predicate then-clause else-clause)
  2.     (cond (predicate then-clause)
  3.         (else else-clause)))

 처음에 혼자서 문제를 풀어 보았다. 잘 되지 않아서 정답을 찾아 보았다…

 관련 링크 : http://nosyu.egloos.com/4016689

 아하! 안되는 것이 맞구나…근데 내꺼는 코드가 약간 이상한데…다시 수정을 한 후, 실행을 해 보았다.

 그런데 결코 실행되어서는 안되는 코드가 척척 실행되는 것이다.

 왜 이럴까…한참을 고민하고 또 고민했다…

 나중에서야 어이없이 답을 알게 되었다.

 깜박하고 제일 마지막….

(Language : text)
  1. (define (sqrt x)
  2.     (sqrt-iter 1.0 x))

 부분을 입력을 안했던 것이다…..그런데 이상하게 실행을 척척 잘 되더라.

 원래는 되지 않아야 하는것이 정상일텐데…아마도 아직 내가 모르는 무언가가 있는 듯 하다.

 아무튼 문제를 해결하니 예상값이 정확하게 나왔다.

 참, 답은 무한 루프이다.

 변경된 new-if 에서 인자를 먼저 계산하니, (sqrt-iter (improve guess x) x) 부분에서 자꾸만 루프가 발생하는 것이다.

사용자 삽입 이미지
 오른쪽 하단에 러닝이 계속 돌아가는 것이 보인다.

 Stop을 누르니 kill 하겠냐는 메시지가 나온다. 당연히(?) Kill 했다.

사용자 삽입 이미지

우분투에서 gcc 컴파일러 관련 라이브러리 설치법

 우분투를 처음 설치하고 컴파일을 하려는 경우

 관련 패키지 혹은 헤더파일이 없다고 에러 메시지가 뜬다.

 이는 특정 패키지를 설치하면 문제가 해결된다.

sudo apt-get install build-essential

 명령어를 입력하면 필요한 패키지들이 자동으로 설치가 된다.

파일 디스크립터와 파일 포인터 사용시 주의점

 네트워크 프로그래밍을 하더도중…한가지 풀리지 않는 의문점이 생겨 KLDP 게시판에 글을 올렸다.

 내용 보기 : http://kldp.org/node/90394

 글을 올린지 30분도 채 안되서 답변이 올라왔다.

 문제인즉…

 다음과 같은 코드를 실행했을때…
 

(Language : c)
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6.  
  7. void error_handling(char *message);
  8.  
  9. int main(void)
  10. {
  11.     int fildes;
  12.     FILE *fp;
  13.  
  14.     fildes = open(“data.dat”, O_WRONLY | O_CREAT | O_TRUNC);
  15.     if(fildes == -1)
  16.         error_handling(“open() error!”);
  17.    
  18.     /* 파일 디스크립터를 이용하여 파일 포인터 생성 */
  19.     fp = fdopen(fildes, “w”);
  20.     write(fileno(fp), “This is write funcion1!! nn, 27);
  21.     fputs(“This is fputs function!! nn, fp);
  22.     write(fileno(fp), “This is write funcion2!! nn, 27);
  23.    
  24.     fclose(fp);
  25.    
  26.     return 0;
  27. }
  28.  
  29. void error_handling(char *message)
  30. {
  31.     fputs(message, stderr);
  32.     fputc(n, stderr);
  33.     exit(1);
  34. }

 나타나는 결과 화면이 다음과 같다는데 있었다.

사용자 삽입 이미지
 즉 fgets() 함수의 호출 순서와 파일에 입력된 순서가 서로 맞지 않는다는 것이었다.

 이유는 간단했다.

 KLDP의 답글에 올라온 내용처럼 C표준 라이브러리의 입/출력 함수의 경우 자체 버퍼를 따로 가지고 있어서 이를 명시적으로 비워 주지 않으면 문제의 소지가 있다는 것이다.

 물론 명시적으로 해주지 않아도 표준 라이브러리만 사용한다면 문제는 없다. 하지만 지금처럼 시스템 함수와 표준 라이브러리를 병행해서 사용할 경우 위와 같은 문제가 생길 수 있기 때문에 혼용한다면 명시적으로 버퍼를 비워주는 작업이 필요하다.

 다음과 같이 말이다. 위의 코드는 아래의 코드를 추가한 결과 정상적으로 작동하였다.

(Language : c)
  1.     fputs(“This is fputs function!! nn, fp);
  2.     fflush(fp);

 원인을 안다면 해결책은 간단한 법이다.