후킹에는 여러가지 종류가 있다. 그중에서 가장 대표적인 전역 키보드 후킹방법을 설명하겠다. 우선 전체적인 순서는 다음과 같다.
(1) 훅 프로시저 DLL파일을 만든다.
(2) DLL을 로드시킬 프로그램을 작성한다.
www.winapi.co.kr에서 KeyBeep예제를 visual studio 2008에서 돌아가도록 변경한 것이다. 프로젝트 생성부터 차근차근 해보겠다. 먼저 visual studio 2008을 실행시킨다.




프로젝트를 생성한다. [File]-[New]-[Project...]
위치는 C:\HookEx\로 하고, Solution Name은 KeyHook로 한다. KeyHook 솔루션안에 KeyHookDll 프로젝트와 KeyHookApp 프로젝트, 두 개의 프로젝트를 만들것이다. 우선, KeyHookDll 프로젝트를 생성한다. template은 Win32Project로 한다.




Application type는 DLL로 하고, Additional options는 아무것도 체크하지 않는다.



Header Files 폴더에 stdafx.h, targetver.h 파일이, Source Files 폴더에 dllmain.cpp, KeyHookDll.cpp, stdafx.cpp 파일이 생성되었다. KeyHookDll.cpp 파일에 다음과 같이 작성한다.


#include "stdafx.h"

HINSTANCE gModule=NULL;
HHOOK hKeyHook=NULL;

LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (nCode>=0) {
		SendMessage(hWndBeeper,WM_USER+1,wParam,lParam);
	}
	return CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}

extern "C" __declspec(dllexport) void InstallHook(HWND hWnd)
{
	hKeyHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyHookProc,gModule,NULL);
}

extern "C" __declspec(dllexport) void UninstallHook()
{
	UnhookWindowsHookEx(hKeyHook);
}
dllmain.cpp 파일에는 다음과 같이 작성한다.
#include "stdafx.h" extern HINSTANCE gModule; BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: gModule = hModule; break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }

KeyHookApp프로젝트에 KeyHookApp.cpp파일을 생성하여 다음과 같이 소스를 작성한다.



#include < windows.h >
#include < tchar.h >

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=_T("KeyHookApp");

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
	  ,LPSTR lpszCmdParam,int nCmdShow)
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst=hInstance;
	
	WndClass.cbClsExtra=0;
	WndClass.cbWndExtra=0;
	WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
	WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
	WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	WndClass.hInstance=hInstance;
	WndClass.lpfnWndProc=(WNDPROC)WndProc;
	WndClass.lpszClassName=lpszClass;
	WndClass.lpszMenuName=NULL;
	WndClass.style=CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&WndClass);

	hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,CW_USEDEFAULT,600,130,
		NULL,(HMENU)NULL,hInstance,NULL);
	ShowWindow(hWnd,nCmdShow);
	hWndMain=hWnd;
	
	while(GetMessage(&Message,0,0,0)) {
		TranslateMessage(&Message);
		DispatchMessage(&Message);
	}
	return (int)Message.wParam;
}

extern "C" __declspec(dllimport) void InstallHook(HWND hWnd);
extern "C" __declspec(dllimport) void UninstallHook();

typedef void (* INSTALL_HOOK)(HWND);
typedef void (* UNINSTALL_HOOK)(void);
INSTALL_HOOK installHook;
UNINSTALL_HOOK uninstallHook;

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	static HINSTANCE hinstDLL = NULL; 
	static TCHAR msg1[128];
	static TCHAR msg2[128];
	static TCHAR msg3[128];
	KBDLLHOOKSTRUCT *kb;

	switch(iMessage) {
	case WM_CREATE:
		hinstDLL=LoadLibrary(_T("..\\Release\\KeyHookDll.dll"));
		installHook=(INSTALL_HOOK)GetProcAddress(hinstDLL,"InstallHook");
		uninstallHook=(UNINSTALL_HOOK)GetProcAddress(hinstDLL,"UninstallHook");
		_stprintf_s(msg1,128,_T("hinstDLL:%d, installHook:%p, uninstallHook:%p"),hinstDLL,installHook,uninstallHook);
		installHook(hWnd);
		return 0;
	case WM_USER+1:
		BYTE kb_state[256];
		kb =( KBDLLHOOKSTRUCT*)lParam;
		TCHAR key_state[64];
		switch(wParam){
		case WM_KEYDOWN:
			_stprintf_s(key_state,64,_T("%s"),_T("WM_KEYDOWN"));break;
		case WM_KEYUP:
			_stprintf_s(key_state,64,_T("%s"),_T("WM_KEYUP"));break;
		case WM_SYSKEYDOWN:
			_stprintf_s(key_state,64,_T("%s"),_T("WM_SYSKEYDOWN"));break;
		case WM_SYSKEYUP:
			_stprintf_s(key_state,64,_T("%s"),_T("WM_SYSKEYUP"));break;
		default: _stprintf_s(key_state,64,_T("%s"),_T("Unexpected KeyState"));
		}
		_stprintf_s(msg2,128,_T("Key Message : %s, lParam : %x "),key_state,lParam);
		_stprintf_s(msg2,128,_T("입력된 키:%d, lParam : %x "),wParam,lParam);
		_stprintf_s(msg3,128,_T("vkCode : %c(%d), scanCode : %d"),kb->vkCode,kb->vkCode,kb->scanCode);
		InvalidateRect(hWnd,NULL,TRUE);
		return 0;
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		TextOut(hdc,10,10,msg1,lstrlen(msg1));
		TextOut(hdc,10,30,msg2,lstrlen(msg2));
		TextOut(hdc,10,50,msg3,lstrlen(msg3));
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		uninstallHook();
		FreeLibrary(hinstDLL);
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


이제 해당 프로젝트를 Build한 후 C:\HookEx\Release폴더에 KeyHookDll.dll과 KeyHookApp.exe가 있는지 확인하고, KeyHookApp.exe를 실행시킨다.


'c/c++' 카테고리의 다른 글

quick sort  (0) 2011.09.08
키보드 전역 후킹  (0) 2011.08.29
Console API 모음 (MSDN)  (0) 2011.07.14
Console API를 이용하여 더블버퍼링  (0) 2011.07.14
쓰레드를 이용한 행렬 곱연산  (0) 2010.09.16
Posted by Нуеоп
,

quick sort

c/c++ 2011. 9. 8. 11:08


 

퀵 정렬은 분할 해결 전략을 통해 리스트를 정렬한다.

  1. 리스트 가운데서 하나의 원소를 고른다. 이렇게 고른 원소를 피벗이라고 한다.
  2. 피벗 앞에는 피벗보다 값이 작은 모든 원소들이 오고, 피벗 뒤에는 피벗보다 값이 큰 모든 원소들이 오도록 피벗을 기준으로 리스트를 둘로 나눈다. 이렇게 리스트를 둘로 나누는 것을 분할이라고 한다. 분할을 마친 뒤에 피벗은 더 이상 움직이지 않는다.
  3. 분할된 두 개의 작은 리스트에 대해 재귀적으로 이 과정을 반복한다. 재귀는 리스트의 크기가 0이나 1이 될 때까지 반복된다.

재귀 호출이 한번 진행될 때마다 최소한 하나의 원소는 최종적으로 위치가 정해지므로, 이 알고리즘은 반드시 끝난다는 것을 보장할 수 있다.

http://ko.wikipedia.org/wiki/%ED%80%B5_%EC%A0%95%EB%A0%AC#.EC.95.8C.EA.B3.A0.EB.A6.AC.EC.A6.98





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

void shuffle(int *arr);
void swap(int *a, int *b);
void print(int * arr, int st, int ed);
void quick(int *arr);
void partition(int *arr,int _st, int _ed);

int main(int argc, char *argv[])
{
    int arr[16];
    for(int r=0; r<50; r++){
        for(int i=0; i<16; i++){
            arr[i] = i;
        }
     srand(r);
     shuffle(arr);
     printf("%10s : ","shuffle");
     print(arr,0,15);

     quick(arr);
     printf("%10s : ","quick");
     print(arr,0,15);

     printf("=============================================================\n");
     //break;
    }
    system("pause > nul");
    return 0;
}

void quick(int *arr){
    partition(arr,0,15);
}
void partition(int *arr,int _st, int _ed){
    int p = _ed;
    int buf_p = arr[p];
    int st=_st,ed=_ed-1;
    while(st<ed){
        //if(st<p){
        if( arr[st]<arr[p]){
            st++;
            continue;
        }
        if( arr[ed]>arr[p]){
            ed--;
            continue;
        }
        if( arr[st] > arr[ed]){
            swap(arr+st, arr+ed);
        }
    }
    //printf("st=%d,ed=%d,p=%d\n",st,ed,p);
    if( st < p ){
        if( arr[st]>arr[p]){
            swap(arr+st, arr+p);
            int t = p;
            p = st;
            st = t;
        }
    }

    st = _st;
    ed = _ed;
    printf("(%2d)%6s : ",buf_p,"quick");
    print(arr,st,ed);
    if (st < p) 
        partition(arr, st, p-1); 
          if (ed > p) 
              partition(arr, p+1, ed); 
}

void shuffle(int *arr){
    int n = 100;
    int a,b;
    while(n--){
        a = rand()%16;
        b = rand()%16;
        swap(arr+a,arr+b);
    }
}

void swap(int *a, int *b){
    int t = *a;
    *a = *b;
    *b = t;
}

void print(int * arr, int st, int ed){
    for(int i=0; i<16; i++){
        if( st<=i && i<=ed){
            printf("%3d",arr[i]);
        }
        else{
            printf("   ");
        }
    }printf("\n");
}


'c/c++' 카테고리의 다른 글

키보드 전역 후킹 예제  (2) 2011.09.14
키보드 전역 후킹  (0) 2011.08.29
Console API 모음 (MSDN)  (0) 2011.07.14
Console API를 이용하여 더블버퍼링  (0) 2011.07.14
쓰레드를 이용한 행렬 곱연산  (0) 2010.09.16
Posted by Нуеоп
,

키보드 전역 후킹

c/c++ 2011. 8. 29. 10:39


KeyHookApp.cpp

#include <windows.h>
#include <tchar.h>
/*
http://cboard.cprogramming.com/windows-programming/99678-setwindowshookex-wm_keyboard_ll.html
http://msdn.microsoft.com/en-us/library/ms644985(v=vs.85).aspx
*/
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=_T("KeyHookApp");

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
   ,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=(WNDPROC)WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW | CS_VREDRAW;
 RegisterClass(&WndClass);

 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,CW_USEDEFAULT,600,130,
  NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 hWndMain=hWnd;
 
 while(GetMessage(&Message,0,0,0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
}

extern "C" __declspec(dllimport) void InstallHook(HWND hWnd);
extern "C" __declspec(dllimport) void UninstallHook();

typedef void (* INSTALL_HOOK)(HWND);
typedef void (* UNINSTALL_HOOK)(void);
INSTALL_HOOK installHook;
UNINSTALL_HOOK uninstallHook;

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;

 static HINSTANCE hinstDLL = NULL;
 static TCHAR msg1[128];
 static TCHAR msg2[128];
 static TCHAR msg3[128];
 KBDLLHOOKSTRUCT *kb;

 switch(iMessage) {
 case WM_CREATE:
  hinstDLL=LoadLibrary(_T("..\\Release\\KeyHookDll.dll"));
  installHook=(INSTALL_HOOK)GetProcAddress(hinstDLL,"InstallHook");
  uninstallHook=(UNINSTALL_HOOK)GetProcAddress(hinstDLL,"UninstallHook");
  _stprintf_s(msg1,128,_T("hinstDLL:%d, installHook:%p, uninstallHook:%p"),hinstDLL,installHook,uninstallHook);
  installHook(hWnd);
  return 0;
 case WM_USER+1:
   kb =( KBDLLHOOKSTRUCT*)lParam;

  BYTE kb_state[256];
  _stprintf_s(msg3,128,_T("vkCode : %c(%d), scanCode : %d"),kb->vkCode,kb->vkCode, kb->scanCode);
 
  TCHAR key_state[64];
 switch(wParam){
 case WM_KEYDOWN:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_KEYDOWN"));break;
 case WM_KEYUP:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_KEYUP"));break;
 case WM_SYSKEYDOWN:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_SYSKEYDOWN"));break;
 case WM_SYSKEYUP:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_SYSKEYUP"));break;
 default: _stprintf_s(key_state,64,_T("%s"),_T("Unexpected KeyState"));
 }
  _stprintf_s(msg2,128,_T("Key Message : %s, lParam : %x "),key_state,lParam);
  InvalidateRect(hWnd,NULL,TRUE);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);
  TextOut(hdc,10,10,msg1,lstrlen(msg1));
  TextOut(hdc,10,30,msg2,lstrlen(msg2));
  TextOut(hdc,10,50,msg3,lstrlen(msg3));
  EndPaint(hWnd, &ps);
  return 0;
 case WM_DESTROY:
  uninstallHook();
  FreeLibrary(hinstDLL);
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}





KeyHookDll.cpp

#include "stdafx.h"

HINSTANCE gModule=NULL;
HHOOK hKeyHook=NULL;
HWND gHwnd=NULL;

LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 if (nCode>=0) {
  SendMessage(gHwnd,WM_USER+1,wParam,lParam);
 }
 return CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}

extern "C" __declspec(dllexport) void InstallHook(HWND hWnd)
{
 gHwnd=hWnd;
 hKeyHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyHookProc,gModule,NULL);
}

extern "C" __declspec(dllexport) void UninstallHook()
{
 UnhookWindowsHookEx(hKeyHook);
}




dllmain.cpp

#include "stdafx.h"

extern HINSTANCE gModule;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  gModule = hModule;
  break;
 case DLL_THREAD_ATTACH:
 case DLL_THREAD_DETACH:
 case DLL_PROCESS_DETACH:
  break;
 }
 return TRUE;
}


'c/c++' 카테고리의 다른 글

키보드 전역 후킹 예제  (2) 2011.09.14
quick sort  (0) 2011.09.08
Console API 모음 (MSDN)  (0) 2011.07.14
Console API를 이용하여 더블버퍼링  (0) 2011.07.14
쓰레드를 이용한 행렬 곱연산  (0) 2010.09.16
Posted by Нуеоп
,

Console API 모음 (MSDN)

c/c++ 2011. 7. 14. 17:40


http://msdn.microsoft.com/en-us/library/ms682073(v=VS.85).aspx

Console Functions

The following functions are used to access a console.

Function Description
AddConsoleAlias Defines a console alias for the specified executable.
AllocConsole Allocates a new console for the calling process.
AttachConsole Attaches the calling process to the console of the specified process.
CreateConsoleScreenBuffer Creates a console screen buffer.
FillConsoleOutputAttribute Sets the text and background color attributes for a specified number of character cells.
FillConsoleOutputCharacter Writes a character to the console screen buffer a specified number of times.
FlushConsoleInputBuffer Flushes the console input buffer.
FreeConsole Detaches the calling process from its console.
GenerateConsoleCtrlEvent Sends a specified signal to a console process group that shares the console associated with the calling process.
GetConsoleAlias Retrieves the specified alias for the specified executable.
GetConsoleAliases Retrieves all defined console aliases for the specified executable.
GetConsoleAliasesLength Returns the size, in bytes, of the buffer needed to store all of the console aliases for the specified executable.
GetConsoleAliasExes Retrieves the names of all executables with console aliases defined.
GetConsoleAliasExesLength Returns the size, in bytes, of the buffer needed to store the names of all executables that have console aliases defined.
GetConsoleCP Retrieves the input code page used by the console associated with the calling process.
GetConsoleCursorInfo Retrieves information about the size and visibility of the cursor for the specified console screen buffer.
GetConsoleDisplayMode Retrieves the display mode of the current console.
GetConsoleFontSize Retrieves the size of the font used by the specified console screen buffer.
GetConsoleHistoryInfo Retrieves the history settings for the calling process's console.
GetConsoleMode Retrieves the current input mode of a console's input buffer or the current output mode of a console screen buffer.
GetConsoleOriginalTitle Retrieves the original title for the current console window.
GetConsoleOutputCP Retrieves the output code page used by the console associated with the calling process.
GetConsoleProcessList Retrieves a list of the processes attached to the current console.
GetConsoleScreenBufferInfo Retrieves information about the specified console screen buffer.
GetConsoleScreenBufferInfoEx Retrieves extended information about the specified console screen buffer.
GetConsoleSelectionInfo Retrieves information about the current console selection.
GetConsoleTitle Retrieves the title for the current console window.
GetConsoleWindow Retrieves the window handle used by the console associated with the calling process.
GetCurrentConsoleFont Retrieves information about the current console font.
GetCurrentConsoleFontEx Retrieves extended information about the current console font.
GetLargestConsoleWindowSize Retrieves the size of the largest possible console window.
GetNumberOfConsoleInputEvents Retrieves the number of unread input records in the console's input buffer.
GetNumberOfConsoleMouseButtons Retrieves the number of buttons on the mouse used by the current console.
GetStdHandle Retrieves a handle for the standard input, standard output, or standard error device.
HandlerRoutine An application-defined function used with the SetConsoleCtrlHandler function.
PeekConsoleInput Reads data from the specified console input buffer without removing it from the buffer.
ReadConsole Reads character input from the console input buffer and removes it from the buffer.
ReadConsoleInput Reads data from a console input buffer and removes it from the buffer.
ReadConsoleOutput Reads character and color attribute data from a rectangular block of character cells in a console screen buffer.
ReadConsoleOutputAttribute Copies a specified number of foreground and background color attributes from consecutive cells of a console screen buffer.
ReadConsoleOutputCharacter Copies a number of characters from consecutive cells of a console screen buffer.
ScrollConsoleScreenBuffer Moves a block of data in a screen buffer.
SetConsoleActiveScreenBuffer Sets the specified screen buffer to be the currently displayed console screen buffer.
SetConsoleCP Sets the input code page used by the console associated with the calling process.
SetConsoleCtrlHandler Adds or removes an application-defined HandlerRoutine from the list of handler functions for the calling process.
SetConsoleCursorInfo Sets the size and visibility of the cursor for the specified console screen buffer.
SetConsoleCursorPosition Sets the cursor position in the specified console screen buffer.
SetConsoleDisplayMode Sets the display mode of the specified console screen buffer.
SetConsoleHistoryInfo Sets the history settings for the calling process's console.
SetConsoleMode Sets the input mode of a console's input buffer or the output mode of a console screen buffer.
SetConsoleOutputCP Sets the output code page used by the console associated with the calling process.
SetConsoleScreenBufferInfoEx Sets extended information about the specified console screen buffer.
SetConsoleScreenBufferSize Changes the size of the specified console screen buffer.
SetConsoleTextAttribute Sets the foreground (text) and background color attributes of characters written to the console screen buffer.
SetConsoleTitle Sets the title for the current console window.
SetConsoleWindowInfo Sets the current size and position of a console screen buffer's window.
SetCurrentConsoleFontEx Sets extended information about the current console font.
SetStdHandle Sets the handle for the standard input, standard output, or standard error device.
WriteConsole Writes a character string to a console screen buffer beginning at the current cursor location.
WriteConsoleInput Writes data directly to the console input buffer.
WriteConsoleOutput Writes character and color attribute data to a specified rectangular block of character cells in a console screen buffer.
WriteConsoleOutputAttribute Copies a number of foreground and background color attributes to consecutive cells of a console screen buffer.
WriteConsoleOutputCharacter Copies a number of characters to consecutive cells of a console screen buffer.

'c/c++' 카테고리의 다른 글

quick sort  (0) 2011.09.08
키보드 전역 후킹  (0) 2011.08.29
Console API를 이용하여 더블버퍼링  (0) 2011.07.14
쓰레드를 이용한 행렬 곱연산  (0) 2010.09.16
c/c++ 2차원(이차원) 배열 동적할당 방법2  (0) 2010.08.06
Posted by Нуеоп
,


CreateConsoleScreenBuffer() 와 SetConsoleActiveScreenBuffer()를 이용하여, 콘솔에서 더블버퍼링을 구현해보았다.

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

void PrintConsoleScreen(const int nCurView, HANDLE hConsoleBuf[2], LPCTSTR lpCharacter, COORD dwWriteCoord);
void UpdateScreen(int *nCurView, HANDLE hConsoleBuf[2]);

void DrawRectangle(){
 char Mark[21][3] = { "☆","★","○","●","◎","◇","◆","□","■","△","▲","▽","▼","◈","▣","♤","♠","♡","♥","♧","♣"};
 int x,y;
 system("cls");
 for(y=0; y<20; y++){
  for(x=0; x<30; x++){
   printf("%s", Mark[rand()%21]);
  }
  printf("\n");
 }
}

void DrawRectangleBuffering(int *nCurView, HANDLE hConsoleBuf[2]){
 COORD pos = {0, 0};
 int x,y;
 
 LPCTSTR Mark[21] = { _T("☆"),_T("★"),_T("○"),_T("●"),_T("◎"),_T("◇"),_T("◆"),_T("□"),_T("■"),_T("△"),_T("▲"),_T("▽"),_T("▼"),_T("◈"),_T("▣"),_T("♤"),_T("♠"),_T("♡"),_T("♥"),_T("♧"),_T("♣")};
 
 for(y=0; y<20; y++){
  pos.Y = y;
  for(x=0; x<30; x++){
   pos.X = 2*x;
   PrintConsoleScreen(*nCurView, hConsoleBuf, Mark[rand()%21],  pos);
  }
 }
 UpdateScreen(nCurView, hConsoleBuf);
}

int main(int argc, const char *argv[]){
 HANDLE hConsoleBuf[2];
 int nCurView=0;
 bool bFlag;
 int i=0;
 hConsoleBuf[0] = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
 hConsoleBuf[1] = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
 while(i++<100){
  //DrawRectangleBuffering(&nCurView, hConsoleBuf);
  DrawRectangleA();
  Sleep(1000);
 }
 return 0;
}
void PrintConsoleScreen(const int nCurView, HANDLE hConsoleBuf[2], LPCTSTR lpCharacter, COORD dwWriteCoord)
{
 WriteConsoleOutputCharacter(hConsoleBuf[nCurView], lpCharacter, _tcslen(lpCharacter), dwWriteCoord, NULL);
}
void UpdateScreen(int *nCurView, HANDLE hConsoleBuf[2])
{
 SetConsoleActiveScreenBuffer(hConsoleBuf[*nCurView]);
 *nCurView = (*nCurView+1)%2;
}




Posted by Нуеоп
,
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
//#include<assert.h>  // thread-unsafe
/***
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine)(void *), void *arg);
***/

#define _CRITICIAL_SECTION 0

typedef struct _MATRIX
{
    int **array;
    int col,row;
}MATRIX,Matrix,*pMatrix;

typedef struct _PARAM
{
    MATRIX M1,M2,R;
    int n;
}PARAM,Param,*ptrParam;

int sample1[] = {
    3,4,2,0,4,7,3,0,9,1,2,8,7,4,9,1,
    7,3,8,2,3,1,0,4,5,8,7,3,5,6,8,2,
};
int sample2[] = {
    7,3,8,2,3,1,0,4,5,8,7,3,5,6,8,2,
    3,4,2,0,4,7,3,0,9,1,2,8,7,4,9,1,
};

int n_thread;

#if _CRITICIAL_SECTION
CRITICAL_SECTION cs;
#endif

void assert(bool a){ if(a!=true) {printf("alert!!\n"); exit(0);}/*return ;*/}
void init_matrix(Matrix *, int, int);
int** create_array(int, int);
void set_zero(Matrix *M);
void free_array(int **, int, int);
void mul_matrix(Matrix *, Matrix *, Matrix *);
void mul_matrix_thread(Matrix *, Matrix *, Matrix *);
void cal_part(Matrix *, Matrix *, Matrix *, int);
DWORD WINAPI cal_part_thread(void* arg);
void set_sample(Matrix *, int *);
void print_matrix(Matrix);

int main(int argc, char *argv[])
{
    Matrix M1,M2,Result;

    init_matrix(&M1, 4, 3 );
    init_matrix(&M2, 3, 4 );

    set_sample(&M1, sample1);
    set_sample(&M2, sample2);

    print_matrix(M1);
    print_matrix(M2);

    n_thread = M1.col;

    mul_matrix_thread(&M1,&M2,&Result);

    print_matrix(Result);

    free_array(M1.array, M1.row, M1.col);
    free_array(M2.array, M2.row, M2.col);
    free_array(Result.array, Result.row, Result.col);

    return 0;
}

void init_matrix(Matrix *M,int w,int h)
{
    M->col = h;
    M->row = w;
    M->array = create_array(w,h);
    set_zero(M);
}

int** create_array(int w, int h)
{
    int height=h,width=w;
    int **array = (int **) malloc( sizeof(int *)* height);
    array[0] = (int *) malloc( sizeof(int) * width*height );
    int i;
    for( i=1 ; i< height ; i++)
        array[i] = array[ i-1 ] + width;
    return array;
}

void set_zero(Matrix *M)
{
    memset(M->array[0], 0x00, sizeof(int)*M->col*M->row);
}

void free_array(int **array, int w, int h)
{
    assert(array!=NULL);
    assert(array[0]!=NULL);
    free(array[0]);
    free(array);
}

void mul_matrix(Matrix *M1, Matrix *M2, Matrix *R)
{
    assert(M1->row == M2->col);
    assert(M1->col == M2->row);
    init_matrix(R,M1->col,M2->row);
    int n;
    for( n=0; n < R->col ; n++ ){
        cal_part(M1,M2,R,n);
    }
}

void mul_matrix_thread(Matrix *M1, Matrix *M2, Matrix *R)
{
    PARAM *param=NULL;
    param = (PARAM*)malloc(sizeof(PARAM)*n_thread);
    HANDLE *hThread=NULL;
    hThread = (HANDLE*)malloc(sizeof(HANDLE)*n_thread);

#if _CRITICIAL_SECTION
    InitializeCriticalSection(&cs);
#endif

    assert(M1->row == M2->col);
    assert(M1->col == M2->row);
    init_matrix(R,M1->col,M2->row);
    int i;
    for( i=0; i< n_thread; i++){
        param[i].M1 = *M1;
        param[i].M2 = *M2;
        param[i].R = *R;
        param[i].n = i;
    }
    int n;
    for( n=0; n < R->col ; n++ ){
        hThread[n] = CreateThread(NULL,0,cal_part_thread,(void*)(param+n),0,NULL);
        if(hThread[n]>0){
            printf("hThread[%d] created\n",n);
        }
        else{
            printf("hThread[%d] fail to create\n",n);
        }
    }
    WaitForMultipleObjects(n_thread,hThread,TRUE,INFINITE);

#if _CRITICIAL_SECTION
    DeleteCriticalSection(&cs);
#endif

    for( n=0; n < R->col ; n++){
        CloseHandle(hThread[n]);
    }
    printf("\n");
}

void cal_part(Matrix *M1, Matrix *M2, Matrix *R, int n)
{
    assert(M1->row == M2->col);
    assert(M1->col == M2->row);
    assert(M1->col == R->row);
    assert(M2->row == R->col);
    int buf;
    int i,j;
    for( i=0 ; i < R->row; i++ ){
        for( j=0,buf=0 ; j < M1->row ; j++ ){
            buf += M1->array[n][j]*M2->array[j][i];
        }
        R->array[n][i] = buf;
    }
}

DWORD WINAPI cal_part_thread(void* arg)
{
    PARAM param = *(PARAM *)arg;
    cal_part(&param.M1,&param.M2,&param.R,param.n);
}

void set_sample(Matrix *M, int *src)
{
    assert(M->array!=NULL);
    int i,j;
    for( i=0; i < M->col; i++){
        for( j=0; j < M->row; j++){
            M->array[i][j] = src[i*M->row + j];
        }
    }
}

void print_matrix(Matrix M)
{
    int i,j;
    for( i=0; i < M.col; i++){
        for( j=0; j < M.row; j++){
            printf("%3d ",M.array[i][j]);
        }
        printf("\n");
    }
    printf("\n");

Posted by Нуеоп
,

int **array = null;
int height=8,width=6;
array = (int **) malloc( sizeof(int *)* height );
for( int i=0; i < height ; i++)
    array[i] = (int *) malloc( sizeof(int)* width );


이런식으로 동적할당 하면 malloc를 height만큼 호출하기 때문에 행과 열이 나누어 진다.

memset으로 한번에 값을 지정할 수도 없고
할당된 메모리를 해제할경우 for문으로 height번만큼 해제해줘야 한다.

int **array = null;
int height=8,width=6;
array = (int **) malloc( sizeof(int *)* height);
array[0] = (int *) malloc( sizeof(int) * width*height );
for( int i=1; i< height ; i++)
    array[i] = array[ 0 ] + i*width;



조금더 고쳐보면..

int **array = null;
int height=8,width=6;
array = (int **) malloc( sizeof(int *)* height);
array[0] = (int *) malloc( sizeof(int) * width*height );
for( int i=1; i< height ; i++)
    array[i] = array[ i-1 ] + width;




Posted by Нуеоп
,

1차원 배열을 동적할당하려면 malloc()를 한번만 사용하면 된다.
2차원 배열을 동적으로 할당하려면 malloc()을 여러번 사용해야한다.

int **array = null;
int height=8,width=6;
array = (int **) malloc( sizeof(int *)* height );
for( int i=0; i < height ; i++)
    array[i] = (int *) malloc( sizeof(int)* width );



전체 소스로 보면..
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char *argv[])
{
        int **array = NULL;
        int HEIGHT = 5;
        int WIDTH = 6;
        //2차원 배열 생성 int array[6][5]
        array = (int **) malloc( sizeof(int*)*HEIGHT );
        for( int i=0; i<HEIGHT; i++) {
            array[i] = (int *) malloc( sizeof(int)*WIDTH );
        }
        //임의의 수 할당
        for( int i=0; i<HEIGHT; i++)
        for( int j=0; j<WIDTH; j++)
            array[i][j] = i*WIDTH + j + 1;
        //2차원 배열 출력
        for( int i=0; i<HEIGHT; i++){
            for( int j=0; j<WIDTH; j++){
                printf(" %2d",array[i][j]);
            }
            printf("\n");
        }
        return 0;
}

Posted by Нуеоп
,
<math.h>의 sqrt()를 사용하지 않고 제곱근을 구하는 소스
NUM_REPEAT값은 16~20 이면 충분하다.
큰수의 제곱근을 구할경우 NUM_REPEAT값을 더 큰수로 정하면 된다.

원리는 뉴튼-랩슨법을 이용한 근사값 구하기

double mysqrt(unsigned int src)
{
    unsigned int NUM_REPEAT = 16;
    unsigned int k;
    double t;
    double buf = (double)src;
    for(k=0,t=buf;k<NUM_REPEAT;k++)
    {
        if(t<1.0)
            break;
        t = (t*t+buf)/(2.0*t);
    }
    return t;
}

'c/c++' 카테고리의 다른 글

쓰레드를 이용한 행렬 곱연산  (0) 2010.09.16
c/c++ 2차원(이차원) 배열 동적할당 방법2  (0) 2010.08.06
c언어 2차원(이차원) 배열 동적 할당 방법  (0) 2010.08.03
sin 그래프  (0) 2010.07.30
중복없는 숫자 뽑기  (0) 2010.07.29
Posted by Нуеоп
,

sin 그래프

c/c++ 2010. 7. 30. 15:54
c언어로 만든 sin 그래프

#include #include #define WIDTH 19 #define HEIGHT 100 #define PI (3.141592) bool isEqual(double d1,double d2, double e); int main(int argc, char *argv[]) { double x=0.0; double y=0.0; int col=0,row=0; printf("%-*d%1d%*d\n",WIDTH,-1,0,WIDTH,1); for(row=0;row0.0?d1-d2:d2-d1) 결과
-1                 0                  1
---------------------------------------
                   *                   
                   |     *             
                   |          *        
                   |              *    
                   |                 * 
                   |                  *
                   |                 * 
                   |              *    
                   |          *        
                   |     *             
                   *                   
             *     |                   
        *          |                   
    *              |                   
 *                 |                   
*                  |                   
 *                 |                   
    *              |                   
        *          |                   
             *     |                   
                   *                   
                   |     *             
                   |          *        
                   |              *    
                   |                 * 
                   |                  *
                   |                 * 
                   |              *    
                   |          *        
                   |     *             
                   *                   
             *     |                   
        *          |                   
    *              |                   
 *                 |                   
*                  |                   
 *                 |                   
    *              |                   
        *          |                   
             *     |                   
                   *                   
                   |     *             
                   |          *        
                   |              *    
                   |                 * 
                   |                  *
                   |                 * 
                   |              *    
                   |          *        
                   |     *             
                   *                   
             *     |                   
        *          |                   
    *              |                   
 *                 |                   
*                  |                   
 *                 |                   
    *              |                   
        *          |                   
             *     |                   
                   *                   
                   |     *             
                   |          *        
                   |              *    
                   |                 * 
                   |                  *
                   |                 * 
                   |              *    
                   |          *        
                   |     *             
                   *                   
             *     |                   
        *          |                   
    *              |                   
 *                 |                   
*                  |                   
 *                 |                   
    *              |                   
        *          |                   
             *     |                   
                   *                   
                   |     *             
                   |          *        
                   |              *    
                   |                 * 
                   |                  *
                   |                 * 
                   |              *    
                   |          *        
                   |     *             
                   *                   
             *     |                   
        *          |                   
    *              |                   
 *                 |                   
*                  |                   
 *                 |                   
    *              |                   
        *          |                   
             *     |                   
Posted by Нуеоп
,