사이드바 열기

이놈의 codepad css 글꼴하고 글자폭 높이 조절이 힘드네


Posted by LaLuna

사용자 삽입 이미지


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

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

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

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

손가락도 잃었느니라.


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

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

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


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

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

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

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

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

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
//
//      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

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
//
//      PRIME.C : Prime algorithm
//
//                      Programmed By Clipper
//  Copyright ⓒ 2007 LaLuna All Rights Reserved.
//

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

#define LOOF 1000000

int is_prime(int n);                                                            //2에서 n-1까지 나누어서 소수판별 
int is_prime_sqrt(int n);                                                       //2에서 sqrt(N)까지 나누어서 소수 판별 

int main(void)
{
    int n, i, j;
    clock_t t1, t2;                                                             //성능측정 변수 
    double result1, result2;                                                    
    
    puts(" 소수구하기 : 입력한 수가 소수인지 아닌지 판별합니다.\n");
    puts("              0 을 입력하면 프로그램이 종료됩니다.\n");
    
    while(1)
    {
        puts("\n판별할 숫자를 입력하십시오 : ");
        scanf("%d", &n);
        
        if(n < 0)
        {
            puts("입력하신 숫자는 음수입니다. 양수를 입력해 주세요\n");         //N이 음수이면 재입력 
            continue;
        }
        if(n == 0)
        {
            puts("프로그램을 종료합니다.\n");                                   //N이 0이면 프로그램을 종료 
            break;
        }
        
        printf("입력하신 수 %d는 %s\n", n, is_prime(n) ? "소수입니다.":"소수가 아닙니다.");
        printf("입력하신 수 %d는 %s\n", n, is_prime_sqrt(n) ? "소수입니다.":"소수가 아닙니다.");
        }
}
       
Posted by LaLuna
History of C Language

(1) The birth of C language and A process of development

C 언어는 1972년에 미국 'Bell' 연구소의 연구원 'Dennis Ritchie'에 의해 개발된 Programing Language이다.
1969년 Bell 연구소에서는 DEC사의 PDP-7이라는 대형 컴퓨터에 사용할 목적으로, UNIX라고 하는 OS(Operation System)을 개발하는 역사적인 Project에 착수하였다. 그러나, 초기의 UNIX는 특정 System의 Hardware에 의존하는 Assembly Language로 작성되어 있어서, 다른 컴퓨터 기종에서는 사용할 수 없는, 큰 단점을 가졌다. 비슷한 시기에 Bell 연구소의 연구원 Ken Thompson은 BCPL이라는 기존의 System Programing Language를 기본으로 하여 Compatibility가 높은 High Level Language인 B Language를 개발하였다.
Dennis Ritchie는 UNIX Operation System의 개발을 맡고 있었는데 운영체제는 그 특성상 하드웨어를 직접 제어할 수 있어야 했다. 또한 당시의 컴퓨터 환경이 지금과는 달라 CPU의 속도나 Memory의 용량이 충분하지 않았기 때문에 Program의 크기는 작아야 했고 속도는 빨라야 했다.
이런 모든 요구를 만족시킬 수 있는 유일한 언어는 Assembly Language뿐이었다. 그러나 Assembly Language는 특정 기계에 종속적이며 이식성이 없기 때문에 여러 Platform에 수정없이 사용하는 것이 목적인 UNIX와는 잘 어울리지 않았다. C Language보다 먼저 발표된 Fortran이나 Basic같은 고급언어들은 효율이 좋지 못해 대형 프로젝트에 쓰기에는 역시 부적합하였다.
1972년 Dennis Ritchie는 B Language의 성능을 개선시켜 Assembly Language의 강력한 기능과 High Level Language의 이식성을 동시에 갖춘 C Language를 개발하였고, Assembly Language로 작성되었던 초기의 UNIX를 C language로 다시 작성하였다. 그 결과로 UNIX는 프로그램의 개발과 연구에 유용한 환경을 제공하는 훌륭한 OS로 새롭게 탄생하게 되었다.

C Language가 발표되기 전의 언어들은 각각 장단점이 있어서 특정 분야에서 독점적인 지위를 가지는 고유의 영역을 확보하고 있었다. 예를 들어 Pascal이나 Basic은 교육용 언어로 분류되었고, COBOL은 상업용 Software 작성에 효율적이었으며, Fortran은 과학 기술용 언어로 주로 사용되었다. 또한 LISP는 인공 지능 구현에 적합했으며 Assembly는 System Programing을 위한 최적의 언어였다. 그러나 이러한 분류는 모든 분야에서 강점을 보이는 범용의 C Language가 등장함으로써 의미를 잃게 되었다.
C Language는 1970년대를 지나면서 UNIX와 함게 점차 보급되기 시작하였고, 1980년대 이후로 PC(Personal Computer)의 대중화에 힘입어 MS-DOS 등에서도 광범위하게 사용되었다. 그러나 Dennis Ritchie가 처음 C Language를 Design할 때에 비해 컴퓨터 환경이 많이 변해 비효율적인 면들이 점점 들어나기 시작했으며 또한 애매한 문법들이 존재했었다.
각 컴파일러 개발사들은 경쟁적으로 수많은 C컴파일러를 발표했다. 각 제작사들은 시장의 요구와 필요에 따라 조금씩 언어의 기능을 확장함으로써 C언어에도 많은 변종들이 생겨나게 되었다. 이렇게 되면 작성한 컴파일러에 따라 소스 차원의 호환성이 없어지는 문제점이 있으며 이는 사회적으로 큰 낭비를 초래하였다. 변화된 환경에 적응하고 경쟁으로 인해 훼손된 이식성을 복구하기 위해서는 표준의 제정이 절실히 필요해졌다. 그래서 ANSI는 83년부터 표준 제정작업에 들어가 89년에 표준안을 완성했으며 90년에 ISO에 의해 승인(ISO9899)되었다. 이때 제정된 C 표준을 ANSI C(또는 C90)라고 하며 그 이전의 C를 Classic C(K&R C)라고 한다. ANSI C는 클래식 C에 비해 안전성을 높이고 애매한 기능을 정리하고 새로운 기능을 추가하게 된다.
최근엔 C Language의 기능에 OOP(Object Oriented Programing) 기법을 도입한 C++라는 새로운 언어가 주목을 받고 있다. C++는 새로운 언어이기는 하지만 C Language를 기본으로 하기 때문에 대부분의 상용 제품들은 C++환경에서 순수한 C grammar만으로도 Programing이 가능하도록 배려하고 있다.

ALGOL60⇒CPL⇒BCPL⇒B⇒C⇒C++

(2) ANSI(American Nation Standards Institute)-C

UNIX를 개발하는 과정에서 탄생한 C Language는 초기에 OS와 같은 System Program의 작성을 위하여 일부 전문가들만이 사용하였다. 그러나 시간이 지날수록 C Language가 가지고 있는 여러 가지 특징과 장점이 대학과 연구 기관을 중심으로 일반 대중들에게 소개되기 시작하였고, 또한 Hardware Technology의 발전으로 PC가 대중화되면서 UNIX System에서만 수행될 수 있었던 여러 가지 복잡한 작업들이 PC에서도 충분히 수행될 수 있게 되었다. 따라서 많은 Software 개발 회사들은 PC에서도 C Language를 쉽게 사용할 수 있도록 다양한 C Compiler를 개발하게 된다. 더욱이 Compiler는 일종의 상품이기 때문에 타사 제품과 차별화되는 기능이 있어야 하고 변화된 환경에 적응할 수 있는 새로운 기능을 추가할 필요가 있다. 각 제작사들은 시장의 요구와 필요에 따라 조금씩 언어의 기능을 확장함으로써 C Language에서도 많은 변종이 생겨나게 되었다. 이렇게 되면 작성한 Compiler에 따라 Source 차원의 호환성이 없어지는 문제점이 있으며 이는 사회적으로 큰 낭비를 초래하였다.
위에 언급하였듯이, ANSI에서 표준을 제정하게 된다. ANSI-C라 불리는 표준 C Language는 안전성, 문법의 정리와 더불어 새로운 기능을 추가하였다.

① Standard Library Function의 규격화, Header File 통일
② Prototype Function 선언 기능 추가(컴파일러의 함수호출부에서 타입체크)
③ 정수, 실수 상수의 type를 지정할 수 있는 L, U, F 등의 접미어 추가
④ enum, void 형과 const, volatile 제한자 추가
⑤ 인접 문자열 상수를 합쳐 주고 확장열의 기능 추가
⑥ 함수 내부에서 선언하는 지역배열이나 구조체의 초기화
⑦ 구조체끼리 대입할 경우 구조체 크기만큼 메모리 복사

이후에도 C표준은 지속적으로 확장되었는데 95년에 유럽과 동양의 언어를 지원하기 위한 멀티 바이트 문자 지원이 추가되었다. 이때 제정된 C 표준을 C95라고 하는데 ANSI C에 비해 언어의 기능상 큰 변화는 없었다.
Posted by LaLuna
이전페이지 1 다음페이지
위로

사이드바 열기