// Filename: HelloWorld.go
//
// Execute: go run HelloWorld.go
// or
// Compile: go build HelloWorld.go
// Execute: ./HelloWorld

package main

import "fmt"

func main() {
    fmt.Printf("Hello, world!\n")
}

 

 

Posted by Scripter
,

Haskell  언어로 행렬 곱셈하는 간단한 소스

(정수로 이루어진 행렬, 분수로 이루어진 행렬, 부동소수점수로 이루어진 행렬, 복소수로 이루어진 행렬 들릐 곱셈을 처리합니다.) 

 

-- Filename: testMatrixMultiplication.hs
--
-- 참조: http://rosettacode.org/wiki/Matrix_multiplication#Haskell

module Main where

import Data.Complex
import Data.Ratio
import Text.Printf
import Data.List 


-- 행렬 곱셉 함수
mmult :: Num a => [[a]] -> [[a]] -> [[a]] 
mmult a b = [ [ sum $ zipWith (*) ar bc | bc <- (transpose b) ] | ar <- a ]


-- 사용 예
main :: IO ()
main = do
    -- matrix of integers
    let test = [[1, 2], 
                  [3, 4]] `mmult` [[-3, -8, 3],
                                            [-2,  1, 4]]
    print test

    -- matrix of floats
    let test = [[1.0, 2.0], 
                    [3.0, 4.0]] `mmult` [[-3, -8, 3],
                                                   [-2,  1, 4]]
    print test

    -- matrix of fraction
    let test = [[(1 % 1),  (2 % 1)], 
                    [(3 % 1), (4 % 1)]] `mmult` [[-3, -8, 3],
                                                                [-2,  1, 4]]
    print test

    -- matrix of complex numbers
    let test = [[(1 :+ 1),  (2 :+ 1)], 
                    [(3 :+ 1), (4 :+ 1)]] `mmult` [[-3, -8, 3],
                                                                [-2,  1, 4]]
    print test

{-
실행: runhaskell testMatrixMultiplication.hs
출력:
-------------------------------------------
[[-7,-6,11],[-17,-20,25]]
[[-7.0,-6.0,11.0],[-17.0,-20.0,25.0]]
[[(-7) % 1,(-6) % 1,11 % 1],[(-17) % 1,(-20) % 1,25 % 1]]
[[(-7.0) :+ (-5.0),(-6.0) :+ (-7.0),11.0 :+ 7.0],[(-17.0) :+ (-5.0),(-20.0) :+ (-7.0),25.0 :+ 7.0]]
-}

 

 

 

Posted by Scripter
,

Haskell 언어로도 (Python 언어 처럼) 복소수 게산과 분수 게산을 쉽게 할 수 있습니다,.

(1) Haskell  언어에서 복소수를 사용하려면   import Data.Complex 구문이 있어야 합니다.
    복소수의 표현은 실수부 :+ 허수부 입니다.

(2) Haskell  언어에서 분수를 사용하려면   import Data.Ratio 구문이 있어야 합니다.
    분수의 표현은 분자 % 분모 입니다.

(3) C 언어의 printf 나 Python 언어의 print 처럼 포맷 출력을 하려면 import Text.Printf 구문이 있어야 합니다.

아래에서 진한 글자체로 된 부분만 입력하고 엔터키를 누르면 됩니다.
(ghci 는 Glasgow Haskell 의 인터프리터이고,. ghc는 Glasgow Haskell 의 컴파일러입니다.)


$ ghci
GHCi, version 7.0.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
-- 몫과 나머지 구하기
Prelude> div 5 3
1
Prelude> mod 5 3
2
Prelude> divMod 5 3
(1,2)
Prelude> 5 `div` 3
1
Prelude> 5 `mod` 3
2
Prelude> 5 `divMod` 3
(1,2)
-- 분수 생성과 계산
Prelude> import Data.Ratio
Prelude Data.Ratio> 5 % 3
5 % 3
Prelude Data.Ratio> 5 % 3 * 2
10 % 3
Prelude Data.Ratio> 5 % 3 + 2
11 % 3
Prelude Data.Ratio> 5 % 3 + 2 % 3
7 % 3
-- 복소수 생성과  계산
Prelude Data.Ratio> import Data.Complex
Prelude Data.Ratio Data.Complex> 2 :+ 3
2.0 :+ 3.0
Prelude Data.Ratio Data.Complex> sqrt 2 :+ 3
1.4142135623730951 :+ 3.0
Prelude Data.Ratio Data.Complex> sqrt (2 :+ 3)
1.6741492280355401 :+ 0.8959774761298381
Prelude Data.Ratio Data.Complex> 2 :+ 3 * 2
2.0 :+ 6.0
Prelude Data.Ratio Data.Complex> 2 :+ 3 - 2

<interactive>:1:1:
    Precedence parsing error
        cannot mix `:+' [infix 6] and `-' [infixl 6] in the same infix expressio
n
Prelude Data.Ratio Data.Complex> (2 :+ 3) - 2
0.0 :+ 3.0
Prelude Data.Ratio Data.Complex> (2 :+ 3) - 0:+2

<interactive>:1:1:
    Precedence parsing error
        cannot mix `-' [infixl 6] and `:+' [infix 6] in the same infix expressio
n
Prelude Data.Ratio Data.Complex> (2 :+ 3) - (0:+2)
2.0 :+ 1.0
Prelude Data.Ratio Data.Complex> (2 :+ 3) * 0:+2

<interactive>:1:13:
    No instance for (RealFloat (Complex a0))
      arising from a use of `:+'
    Possible fix:
      add an instance declaration for (RealFloat (Complex a0))
    In the expression: (2 :+ 3) * 0 :+ 2
    In an equation for `it': it = (2 :+ 3) * 0 :+ 2
Prelude Data.Ratio Data.Complex> (2 :+ 3) * (0:+2)
(-6.0) :+ 4.0
Prelude Data.Ratio Data.Complex> conjugate 2 :+ 3

<interactive>:1:13:
    No instance for (RealFloat (Complex a0))
      arising from a use of `:+'
    Possible fix:
      add an instance declaration for (RealFloat (Complex a0))
    In the expression: conjugate 2 :+ 3
    In an equation for `it': it = conjugate 2 :+ 3
Prelude Data.Ratio Data.Complex> conjugate (2 :+ 3)
2.0 :+ (-3.0)
relude Data.Ratio Data.Complex> 1 / 2 :+ 3
.5 :+ 3.0
Prelude Data.Ratio Data.Complex> 1 / (2 :+ 3)
.15384615384615385 :+ (-0.23076923076923078)
Prelude Data.Ratio Data.Complex>
Prelude Data.Ratio Data.Complex Text.Printf> let x = 2 :+ 5
Prelude Data.Ratio Data.Complex Text.Printf> printf "x = %f + %fj\n" (realPart x) (imagPart x)
x = 2.0 + 5.0j
-- 복소수 츨력하기
Prelude Data.Ratio Data.Complex Text.Printf> let printComplex a = print ((show (
realPart a)) ++ " + " ++ (show (imagPart a)) ++ "j")
Prelude Data.Ratio Data.Complex Text.Printf> printComplex x
"2.0 + 5.0j"
Prelude Data.Ratio Data.Complex Text.Printf> printComplex (conjugate x)
"2.0 + -5.0j"
Prelude Data.Ratio Data.Complex Text.Printf> printComplex (sin x)
"67.47891523845588 + -30.879431343588244j"
Prelude Data.Ratio Data.Complex Text.Printf> printComplex (asin (sin x))
"1.1415926535897933 + -5.0j"
Prelude Data.Ratio Data.Complex Text.Printf> printComplex ((asin . sin) x)
"1.1415926535897933 + -5.0j"
-- 분수 츨력하기
Prelude Data.Ratio Data.Complex Text.Printf> let printFraction a = print ((show
(numerator a)) ++ "/" ++ (show (denominator a)))
Prelude Data.Ratio Data.Complex Text.Printf> let b = 2 % 3
Prelude Data.Ratio Data.Complex Text.Printf> printFraction b
"2/3"
Prelude Data.Ratio Data.Complex Text.Printf> printFraction (1/b)
"3/2"
Prelude Data.Ratio Data.Complex Text.Printf> printFraction ((1/b)*2)
"3/1"
-- (인용 부호 없이) 분수 츨력하기
Prelude Data.Ratio Data.Complex Text.Printf> let printFraction a = printf "%d/%d
\n" (numerator a) (denominator a)
Prelude Data.Ratio Data.Complex Text.Printf> printFraction b
2/3
Prelude Data.Ratio Data.Complex Text.Printf> printFraction (1/b)
3/2
Prelude Data.Ratio Data.Complex Text.Printf> printFraction ((1/b)*2)
3/1
-- (인용 부호 없이) 복소수 츨력하기
Prelude Data.Ratio Data.Complex Text.Printf> let printComplex a = printf "%f + %
fj\n" (realPart a) (imagPart a)
Prelude Data.Ratio Data.Complex Text.Printf> printComplex x
2.0 + 5.0j
Prelude Data.Ratio Data.Complex Text.Printf> printComplex (conjugate x)
2.0 + -5.0j
Prelude Data.Ratio Data.Complex Text.Printf> printComplex (sin x)
67.47891523845588 + -30.879431343588244j
Prelude Data.Ratio Data.Complex Text.Printf> printComplex (asin (sin x))
1.1415926535897933 + -5.0j
Prelude Data.Ratio Data.Complex Text.Printf> printComplex ((asin . sin) x)
1.1415926535897933 + -5.0j
Prelude Data.Ratio Data.Complex Text.Printf> :q
Leaving GHCi.

 

 

※ 다음은 위에 입력한 내용들을 모아서 만든 Haskell 소스 파일입니다.

{-#
      Filename: complexAndFraction.hs
          Testing the expressions and calculations of complex numbers and fractions in Haskell.

     Compile: ghc complexAndFraction.hs
     Execute: ./complexAndFraction

     Or
 
     Execute: runhaskell complexAndFraction.hs
#-}

module Main where

import Data.Complex
import Data.Ratio
import Text.Printf


{-#  복소수 출력하는 함수 #-}
printC :: (RealFloat a, Show a) => Complex a -> IO ()
printC a = print ((show (realPart a)) ++ " + " ++ (show (imagPart a)) ++ "j")

{-#  분수 출력하는 함수 #-}
printF :: (Integral a, Num a, Eq a, Show a) => Ratio a -> IO ()
printF a = print ((show(numerator a)) ++ "/" ++ (show (denominator a)))

{-#  (인용 부호 없이) 복소수 출력하는 함수 #-}
-- printfFraction :: (PrintfArg a, Show a, Eq a, Integral a) => Ratio a -> IO ()
printFraction :: (Show a, Integral a) => Ratio a -> IO ()
printFraction a = printf "%s/%s\n" (show (numerator a)) (show (denominator a))

{-#  (인용 부호 없이) 분수 출력하는 함수 #-}
-- printfComplex :: (Num a, RealFloat a, Show a, PrintfArg a) => Complex a -> IO ()
printComplex :: (Show a, RealFloat a) => Complex a -> IO ()
printComplex a = printf "%s + %sj\n" (show (realPart a)) (show (imagPart a))


main :: IO ()       
main = do
    -- 몫과 나머지 구하기
    print (div 5 3)
    print (mod 5 3)
    print (divMod 5 3)
    print (5 `div` 3)
    print (5 `mod` 3)
    print (5 `divMod` 3)

    -- 분수 생성과 계산
    print (5 % 3)
    print (5 % 3 * 2)
    print (5 % 3 + 2)
    print (5 % 3 + 2 % 3)

    -- 복소수 생성과  계산
    print (2 :+ 3)
    print (sqrt 2 :+ 3)
    print (sqrt (2 :+ 3))
    print (2 :+ 3 * 2)
    print ((2 :+ 3) - 2)
    print ((2 :+ 3) - (0:+2))
    print ((2 :+ 3) * (0:+2))
    print (conjugate (2 :+ 3))
    print (1 / 2 :+ 3)
    print (1 / (2 :+ 3))

    let x = 2 :+ 5
    printf "x = %s + %sj\n" (show (realPart x)) (show (imagPart x))

    -- 복소수 츨력하기 --
    printC x
    printC (conjugate x)
    printC (sin x)
    printC (asin (sin x))
    printC ((asin . sin) x)

    -- 분수 츨력하기
    let b = 2 % 3
    printF b
    printF (1/b)
    printF ((1/b)*2)

    -- (인용 부호 없이) 분수 츨력하기
    printFraction b
    printFraction (1/b)
    printFraction ((1/b)*(2%1))

    -- (인용 부호 없이) 복소수 츨력하기
    printComplex x
    printComplex (conjugate x)
    printComplex (sin x)
    printComplex (asin (sin x))
    printComplex ((asin . sin) x)
{-
------
Output:
------
1
2
(1,2)
1
2
(1,2)
5 % 3
10 % 3
11 % 3
7 % 3
2.0 :+ 3.0
1.4142135623730951 :+ 3.0
1.6741492280355401 :+ 0.8959774761298381
2.0 :+ 6.0
0.0 :+ 3.0
2.0 :+ 1.0
(-6.0) :+ 4.0
2.0 :+ (-3.0)
0.5 :+ 3.0
0.15384615384615385 :+ (-0.23076923076923078)
x = 2.0 + 5.0j
"2.0 + 5.0j"
"2.0 + -5.0j"
"67.47891523845588 + -30.879431343588244j"
"1.1415926535897933 + -5.0j"
"1.1415926535897933 + -5.0j"
"2/3"
"3/2"
"3/1"
2/3
3/2
3/1
2.0 + 5.0j
2.0 + -5.0j
67.47891523845588 + -30.879431343588244j
1.1415926535897933 + -5.0j
1.1415926535897933 + -5.0j
-}

 

 

 

Posted by Scripter
,

 

GHC 의 runhaskell 명령으로 소스 파일을 직접 실행해도 되고,

ghc 명령으로 컴파일하여 생성된 실행파일을 실행해도 된다.

 

-- Filename: solveQuadratic.hs
--    Solve a quadratic equation.
--
--   Compile: ghc solveQuadratic.hs
--   Execute: solveQuadratic 1 3 2
--
--   Or
--
--   Execute: runhaskell solveQuadratic.hs 1 3 2

{-
Compile: ghc solveQuadratic.hs
Execute & Result: solveQuadratic 1 0 4
     Quadratic Equation: 1.0x^2 + 0.0x + 4.0 = 0
     Discriminant D = -16.0
     x1 = 2.0j
     x2 = -2.0j

Or

Execute & Result: runhaskell solveQuadratic.hs 1 0 4
     Quadratic Equation: 1.0x^2 + 0.0x + 4.0 = 0
     Discriminant D = -16.0
     x1 = 2.0j
     x2 = -2.0j
-}

module Main where

import System.Environment
import Data.Complex
import Text.Printf

printUsing :: IO ()
printUsing = do
    putStrLn "Using: runhugs solveQuadratic.hs coeff2  coeff1  coeff0"
    putStrLn "Or solveQuadratic coeff2  coeff1  coeff0"
    putStrLn "Find the roots pf a quadratic equations."


printSolution :: [Char] -> Double -> Double -> IO()
printSolution msg x y = do
           if not (y == 0) && not (x == 0)
           then
               printf "%s%f + %fj\n" msg x y
           else  if not (y == 0) && (x == 0)
           then
               printf "%s%fj\n" msg y
           else
               printf "%s%f\n" msg x

printEquation :: Double -> Double -> Double -> IO()
printEquation a b c =    printf "Quadratic Equation: %fx^2 + %fx + %f = 0\n" a b c

solveEquation :: (RealFloat a) => a -> a -> a -> [Complex a]
solveEquation a b c = x1:x2:[] where
                        za = (a :+ 0)
                        zb = (b :+ 0)
                        zc = (c :+ 0)
                        discr = zb*zb - 4*za*zc
                        x1 = (-zb + sqrt (discr))/(2*za)
                        x2 = (-zb - sqrt (discr))/(2*za)

main :: IO ()       
main = do
    args <- getArgs

    if not ((length args) == 3)
        then printUsing
    else do
    let a1:b1:c1:ts = args
    let a = read a1 :: Double
    let b = read b1 :: Double
    let c = read c1 :: Double
    let d = b*b - 4.0*a*c

    printEquation a b c
    printf "Discriminant D = %g\n" d
    let sols = solveEquation a b c
    let x1:x2:x3 = sols

    printSolution "x1 = " (realPart x1) (imagPart x1)
    printSolution "x2 = " (realPart x2) (imagPart x2)

 

 

Posted by Scripter
,

Quick Sort 알고리즘을 이용하여 C 스트링들을 분류하는 소스입니다.


#include를 #import로 바꾼 것 외에는 C 소스와 똑 같습니다.

Dev-C++  IDE 에서도 캄파일과 실행이 잘 됩니다.

-----------------------------------------------------------------
/**
 * Filename: testSort.m
 *
 * Compile: gcc -o testSort testSort.m -lobjc
 * Execute: ./testSort 하나 둘 셋 넷
 *          ./testSort one two thee four
 *
 * Date: 2012/05/02
 * Author: pkim (AT) scripts.pe.kr
 */

#import <stdio.h>
#import <string.h>

char SBUF[20][80];
char TBUF[80];

void quickSort(char array[20][80], int start, int end);
void swap(char array[20][80], int x, int y);
void printArray(char array[20][80], int start, int end);
void exit(int n);

int main(int argc, char* argv[]) {
    char* pbuf;
    int i;
    if (argc > 1 && argc < 22) {
        for (i = 0; i < argc - 1; i++) {
            if (strlen(argv[i+1]) > 79) {
                printf("Caught: strlen(\"%s\") = %d, which is too long.\n", argv[i+1], strlen(argv[i+1]));
                exit(1);
            }
            sprintf(SBUF[i], argv[i+1]);
        }
        quickSort(&SBUF[0], 0, argc - 2);
        printArray(SBUF, 0, argc - 2);
    }
    else if (argc > 21) {
        printf("Given too many items. (The counter of items should be less then 20.)\n");
        exit(1);
    }
    return 0;
}

void quickSort(char array[20][80], int start, int end) {
    int i = start;
    int k = end;
    char pivot[80];

    if (end - start >= 1) {
        strcpy(pivot, array[start]);
        while (k > i) {
            while (strcmp(array[i], pivot) <= 0 && i <= end && k > i)
                i++;
            while (strcmp(array[k], pivot) > 0 && k >= start && k >= i)
                k--;
            if (k > i) {
                swap(array, i, k);
            }
        }
        swap(array, start, k);

        quickSort(array, start, k - 1);
        quickSort(array, k + 1, end);
    }
    else {
        return;
    }
}

void swap(char array[20][80], int x, int y) {
     strcpy(TBUF, array[x]);
     strcpy(array[x], array[y]);
     strcpy(array[y], TBUF);
}

void printArray(char array[20][80], int start, int end) {
    int i;
    printf("[");
    for (i = start; i < end; i++) {
        printf("%s, ", array[i]);
    }
    if (end >= start)
        printf("%s", array[end]);
    printf("]\n");
}
/*
실행 및 실행 결과:
$ ./testSort 하나 둘 셋 넷
[넷, 둘, 셋, 하나]

$ ./testSort one two thee four
[four, one, thee, two]
*/
------------------------------------------------


컴파일> Dev-C++ 개발 도구(IDE)에서 Ctrl+F11 클릭
또는
컴파일> gcc -o testSort testSort.m -lobjc


실행> testSort 하나 둘 셋 넷
[넷, 둘, 셋, 하나]

실행> ./testSort one two thee four
[four, one, three, two]


 

Posted by Scripter
,


초등학교 때 배우는 두 정수의 곱셈표를 만들어 주는 C 소스이다.

/* * Filename: makeMultTableMain.m * * Print a multiplication table. * * Compile: Click Ctrl+F11 on Dev-C++ IDE * Execute: makeMultTable 230 5100 * * Date: 2012/05/01 * Author: pkim (AT) scripts.pe.kr */ #import <Foundation/Foundation.h> #import <stdio.h> #import <string.h> #import <math.h> void printUsing(); void printMultTable(long x, long y); int main(int argc, const char *argv[]) { long x, y; if (argc >= 3) { x = atoi(argv[1]); y = atoi(argv[2]); printf("\n"); printMultTable(x, y); } else { printUsing(); } return 0; } void printUsing() { // printf("Using: makeMultTable [number1] [number2]\n"); // printf("Print a multiplication table for the given two integers.\n"); printf("사용법: makeMultTable [자연수1] [자연수2]\n"); printf("(손으로 계산하는) 곱셈 계산표를 출력해 줍니다.\n"); } void printMultTable(long x, long y) { long nx, ny; long z; int ntail1; int ntail2; int n; int y1; int i; char strX[80]; char strY[80]; char strZ[80]; char strT[80]; char zeros[80]; char whites[80]; char bars[80]; char line1[80]; char line2[80]; char line3[80]; char line4[80]; char loffset[20]; char buf[80]; nx = (x >= 0) ? x : - x; ny = (y >= 0) ? y : - y; ntail1 = 0; ntail2 = 0; while (nx % 10L == 0L) { nx = nx / 10L; ntail1++; } while (ny % 10L == 0L) { ny = ny / 10L; ntail2++; } z = nx * ny; sprintf(strZ, "%ld", z); sprintf(strX, "%ld", nx); sprintf(strY, "%ld", ny); n = strlen(strY); strcpy(zeros, "0000000000000000000000000000000000000000"); strcpy(whites, " "); strcpy(bars, "----------------------------------------"); strcpy(loffset, " "); sprintf(line4, "%s%ld", loffset, nx*ny); strncpy(buf, zeros, ntail1 + ntail2); buf[ntail1 + ntail2] = '\0'; strcat(line4, buf); strcpy(line1, loffset); strncpy(buf, whites, strlen(strZ) - strlen(strX)); buf[strlen(strZ) - strlen(strX)] = '\0'; strcat(buf, strX); strcat(line1, buf); strncpy(buf, zeros, ntail1); buf[ntail1] = '\0'; strcat(line1, buf); strcpy(line2, " x ) "); strncpy(buf, whites, strlen(strZ) - strlen(strY)); buf[strlen(strZ) - strlen(strY)] = '\0'; strcat(buf, strY); strcat(line2, buf); strncpy(buf, zeros, ntail2); buf[ntail2] = '\0'; strcat(line2, buf); strcpy(line3, " --"); strncpy(buf, bars, strlen(strZ)); buf[strlen(strZ)] = '\0'; strcat(line3, buf); printf("%s\n", line1); printf("%s\n", line2); printf("%s\n", line3); if (strlen(strY) > 1) { for (i = 0; i < strlen(strY); i++) { buf[0] = strY[strlen(strY) - i - 1]; buf[1] = '\0'; y1 = atoi(buf); if (y1 != 0) { sprintf(strT, "%ld", nx * y1); strcpy(line2, loffset); strncpy(buf, whites, strlen(strZ) - strlen(strT) - i); buf[strlen(strZ) - strlen(strT) - i] = '\0'; strcat(buf, strT); strcat(line2, buf); printf("%s\n", line2); } } printf("%s\n", line3); } printf("%s\n", line4); }




컴파일은 Dev-C++ 개발도구에서 Ctrl+F11 클릭

실행> makeMultTable 230 5100
결과>

          230
   x )   5100
     ------
         23
       115
     ------
       1173000

 

Posted by Scripter
,

다음은 초등학교에서 배우는 나눗셈 계산표를 만들어주는 Objective-C 소스 코드이다.

소스 내용은 C 언어 용이나 거의 마찬가지이다.


나눗셈 계산표를 완성하고 나서 약수, 배수 관계를 알려준다.


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



실행> 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 언어용으로 만들어 둔 것들Cygwin 환경에서의 Objective-C 언어용으로 수정한 것들이다.  컴파일 벙법과 #import 부분만 수정하였으므로 C 언어용과 거의 마찬가지이다.

 

콘솔에 삼각형

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


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

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

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


삼각형 출력 예제 1
/*
 *  Filename: printTriangle1.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -o printTriangle1 printTriangle1.m -lobjc
 *  Execute: ./printTriangle1
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -o printTriangle2 printTriangle2.m -lobjc
 *  Execute: ./printTriangle2
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -o printTriangle3 printTriangle3.m -lobjc
 *  Execute: ./printTriangle3
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#import <stdio.h>
#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -o printTriangle4 printTriangle4.m -lobjc
 *  Execute: ./printTriangle4
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#import <stdio.h>
#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -o printTriangle5 printTriangle5.m -lobjc
 *  Execute: ./printTriangle5
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#import <stdio.h>
#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -v -o printTriangle5 printTriangle5.m -lobjc
 *  Execute: ./printTriangle6
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

// #import <Foundation/Foundation.h>  // for usual Linux system with GNUStep installed
#import <Objc/Object.h>  // for Cygwin system with GNUStep npninstalled
#import <stdio.h>
#import <string.h>
#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -v -o printTriangle7 printTriangle7.m -lobjc
 *  Execute: ./printTriangle7
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

// #import <Foundation/Foundation.h>  // for usual Linux system with GNUStep installed
#import <Objc/Object.h>  // for Cygwin system with GNUStep npninstalled
#import <stdio.h>
#import <string.h>
#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -v -o printTriangle8 printTriangle8.m -lobjc
 *  Execute: ./printTriangle8
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

// #import <Foundation/Foundation.h>  // for usual Linux system with GNUStep installed
#import <Objc/Object.h>  // for Cygwin system with GNUStep npninstalled
#import <stdio.h>
#import <string.h>
#import <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();
}




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



삼각형 출력 예제 9
/*
 *  Filename: printTriangle9.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -v -o printTriangle9 printTriangle9.m -lobjc
 *  Execute: ./printTriangle9
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

// #import <Foundation/Foundation.h>  // for usual Linux system with GNUStep installed
#import <Objc/Object.h>  // for Cygwin system with GNUStep npninstalled
#import <stdio.h>
#import <string.h>
#import <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.m
 *            Print a triangle on console.
 *
 *  Compile: gcc -o printTriangle10 printTriangle10.m -lobjc
 *  Execute: ./printTriangle10
 *
 *      Date:  2012/05/01
 *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
 */

#import <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 )

소스 코드 중에 진법변환에 필요한 함수

        convertAtoI()
        convertItoA()

의 구현도 포함되어 있다.

다음 소스는  C 언어 용으로 만들어 두었던 7비트 ASCII 코드표 만들기 예제 with C and Ch 를 수정한 것이다.

19쩨 줄의 enum { FALSE, TRUE }; 부분은 주석 처리하였는데. Objective-C에서는 TRUE와 FALSE가 이미 정의되어 있기 때문이다.

 

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




컴파일은 Dev-C++ 개발 도구에서 Ctrl+F11 클릭

실행> 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진법의 표로 만들어 보여주는 Objective-C 소스 코드이다. 진법 변환에 필요한 함수

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

를 C 뭉 Objective-C 코드로 자체 작성하여 사용하였다.

 

다음 소스는  C 언어 용으로 만들어 두었던 진법(radix) 표 만들기 예제 with C and Ch 를 수정한 것이다.

19쩨 줄의 enum { FALSE, TRUE }; 부분은 주석 처리하였는데. Objective-C에서는 TRUE와 FALSE가 이미 정의되어 있기 때문이다.

 

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



컴파일은 Dev-C++에서 Ctrl+F11 클릭

실행> 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
,