2013년 11월 25일 월요일

[C] 포인터(Pointer)에 대해서

들어가며

많은 분들이 C언어의 포인터를 어려워하십니다. 저 역시 그랬구요.

하지만 지금 되돌아보면
사실 간단한 것인데 주변에서 어렵다 어렵다 하니
저도 그렇게 생각했었던 것 같더라구요

이 글은 포인터를 어려워하시는 분들에게 도움을 드리고 싶어서
포인터에 관한 제 생각을 써보았습니다


왜 포인터를 쓰는 것 일까요?



  • 이 글을 읽고 왜 포인터를 사용하는지 생각해봐요

만약 여러분이 학교나 회사에 갈 때 집을 들고 다닌다면 어떨까요?















바닥에 고정되어있는데다가 너무 무거우니 아무도 그런 것은 하고 싶지 않을거에요










소라개나 달팽이같은 동물들은 집이 무거워서 빠르게 다니지 못해요 ㅠ,ㅠ


그래서 우리는 이런 느린 동물들처럼 집을 들고다니는 대신 주소를 외우고 다니지요

그 편이 훨씬 효율적이고 빠르잖아요 ㅎㅎ


이제 이것을 컴퓨터에 적용시켜보도록 해요


배열이나 구조체같은 것은 변수들을 많이 저장할 수 있어요

변수들에게 집이나 마찬가지이지요

그런데 그런 배열이나 구조체를 변수들이 직접 가지고 다니고 싶어할까요?


물론 컴퓨터를 만들때 굳이 그렇게 시킨다면

변수들을 속으로 울면서도 힘내서 자기들의 집을 들고 다니겠죠

하지만 그렇게하면 분명 컴퓨터가 느려질거에요

여러분은 그런 느린 컴퓨터를 사용하고 싶으신가요?

컴퓨터는 여러분을 기다리게 하지않기 위해서

주소를 적어놓은 변수(포인터)를 쓰는거랍니다.


컴퓨터의 주소는 어떻게 쓸까요?

  • 여기서부터 변수를 종이, 값을 내용이라고 쓸거에요
  • 예제 1과 예제 2를 비교해보아요

예제 1) 포인터를 사용하지 않는 예제



















이 코드를 실행하면 어떤 결과가 나올까요?










이제 이 결과가 왜 이렇게 나왔는지 생각해보도록 해요

우선 우리는

int Value = 10;

이라는 코드를 썼어요.

이것은 Value라는 종이에 10이라는 내용을 쓴 거에요

















그 다음에 실행될 코드는

Increase(Value);

네요. 여기서 main함수의 Value에서 Increase로 Input으로 내용을 전달해요
















이제 Increase함수 안의 코드를 살펴봐요

Input = Input + 1;

Input 이라는 종이에 적힌 내용에 1을 더하고 있어요















하지만 1을 더한 것은 Input이라는 종이이기때문에

Value 종이에는 그대로 10이라고 써있네요

그래서

printf("Value : %d", Value);

를 했을때 10이 나온 것이에요

그럼 여기서 포인터를 사용하면 어떻게 될까요?



예제 2) 포인터를 사용하는 예제




















이 예제의 결과는 어떨까요?










예제 1의 결과와 다른 점이 보이시나요?

예제 1에서는 결과가 10 이었지만

몇 글자를 더 추가한 이 예제는 결과가 11이에요.

이제 예제 2가 왜 이런 결과를 냈는지 설명해드릴께요


main함수의 맨 첫번째는 예제 1과 똑같아요

int Value = 10;

















그런데 두번째 코드는 약간 달라진 점이 있어요

Increase(&Value);

왜 &라는 것을 더 추가했을까요?

왜냐하면 &는 주소를 가르쳐주기때문이에요!
















이제 Input은 Value의 주소를 내용으로 가지고 있어요

그 다음 Increase함수의 내용을 보면

*Input = *Input + 1;

이라고 써있네요.

&이 주소를 가르쳐주는 연산자라면 *는 어떤 연산자일까요?

바로 주소를 따라가는 연산자에요

즉, *Input은 Input에 적힌 주소를 따라가서 Value를 데려오는거에요

















Increase함수에 있던 Input이

주소를 보고 main함수의 Value를 직접 데려와 1을 더해서

printf("Value : %d", Value);

이 코드에서 Value의 내용이 1 늘어난 11 인거에요

이해가 되셨나요?

만약 이해가 않되신다면 직접 코드를 짜서 실험해보면 도움이 될거에요 ㅎㅎ



포인터를 사용하려면 어떻게 해야할까?

포인터를 실제로 사용하려면 딱 세 가지만 알고 있으면 되요
  • int*은 int의 주소를 저장하는 타입
  • &는 주소를 가르쳐주는 연산자
  • *는 주소를 따라가서 데려오는 연산자

이 세 가지만 알면 포인터에 대해서 더 이상 알 것이 없어요. 참 쉽죠?

2013년 11월 19일 화요일

[C#] XML Serialization Sample for Dictionary

Why need it?

Dictionary in System.Collections.Generic is can't serialize to xml.

So, You must make custom dictionary class inherited from IXmlSerializable Interface.


This sample help you for serializing dictionary

and for customizing serialization.


Caution

If you not need to serialize for dictionary,

see other article : Xml serialization

It will give more easy solution.


Source

dropbox(7-zip archive)

2013년 11월 16일 토요일

[C#] Xml Serialization Example ( Directly Write and Read Object as XML )

For serializtion, need something

To make serializable object

namespace

  • using System.Xml.Serialization

class

  • System.Xml.Serialization.XmlRoot Attribute
  • System.Xml.Serialization.XmlElement Attribute
  • System.Xml.Serialization.XmlAttribute Attribute
  • System.Xml.Serialization.XmlArrayItem Attribute
  • ETC


To Write or Read

namespace

  • using System.Xml
  • using System.Xml.Serialization

class

  • System.Xml.Serialization.XmlSerializer Class


Source




Pictures

class World


class Human
















class Pet
















static void Main()

















Result Console















Result File


[C#] Serialization Example ( Directly Write and Read Object as File )

For serializtion, need something

To make serializable object

namespace

  • using System.Runtime.Serialization

class

  • System.Runtime.Serialization.Serializable Attribute
  • System.Runtime.Serialization.ISerializable Interface


To Write or Read

namespace

  • using System.Runtime.Serialization.Formatters.Binary

class

  • System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Class


Source




Pictures

class Human





















class Pet





















static void Main()



















Result


2013년 11월 10일 일요일

[C#] API를 이용한 마우스 제어

들어가며


저는 이 내용을 제가 만든 클래스를 바탕으로 소개하려고 합니다.

API 함수 중에서 mouse_event 라는 함수를 이용하여 만든 것입니다.

정확한 내용을 원하시면 MSDN 에 글이 있으니 읽어보시기를 바랍니다.

※주의 : 마우스 제어를 위한 모든 기능이 갖춰져 있는 것은 아닙니다.

※2013-11-16일 수정

※2016-10-15일 수정
WindowsForm의 기능을 이용하여 수정한 클래스와
WPF에서의 예제 추가


1. enum MouseEventFlag

이 열거체는 mouse_event 함수에 사용하는 매크로들을 모아둔 것입니다.

이름을 보면 대부분 쉽게 이해할 수 있을 것입니다.

원래 API를 위해서 정의된 매크로 리스트
  • const int MOUSEEVENTF_ABSOLUTE = 0x8000;
  • const int MOUSEEVENTF_LEFTDOWN = 0x0002;
  • const int MOUSEEVENTF_LEFTUP = 0x0004;
  • const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
  • const int MOUSEEVENTF_MIDDLEUP = 0x0040;
  • const int MOUSEEVNETF_MOVE = 0x0001;
  • const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
  • const int MOUSEEVENTF_RIGHTUP = 0x0010;
  • const int MOUSEEVENTF_WHEEL = 0x0800;
  • const int MOUSEEVENTF_XDOWN = 0x0080;
  • const int MOUSEEVENTF_XUP = 0x0100;
  • const int MOUSEEVENTF_HWHEEL = 0x1000;
위의 매크로들이 너무 길어서 짧게 고쳤습니다.

[Flags()]
public enum MouseEventFlag : int
{
Absolute = 0x8000,
LeftDown = 0x0002,
LeftUp = 0x0004,
MiddleDown = 0x0020,
MiddleUp = 0x0040,
Move = 0x0001,
RightDown = 0x0008,
RightUp = 0x0010,
Wheel = 0x0800,
XDown = 0x0080,
XUp = 0x0100,
HWheel = 0x1000,
}

여기서 Absolute 란 절대적인 좌표로 마우스를 이동시키는 것을 의미합니다.

마우스를 움질일 때 이 상수를 사용하지 않으면

현재 마우스 좌표를 기준으로 움직이고

이 상수를 사용하면

정확히 정한 좌표로 움직입니다.


2. enum MouseButton

public enum MouseButton
{
Left,
Right,
Middle,
X,
}

3. class Size

public class Size
{
public double Width { set; get; }
public double Height { set; get; }

public Size() { }
public Size(double Width, double Height)
{ this.Width = Width; this.Height = Height; }
}

4. class Point

public struct Point
{
public double X { set; get; }
public double Y { set; get; }

public Point(double X, double Y)
: this()
{ this.X = X; this.Y = Y; }
}

3. class MyMouse

이제 본격적인 본체입니다.

//필요한 네임스페이스
using System;
using System.Runtime.InteropServices; // DllImport를 위한 네임스페이스

public class MyMouse
{
// API함수를 C#에서 사용할 수 있도록 합니다.
#region DllImport
DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);
#endregion

// 절대적인 좌표로 마우스를 움직일때, 약간 특수한 계산이 필요합니다.
#region Constant
const int ABSOLUTE_SIZE = 65535;
#endregion

// 절대적인 좌표로 마우스를 움질일때, 화면 크기를 꼭 알아야합니다.
#region Property
public Size DisplaySize { set; get; }
#endregion

// 마우스를 제어하는 함수들입니다.
#region Moving
public void Move(Point Point) { MouseEventFlag Flag = MouseEventFlag.Move; mouse_event((int)Flag, (int)Point.X, (int)Point.Y, 0, IntPtr.Zero); } public void MoveAt(Point Point) { MouseEventFlag Flag = MouseEventFlag.Move | MouseEventFlag.Absolute;
int X = (int)(ABSOLUTE_SIZE / DisplaySize.Width * Point.X); int Y = (int)(ABSOLUTE_SIZE / DisplaySize.Height * Point.Y); mouse_event((int)Flag, X, Y, 0, IntPtr.Zero); } public void MoveAbsolute(Point Point) { MouseEventFlag Flag = MouseEventFlag.Move | MouseEventFlag.Absolute; mouse_event((int)Flag, (int)Point.X, (int)Point.Y, 0, IntPtr.Zero); } #endregion #region Input public void Down(MouseButton Button) { MouseEventFlag Flag = null; switch (Button) { case MouseButton.Left: Flag = MouseEventFlag.LeftDown; break; case MouseButton.Right: Flag = MouseEventFlag.RightDown; break; case MouseButton.Middle: Flag = MouseEventFlag.MiddleDown; break; case MouseButton.X: Flag = MouseEventFlag.XDown; break; } mouse_event((int)Flag, 0, 0, 0, IntPtr.Zero); } public void Up(MouseButton Button) { MouseEventFlag Flag = null; switch (Button) { case MouseButton.Left: Flag = MouseEventFlag.LeftUp; break; case MouseButton.Right: Flag = MouseEventFlag.RightUp; break; case MouseButton.Middle: Flag = MouseEventFlag.MiddleUp; break; case MouseButton.X: Flag = MouseEventFlag.XUp; break; } mouse_event((int)Flag, 0, 0, 0, IntPtr.Zero); } #endregion
}

예제 : https://www.dropbox.com/s/k9sobbrkgn9yo5m/MouseControlExample.zip?dl=0
Visual Studio 2015 프로젝트입니다

예제 파일만 실행하시려면 [MouseTracker]->[bin]->[Debug]->[MouseTracker.exe]를 실행하시길 바랍니다

2013년 10월 19일 토요일

[C#] 프로세스 생성과 표준입출력을 통해 다른 프로그램과 통신

제가 cUrl 이라는 것을 사용하기 위해서 찾았던 내용들을 여기에 써놓습니다.


1. 프로세스 생성

C#에서 프로세스 생성은 아래의 코드로 할 수 있습니다
아래의 코드는 cmd를 생성하고 도움말을 요청합니다.

필수 : using System.Diagnostics;

ProcessStartInfo CmdInfo = new ProcessStartInfo();
Process Cmd = new Process();

CmdInfo.FileName = @"Cmd"; // 상대경로 가능

CmdInfo.WindowStyle = ProcessWindowStyle.Hidden; // 창이 나타나지 않도록 함
CmdInfo.CreateNoWindow = true;

CmdInfo.UseShellExecute = false;
CmdInfo.RedirectStandardInput = true; // 표준입력을 사용하려면 true
CmdInfo.RedirectStandardOutput = true; // 표준출력을 사용하려면 true
CmdInfo.RedirectStandardError = true; // 표준에러를 사용하려면 true

// void Main(object[] Args) 에서 Args를 여기에서 넣을 수 있다.
// CmdInfo.Arguments = "help";

Cmd.EnableRaisingEvents = false;
Cmd.StartInfo = CurlInfo;


2. 다른 프로그램과 통신

Curl.Start(); // 프로세스 시작

Cmd.StandardInput.WriteLine("help"); // help 라고 cmd에 입력
Cmd.StandardInput.Close(); // 표준 입력을 닫음. 안닫으면 출력을 받을 수 없다.
// StackOverflow에 했던 질문 참조

string Result =  Cmd.StandardOutput.ReadToEnd(); // 표준 출력으로 결과를 받음


3. 장점과 단점

장점 : 어떤 언어로 어떤 컴파일러로 프로그래밍한 실행파일이든 표준입출력만 지원하면
          가져다쓸 수 있다.
단점 : 한 번만 통신할 수 있다는 한계가 아쉽다.

2013년 9월 8일 일요일

[openCV, Python] Basic openCV2 usage in python

<Warning>
    This article was written based on my experience.
</Warning>



1. How Read Image in disc?


You can read by using cv2.imread function.

<Caution>
    In python version 2.7, you need writing path '\\', not '\'
</Caution>

<Code>
import cv2
Image = cv2.imread("Path", cv2.CV_LOAD_IMAGE_GRAYSCALE)
</Code>



2. How Show Image in memory?


Need cv2.imshow function

<Caution>
    If you not use cv2.waitKey && ( cv2.destroyWindow || cv2.destroyAllWindows ).
    It make python IDE to restart
</Caution>

<Code>
import cv2

def ShowImage(Image, WinName="TempWinName"):
    cv2.imshow(WinName, Image)
    cv2.waitKey()
    cv2.destroyWindow(WinName)

ShowImage(Image)
</Code>


3. How Get Size of Image?

Because openCV2 use numpy's array.

You can get size by using Image.shape

shape == (Row, Col, nChannel) or (Height, Width, nChannel)

<Caution>
    If Image is 3 channel (like RGB or BGR), shape's length is 3
    If Image is grayscale, shape's length is 2

    So if you access nChannel in grayscale, It raiseIndexError
</Caution>

<Code>

</Code>


4. How Access each pixel in Image?

Just you "[]" :)

<Caution>
    Image[☆Height, ☆Width, nChannel]

    If you access all the pixel by using for(;;),
    It will waste long time

    Must use openCV function as possible as you can.
</Caution>

<Code>

</Code>

2013년 7월 24일 수요일

[openCV, Python] Test Median Blur by using Salt&Pepper Noise

Median Filter : http://en.wikipedia.org/wiki/Median_filter (Wiki)

You can remove drastic noise efficiently.


import cv2
import numpy as np
import random

def MakeSaltAndPepperNoise (Image, SaltNum, PepperNum):
CopyImage = Image.copy()
nChannel = 0

# Get Image size
Width = CopyImage.shape[0]
Height = CopyImage.shape[1]

# If image is grayscale, it not have Image.shape[2]
# so it raise IndexError exception
try:
nChannel = CopyImage.shape[2]
except IndexError:
nChannel = 1

# Make Salt Noise
for Salt in range(0, SaltNum):
# Generate Random Position
RWidth = random.randrange(0, Width)
RHeight = random.randrange(0, Height)
# Make Noise
if nChannel > 1:
for c in range(0, nChannel):
CopyImage[RWidth, RHeight, c] = 255
else:
CopyImage[RWidth, RHeight] = 255

# Make Pepper Noise
for Pepper in range(0, PepperNum):
# Generate Random Position
RWidth = random.randrange(0, Width)
RHeight = random.randrange(0, Height)
# Make Noise
if nChannel > 1:
for c in range(0, nChannel):
CopyImage[RWidth, RHeight, c] = 0
else:
CopyImage[RWidth, RHeight] = 0

return CopyImage



In IDE



NoiseImage



Proccesed Image

2013년 7월 17일 수요일

[Python] Convert Integer to String

def itoa(Number, Radix=10):
    # Optional code
    if Radix > 16:
        raise ValueError("Radix bigger then 16")

    BASE = "0123456789ABCDEF"
    AlphaList = []

    while Number > 0:
        AlphaList.append(BASE[Number%Radix])
        Number /= Radix

    AlphaList.reverse()

    return "".join(AlphaList)


# in IDE

[openCV, Python] Simple trackbar code for threshold

import cv2
import numpy as np

# Callback Function for Trackbar (but do not any work)
def nothing(*arg):
    pass

# Code here
def SimpleTrackbar(Image, WindowName):
# Generate trackbar Window Name
TrackbarName = WindowName + "Trackbar"

# Make Window and Trackbar
cv2.namedWindow(WindowName)
cv2.createTrackbar(TrackbarName, WindowName, 0, 255, nothing)

# Allocate destination image
Threshold = np.zeros(Image.shape, np.uint8)

# Loop for get trackbar pos and process it
while True:
# Get position in trackbar
TrackbarPos = cv2.getTrackbarPos(TrackbarName, WindowName)
# Apply threshold
cv2.threshold(Image, TrackbarPos, 255, cv2.THRESH_BINARY, Threshold)
# Show in window
cv2.imshow(WindowName, Threshold)

# If you press "ESC", it will return value
ch = cv2.waitKey(5)
if ch == 27:
   break

 cv2.destroyAllWindows()
return Threshold


# in IDE




# Result