사이드바 열기


사용자 삽입 이미지


너희들은 오히려 인연하는 마음으로 법을 듣고 있으니, 이 법도 인연일 뿐,

법의 본성을 얻은 것이 아니니라. 어떤 사람이 손으로 달을 가리켜 다른 사람에게 보인다면,

그 사람은 당연히 손가락을 따라 달을 보아야 하는데,

여기서 만일 손가락을 보고 달 자체로 여긴다면, 그 사람은 어찌 달만 잃었겠느냐.

손가락도 잃었느니라.


왜냐하면 가리킨 손가락을 밝은 달로 여겼기 때문이다. 어찌 손가락만 잃었다고 하겠느냐.

밝음과 어둠도 모른다고 하리라. 왜냐하면 손가락 자체를 달의 밝은 성질로 여겨서,

밝고 어두운 두 성질을 알지 못하기 때문이다.


汝等尙以緣心聽法。此法亦緣非得法性。如人以手指月示人。

彼人因指當應看月。若復觀指以爲月體。此人豈唯亡失月輪亦亡其指。

何以故。以所標指爲明月故。豈唯亡指。亦復不識明之與暗。

何以故。卽以指體爲月明性。明暗二性無所了故。

汝亦如是若以分別我說法音爲汝心者。此心自應離分別音有分別性。

Posted by LaLuna

이 문제는 이중포인터에 대한 문제입니다. 이중포인터를 사용하여 인자를 전달하는 방법으로
이렇게 쓸 필요는 없으며, 상당히 가독성도 떨어지는 코드입니다.

어떠한 카페에 가서 질답게시판에 가보니 이러한 소스가 올라와 포인터에 대해 잘 알아볼 기회가 될 것같아 만들어본 것입니다.

#include 
#include 


void Input(struct Data **D, int *num);  //입력 담당 함수
void Output(struct Data **D, int *num);  //출력 담당 함수

typedef struct Data
 {
       char name[20];  //작가이름
       char book[40];  //책이름
       int page;   //페이지수
 }Data;


/* 메인함수 */
int main(void)
{
      int number;  //입력받을 권수를 저장할 변수
      struct Data *D;

      fputs("몇권을 입력? : ", stdout);
      scanf("%d", &number);
      fflush(stdin);  //버퍼에 남은 입력을 비움
 
      D=(Data*)calloc(number , sizeof(Data));
      if(D==NULL){
      puts("메모리 할당 실패!");
      exit(1);
      }
 
      Input(&D, &number);
      Output(&D, &number);

    

      free(D);

      return 0;
}


/* 데이터 입력 함수 */
void Input(struct Data **D, int *num)
{
      int i;
 
      puts("도서 정보 입력");
 
      for(i=0; i<*num; i++)
     {
      //저자 입력
      fputs("저자:", stdout);
      fgets(D[i]->name, sizeof(D[i]->name), stdin);
 
       /* 이 아래줄은 fgets가 \n까지 저장해 한줄을 띄어버리는 것을 막기 위함임
          인터넷에서 참고했음  */
      { register char *p; for(p=D[i]->name;*p;p++) if(*p=='\r' || *p=='\n'){ *p = '\0'; break;} }
 
       //제목 입력
       fputs("제목:", stdout);
       fgets(D[i]->book, sizeof(D[i]->book), stdin);
      { register char *p; for(p=D[i]->book;*p;p++) if(*p=='\r' || *p=='\n'){ *p = '\0'; break;} }
 
       //페이지수 입력
       fputs("페이지수:", stdout);
       scanf("%d", &D[i]->page);
 
       puts("");
       fflush(stdin); //버퍼에 남아있는 입력을 비움
      }
}

/* 데이터 출력 함수 */
void Output(struct Data **D, int *num)
{
      int i;
 
      puts("도서 정보 출력");
 
      for(i=0; i<*num; i++)
      {
          printf("book%d \n",i+1);
          printf("저자:%s\n",D[i]->name);
          printf("제목:%s\n",D[i]->book);
          printf("페이지수:%d\n", D[i]->page);
          puts("");
      }
}
Posted by LaLuna
우리가 알고 있다시피 Invariable(상수) Variable(변수)에는 Data Type이 있습니다. Data Value에 따라서 Data Type를 지정해주어야 하는데, Invariable는 그 자신의 Value에 대한 표기로 Data Type를 나타낼 수 있기 때문에 Data Type를 선언해줄 필요는 없습니다. 그러나 Variable의 경우 Value가 언제든지 바뀔 수 있기 때문에 Data type를 선언해 주어야 합니다. 그런데 모든 Variable에는 Data Type 이외에 Storage Class라는 존재합니다.

 

Storage Class란 어떠한 Variable의 기억장소에 대한 지정과 지정한 Variable의 유효범위를 결정하는 것이 Storage Class입니다. 여기서 유효범위란 어떠한 Variable Program Code의 활용범위에 따른 분류와 기억 장소를 점유하는 시간에 따른 분류를 말하는 것입니다.

Variables의 성격은 변수를 선언하는 Storage Class Specifiers(기억부류 지정자)와 선언장소(함수의 내부이냐 외부이냐)에 의하여 결정됩니다.

 

하나의 함수는 ‘{‘ 으로 시작해서 ‘}’ 으로 끝이 나며, 이 내부에서 선언된 Variables는 이 함수 안에서만 사용이 가능하며, 이것을 Local Variables라 부릅니다. 또한 모든 함수의 외부에서 선언되어 파일 안의 모든 함수에서 사용이 가능한 Variables Global Variables 이라 부릅니다.

Global Variables는 초기화를 시키지 않아도 자동적으로 0으로 정해지며, Local Variables는 초기화가 되지 않고 임의의 값(Memory가 원래 가지고 있던 쓰레기 값)을 가지게 됩니다.

 

Storage Class Speciriers에 의한 분류는 아래의 표와 같습니다.

 

Storage Class

External Variables

Automatic Variables

Static Variables

Register Variables

지 정 자

extern

auto

static

Register


저장장소

정적

데이터영역


스택

정적

데이터영역

CPU

레지스터

선언위치

함수의 외부

함수의 내부

함수의 내부

함수의 내부


통용범위

프로그램

전체


함수의 내부


함수의 내부


함수의 내부


파괴시기

프로그램

종료시


함수 종료시


프로그램 종료


함수 종료시


초 기 값


0

초기화

되지 않음


0

초기화

되지 않음

 

1. External Variables(외부 변수)

하나의 프로그램을 짜기 위해 여러 사람이 각기 다른 파일에서 작업을 하거나, 혹은 Source를 분산 시킬 필요성이 있을 경우 사용하는 지정자입니다. 전역변수는 하나의 파일 안에서 모든 함수들이 사용할 수 있지만 다른 파일은 접근이 불가능 합니다. 이런 경우 External Variables으로 선언하여 다른 파일에서 접근이 가능하도록 알려주는 역할을 합니다.

 

2. Automatic Variables(자동 변수)

우리들이 흔히 사용하는 변수는 대부분 Automatic Varibles입니다. 기본적으로 함수의 내부에서 사용되며 임시적으로 사용하는 Variable입니다. 저장장소는 스택에 위치하며, 함수의 종류시 자동적으로 없어지며, 전역으로 사용 혹은 다른 함수에서 접근이 불가능 한 변수입니다.

 

3. Static Variables(정적 변수)

기본적으로 Automatic Variables와 비슷하게 함수안에서 쓰이며, 함수가 종료되어도 없어지지 않는 특징을 가지고 있습니다. 생성은 스택이 아닌 메모리의 정적구간에 생성이 되고 프로그램 자체가 끝날 때까지 보존되어지는 정적인 의미를 지닌 Variables입니다. Static Variables의 사용은 프로그램이 끝날 때까지 존재는 하되 소속된 함수가 실행될때만 접근이 가능하다는 특징을 지니고 있습니다.

 

4. Register Variables(레지스터 변수)

Register Variables는 위의 Variables와 다르게 RAM에 생성되지 않고 CPU Register에 생성되어지는 특징을 가지고 있습니다. CPU Rigister RAM보다 입출력이 빠르기 때문에 프로그램중에 자주 사용하는 값을 Register에 위치해 놓음으로써 수행 속도를 높일 수 있게 하는 Variables입니다. 주의할 점은 Variable Register Variables로 지정할 때 Register에 충분한 공간이 존재한다면 Register에 생성이 되지만, 공간이 충분하지 않는다면 Automatic Variable로 취급하여 메모리의 스택에 위치하게 됩니다.

Posted by LaLuna

Analysis of Algorithm

Empirical analysis(경험적 분석)     : 알고리즘을 프로그래밍 언어로 구현을 한 뒤, 이를 실행시켜 실시간을 비교해 보는 것

Mathematical analysis(수학적 분석) : 알고리즘을 프로그래밍 언어로 구현하지 않고, 단지 알고리즘 자체만으로 수학적 분석을 하는 것

 

Best case and Worst case

Bast case  : 가장 작은 시간과 공간을 필요로 하는 경우

Worst case : 가장 많은 시간과 공간을 필요로 하는 경우

- 어떠한 알고리즘의 일반적인 경우 다른 알고리즘에 비해 매우 성능이 뛰어나나 최악의 경우에 많은 시간과 공간을 필요로 할 수 있는 현상이 있고, 어떤 알고리즘의 일반적인 경우는 다른 알고리즘에 비해 성능은 떨어지나 최악의 경우에도 일반적인 경우와 별 차이가 없는 현상이 있다.

- 최악의 경우는 알고리즘의 성능을 표현하는데 많이 쓰인다. 알고리즘의 속도를 표현할 때, 아무리 많은 시간과 공간이 필요한다 해도 최악의 경우를 넘지 않는다는 것을 보증할 때 쓰인다.

 

평균적 경우라는 개념도 존재하는데, 평균적인 경우를 사용하는 데에는 몇 가지의 문제점이 있다.

1. 평균적인 경우 자체가 수학적으로 매우 어려운 개념이라 확정짓기가 어렵다.

2. 평균적인 경우가 실제의 상황과 같지 않다는 점이다.

 

● 알고리즘의 분석의 단계

1. 알고리즘을 판단할 수 있는 입력자료 결정
2.
알고리즘을 구성하는 동작들을 추상적이고 기본적인 동작들로 분해하여 동작들의 수행시간을 계산
3.
수학적인 알고리즘 분석


 

알고리즘의 유형

 

알고리즘의 분석 결과는 입력되는 자료의 수 N에 대한 수행시간을 함수 관계로 표현

★ 1

입력자료 수에 관계없이 일정한 실행시간을 갖는 알고리즘

★ log N

입력자료 수에 따라 실행시간이 조금씩 늘어남. 주로 커다란 문제를 일정한 크기를 갖는 작은 문문제 쪼갤 때 나타는 유형

★ N

입력 자료수에 따라 선형적으로 실행시간이 걸리는 경우.

★ N log N

커다란 문제를 독립적인 작은 문제로 쪼개어 각각 해결하고 나중에 다시 하나로 합치는 경우.

★ N2

이중 루프 내에서 입력자료를 처리하는 경우.

★ N3

삼중 루프 내에서 입력자료를 처리하는 경우.

★ 2N

 입력자료의 수가 늘어남에 따라 급격한 실행시간의 증가.

 

사용자 삽입 이미지

 

Posted by LaLuna
//
//      One-Dimension Array.c : Example of One-Dimension array
//
//                      Programmed By Clipper
//  Copyright ⓒ 2007 LaLuna All Rights Reserved.
//

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

#define MAX 10

int average(int a[], int n) /* int a[]을 int *a로 바꾸어 줘도 괜찮다.*/
{
    int sum = 0;
    int i;

    for(i = 0; i < n; i++)
    {
        sum    += a[i];
    }

    return (sum/n);
}

int main(void)
{
    int array[MAX];
    int i;

    printf("정수를 10개만 입력하세요 : ");
    for(i = 0 ; i < MAX ; i++)                  /* MAX개의 정수를 입력받아 배열에 저장 */
    {
        scanf("%d", array + i);               /* array+i는 &array[i]와 같다. */
    }
    printf("입력하신 정수 %d개의 평균은 %d입니다.\n", MAX, average(array, MAX));
    /* 배열명과 크기를 넘긴다. */
    system("pause");
    return 0;
}
배열을 parameter로 넘겨주는 함수이다.

방법은 포인터로 표현하는 방법과 배열로 표현하는 방법이 있지만 이 두가지 방법은 완전히 같다.

C에서는 배열의 크기를 메모리에 공간이 할당될때만 신경을 쓰고, 실행시에는 배열의 크기에 대해서는 컴파일러가 신경을 써주지 않는다. 이러한 이유로 인해서 average() 함수는 n이라는 배열의 크기를 인자로 따로 받는다. 그리고 인자로 받는 배열 a도  []로 배열표시만 해줄뿐 크기를 명시하지 않는다.
(크기를 명시한다 해도 컴파일러는 이를 무시한다.)


배열은 포인터와 동일한 표현이므로 위의 average()를 포인터의 표현으로 바꿀 수 있다.

int average(int *a, int n)                     /* 포인터로 표현 */

Posted by LaLuna
//
//      HelloWorld.cs
//
//                      Programmed By Clipper
//  Copyright ⓒ 2007 LaLuna All Rights Reserved.
//


namespace Clipper{
    class Helloworld {
       static void Main() {
          System.Console.WriteLine("Hello World~!");
       }
    }
}
이것이 C#의 Hello World랍니다. ㅎㅎ

Java와 많이 비슷하죠?

C나 C++, 그리고 Java와 다르게 main()함수의 첫글자가 대문자이네요 ㅎ

정상적으로 Hello World~!가 출력이 된답니다.

참고로 Microsoft.NET FrameWork 가 설치되어 있어야 하는것 같아요

아직 C#은 Hello World~! 찍는 방법 뿐이 몰라서 문제내요 ㅎ

열심히 공부해야죠

Posted by LaLuna
//
//      HelloWorld.java
//
//                      Programmed By Clipper
//  Copyright ⓒ 2007 LaLuna All Rights Reserved.
//

public class HelloWorld {
    public static void main(String arg[])
    {
        System.out.println("HelloWorld~!");
    }
}
ㅎㅎ 이번엔 java로 Hello World~! 를 찍어봤어요.

뭐 전설적인 code인 Hello World~!

이거 찍을 수 있고, 이해를 한다면 당신은 이미 프로그래머의 길에 들어선 겁니다.
Posted by LaLuna

Hello World~!

키보드질/C / C++ 2008. 1. 14. 19:13
#include <stdio.h>

int main(void)
{
    printf("Hello World~!");

    retunr 0;
}

그 유명한 Hello World~! 문구를 출력하는 소스입니다.

뭐 설명은 어디서든 보실 수 있고, C언어 기초 1장 부분에서 항상 나오는 코드이니

익숙하실 겁니다.

아직 블로그를 복구하느라 많이 힘들군요. 백업파일도 없어서 수동으로 복구를 할려니..

이제부터 항상 백업을 해놓는 습관을 들여야 겠습니다.

Posted by LaLuna
//
//      TIMER.H : Header file for timer macro
//
//                      Programmed By Clipper
//  Copyright ⓒ 2007 LaLuna All Rights Reserved.
//

#ifndef _TIMER_H
#define _TIMER_H

#include <time.h>

#define diff_clock(t1, t2) (double)((t2)-(t1))
#define diff_second(t1, t2) ((double)((t2)-(t1)) / CLOCKS_PER_SEC)

#endif

----------------------------------------------------------------------------------------------
사용 방법은

Data Type를 clock_t 로 하여 2개의 변수를 생성, 작동시간을 받아줄 float함수를 생성.

함수가 시작하는 부분에서 clock(); 함수로 시간을 받아주고, 끝나는 시점에서 받아준다음

끝나는시점 - 시작한시점 = 함수의 작동 시간

이 나옵니다.

예제로
        clock_t t1, t2;
        float = result;

        t1 = clock();
        for(i=0;i<LOOF;i++)
        {
            temp = get_gcd(u,v);
        }
        t2 = clock();
        result = diff_clock(t1,t2);

위와 같이 사용하시면 됩니다.
Posted by LaLuna
//
//      EUCLID1.C : Implementation of Euclid's Algorithm
//
//                      Programmed By Clipper
//  Copyright ⓒ 2007 LaLuna All Rights Reserved.
//

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

int get_gcd(int u, int v);          //뻴셈만을 이용한 유클리드 : 최대공약수
int gcd_modulus(int u, int v);      //나머지연산을 이용한 유클리드 : 최대공약수
int gcd_recursion(int u, int v);    //재귀호출을 이용한 유클리드 : 최대공약수

#define LOOF 10000000               //함수의 성능 테스트를 위한 반복 횟수

int main(int argc, char *argv[])
{
    int u, v, temp;
    clock_t t1, t2;                 //함수 측정시간을 정하기 위한 변수
    float result1 = 0, result2 = 0, result3 = 0;//함수 측정시간을 저장하기 위한 변수
    int i;
    
    puts("\n EUCLID1 : 두 양수의 최대 공약수 찾기 ");
    puts("\n           0을 입력하면 종료");
    
    while(1)
    {
        puts("\n\n 두 양수를 입력하세요 -> ");
        scanf("%d %d", &u, &v);
        
        if(u < 0 || v < 0)//음수의 입력은 무효로 한다.
        {
            puts("음수를 입력하셨습니다. 양수를 입력하세요\n");
            continue;
        }
        if(u == 0 || v == 0)//0이 입력되면 종료한다.
        {
            puts("0을 입력하셨습니다. 프로그램을 종료하겠습니다.\n");
            break;
        }
        t1 = clock();
        for(i=0;i<LOOF;i++)
        {
            temp = get_gcd(u,v);
        }
        t2 = clock();
        result1 = diff_clock(t1,t2);//빼기, 교환 함수 시간 측정
        t1 = clock();
        for(i=0;i<:LOOF;i++)
        {
            temp = gcd_modulus(u,v);
        }
        t2 = clock();
        result2 = diff_clock(t1,t2);//나머지 함수 시간 측정

        t1 = clock();
        for(i=0;i<LOOF;i++)
        {
            temp = gcd_recursion(u,v);
        }
        t2 = clock();
        result3 = diff_clock(t1,t2);//재귀호출 시간측정
                
        printf("두 양수 %d와 %d의 최대 공약수는 %d입니다.(뺄셈과 교환)\n", u, v, get_gcd(u,v));
        printf("두 양수 %d와 %d의 최대 공약수는 %d입니다.(나머지연산)\n", u, v, gcd_modulus(u,v));
        printf("두 양수 %d와 %d의 최대 공약수는 %d입니다.(재귀호출)\n", u, v, gcd_recursion(u,v));
        printf("빼기연산 : %5.2f 나머지 연산 : %5.2f 재귀호출 연산 : %5.2f", result1, result2, result3);
    }
    system("pause");
    return 0;
}

int get_gcd(int u, int v)
{
    int temp;
    while(u)//u가 0이면 v를 리턴, 아니면 루프를 돈다.
    {
        if(u < v)//u가 v보다 작으면 교환한다.
        {
            temp = u;
            u = v;
            v = temp;
        }
        u = u - v;
    }
    return v;
}

int gcd_modulus(int u, int v)
{
    int t;
    while(v)//v가 0이면 u를 리턴, 아니면 루프를 돈다.
    {
        t = u % v;
        u = v;
        v = t;
    }
    
    return u;
}
   
int gcd_recursion(int u, int v)
{
    if(v == 0)
    {
        return u;
    }
    else
    {
        return gcd_recursion(v, u%v);//재귀호출을 이용하여 나머지 연산
    }
}

Posted by LaLuna
이전페이지 1 2 3 4 다음페이지
위로

사이드바 열기