아래의 소스는

            Visual Studio 2008 Express (Visual C++ 9.0),
            GNU C 3.4.4 (gcc), 
            Borland C++ 5.5 (free)
            Digital Mard (free) 

C 컴파일러에서 한글도 잘 처리됨을 확인하였다.  그러나 Bloodshed Dev-C++ 에서는 gets()에 의한 한글 입력과 printf()에 의한 한글 출력이 되지 않았다.


/*
 *  inputTest.c
 *
 *  Compile:
 *          gcc inputTest.c
 *          dmc inputTest.c
 *          bcc32 inputTest.c
 *          cl inputTest.c
 *
 *  Execute:
 *          inputTest 2
 */

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

void printStr(char **);

int main(int argc, char **argv) {
    char temp[80];
    char **str;
    int max;
    int i;

    if (argc != 2) {
        printf("Usage: inputTest <숫자>\n");
        exit(1);
    }

    max = atoi(argv[1]); // 문자열을 수치값으로 변환
    str = (char **)malloc((max+1) * sizeof(char *));

    i=0;
    while (1) {
        printf("%d째 문자열을 입력하세요> ", i+1);
        gets(temp);
        if (temp[0] == '\0')
            break;

        str[i] = (char *)malloc(strlen(temp) + 1);
        strcpy(str[i], temp);
        i++;
        if (i == max) {
            printf("문자열 입력을 완료했습니다.\n");
            break;
        }
    }

    str[i] = 0;
    printStr(str);
    i = 0;
    while (str[i] != 0) {
        free(str[i]);
        ++i;
    }
    free(str);
    return 0;
}

void printStr(char **sp) {
    while (*sp != 0) {
        printf("%s \n", *sp);
        sp++;
    }
}





실행 결과:
프롬프트> inputTest 2
1째 문자열을 입력하세요> 하나
2째 문자열을 입력하세요> 둘
문자열 입력을 완료했습니다.
하나

Posted by Scripter
,

다음은 초등학교에서 배우는 나눗셈 계산표를 만들어주는 C 소스 코드이다.
나눗셈 계산표를 완성하고 나서 약수, 배수 관계를 알려준다.


  1. /*
  2.  *  Filename: makeDivisionTable.c
  3.  *
  4.  *  Purpose:  Make a division table in a handy written form.
  5.  *
  6.  *  Compile: cl makeDivisionTable.c
  7.  *
  8.  *  Execute: makeDivisionTable 12345 32
  9.  *           makeDivisionTable 500210 61
  10.  *
  11.  *     Date:  2008/05/15
  12.  *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
  13.  */
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <math.h>
  17. #include <memory.h>
  18. enum { FALSE, TRUE };
  19. void println(char s[]) {
  20.     printf("%s\n", s);
  21. }
  22. void print(char s[]) {
  23.     printf("%s", s);
  24. }
  25. void printUsage() {
  26.     // println("Using: makeDivisionTable [numerator] [denominator]");
  27.     // println("Make a division table in a handy written form.");
  28.     println("사용법: makeDivisionTable [피제수] [제수]");
  29.     println("손으로 작성한 형태의 나눗셈 표를 만들어준다.");
  30. }
  31. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  32. // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  33. char *simplify(double v, int width) {
  34.     int n, len;
  35.     static char t[] = "                               ";
  36.     char tmp[] = "                               ";
  37.     sprintf(t, "%g", v);
  38.     n = strlen(t);
  39.     if ((n > 2) && (t[n - 2] == '.') && (t[n - 1] == '0'))
  40.         t[n-2] = '\0';
  41.     len = strlen(t);
  42.     strcpy(tmp, t);
  43.     if (len < width) {
  44.         strncpy(t, "               ", width - len);
  45.         t[width - len] = '\0';
  46.         strcat(t, tmp);
  47.     }
  48.     return (char *) t;
  49. }
  50. // 발음상 숫자에 맞는 주어 조사 "은", "는"을 결정한다.
  51. void getSuffix(char *buf, long v) {
  52.     long t = v % 10L;
  53.     char suffix[3];
  54.     char tbuf[2];
  55.     char suf[2][3] = { "은",  "는"};
  56.     strcpy(suffix, suf[0]);
  57.     sprintf(tbuf, "%d", t);
  58.     if (strchr("2459", tbuf[0]) != NULL) {
  59.         strcpy(suffix, suf[1]);
  60.     }
  61.     strcpy(buf, suffix);
  62. }
  63. long makeTable(long numer, long denom, long quotient) {
  64.     char sbuf[81];
  65.     char strNumer[40];
  66.     char strDenom[40];
  67.     char strQuotient[40];
  68.     char strTmpR[40];
  69.     char whiteChars[] = "                                                                                 ";
  70.     char underbarChars[]  = "_________________________________________________________________________________";
  71.     char barChars[]  = "---------------------------------------------------------------------------------";
  72.     char offsetSpaces[81];
  73.     char biasSpaces[81];
  74.     char spaces[81];
  75.     char uline[81];
  76.     char sline[81];
  77.     int i;
  78.     int lenN;
  79.     int lenD;
  80.     int lenQ;
  81.     int offsetLeft;
  82.     int bias;
  83.     long tmpR;
  84.     long tmpSub;
  85.     char oneDigit;
  86.     sprintf(strNumer, "%ld", numer);
  87.     sprintf(strDenom, "%ld", denom);
  88.     sprintf(strQuotient, "%ld", quotient);
  89.     lenN = strlen(strNumer);
  90.     lenD = strlen(strDenom);
  91.     lenQ = strlen(strQuotient);
  92.     offsetLeft = 3 + lenD + 3;
  93.     bias = lenN - lenQ;
  94.     strncpy(offsetSpaces, whiteChars, offsetLeft);
  95.     offsetSpaces[offsetLeft] = '\0';
  96.     strncpy(biasSpaces, whiteChars, bias);
  97.     biasSpaces[bias] = '\0';
  98.     strncpy(uline, underbarChars, lenN + 2);
  99.     uline[lenN + 2] = '\0';
  100.     strncpy(sline, barChars, lenN);
  101.     sline[lenN] = '\0';
  102.     printf("%s%s%ld\n", offsetSpaces, biasSpaces, quotient);
  103.     sprintf(sbuf, offsetSpaces);
  104.     sbuf[offsetLeft - 2] = '\0';
  105.     printf("%s%s\n", sbuf, uline);
  106.     printf("   %s ) %s", strDenom, strNumer);
  107.     strncpy(strTmpR, strNumer, bias + 1);
  108.     strTmpR[bias + 1] = '\0';
  109.     tmpR = atoi(strTmpR);
  110.     tmpSub = 0L;
  111.     for (i = 0; i < lenQ; i++) {
  112.         if (strQuotient[i] == '0') {
  113.             if (i + 1 < lenQ) {
  114.                 oneDigit = strNumer[bias + i + 1];
  115.                 printf("%c", oneDigit);
  116.                 sprintf(sbuf, "%c", oneDigit);
  117.                 strcat(strTmpR, sbuf);
  118.                 tmpR = atoi(strTmpR);
  119.             }
  120.         }
  121.         else {
  122.             println("");
  123.             tmpSub = (long)(strQuotient[i] - '0') * denom;
  124.             printf("%s%s\n", offsetSpaces, simplify(tmpSub, bias + i + 1));
  125.             printf("%s%s\n", offsetSpaces, sline);
  126.             tmpR = tmpR - tmpSub;
  127.             if (tmpR == 0L && i + 1 < lenQ) {
  128.                 strncpy(sbuf, whiteChars, bias + i + 1);
  129.                 sbuf[bias + i + 1] = '\0';
  130.                 printf("%s%s", offsetSpaces, sbuf);
  131.             }
  132.             else {
  133.                 printf("%s%s", offsetSpaces, simplify(tmpR, bias + i + 1));
  134.             }
  135.             sprintf(strTmpR, "%ld", tmpR);
  136.             if (i + 1 < lenQ) {
  137.                 oneDigit = strNumer[bias + i + 1];
  138.                 printf("%c", oneDigit);
  139.                 sprintf(sbuf, "%c", oneDigit);
  140.                 strcat(strTmpR, sbuf);
  141.                 tmpR = atoi(strTmpR);
  142.             }
  143.         }
  144.     }
  145.     println("");
  146.     return tmpR;
  147. }
  148. // C/C++/Ch 언어의 실행 시작 지점
  149. int main(int argc, char *argv[]) {
  150.     int i;
  151.     int SIZE = argc - 2;
  152.     long a, b, q, r, k;
  153.     char mbuf[3];
  154.     if (argc < 3) {
  155.         printUsage();
  156.         exit(1);
  157.     }
  158.     a = atoi(argv[1]);
  159.     b = atoi(argv[2]);
  160.     if (a <= 0L) {
  161.         printf("피제수: %ld\n", a);
  162.         println("피제수는 양의 정수라야 합니다.");
  163.         exit(1);
  164.     }
  165.     if (b <= 0L) {
             printf("제수: %ld\n", b);
  166.          println("제수는 양의 정수라야 합니다.");
  167.          exit(1);
  168.     }
  169.     q = a / b;
  170.     r = a % b;
  171.     printf("나눗셈 %ld ÷ %ld 의 결과: ", a, b);
  172.     printf("몫: %ld, ", q);
  173.     printf("나머지: %ld\n", r);
  174.     println("");
  175.     k = makeTable(a, b, q);
  176.     if (k == r) {
  177.         printf("\n나머지: %ld\n", k);
  178.     }
  179.     if (k == 0L) {
  180.         printf("%ld = %ld x %ld\n", a, b, q);
  181.         getSuffix(mbuf, a);
  182.         printf("%ld%s %ld의 배수(mupltiple)이다.\n", a, mbuf, b);
  183.         getSuffix(mbuf, b);
  184.         printf("%ld%s %ld의 약수(divisor)이다.\n", b, mbuf, a);
  185.     }
  186.     else {
  187.         getSuffix(mbuf, a);
  188.         printf("%ld = %ld x %ld + %ld\n", a, b, q, r);
  189.         printf("%ld%s %ld의 배수(mupltiple)가 아니다.\n", a, mbuf, b);
  190.     }
  191.     return 0;
  192. }




실행> makeDivisionTable 500210 61

나눗셈 500210 ÷ 61 의 결과: 몫: 8200, 나머지: 10

          8200
      ________
   61 ) 500210
        488
        ------
         122
         122
        ------
            10

나머지: 10
500210 = 61 x 8200 + 10
500210은 61의 배수(mupltiple)가 아니다.



 

Posted by Scripter
,

콘솔에 삼각형

         *
       * *
      *   *
     *     *
    *       *
   *         *
  *           *
 *             *
*****************


을 출력하는 C 애플리케이션을 만들어 보자. 이런 소스 코드의 작성은 학원이나 학교에서 프로그래밍 입문자에게 과제로 많이 주어지는 것 중의 하나이다. 코끼리를 보거나 만진 사람들이 저마다 그 생김새를 말할 때 제각기 다르게 표현할 수 있듯이 이런 소스 코드의 작성도 알고 보면 얼마든지 많은 방법이 있을 것이다. 여기서는 쉬운 코드 부터 작성해 보고 차츰차츰 소스를 바꾸어 가면서 C 프로그래밍의 기초부분을 터득해 보기로 한다.

삼각형 출력 부분을 main() 함수에서 하지 않고, 별도로 구현된 printTriange() 함수에서 하기로 한다.

우선 첫번 째 예제는 C 언어의 컨솔 출력 함수 printf() 의 사용법 만 알면 누구나 코딩할 수 있는 매우 단순한 소스 코드이다.


삼각형 출력 예제 1
/*
 *  Filename: printTriangle1.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle1.c
 *  Execute: printTriangle1
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#include <stdio.h>

void println(const char *s) {
 printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

void printTriange() {
    println("        *        ");
    println("       * *       ");
    println("      *   *      ");
    println("     *     *     ");
    println("    *       *    ");
    println("   *         *   ");
    println("  *           *  ");
    println(" *             * ");
    println("*****************");
}

void main(int argc, char *argv) {
    printTriange();
}




위의 소스 코드는 아무 알고리즘도 없는 너무 단순한 코드이다. 이런 코드를 작성했다간 출력 모양이나 크기를 변경해야 하는 상황을 맞이하면 워드프로세서로 문서 만드는 것 이상으로 많은 수작업을 하거나 아니면 포기하는 지경에 이를 수도 있다. 그래서 다음 처럼 좀 더 나은 소스 코드를 작성하였다.



삼각형 출력 예제 2
/*
 *  Filename: printTriangle2.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle2.c
 *  Execute: printTriangle2
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#include <stdio.h>

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

void printTriange() {
    int i, k;
    for (i = 0; i < 8; i++) {
        for (k = 0;  k < 8 - i; k++) {
            print(" ");
        }
        for (k = 0;  k < 2*i + 1; k++) {
            if (k == 0 || k == 2*i)
                print("*");
            else
                print(" ");
        }
        for (k = 0;  k < 8 - i; k++) {
            print(" ");
        }
        println("");
    }
    for (i = 0; i < 17; i++) {
        print("*");
    }
    println("");
}

void main(int argc, char *argv) {
    printTriange();
}



위의 소스 코드는 컨솔 출력 함수 printf() 와  for 구문을 적절히 사용하여 구현되었다. 숫자 몇 곳만 수정하면 출력되는 삼각형의 크기를 바꿀 수 있다. 한 줄에 출력될 문자를 구성하는 알고리즘은 위의 예제와 근본적으로 같지만 char[] 과 char * 타입의 변수를 적절히 사용하여 한 즐씩 출력하는 소스 코드를 다음 예제와 같이 작성해 보았다.



삼각형 출력 예제 3
/*
 *  Filename: printTriangle3.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle3.c
 *  Execute: printTriangle3
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

void printTriange() {
    char line[] = "                 ";
    char line2[] = "                 ";
    char *pline2 = (char *) line2;
    int i, k;
    for (i = 0; i < 8; i++) {
        strcpy(pline2, line);
        pline2[8-i] = '*';
        pline2[8+i] = '*';
        println(line2);
    }

    strcpy(pline2, line);
    for (i = 0; i < 17; i++) {
        pline2[i] = '*';
    }
    println(line2);
}

void main(int argc, char *argv) {
    printTriange();
}




별(*) 문자를 이용하여 삼각형을 출력하는 일은 빈칸  문자와 별 문자를 적당한 좌표(위치)에 촐력하는 일이다. 기본 문자열을 빈칸 만으로로 구성된 문자열로 하고, 이 st문자열에 한 두 개의 빈칸을 별(*) 문자로 바꾸어 출력하는 기법으로 작성한 것이 다음 소스 코드이다. 단, 마지막 줄에 츨력될 문자열은 stars라는 별도의 변수로 처리하였다.



삼각형 출력 예제 4
/*
 *  Filename: printTriangle4.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle4.c
 *  Execute: printTriangle4
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

void printTriange() {
    char whites[] = "                 ";
    char stars[]  = "*****************";
    char line2[]  = "                 ";
    int i;
    strncpy(line2 + 8, "*", 1);
    println(line2);
    for (i = 1; i < 8; i++) {
        strcpy(line2, whites);
        strncpy(line2 + 8 - i, "*", 1);
        strncpy(line2 + 8 + i, "*", 1);
        println(line2);
    }
    println(stars);
}

void main(int argc, char *argv) {
    printTriange();
}




빈칸 문자를 별(*) 문자로 바꾸기 위해, 위의 소스 코드에서는 strcpy() 함수를 이용하였지만, 다음 소스 코드에서는 str[인덱스] = 문자 의 구문을 이용하였다.



삼각형 출력 예제 5
/*
 *  Filename: printTriangle5.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle5.c
 *  Execute: printTriangle5
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

void printTriange() {
    char whites[] = "                 ";
    char stars[]  = "*****************";
    char line[]  = "                 ";
    int i;
    int start = 8;
    line[start] = '*';
    println(line);
    for (i = 1; i < 8; i++) {
        strcpy(line, whites);
        line[start - i] = '*';
        line[start + i] = '*';
        println(line);
    }
    println(stars);
}

void main(int argc, char *argv) {
    printTriange();
}




출력되는 삼각형이 좌우 대칭이라는 사실에 착안하여, 다음 소스 코드에서는 각 줄을 처음 8자, 중앙 한 문자, 끝 8자(처음 8자의 역순)로 string을 만들어 출력하였다.



삼각형 출력 예제 6
/*
 *  Filename: printTriangle6.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle6.c
 *  Execute: printTriangle6
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

void reverse(char *s) {
    int n = strlen(s);
    int i;
    char c;
    for (i = 0; i < n/2; i++) {
        c = s[n - i - 1];
        s[n - i - 1] = s[i];
        s[i] = c;
    }
}

void printTriange() {
    char whites[] = "        ";
    char stars[]  = "********";
    char *pline = NULL;
    int i;
    int start = 8;

    pline = (char *) calloc(sizeof(char), 17 + 1);
    if (pline != NULL) {
        print(whites);
        print("*");
        println(whites);
        for (i = 1; i < 8; i++) {
            strcpy(pline, whites);
            pline[start - i] = '*';
            print(pline);
            print(" ");
            reverse(pline);
            println(pline);
        }
        print(stars);
        print("*");
        println(stars);

        free(pline);
    }
}

void main(int argc, char *argv) {
    printTriange();
}




다음 소스 코드는 한 줄에 출력될 문자열의 데이터를 17비트 이진법 수로 구성하고, 이 이진법수의 비트가 0인 곳에는 빈칸을, 1인 곳에는 별(*)을 출력하는 기법으로 작성되었다.



삼각형 출력 예제 7
/*
 *  Filename: printTriangle7.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle7.c
 *  Execute: printTriangle7
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

#define MAX_BUF 81

enum { FALSE, TRUE };

char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void convertItoA(char *pstr, long num, int radix) {
    char tmp[2];
    char ret[MAX_BUF];
    char arr[MAX_BUF];
    long q, r;
    int i, n;
    int isNegative = FALSE;
    if (num < 0L) {
        isNegative = TRUE;
        num = -num;
    }

    arr[0] = '\0';

    q = num;
    r = 0L;

    while (q >= (long) radix) {
        r = q % (long) radix;
        q = q / (long) radix;
        tmp[0] = BASE36[r];
        tmp[1] = '\0';
        strcat(arr, tmp);
    }
    tmp[0] = BASE36[q];
    tmp[1] = '\0';
    strcat(arr, tmp);
    if (isNegative) {
        strcat(arr, "-");
    }
    n = strlen(arr);
    for (i = 0; i < n; i++) {
        ret[i] = arr[n - i - 1];
    }
    ret[n] = '\0';
    strcpy(pstr, (char *) ret);
}

long convertAtoI(const char *pstr, int radix) {
    char tmp[2];
    long ret = 0L;
    char arr[MAX_BUF];
    long q, r;
    int isNegative = FALSE;

    int len = strlen(pstr);
    char c;
    int i;
    long val;

    c = pstr[0];
    if (c == '-') {
        isNegative = TRUE;
    }
    else if (c >= '0' && c <= '9') {
        ret = (long) (c - '0');
    }
    else if (c >= 'A' && c <= 'Z') {
        ret = (long) (c - 'A') + 10L;
    }
    else if (c >= 'a' && c <= 'z') {
        ret = (long) (c - 'a') + 10L;
    }
    if (ret >= (long) radix) {
        println("        Invalid character!");
        return ret;
    }

    for (i = 1; i < len; i++) {
        c = pstr[i];
        ret *= radix;
        if (c >= '0' && c <= '9') {
            val = (long) (c - '0');
        }
        else if (c >= 'A' && c <= 'Z') {
            val = (long) (c - 'A') + 10L;
        }
        else if (c >= 'a' && c <= 'z') {
            val = (long) (c - 'a') + 10L;
        }
        if (val >= (long) radix) {
            println("        Invalid character!");
            return ret;
        }
        ret += val;
    }

    return ret;
}

void printTriange() {
    int start = 0x100;
    int total = 0;
    int val = start;
    char data[18];
    int i, k;

    for (k = 0; k < 8; k++) {
        val = (start << k) | (start >> k);
        convertItoA(data, val, 2);
        for (i = 0; i < 17 - strlen(data); i++) {
            print(" ");
        }
        for (i = 0; i < strlen(data); i++) {
            if (data[i] == '0')
                print(" ");
            else
                print("*");
        }
        println("");
        total |= val;
    }
    val = (start << 8) | (start >> 8);
    total |= val;
    convertItoA(data, total, 2);
    for (i = 0; i < 17 - strlen(data); i++) {
        print(" ");
    }
    for (i = 0; i < strlen(data); i++) {
        if (data[i] == '0')
            print(" ");
        else
            print("*");
    }
    println("");
}

void main(int argc, char *argv) {
    printTriange();
}




기본적인 원리는 위의 소스 코드와 같지만 이진법수의 한 비트 마다 한 문자씩 츨력하는 대신에 출력된 한 줄의 문자열을 완성하여 이를 printf() 로 출력하는 기법으로 재작성한 것이 다음의 소스 코드이다. 자체 구현된 replaceAll() 함수를 이용하여, 모든 0을 빈칸으로, 모든 1을 별(*) 문자로 바꾸었으며, 별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 변수 total을 준비하였다. for 반복 구문의 블럭 내에서 구문

            total |= val;

이 하는 일이 무엇인지 이해할 수 있으면 좋다.




삼각형 출력 예제 8
/*
 *  Filename: printTriangle8.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle8.c
 *  Execute: printTriangle8
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

#define MAX_BUF 81

enum { FALSE, TRUE };

char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void convertItoA(char *pstr, long num, int radix) {
    char tmp[2];
    char ret[MAX_BUF];
    char arr[MAX_BUF];
    long q, r;
    int i, n;
    int isNegative = FALSE;
    if (num < 0L) {
        isNegative = TRUE;
        num = -num;
    }

    arr[0] = '\0';

    q = num;
    r = 0L;

    while (q >= (long) radix) {
        r = q % (long) radix;
        q = q / (long) radix;
        tmp[0] = BASE36[r];
        tmp[1] = '\0';
        strcat(arr, tmp);
    }
    tmp[0] = BASE36[q];
    tmp[1] = '\0';
    strcat(arr, tmp);
    if (isNegative) {
        strcat(arr, "-");
    }
    n = strlen(arr);
    for (i = 0; i < n; i++) {
        ret[i] = arr[n - i - 1];
    }
    ret[n] = '\0';
    strcpy(pstr, (char *) ret);
}

long convertAtoI(const char *pstr, int radix) {
    char tmp[2];
    long ret = 0L;
    char arr[MAX_BUF];
    long q, r;
    int isNegative = FALSE;

    int len = strlen(pstr);
    char c;
    int i;
    long val;

    c = pstr[0];
    if (c == '-') {
        isNegative = TRUE;
    }
    else if (c >= '0' && c <= '9') {
        ret = (long) (c - '0');
    }
    else if (c >= 'A' && c <= 'Z') {
        ret = (long) (c - 'A') + 10L;
    }
    else if (c >= 'a' && c <= 'z') {
        ret = (long) (c - 'a') + 10L;
    }
    if (ret >= (long) radix) {
        println("        Invalid character!");
        return ret;
    }

    for (i = 1; i < len; i++) {
        c = pstr[i];
        ret *= radix;
        if (c >= '0' && c <= '9') {
            val = (long) (c - '0');
        }
        else if (c >= 'A' && c <= 'Z') {
            val = (long) (c - 'A') + 10L;
        }
        else if (c >= 'a' && c <= 'z') {
            val = (long) (c - 'a') + 10L;
        }
        if (val >= (long) radix) {
            println("        Invalid character!");
            return ret;
        }
        ret += val;
    }

    return ret;
}

void replaceAll(char *str, char s, char t) {
    int i;
    for (i = 0; i < strlen(str); i++) {
    if (str[i] == s)
        str[i] = t;
    }
}

void printTriange() {
    char zeros[] = "00000000";
    int start = 0x100;
    int total = 0;
    int val = start;
    char data[17 + 1];
    char line[MAX_BUF];
    int i, k;

    for (k = 0; k < 8; k++) {
        val = (start << k) | (start >> k);
        convertItoA(data, val, 2);
        strncpy(line, zeros, 17 - strlen(data));
        line[17 - strlen(data)] = '\0';
        strcat(line, data);
        replaceAll(line, '0', ' ');
        replaceAll(line, '1', '*');
        println(line);
        total |= val;
    }
    val = (start << 8) | (start >> 8);
    total |= val;
    convertItoA(line, total, 2);
    replaceAll(line, '0', ' ');
    replaceAll(line, '1', '*');
    println(line);
}

void main(int argc, char *argv) {
    printTriange();
}




심각형의 좌우 대칭성과 char[] 타입의 자료를 이용하여 한 줄씩 출력하는 기법이다.
별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 변수 last를 준비하였다.



삼각형 출력 예제 9
/*
 *  Filename: printTriangle9.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle9.c
 *  Execute: printTriangle9
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

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

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

#define WIDTH 17

void printTriange() {
    int start = 8;
    char data[WIDTH];
    char last[WIDTH];
    int i, k;

    for (k = 0; k < WIDTH; k++) {
         data[k] = ' ';
         last[k] = ' ';
    }
    data[start] = '*';
    last[start] = '*';
    for (i = 0; i < WIDTH; i++) {
        printf("%c", data[i]);
    }
    println("");
    data[start] = ' ';

    for (k = 1; k < WIDTH/2; k++) {
        data[start - k] = '*';
        last[start - k] = '*';
        data[start + k] = '*';
        last[start + k] = '*';

        for (i = 0; i < WIDTH; i++) {
            printf("%c", data[i]);
        }
        println("");
        data[start - k] = ' ';
        data[start + k] = ' ';
    }

    last[start - WIDTH/2] = '*';
    last[start + WIDTH/2] = '*';
    for (i = 0; i < WIDTH; i++) {
        printf("%c", last[i]);
    }
    println("");
}

void main(int argc, char *argv) {
    printTriange();
}




다음 예제는 수학에서 xy-좌표평면에 점을 찍듯이 논리 구문

             (x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0)

가 참이 되는 위치에 별(*) 문자를 표시하는 기법으로 작성된 소스 코드이다.




삼각형 출력 예제 10
/*
 *  Filename: printTriangle10.c
 *            Print a triangle on console.
 *
 *  Compile: cl printTriangle10.c
 *  Execute: printTriangle10
 *
 *      Date:  2008/04/04
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#include <stdio.h>

void println(const char *s) {
    printf("%s\n", s);
}

void print(const char *s) {
    printf("%s", s);
}

#define WIDTH 17

void printTriange() {
    char a;
    int x, y;

    for (y = 0; y <= 8; y++) {
        for (x = 0; x <= 16; x++) {
            if ((x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0))
                a = '*';
            else
                a = ' ';
            printf("%c", a);
        }
        println("");
    }
}

void main(int argc, char *argv) {
    printTriange();
}



Posted by Scripter
,

ASCII(애스키)란 American Standard Code for Information Interchange의 줄임글로서, 영문자에 기초한 문자 인코딩이다.  이 문자 인코딩에는 C0 제어문자(C0 control character)도 포함되어 있다.  ( 참고:  ASCII - Wikipedia, the free encyclopedia )

다음은  7bit ASCII 코드표를 만들어 보여주는 C 언어 소스 코드이다. 소스 코드 중에 진법변환에 필요한 함수

        convertAtoI()
        convertItoA()

의 구현도 포함되어 있다.



  1. /*
  2.  *  Filename: makeAsciiTable.c
  3.  *            Make a table of ascii codes.
  4.  *
  5.  *  Compile: cl makeAsciiTable.c
  6.  *  Execute: makeAsciiTable
  7.  *
  8.  *      Date:  2008/03/27
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #define MAX_BUF 81
  15. enum { FALSE, TRUE };
  16. void println(char s[]) {
  17.     printf("%s\n", s);
  18. }
  19. void print(char s[]) {
  20.     printf("%s", s);
  21. }
  22. void printUsage() {
  23.     println("Usage: makeAsciiTable");
  24.     println("Make a table of ascii codes.");
  25. }
  26. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  27. void convertItoA(char *pstr, long num, int radix) {
  28.     char tmp[2];
  29.     char ret[MAX_BUF];
  30.     char arr[MAX_BUF];
  31.     long q, r;
  32.     int i, n;
  33.     int isNegative = FALSE;
  34.     if (num < 0L) {
  35.         isNegative = TRUE;
  36.         num = -num;
  37.     }
  38.     arr[0] = '\0';
  39.     q = num;
  40.     r = 0L;
  41.     while (q >= (long) radix) {
  42.         r = q % (long) radix;
  43.         q = q / (long) radix;
  44.         tmp[0] = BASE36[r];
  45.         tmp[1] = '\0';
  46.         strcat(arr, tmp);
  47.     }
  48.     tmp[0] = BASE36[q];
  49.     tmp[1] = '\0';
  50.     strcat(arr, tmp);
  51.     if (isNegative) {
  52.         strcat(arr, "-");
  53.     }
  54.     n = strlen(arr);
  55.     for (i = 0; i < n; i++) {
  56.         ret[i] = arr[n - i - 1];
  57.     }
  58.     ret[n] = '\0';
  59.     strcpy(pstr, (char *) ret);
  60. }
  61. long convertAtoI(const char *pstr, int radix) {
  62.     char tmp[2];
  63.     long ret = 0L;
  64.     char arr[MAX_BUF];
  65.     long q, r;
  66.     int isNegative = FALSE;
  67.     int len = strlen(pstr);
  68.     char c;
  69.     int i;
  70.     long val;
  71.     c = pstr[0];
  72.     if (c == '-') {
  73.        isNegative = TRUE;
  74.     }
  75.     else if (c >= '0' && c <= '9') {
  76.         ret = (long) (c - '0');
  77.     }
  78.     else if (c >= 'A' && c <= 'Z') {
  79.         ret = (long) (c - 'A') + 10L;
  80.     }
  81.     else if (c >= 'a' && c <= 'z') {
  82.         ret = (long) (c - 'a') + 10L;
  83.     }
  84.     if (ret >= (long) radix) {
  85.         println("        Invalid character!");
  86.         return ret;
  87.     }
  88.     for (i = 1; i < len; i++) {
  89.         c = pstr[i];
  90.         ret *= radix;
  91.         if (c >= '0' && c <= '9') {
  92.             val = (long) (c - '0');
  93.         }
  94.         else if (c >= 'A' && c <= 'Z') {
  95.             val = (long) (c - 'A') + 10L;
  96.         }
  97.         else if (c >= 'a' && c <= 'z') {
  98.             val = (long) (c - 'a') + 10L;
  99.         }
  100.         if (val >= (long) radix) {
  101.             println("        Invalid character!");
  102.             return ret;
  103.         }
  104.         ret += val;
  105.     }
  106.     return ret;
  107. }
  108. char asc[33][4]  = {
  109.      "NUL", "SOH", "STX", "ETX", "EOT",
  110.      "ENQ", "ACK", "BEL", "BS", "HT",
  111.      "LF", "VT", "FF", "CR", "SO",
  112.      "SI", "DLE", "DC1", "DC2", "DC3",
  113.      "DC4", "NAK", "SYN", "ETB", "CAN",
  114.      "EM", "SUB", "ESC", "FS", "GS",
  115.      "RS", "US", "Spc"
  116.  };
  117. char control[33][36]  = {
  118.         "NUL (null)",
  119.         "SOH (start of heading)",
  120.         "STX (start of text)",
  121.         "ETX (end of text)",
  122.         "EOT (end of transmission)",
  123.         "ENQ (enquiry)",
  124.         "ACK (acknowledge)",
  125.         "BEL (bell)",
  126.         "BS  (backspace)",
  127.         "TAB (horizontal tab)",
  128.         "LF  (line feed, NL new line)",
  129.         "VT  (vertical tab)",
  130.         "FF  (form feed, NP new page)",
  131.         "CR  (carriage return)",
  132.         "SO  (shift out)",
  133.         "SI  (shift in)",
  134.         "DLE (data link escape)",
  135.         "DC1 (device control 1)",
  136.         "DC2 (device control 2)",
  137.         "DC3 (device control 3)",
  138.         "DC4 (device control 4)",
  139.         "NAK (negative acknowledge)",
  140.         "SYN (synchronous idle)",
  141.         "ETB (end of trans. block)",
  142.         "CAN (cancel)",
  143.         "EM  (end of medium)",
  144.         "SUB (substitute, EOF end of file)",
  145.         "ESC (escape)",
  146.         "FS  (file separator)",
  147.         "GS  (group separator)",
  148.         "RS  (record separator)",
  149.         "US  (unit separator)",
  150.     };
  151. void makeTable() {
  152.     char sbuf[MAX_BUF];
  153.     char abuf[MAX_BUF/2];
  154.     char tbuf[MAX_BUF/2];
  155.     int i, j;
  156.     unsigned char c;
  157.     print("    ");
  158.     for (i = 0; i < 8; i++) {
  159.         print("+----");
  160.     }
  161.     print("+");
  162.     println("");
  163.     print("    ");
  164.     print("| 0- ");
  165.     print("| 1- ");
  166.     print("| 2- ");
  167.     print("| 3- ");
  168.     print("| 4- ");
  169.     print("| 5- ");
  170.     print("| 6- ");
  171.     print("| 7- ");
  172.     print("|");
  173.     println("");
  174.     print("+---");
  175.     for (i = 0; i < 8; i++) {
  176.         print("+----");
  177.     }
  178.     print("+");
  179.     println("");
  180.     for (i = 0; i < 16; i++) {
  181.         tbuf[0] = '\0';
  182.         convertItoA(sbuf, (long) i, 16);
  183.         strcat(tbuf, "| ");
  184.         strcat(tbuf, sbuf);
  185.         strcat(tbuf, " ");
  186.         for (j = 0; j < 8; j++) {
  187.             if (j*16 + i <= 32) {
  188.                 sprintf(abuf, "| %-3s", asc[j*16 + i]);
  189.             }
  190.             else if (j*16 + i == 127) {
  191.                 sprintf(abuf, "| %-3s", "DEL");
  192.             }
  193.             else {
  194.                 c = (char) (j*16 + i);
  195.                 sprintf(abuf, "| %2c ", c);
  196.             }
  197.             strcat(tbuf, abuf);
  198.         }
  199.         strcat(tbuf, "|");
  200.         println(tbuf);
  201.     }
  202.     print("+---");
  203.     for (i = 0; i < 8; i++) {
  204.         print("+----");
  205.     }
  206.     print("+");
  207.     println("");
  208.     println("");
  209.     for (i = 0; i < 16; i++) {
  210.         sprintf(sbuf, "%-30s",  control[i]);
  211.         sprintf(tbuf, "  %-34s",  control[i+16]);
  212.         print(sbuf);
  213.         println(tbuf);
  214.     }
  215. }
  216. void main(int argc, char *argv[]) {
  217.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  218.         printUsage();
  219.         exit(1);
  220.     }
  221.     makeTable();
  222. }




컴파일> cl makeAsciiTable.c

실행> makeAsciiTable

    +----+----+----+----+----+----+----+----+
    | 0- | 1- | 2- | 3- | 4- | 5- | 6- | 7- |
+---+----+----+----+----+----+----+----+----+
| 0 | NUL| DLE| Spc|  0 |  @ |  P |  ` |  p |
| 1 | SOH| DC1|  ! |  1 |  A |  Q |  a |  q |
| 2 | STX| DC2|  " |  2 |  B |  R |  b |  r |
| 3 | ETX| DC3|  # |  3 |  C |  S |  c |  s |
| 4 | EOT| DC4|  $ |  4 |  D |  T |  d |  t |
| 5 | ENQ| NAK|  % |  5 |  E |  U |  e |  u |
| 6 | ACK| SYN|  & |  6 |  F |  V |  f |  v |
| 7 | BEL| ETB|  ' |  7 |  G |  W |  g |  w |
| 8 | BS | CAN|  ( |  8 |  H |  X |  h |  x |
| 9 | HT | EM |  ) |  9 |  I |  Y |  i |  y |
| A | LF | SUB|  * |  : |  J |  Z |  j |  z |
| B | VT | ESC|  + |  ; |  K |  [ |  k |  { |
| C | FF | FS |  , |  < |  L |  \ |  l |  | |
| D | CR | GS |  - |  = |  M |  ] |  m |  } |
| E | SO | RS |  . |  > |  N |  ^ |  n |  ~ |
| F | SI | US |  / |  ? |  O |  _ |  o | DEL|
+---+----+----+----+----+----+----+----+----+

NUL (null)                      DLE (data link escape)
SOH (start of heading)          DC1 (device control 1)
STX (start of text)             DC2 (device control 2)
ETX (end of text)               DC3 (device control 3)
EOT (end of transmission)       DC4 (device control 4)
ENQ (enquiry)                   NAK (negative acknowledge)
ACK (acknowledge)               SYN (synchronous idle)
BEL (bell)                      ETB (end of trans. block)
BS  (backspace)                 CAN (cancel)
TAB (horizontal tab)            EM  (end of medium)
LF  (line feed, NL new line)    SUB (substitute, EOF end of file)
VT  (vertical tab)              ESC (escape)
FF  (form feed, NP new page)    FS  (file separator)
CR  (carriage return)           GS  (group separator)
SO  (shift out)                 RS  (record separator)
SI  (shift in)                  US  (unit separator)


Posted by Scripter
,

컴퓨터 프로그래밍에서 꼭 알아두어야 할 주요 진법은 당연히 10진법, 2진법, 8진법, 16진법이다.
다음은  0 에서 15 까지의 정수를 10진법, 2진법, 8진법, 16진법의 표로 만들어 보여주는 C 소스 코드이다. 진법 변환에 필요한 함수

        convertAtoI(string, radix)
        convertItoA(long, radix)

를 C 코드로 자체 작성하여 사용하였다.
(Ch를 사용하면 컴파일 과정 없이 소스 코드를 그대로 실행시킬 수 있다.)



  1. /*
  2.  *  Filename: makeRadixTable.c
  3.  *            Show the radix table with 10-, 2-, 8-, 16-radices.
  4.  *
  5.  *  Compile: cl makeRadixTable.c
  6.  *  Execute: makeRadixTable
  7.  *
  8.  *      Date:  2008/03/27
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #define MAX_BUF 81
  15. enum { FALSE, TRUE };
  16. void println(char s[]) {
  17.     printf("%s\n", s);
  18. }
  19. void print(char s[]) {
  20.     printf("%s", s);
  21. }
  22. void printUsage() {
  23.     println("Usage: makeRadixTable");
  24.     println("Show the radix table with 10-, 2-, 8-, 16-radices.");
  25. }
  26. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  27. void convertItoA(char *pstr, long num, int radix) {
  28.     char tmp[2];
  29.     char ret[MAX_BUF];
  30.     char arr[MAX_BUF];
  31.     long q, r;
  32.     int i, n;
  33.     int isNegative = FALSE;
  34.     if (num < 0L) {
  35.         isNegative = TRUE;
  36.         num = -num;
  37.     }
  38.     arr[0] = '\0';
  39.     q = num;
  40.     r = 0L;
  41.     while (q >= (long) radix) {
  42.         r = q % (long) radix;
  43.         q = q / (long) radix;
  44.         tmp[0] = BASE36[r];
  45.         tmp[1] = '\0';
  46.         strcat(arr, tmp);
  47.     }
  48.     tmp[0] = BASE36[q];
  49.     tmp[1] = '\0';
  50.     strcat(arr, tmp);
  51.     if (isNegative) {
  52.         strcat(arr, "-");
  53.     }
  54.     n = strlen(arr);
  55.     for (i = 0; i < n; i++) {
  56.         ret[i] = arr[n - i - 1];
  57.     }
  58.     ret[n] = '\0';
  59.     strcpy(pstr, (char *) ret);
  60. }
  61. long convertAtoI(const char *pstr, int radix) {
  62.     char tmp[2];
  63.     long ret = 0L;
  64.     char arr[MAX_BUF];
  65.     long q, r;
  66.     int isNegative = FALSE;
  67.     int len = strlen(pstr);
  68.     char c;
  69.     int i;
  70.     long val;
  71.     c = pstr[0];
  72.     if (c == '-') {
  73.        isNegative = TRUE;
  74.     }
  75.     else if (c >= '0' && c <= '9') {
  76.         ret = (long) (c - '0');
  77.     }
  78.     else if (c >= 'A' && c <= 'Z') {
  79.         ret = (long) (c - 'A') + 10L;
  80.     }
  81.     else if (c >= 'a' && c <= 'z') {
  82.         ret = (long) (c - 'a') + 10L;
  83.     }
  84.     if (ret >= (long) radix) {
  85.         println("        Invalid character!");
  86.         return ret;
  87.     }
  88.     for (i = 1; i < len; i++) {
  89.         c = pstr[i];
  90.         ret *= radix;
  91.         if (c >= '0' && c <= '9') {
  92.             val = (long) (c - '0');
  93.         }
  94.         else if (c >= 'A' && c <= 'Z') {
  95.             val = (long) (c - 'A') + 10L;
  96.         }
  97.         else if (c >= 'a' && c <= 'z') {
  98.             val = (long) (c - 'a') + 10L;
  99.         }
  100.         if (val >= (long) radix) {
  101.             println("        Invalid character!");
  102.             return ret;
  103.         }
  104.         ret += val;
  105.     }
  106.     return ret;
  107. }
  108. void makeTable() {
  109.     char sbuf[MAX_BUF];
  110.     char abuf[MAX_BUF/2];
  111.     char tbuf[MAX_BUF/2];
  112.     int i;
  113.     for (i = 0; i < 4; i++) {
  114.         print("+-------");
  115.     }
  116.     print("+");
  117.     println("");
  118.     print("|  Dec");
  119.     print("\t|   Bin");
  120.     print("\t|  Oct");
  121.     print("\t|  Hex  |");
  122.     println("");
  123.     for (i = 0; i < 4; i++) {
  124.         print("+-------");
  125.     }
  126.     print("+");
  127.     println("");
  128.     for (i = 0; i < 16; i++) {
  129.         sprintf(sbuf, "|   %2d", i);
  130.         convertItoA((char *)abuf, (long) i, 2);
  131.         sprintf(tbuf, "\t|  %4s", abuf);
  132.         strcat(sbuf, tbuf);
  133.         convertItoA((char *)abuf, (long) i, 8);
  134.         sprintf(tbuf, "\t|   %2s", abuf);
  135.         strcat(sbuf, tbuf);
  136.         convertItoA((char *)abuf, (long) i, 16);
  137.         sprintf(tbuf, "\t|    %-2s |", abuf);
  138.         strcat(sbuf, tbuf);
  139.         println(sbuf);
  140.     }
  141.     for (i = 0; i < 4; i++) {
  142.         print("+-------");
  143.     }
  144.     print("+");
  145.     println("");
  146. }
  147. void main(int argc, char *argv[]) {
  148.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  149.         printUsage();
  150.         exit(1);
  151.     }
  152.     makeTable();
  153. }



컴파일> cl makeRadixTable.c

실행> makeRadixTable

+-------+-------+-------+-------+
|  Dec  |   Bin |  Oct  |  Hex  |
+-------+-------+-------+-------+
|    0  |     0 |    0  |    0  |
|    1  |     1 |    1  |    1  |
|    2  |    10 |    2  |    2  |
|    3  |    11 |    3  |    3  |
|    4  |   100 |    4  |    4  |
|    5  |   101 |    5  |    5  |
|    6  |   110 |    6  |    6  |
|    7  |   111 |    7  |    7  |
|    8  |  1000 |   10  |    8  |
|    9  |  1001 |   11  |    9  |
|   10  |  1010 |   12  |    A  |
|   11  |  1011 |   13  |    B  |
|   12  |  1100 |   14  |    C  |
|   13  |  1101 |   15  |    D  |
|   14  |  1110 |   16  |    E  |
|   15  |  1111 |   17  |    F  |
+-------+-------+-------+-------+



 

Posted by Scripter
,

다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 C 소스 코드이다.
(Ch를 이용하면 컴파일 하지 않고 소스를 그대로 실행시킬 수 있다.)
메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환을 하는 핵심 함수 convertAtoI()와 convertItoA()의 소스가 자체 제작되어 포함되어 있다. 이를 이용하는 부분은 153~154째 줄에 있는

         val = convertAtoI(s, srcRdx);
         convertItoA((char *) ret, val, destRdx);

이다. 지원되는 진법은 2진법에서 36진법 까지이다.



  1. /*
  2.  *  Filename: convertRadix.c
  3.  *            Convert radix in a interactive mode.
  4.  *
  5.  *  Compile: cl convertRadix.c
  6.  *  Execute: convertRadix
  7.  *
  8.  *      Date:  2008/03/25
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #define MAX_BUF 300
  15. enum { FALSE, TRUE };
  16. struct _TOKEN {
  17.     char a[81];
  18.     char b[81];
  19. };
  20. void println(char s[]) {
  21.     printf("%s\n", s);
  22. }
  23. void print(char s[]) {
  24.     printf("%s", s);
  25. }
  26. void printUsage() {
  27.     println("Usage: convertRadix");
  28.     println("Convert radix in a interactive mode, where the maximum radix is 36.");
  29. }
  30. void printAbout() {
  31.     println("    About: Convert radix in a interactive mode.");
  32. }
  33. void printMainMenu() {
  34.     println("  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it");
  35. }
  36. void printMainPrompt() {
  37.     print("  Prompt> ");
  38. }
  39. void printSubMenu(int srcRadix, int destRadix) {
  40.     char sbuf[MAX_BUF];
  41.     sprintf(sbuf, "    Convert Radix_%d to Radix_%d", srcRadix, destRadix);
  42.     println(sbuf);
  43.     println("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit");
  44. }
  45. void printSubPrompt() {
  46.     print("    Input Value>> ");
  47. }
  48. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  49. void convertItoA(char *pstr, long num, int radix) {
  50.     char tmp[2];
  51.     char ret[MAX_BUF];
  52.     char arr[MAX_BUF];
  53.     long q, r;
  54.     int i, n;
  55.     int isNegative = FALSE;
  56.     if (num < 0L) {
  57.         isNegative = TRUE;
  58.         num = -num;
  59.     }
  60.     arr[0] = '\0';
  61.     q = num;
  62.     r = 0L;
  63.     while (q >= (long) radix) {
  64.         r = q % (long) radix;
  65.         q = q / (long) radix;
  66.         tmp[0] = BASE36[r];
  67.         tmp[1] = '\0';
  68.         strcat(arr, tmp);
  69.     }
  70.     tmp[0] = BASE36[q];
  71.     tmp[1] = '\0';
  72.     strcat(arr, tmp);
  73.     if (isNegative) {
  74.         strcat(arr, "-");
  75.     }
  76.     n = strlen(arr);
  77.     for (i = 0; i < n; i++) {
  78.         ret[i] = arr[n - i - 1];
  79.     }
  80.     ret[n] = '\0';
  81.     strcpy(pstr, (char *) ret);
  82. }
  83. long convertAtoI(const char *pstr, int radix) {
  84.     long ret = 0L;
  85.     char arr[MAX_BUF];
  86.     long q, r;
  87.     int isNegative = FALSE;
  88.     int len = strlen(pstr);
  89.     char c;
  90.     int i;
  91.     long val;
  92.     c = pstr[0];
  93.     if (c == '-') {
  94.         isNegative = TRUE;
  95.     }
  96.     else if (c >= '0' && c <= '9') {
  97.         ret = (long) (c - '0');
  98.     }
  99.     else if (c >= 'A' && c <= 'Z') {
  100.         ret = (long) (c - 'A') + 10L;
  101.     }
  102.     else if (c >= 'a' && c <= 'z') {
  103.         ret = (long) (c - 'a') + 10L;
  104.     }
  105.     if (ret >= (long) radix) {
  106.         println("        Invalid character!");
  107.         return ret;
  108.     }
  109.     for (i = 1; i < len; i++) {
  110.         c = pstr[i];
  111.         ret *= radix;
  112.         if (c >= '0' && c <= '9') {
  113.             val = (long) (c - '0');
  114.         }
  115.         else if (c >= 'A' && c <= 'Z') {
  116.             val = (long) (c - 'A') + 10L;
  117.         }
  118.         else if (c >= 'a' && c <= 'z') {
  119.             val = (long) (c - 'a') + 10L;
  120.         }
  121.         if (val >= (long) radix) {
  122.             println("        Invalid character!");
  123.             return ret;
  124.         }
  125.         ret += val;
  126.     }
  127.     return ret;
  128. }
  129. void convertRadix(char *pstr, char s[],  int srcRdx, int destRdx) {
  130.     long val;
  131.     char ret[MAX_BUF];
  132.     val = convertAtoI(s, srcRdx);
  133.     convertItoA((char *) ret, val, destRdx);
  134.     strcpy(pstr, ret);
  135. }
  136. void readLine(char *pdata) {
  137.     scanf("%s", pdata);
  138. }
  139. void readTwo(struct _TOKEN *ptoken) {
  140.     scanf("%s", ptoken->a);
  141.     scanf("%s", ptoken->b);
  142. }
  143. void tokenize(struct _TOKEN *ptoken, const char *line, char c) {
  144.     int len = strlen(line);
  145.     int i;
  146.     int from, to;
  147.     i = 0;
  148.     while (line[i] != c) {
  149.         i++;
  150.     }
  151.     from = i;
  152.     while (line[i] == c) {
  153.         i++;
  154.     }
  155.     to = i;
  156.     strncpy(ptoken->a, line, to - from);
  157.     ptoken->a[to - from] = '\0';
  158.     while (line[i] != c) {
  159.         i++;
  160.     }
  161.     from = i;
  162.     while (line[i] == c) {
  163.         i++;
  164.     }
  165.     to = i;
  166.     strncpy(ptoken->b, line, to - from);
  167.     ptoken->b[to - from] = '\0';
  168. }
  169. void doConvert(int srcRadix, int destRadix) {
  170.     char sbuf[MAX_BUF];
  171.     char line[MAX_BUF];
  172.     char cmd[MAX_BUF];
  173.     char srcStr[MAX_BUF], destStr[MAX_BUF];
  174.     long tmp;
  175.     println("");
  176.     printSubMenu(srcRadix, destRadix);
  177.     do {
  178.         printSubPrompt();
  179.         readLine((char *)cmd);
  180.         while (strlen(cmd) <= 0) {
  181.             readLine((char *)cmd);
  182.         }
  183.         if (strcmp("main()", cmd) == 0) {
  184.             return;
  185.         }
  186.         else if (strcmp("exit()", cmd) == 0 || strcmp("quit()", cmd) == 0) {
  187.             exit(0);
  188.         }
  189.         tmp = convertAtoI(cmd, srcRadix);
  190.         strcpy(srcStr, cmd);
  191.         convertRadix(destStr, srcStr, srcRadix, destRadix);
  192.         sprintf(sbuf, "        ( %s )_%d   --->   ( %s )_%d", srcStr, srcRadix, destStr, destRadix);
  193.         println(sbuf);
  194.         println("");
  195.     } while (TRUE);
  196. }
  197. void doStart() {
  198.     char line[MAX_BUF];
  199.     char cmd[MAX_BUF];
  200.     int srcRadix = 10, destRadix = 10;
  201.     char srcStr[MAX_BUF], destStr[MAX_BUF];
  202.     struct _TOKEN st;
  203.     int onlyOnce = TRUE;
  204.     do {
  205.         println("");
  206.         if (onlyOnce) {
  207.             println("  The supported maximum radix is 36.");
  208.             onlyOnce = FALSE;
  209.         }
  210.         printMainMenu();
  211.         printMainPrompt();
  212.         readLine((char *)cmd);
  213.         while (strlen(cmd) <= 0) {
  214.             readLine((char *)cmd);
  215.         }
  216.         if (strstr("qQxX", cmd) != NULL && strlen(cmd) == 1) {
  217.             exit(0);
  218.         }
  219.         else if (strstr("aA", cmd) != NULL && strlen(cmd) == 1) {
  220.             printAbout();
  221.         }
  222.         else if (strstr("sS", cmd) != NULL && strlen(cmd) == 1) {
  223.             print("  Input the source and target radices (say, 16 2): ");
  224.             readTwo((struct _TOKEN *) &st);
  225.             srcRadix = convertAtoI(st.a, 10);
  226.             destRadix = convertAtoI(st.b, 10);
  227.             doConvert(srcRadix, destRadix);
  228.         }
  229.     } while (TRUE);
  230. }
  231. void main(int argc, char *argv[]) {
  232.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  233.         printUsage();
  234.         exit(1);
  235.     }
  236.     doStart();
  237. }




컴파일> cl convertRadix.c

실행> convertRadix

  The supported maximum radix is 36.
  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 8 16

    Convert Radix_8 to Radix_16
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 1234
        ( 1234 )_8   --->   ( 29C )_16

    Input Value>> main()

  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 16 8

    Convert Radix_16 to Radix_8
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 29c
        ( 29c )_16   --->   ( 1234 )_8

    Input Value>> exit()



Posted by Scripter
,

다음은  이차방정식 x^2 - x - 1  = 0 의 양의 근 즉 황금비율(golden ratio)을 구하는 C 애플리케이션 소스이다. 황금비율을 구하는 비례방정식은   1 : x = x : (x+1) 이며, 이를 이차방정식으로 표현한 것이 x^2 - x - 1  = 0 이다.

See:  Golden ratio - Sajun.org


  1. /*
  2.  *  Filename: testGoldenRatio.c
  3.  *    황금률(즉, 이차방정식 x^2 - x - 1  = 0 의 양의 근)을 계산한다.
  4.  *
  5.  *   Compile: cl testGoldenRatio.c
  6.  *
  7.  *   Execute: testGoldenRatio
  8.  *
  9.  *      Date:  2008/03/24
  10.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  11.  */
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <math.h>
  15. typedef struct _PAIR {
  16.     double x1;
  17.     double x2;
  18. } PAIR;
  19. void printUsing() {
  20.     printf("Using: testGoldenRatio [-h|-help]\n");
  21.     printf("This calculates the value of the golden ratio.\n");
  22. }
  23. // 이차방정식 a x^2 + b x + c  = 0 의 근을 구한다.
  24. PAIR *findQuadraticRoot(double a, double b, double c) {
  25.     static PAIR zeros;
  26.     if (a == 0.0) {
  27.         fprintf(stderr, "Since the highest coefficient is zero, the given equation is not a quadratic equation.\n");
  28.         exit(1);
  29.     }
  30.     else if (b*b - 4*a*c < 0.0) {
  31.         fprintf(stderr, "Since the discriminant %f is negative, the given equation has no real root.\b", b*b - 4*a*c);
  32.     exit(1);
  33.     }
  34.     zeros.x1 = (-b + sqrt(b*b - 4*a*c)) / (2.0 * a);
  35.     zeros.x2 = (-b - sqrt(b*b - 4*a*c)) / (2.0 * a);
  36.     return (PAIR *) &zeros;
  37. }
  38. void main(int argc, char *argv[]) {
  39.     double x1, x2;
  40.     PAIR *values = (PAIR *) findQuadraticRoot(1.0, -1.0, -1.0);
  41.     if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0)) {
            printUsing();
  42.         exit(1);
  43.     }
  44.     values = findQuadraticRoot(1.0, -1.0, -1.0);
  45.     x1 = values->x1;
  46.     x2 = values->x2;
  47.     if (x1 >= x2) {
  48.         printf("The bigger root is %lf, \n", x1);
  49.         printf("and the less root is %lf.\n", x2);
  50.     }
  51.     else {
  52.         printf("The bigger root is %lf, \n", x2);
  53.         printf("and the less root is %lf.\n", x1);
  54.     }
  55. }



컴파일> cl testGoldenRatio.c

실행> testGoldenRatio
The bigger root is 1.618034,
and the less root is -0.618034.


Ch를 이용하면 C 언어 소스 코드를 (컴파일하지 않고) 직접 실행시킬 수 있다.

실행> ch testGoldenRatio.c
The bigger root is 1.618034,
and the less root is -0.618034.



Posted by Scripter
,
현재 시각을 컨솔에 보여주는 간단한 애플리케이션의 C 언어 소스 코드이다.
UTC란 1970년 1월 1일 0시 0분 0초를 기준으로 하여 경과된 초 단위의 총 시간을 의미한다.
* UTC(Universal Time  Coordinated, 협정세계시, 協定世界時)

  1. /*
  2.  *  Filename: testCTime.c
  3.  *
  4.  *  Compile: cl testCTime.c
  5.  *
  6.  *  Execute: testCTime
  7.  */
  8. #include <stdio.h>
  9. #include <time.h>
  10. char weekNames[7][3] = {
  11.  "일", "월", "화", "수", "목", "금", "토"
  12. };
  13. int main() {
  14.     time_t timer;
  15.     struct tm *t;
  16.     timer = time(NULL); // 현재 시각을 초 단위로 얻기
  17.     t = localtime(&timer); // 초 단위의 시간을 분리하여 구조체에 넣기
  18.     // 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초
  19.     printf("UTC: %d초\n", timer);
  20.     // 현재 시각 표시: 200x년 x월 xx일 (x요일) xx시 xx분 xx초
  21.     printf("%d년 %d월 %d일 (%s요일) ", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, weekNames[t->tm_wday]);
  22.     printf("%d시 %d분 %d초\n", t->tm_hour, t->tm_min, t->tm_sec);
  23.     // t->tm_yday의 값: 1월 1일은 0, 1월 2일은 1
  24.     printf("올해 몇 번째 날: %d, ", 1 + t->tm_yday);
  25.     // t->tm_isdst의 값: 0 이면 서머타임 없음
  26.     printf("서머타임 적용 여부: %s\n", (t->tm_isdst == 0) ? "안함" : "함");
  27.     return 0;
  28. }



컴파일> cl testCTime.c

실행> testCTime
UTC: 1206322402초
2008년 3월 24일 (월요일) 10시 33분 22초
올해 몇 번째 날: 84, 서머타임 적용 여부: 안함



Posted by Scripter
,
GMP는 The GNU Multiple Precision Arithmetic Library(고정밀도 연산을 위한 GNU 라이브러리)의 줄임글로서 GNU MP라고도 한다. 리눅스 호환 환경이면 대부분 GMP는 이미 설치되어 있을 것이다. GMP의 공식 홈페이지는 http://gmplib.org 이고, GMP는 LGPL 하에서 배포된다.

또 gcc는 리눅스 호환 환경에서 쓸 수 있는 C 컴파일러(GNU C 컴파일러)이다. 대부분의 리눅스 호환 환경에는 gcc가  설치되어 있을 것이다.

다음 소스 코드는 GMP의 설치 테스트를 하기 위한 간단한 예제이다.

C 언어에서 GMP 라이브러리를 사용하기 위해서는 헤더 파일 gmp.h를 인클루드한다.
컴파일할 때는 반드시 컴파일 옵션 -lgmp 를 주어야 한다.
또 컴파일 옵션 -o testGMP 을 준 것은 생성될 실행파일명을 testGMP로 하라는 의미이다.
이 옵션을 생략하면 생성되는 실행파일명이 a.out(단, cygwin의 경우에는 a.exe)이다.

((  참고로, Visual C++ 6 에서 컴파일하는 명령은
           cl -I. testGMP.c /link gmp.lib /NODEFAULTLIB:LIBCMT
이다. 필자는 Visual C++ 6 에서 GMP 라이브러리를 사용하기 위해 영국에 사는 Brian Gladman 씨가 http://www.gladman.me.uk/computing/ 에서 제공하는 gmp-4.1.4.diffs.zip 을 써서 Visual C++ 6 용 GMP 라이브러리 gmp.lib 를 빌드하였다. ))

mpz_mul_ui 함수는 mpz_t 타입의 정수에 unsigned long 타입의 정수를 곱하는 함수이고,
mpz_add_ui 함수는 mpz_t 타입의 정수에 unsigned long 타입의 정수를 합하는 함수이다.

        mpz_init(r);

mpz_init 함수는 mpz_t 타입의 정수 변수를 초기화 하는 함수이다. (초기화된 값은 0)

       mpz_init_set_str(n, "123456", 10);

또 mpz_init_set_str 함수는 두번째 인수에 주어진 ASCIZ 문자열을 세 번째 인수에 주어진 적당한 진법(이 예에서는 10)을 적용하여 첫번째 인수에 주어진 mpz_t 타입의 정수 변수(이 예에서는 n)에 저장하는 함수이다.


  1. /*
  2.  *  Filename: testGMP.c
  3.  *
  4.  *   Compile: gcc -o testGMP testGMP.c -lgmp
  5.  *
  6.  *   Execute: ./testGMP
  7.  *    Output: 2470450
  8.  */
  9. #include <gmp.h>
  10. void foo(mpz_t result, const mpz_t param, unsigned long n) {
  11.     unsigned long i;
  12.     mpz_mul_ui(result, param, n);
  13.     for (i = 1; i < n; i++) {
  14.         mpz_add_ui (result, result, i*7);
  15.     }
  16. }
  17. int main(void) {
  18.     mpz_t r, n;
  19.     mpz_init(r);
  20.     mpz_init_set_str(n, "123456", 10);
  21.     foo(r, n, 20L);
  22.     gmp_printf("%Zd\n", r);
  23.     return 0;
  24. }



컴파일> gcc -o testGMP testGMP.c -lgmp

실행> ./testGMP
2470450



Win32의 Visual C++ 6 상에서 컴파일하기:
컴파일>cl -I. testGMP.c /link gmp.lib /NODEFAULTLIB:LIBCMT

실행> testGMP
2470450



Visual C++ 9.0 (Visual Studio 2008) 에서 컴파일하기:
컴파일>cl testGMP.c gmp.lib

실행> testGMP
2470450



Posted by Scripter
,
다항식 p(x) 를 1차 다항식 x - a 로 나눌 때의 몫과 나머지를 구하는 조립제법을
C 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.

         p(x) = (x - a)q(x) + r

여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.

[참고]
    * 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표 
    * 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수


아래의 소스파일은 Ch를 사용하면 컴파일하지 않고 수정 없이 그대로 실행된다.
(실행 예:  ch testSyntheticDivision.c 1 2 3 4 5  )


  1. /*
  2.  *  Filename: testSyntheticDivision.c
  3.  *
  4.  *  Purpose:  Find the quotient and remainder when some polynomial is
  5.  *            divided by a monic polynomial of the first degree.
  6.  *
  7.  *  Compile:  cl testSyntheticDivision.c
  8.  *
  9.  *  Execute:  testSyntheticDivision -2 1 3 3 1
  10.  */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include <memory.h>
  15. void print(char str[]) {
  16.     printf("%s", str);
  17. }
  18. void println(char str[]) {
  19.     printf("%s\n", str);
  20. }
  21. // 사용법 표시
  22. void printUsage() {
  23.      println("사용법: testSyntheticDivision [수] [피제식의 계수들]");
  24.      println("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.");
  25. }
  26. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  27. // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  28. char *simplify(double v, int width) {
  29.     int n, len;
  30.     static char t[] = "                               ";
  31.     char tmp[] = "                               ";
  32.     sprintf(t, "%g", v);
  33.     n = strlen(t);
  34.     if ((n > 2) && (t[n - 2] == '.') && (t[n - 1] == '0'))
  35.         t[n-2] = '\0';
  36.     len = strlen(t);
  37.     strcpy(tmp, t);
  38.     if (len < width) {
  39.         strncpy(t, "               ", width - len);
  40.         t[width - len] = '\0';
  41.         strcat(t, tmp);
  42.     }
  43.     return (char *) t;
  44. }
  45. // 다항식을 내림차순의 문자열로로 반환하는 함수
  46. // 반환된 문자열은 동적 메모리에 존재하므로.
  47. // 사용 후 반드시 해제(free)하여야 한다.
  48. char *toPolyString(double c[], int size) {
  49.     int SIZE = size;
  50.     int i;
  51.     static char t[300];
  52.     char tmp[80];
  53.     char *pc = simplify(c[0], -1);
  54.     char *pci;
  55.     if (SIZE > 2) {
  56.         if (strlen(pc) == 1 && pc[0] == '1')
  57.             sprintf(t,  "x^%d", SIZE - 1);
  58.         else if (strlen(pc) == 2 && pc[0] == '-' && pc[1] == '1')
  59.             sprintf(t,  "-x^%d", SIZE - 1);
  60.         else
  61.             sprintf(t,  "%s x^%d", simplify(c[0], -1), SIZE - 1);
  62.     }
  63.     else if (SIZE == 2) {
  64.         if (strlen(pc) == 1 && pc[0] == '1')
  65.             strcpy(t,  "x");
  66.         else if (strlen(pc) == 2 && pc[0] == '-' && pc[1] == '1')
  67.             strcpy(t,  "-x");
  68.         else
  69.             sprintf(t,  "%s x", simplify(c[0], -1));
  70.     }
  71.     else if (SIZE == 1) {
  72.         sprintf(t,  "%s", simplify(c[0], -1));
  73.     }
  74.     for (i = 1; i < SIZE; i++) {
  75.         pci = simplify(c[i], -1);
  76.         if (SIZE - 1 - i > 1) {
  77.             if (c[i] > 0.0) {
  78.                 if (strlen(pci) == 1 && pci[0] == '1') {
  79.                     sprintf(tmp,  " + x^%d", SIZE - 1 - i);
  80.                     strcat(t, tmp);
  81.                 }
  82.                 else {
  83.                     sprintf(tmp,  " + %s x^%d", simplify(c[i], -1), SIZE - 1 - i);
  84.                     strcat(t, tmp);
  85.                 }
  86.             }
  87.             else if (c[i] < 0.0) {
  88.                 if (strlen(pci) == 2 && pci[0] == '-' && pci[1] == '1') {
  89.                     sprintf(tmp,  " - x^%d", SIZE - 1 - i);
  90.                     strcat(t, tmp);
  91.                 }
  92.                 else {
  93.                     sprintf(tmp,  " - %s x^%d", simplify(fabs(c[i]), -1), SIZE - 1 - i);
  94.                     strcat(t, tmp);
  95.                 }
  96.             }
  97.         }
  98.         else if (SIZE - 1 - i == 1) {
  99.             if (c[i] > 0.0) {
  100.                 if (strlen(pci) == 1 && pci[0] == '1') {
  101.                     strcat(t, " + x");
  102.                 }
  103.                 else {
  104.                     sprintf(tmp,  " + %s x", simplify(c[i], -1));
  105.                     strcat(t, tmp);
  106.                 }
  107.             }
  108.             else if (c[i] < 0.0) {
  109.                 if (strlen(pci) == 2 && pci[0] == '-' && pci[1] == '1') {
  110.                     strcat(t, " - x");
  111.                 }
  112.                 else {
  113.                     sprintf(tmp,  " - %s x", simplify(fabs(c[i]), -1));
  114.                     strcat(t, tmp);
  115.                 }
  116.             }
  117.         }
  118.         else if (SIZE - 1 - i == 0) {
  119.             if (c[i] > 0.0) {
  120.                 sprintf(tmp,  " + %s", simplify(c[i], -1));
  121.                 strcat(t, tmp);
  122.             }
  123.             else if (c[i] < 0.0) {
  124.                 sprintf(tmp,  " - %s", simplify(fabs(c[i]), -1));
  125.                 strcat(t, tmp);
  126.             }
  127.         }
  128.     }
  129.     return (char *) t;
  130. }
  131. // 다향식 나눗셈 결과를
  132. //     (피제식) = (제식)(몫) + (나마지)
  133. // 형태로 출력
  134. void printDivisionResult(double a, double c[], double b[], int size) {
  135.     int SIZE = size;
  136.     int i;
  137.     double *pTmpPoly;
  138.     double r;
  139.     double monic[] = { 1.0, 0.0 };
  140.     print("  ");
  141.     print(toPolyString(c, SIZE));
  142.     println("");
  143.     print("    = ( ");
  144.     monic[1] = -a;
  145.     print(toPolyString(  monic, 2 ));
  146.     print(" )");
  147.     pTmpPoly = (double *)  calloc(SIZE - 1, sizeof(double));
  148.     for (i = 0; i < SIZE - 1; i++) {
  149.         pTmpPoly[i] = b[i];
  150.     }
  151.     print("( ");
  152.     print(toPolyString(pTmpPoly, SIZE - 1));
  153.     print(" )");
  154.     free(pTmpPoly);
  155.     r = b[SIZE - 1];
  156.     if (r > 0.0) {
  157.         print(" + ");
  158.         print(simplify(r, -1));
  159.     }
  160.     else if (r < 0.0) {
  161.         print(" - ");
  162.         print(simplify(fabs(r), -1));
  163.     }
  164.     println("");
  165. }
  166. // 조립제법 계산표 출력 함수
  167. void printSyntheticTable(double a, double c[], double s[], double q[], int size) {
  168.     int SIZE = size;
  169.     int i;
  170.     print("       | ");
  171.     print(simplify(c[0], 6));
  172.     for (i = 1; i < SIZE; i++) {
  173.         print("  ");
  174.         print(simplify(c[i], 6));
  175.     }
  176.     println("");
  177.     print(simplify(a, 6));
  178.     print(" | ");
  179.     print("        ");
  180.     print(simplify(s[1], 6));
  181.     for (i = 2; i < SIZE; i++) {
  182.         print("  ");
  183.         print(simplify(s[i], 6));
  184.     }
  185.     println("");
  186.     print("       |-");
  187.     for (i = 0; i < SIZE; i++) {
  188.         print("--------");
  189.     }
  190.     println("");
  191.     print("         ");
  192.     print(simplify(q[0], 6));
  193.     for (i = 1; i < SIZE; i++) {
  194.         print("  ");
  195.         print(simplify(q[i], 6));
  196.     }
  197.     println("");
  198. }
  199. // C/C++/Ch 언어의 실행 시작 지점
  200. int main(int argc, char *argv[]) {
  201.     int i;
  202.     int SIZE = argc - 2;
  203.     double a, c[15], s[15], b[15];
  204.     if (argc < 4) {
  205.         printUsage();
  206.         exit(1);
  207.     }
  208.     //////////////////////////////////////////////////////
  209.     // 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  210.     // 제식은 x -  a
  211.     a = atof(argv[1]);
  212.     for (i = 0; i < SIZE; i++) {
  213.         c[i] = atof(argv[i + 2]);
  214.     }
  215.     //////////////////////////////////////////////////////
  216.     // 조립제법의 주요 부분
  217.     s[0] = 0.0;
  218.     b[0] = c[0];
  219.     for (i = 1; i < SIZE; i++) {
  220.         s[i] = b[i-1]*a;
  221.         b[i] = c[i] + s[i];
  222.     }
  223.     //////////////////////////////////////////////////////
  224.     // 몫의 계수와 나머지를 출력한다.
  225.     print("몫의 계수는 ");
  226.     for (i = 0; i < SIZE - 2; i++) {
  227.         print(simplify(b[i], -1));
  228.         print(", ");
  229.     }
  230.     print(simplify(b[SIZE - 2], -1));
  231.     print(" 이고, 나머지는 ");
  232.     print(simplify(b[SIZE - 1], -1));
  233.     println(" 이다.");
  234.     println("");
  235.     //////////////////////////////////////////////////////
  236.     // 조립제법 표를 출력한다.
  237.     printSyntheticTable(a, c, s, b, SIZE);
  238.     println("");
  239.     //////////////////////////////////////////////////////
  240.     // (피제식) = (제식) x (몫) + (나머지)
  241.     printDivisionResult(a, c, b, SIZE);
  242.     return 0;
  243. }




컴파일> cl testSyntheticDivision.c

실행> testSyntheticDivision 1 2 3 4 5
몫의 계수는 2, 5, 9 이고, 나머지는 14 이다.

       |      2       3       4       5
     1 |              2       5       9
       |---------------------------------
              2       5       9      14

  2 x^3 + 3 x^2 + 4 x + 5
    = ( x - 1 )( 2 x^2 + 5 x + 9 ) + 14



 

Posted by Scripter
,