'C'에 해당 되는 글 3건

  1. 2010.01.20 n by n matrix의 determinant 구하기
  2. 2009.08.10 sin 그래프 그리기
  3. 2008.08.23 [펌]Visual C++ 6.0 사용하기 - 디버깅
2010. 1. 20. 00:03

n by n matrix의 determinant 구하기

/***************************************************************
* 기능 : 사용자로부터 square matrix의 크기와 성분들을 입력받아
*   cofactor를 이용해determinant를 구함
* 입력 : square matrix의 크기, matrix의 성분들
* 출력 : 입력받은 matrix, matrix의 determinant*
*
* 작성일 : 09년 12월 07일
* 최종 수정일 : 09년 12월 07일
***************************************************************/

#include <stdio.h>  //입출력을 위한 헤더파일
#include <stdlib.h>  //dynamic memory 할당을 위한 헤더파일
#include <math.h>  //x^n을 계산하는 pow함수를 이용하기 위한 헤더파일

void InputMat(double **mat, int size);     //사용자로부터 matrix의 성분들을 입력받는 함수
void ShowMat(double **mat, int size);     //사용자로부터 입력받은 matrix를 출력하는 함수
double DetMat(double **mat, int size);     //matrix와 size를 입력받아 determinant를 반환하는 함수
double CofacMat(double **mat, int p, int q, int size); //matrix와 size, index를 입력받아 cofactor를 반환하는 함수

int main(void)
{
 int size=2;
 int i=0;
 double **mat;

 printf("Square matrix의 크기를 입력하세요 >>");
 scanf_s("%d", &size);

 //matrix의 dynamic memory 할당
 mat = (double**)malloc( sizeof(double*) * size );
 for (i=0 ; i<size ; i++) {
  mat[i] = (double*)malloc( sizeof(double) * size );
 }

 InputMat(mat, size);  //사용자로부터 matrix를 입력받음
 ShowMat(mat, size);   //입력받은 matrix를 출력함
 
 printf("\nDeterminant = %.2lf\n", DetMat(mat, size));

 //matrix의 dynamic memory 해제
 for (i=0 ; i<size ; i++) {
  free(mat[i]);
 }
 free(mat);
 return 0;
}

void InputMat(double **mat, int size) {
 int p=0, q=0;

 for (p=0; p<size; p++) {
  for (q=0; q<size; q++) {
   printf("row %d, column %d의 성분을 입력해 주세요 >>", p+1, q+1);
   scanf_s("%lf", &mat[p][q]);
  }
 }
}

void ShowMat(double **mat, int size) {
 int p=0, q=0;
 
 printf("matrix = \n");
 for (p=0; p<size; p++) {
  if (p == 0) {
   printf("┌");
  } else if(p == size-1) {
   printf("└");
  } else {
   printf("│");
  }

  for (q=0; q<size; q++) {
   printf(" %.2lf", mat[p][q]);
  }

  if (p == 0) {
   printf(" ┐\n");
  } else if(p == size-1) {
   printf(" ┘\n");
  } else {
   printf(" │\n");
  } 
 }
}

double DetMat(double **mat, int size) {
 int p=0, q=0;
 double det=0;

 if (size == 1) {   //determinant of 1 by 1 matrix
  return mat[0][0];
 } else if ( size == 2 ) { //determinant 2 by 2 matrix
  return mat[0][0]*mat[1][1] - mat[0][1]*mat[1][0];
 } else {     //3 by 3 이상
  for (q=0, det=0 ; q<size ; q++) {
   det = det + mat[0][q]*CofacMat(mat, 0, q, size);
  }
  return det;
 }
 return 0;
}

double CofacMat(double **mat, int p, int q, int size) {
 int i=0, j=0;  //인자로 받은 matrix의 index
 int x=0, y=0;  //cmat의 index
 double **cmat;
 double cofactor=0;
 
 //cofactor matrix의 dynamic memory 할당
 cmat = (double**)malloc( sizeof(double*) * (size-1) );
 for (i=0 ; i<(size-1) ; i++) {
  cmat[i] = (double*)malloc( sizeof(double) * (size-1) );
 }

 //mat으로 부터 cmat추출(cmat은 mat의 p행과 q열의 원소를 제외한 나머지 원소들로 구성된 matrix)
 for (i=0,x=0 ; i<size ; i++) {
  if (i != p) {
   for (j=0,y=0 ; j<size ; j++) {
    if (j != q) {
     cmat[x][y] = mat[i][j];
     y++;
    }
   }
   x++;
  }
 }
 
 //cofactor를 계산
 cofactor = pow(-1,p)*pow(-1,q)*DetMat(cmat,size-1);

 //cofactor matrix의 dynamic memory 해제
 for (i=0 ; i<(size-1) ; i++) {
  free(cmat[i]);
 }
 free(cmat);

 return cofactor;
}


사용자 삽입 이미지

2009. 8. 10. 08:06

sin 그래프 그리기



#include <stdio.h>
#include <math.h>

#define X 50
#define Y 79

void graphSine(void);    //sine 함수의 그래프를 그리는 함수
double PI(void);     //원주율을 반환하는 함수
void initializing(char graph[][X], double x[], double y[], int index[]); //초기화 함수
void settingStar(char graph[][X], int index[]);        //그래프모양을 '*'로 세팅
void plot(char graph[][X]);   //그래프를 plot

int main(void)
{
 graphSine();
 return 0;
}

void graphSine(void) {    //sine 함수의 그래프를 그리는 함수
 char graph[Y][X] = {' '};  //그래프 모양의 '*'를 저장할 배열
 double x[X];     //x축 값을 저장할 배열
 double y[X];     //y축 값을 저장할 배열
 int index[X];     //graph에서 '*'로 표시될 index를 저장하기 위한 배열

 initializing(graph, x, y, index);
 settingStar(graph, index);
 plot(graph);
}

double PI(void) {     //원주율을 반환하는 함수
 return acos(-1);
}

void initializing(char graph[][X], double x[], double y[], int index[]) {  //초기화 함수
 const double T = 2*PI();  //주기 2pi
 const double dx = T/(X-1);  //x축값들 사이의 간격
 int i, j;

 for(i=0 ; i<X ; i++) {   //x축을 나타내기 위한 세팅
  graph[(Y-1)/2][i] = '|';
 }

 for(i=0 ; i<X ; i++) {   //x 값을 0부터 2pi까지 등간격으로 나누어 초기화
  x[i] = i*dx;
 }

 for(i=0 ; i<X ; i++) {   //x 값에 대응하는 sin(x)값을 초기화후 0부터 Y-1 사이의 값으로 확대
  y[i] = sin(x[i]);
  y[i] = (Y-1)/2*(y[i]+1);
 }

 for(i=0 ; i<X ; i++) {   //y값을 0부터 Y-1 사이의 정수 값으로 이산화
  for(j=0 ; j<Y ; j++) {
   if(j-0.5 <= y[i] && y[i] < j+0.5) {
    index[i] = j;
    break;
   }
  }
 }
}

void settingStar(char graph[][X], int index[]) {  //그래프모양을 '*'로 세팅
 int i;

 for(i=0 ; i<X ; i++) {
  graph[index[i]][i] = '*';
 }
}

void plot(char graph[][X]) {  //그래프를 plot
 int i;
 int j;

 for(i=0 ; i<Y ; i++) {   //y축 그리기
  switch(i) {
   case 0:
    printf("-1");
    break;
   case (Y-1)/2-1:
    printf("0");
    break;
   case Y-1:
    printf("1\n");
    break;
   default:
    printf("-");
  }
 }

 for(j = 0 ; j<X ; j++) {  //'*'를 이용해 그래프를 출력
  for(i=0 ; i<Y ; i++) {
   printf("%c", graph[i][j]);
  } puts("\n");
 }
}


사용자 삽입 이미지

2008. 8. 23. 20:58

[펌]Visual C++ 6.0 사용하기 - 디버깅



이번에는 VC++ 6.0으로 디버그하는 법을 한번 알아보겠습니다.

프로그래밍에서 가장 어렵고 많은 시간을 차지하는게 디버깅이죠.


VC++은 여러가지 기능을 제공하여 좀더 수월하게 디버깅을 할 수 있습니다.


십진수의 이진수 값을 보여주는 간단한 예제를 통해 디버깅 방법을 알아보도록 하겟습니다.


#include <iostream>
#include <climits>              // for CHAR_BIT
using namespace std;

void main()
{
    int num = 2004, size, mask = 0x80000000;
    char bin[64];

    // int형의 비트 크기를 구한다.
    size = sizeof(int) * CHAR_BIT

    for( int i = 0; i < size; i++ )
    {
        if( (num & mask) == 0 ) bin[i] = '0';
        else bin[i] = '1';

        mask >>= 1;        // 우측 시프트
    }
    bin[i] = '\0';

    prinft("%d = %s\n", num, bin);
}



▷ 문법에러 디버깅


위 소스를 컴파일하면 에러가 발생하고 에러 정보가 아래 빌드창에 나타나게 됩니다.


 

에러 메세지를 더블클릭하거나 F4를 누르면 해당 에러위치로 에디터 창의 커서가 바로 이동하게 됩니다.



▷ 논리에러 디버깅


문법에러는 컴파일러가 명확하게 알려주기 때문에 디버깅이 아주 쉽습니다. 그러나 논리에러는 프로그래머가 직접 찾아내는수 밖에 없죠.


위 소스의 문법에러를 고치고 컴파일을 하면


2004 = 00000000000000000000011111111111


라는 결과가 나오지만 사실 십진수 2004는 이진수로 11111010100 입니다.


어디서 잘못됬는지 디버깅을 해보겠습니다.


디버깅을 시작할려면 먼저 툴바의 아이콘이나 단축키 F9로 브레이크 포인트를 지정합니다.



그 다음에 툴바의 아이콘이나 단축키 F5로 디버그를 시작합니다.

 
그럼 디버그 모드로 전환되고 디버그 툴바와 진행화살표가 브레이크포인트에서 멈춰있는것을 볼 수 있습니다.


 

아래 세 버튼을 적절히 사용해서 한줄씩 디버그를 해나가면 됩니다.

(코드가 복잡할 경우 브레이크 포인트를 여러개 잡아서 F5 를 눌러가며 디버그 할 수도 있습니다.)

Step Into : 한줄씩 실행하며 함수 내부로 들어간다. (F11)


Step Over : 한줄씩 실행하며 함수 내부로 들어가지 않는다. (F10)


Step Out : 함수에서 바로 빠져나온다. (Shift + F11)


디버그 중에 현재 변수의 값을 알려면 변수 위에 마우스를 가져다 두거나 Watch 창을 이용할 수 있습니다.


bin[] 배열과 mask 변수가 어떻게 변하는지 Watch 창으로 감시해보도록 하죠.


Watch 창에 두 변수의 이름을 추가합니다.



(변수이름 길어서 타이핑하기가 귀찮으면 블럭을 잡아서 마우스로 드래그해도 됩니다. )
 
 
그런데 mask 값이 10진수로 나와서 보기 불편하기 때문에 아래처럼 쉼표(,)를 찍고 포맷을 정하는 기호를 붙일수 있습니다. ( x 16진수, s 문자열, d 십진수, c 문자 등 )

디버깅을 해보면 우측 시프트한 mask 값이 잘못 되었다는 것을 알수 있습니다.
 

mask 변수값이 0x80000000 일때 mask >>= 1; 을  하면 0x40000000 가 되어야 하는데 mask 변수의 자료형이 signed int 이기 때문에 우측 산술시프트가 되어버려서 0xc0000000 가 되었던 겁니다.
 
우측 논리시프트를 하기 위해서 int mask = 0x80000000; 를 unsigned int mask = 0x80000000 로 고침으로써 제대로된 결과를 얻었습니다.
 
 
 
다음에는 Quick Watch 와 Call Stack 창 그리고 Break Point 대해 설명해보도록 하겠습니다.
 
 
 
참고도서 -------------------------------------------
 
DEBUGGING C++ ( H.PAPPAS 저 이준하 역 ) 인포북 출판
 
 
 
출처 : 네이버카페
http://cafe.naver.com/cafec/1339