본문 바로가기

예제 모음/C/C++

[C언어] printf를 이용해 소수점 이하 자릿수 설정하기 ※ 요약 C언어의 printf를 이용하여 float형이나 double형을 출력할때 소수점 이하 자릿수를 조절해서 출력하는 방법에 대한 글이다. C언어의 printf를 이용하여 자릿수를 정할 때는 보통 printf( "%.2f\n", 3.141592 );와 같이 자릿수를 설정하면 런타임 때 자릿수를 바꿀 수 없지만 이번에 포스팅하는 방법으로는 런타임 때도 자릿수를 바꿀 수 있어 좀 더 유연하게 출력이 가능하다.C++의 cout도 궁금하다면 부동 소수점의 출력 정밀도 설정을 참고하기 바란다. ※ 소스코드 소스코드는 딱히 설명이 필요없을 정도로 간단하다. 필자는 예제를 위해 아래처럼 Print함수를 제작하였고, 필요에 따라 자릿수를 변경하여 출력하도록 하였다. 참고로 인자로 받을때 레퍼런스로 받도록 &를 붙였.. 더보기
[C/C++] sin, cos을 이용해서 원 그리기 ※ 요약 sin과 cos을 이용하여 직접 원을 그리는 방법이다. 직접 원을 그리므로 원하는 각도 만큼만 그릴수 있는데, 필자는 이를 신입때 만든 각도기 프로그램에 접목시켰다. 지금 이 예제는 Win32 API + OpenGL인데, MFC에서 GDI를 이용한 예제도 올리도록 하겠다. 또 타원 그리기 예제도 올릴것이고, 그 후에는 임의의 점이 원이나 타원에 속해 있는지 판별하는 예제도 올리도록 하겠다. 또 그후에는 타원이나 사각형 등의 도형을 직접 회전하는 예제도 올리겠다. 또 원 안에만 점을 찍는 예제는 여기서 확인할 수 있다. ※ 특징 math.h에 있는 sin과 cos을 이용하여 원을 그린다. DrawCircle2D가 원을 그리는 함수다. 배포하고 있는 프로그램이라 소스 코드의 일부만 올렸는데, MFC.. 더보기
[C++] 두 점 사이의 거리 구하기 ※ 요약 이전에는 C언어로 두 점 사이의 거리를 구했는데, 같은 예제를 이번엔 C++로 작성해보았다. 사실 매일 하나의 글을 포스팅하기 위해 C언어와 C++을 나눠서 하느라 가끔 억지스러운 면이 없지 않아 있는거 같다. ※ 특징 C++을 이용해 피타고라스 정리를 구현하여 두 점 사이의 거리를 구한다. 좀 더 자세한 설명은 이전 글에 있으니 필요하다면 참고하기 바란다. 큰 틀은 C언어로 작성한 것과 같다. template 클래스와 template 함수로 작성하여 타입에 상관없이 거리를 구할 수 있게 하였다. 이렇게 template으로 만든 이유는, 윈도우 클라이언트 영역은 정수 타입이고, OpenGL이나 DirectX는 보통 실수 타입이기 때문이다. 또 필자는 아직 template 문법에 약하기 때문에 조.. 더보기
[C언어] 두 점 사이의 거리 구하기 ※ 요약 피타고라스의 정리를 이용한 두 점 사이의 거리 구하기다. 아래 그림과 같은 직각 삼각형이 있을때, 세 변의 길이는 a^2+b^2=c^2인 관계가 성립한다는 것이 피타고라스 정리다. 위 같은 공식을 아래 그림에 적용해보자. 먼저 빨간점 p1과 p2가 있고, 각각 가상의 수직선과 수평선을 그었다. 그리고 가상의 노란 빗변을 이어주니 직각 삼각형이 되었다. 이제 a^2+b^2=c^2를 이용하여 두 점 사이의 거리를 구한다는게 느낌이 올 것이다. (좀더 자세히 쓰려다가 그림 그리기도 귀찮고 수식 입력도 안되서 여기까지 작성함) ※ 특징 C언어를 이용해 피타고라스 정리를 구현하여 두 점 사이의 거리를 구한다. C언어 소스는 아래와 같다. 임의의 점 p1(432, 189)과 p2(38, 392)의 거리를 .. 더보기
[C++11] 중복없는 로또 프로그램2 ※ 로또 프로그램 요약 얼마 전 C++11 문법을 이용한 로또 프로그램을 올렸는데, 그 때 올린건 이전에 만든 C 스타일과의 비교를 위해 class를 이용하지 않았었다. 이번에 만든 건 class를 이용하여 만든 버전이다. 더불어 Sunny Holic님이 언급하신 std::shuffle 방식과 random 방식의 속도 비교도 해보았다. ※ 로또 프로그램 특징 - 이전에 만들었던 것과 다르게 class를 이용하여 제작하였다. - random 방식과 std::shuffle 방식을 이용하여 번호를 생성하며, 두 방법의 속도를 비교 하였다. 아래는 예제 소스코드다, 소스코드는 첨부해뒀으니 Visual Studio 2013 이상이라면 바로 컴파일해 볼 수 있다. - header file main.cpp 아래는 속.. 더보기
[C++11] 중복없는 로또 프로그램 ※ 로또 프로그램 요약 C++11 문법을 이용하여 제작한 간단한 로또 프로그램이다. 전에 C언어로 제작한 로또 프로그램을 C++11 문법으로 리팩토링 하였다. 알고리즘 및 큰 흐름은 거의 같고 문법만 C에서 C++11로 바꿨으니 둘을 비교하면서 보면 좋을 것이다. ※ 로또 프로그램 특징 - C++11에 추가된 새로운 random(Mersenne Twister)을 이용하여 속도가 빠르고 품질이 좋다. - 중복 판별을 위한 인덱스를 따로 관리하여 요소 개수가 많더라도 중복 판별에 상수 시간 복잡도를 갖을 수 있어 매우 빠르다. - 표준 문법으로만 작성하여 윈도우, 리눅스 모두 컴파일 가능하다. (단 VS2013(12.0) 이상, gcc 4.8 이상) #include //std::cout #include //.. 더보기
[C++11] 원 안에만 점 찍기 친구가 임의의 위치와 임의의 크기의 원 안에만 점을 찍고 싶다고 해서 만든 함수 입니다. 함수의 첫 번째 인자는 원의 중심 위치고 두 번째는 반지름, 세 번째는 점의 크기입니다. 랜덤 함수로는 C++11의 random헤더에 있는 random_device와 mt19937_64를 사용 했습니다.원 안에만 점을 찍는 이유는 포탄이나 탄알이 조준 한 곳에 안 맞고 오차가 있기 때문입니다.서든어택이나 AVA 등의 FPS 게임 해보신 분들은 잘 아실듯요.원 그리기는 이 링크에 있습니다. ※함수void CFigure::DrawRandomPoint2D( const POINT ptPos, const float nRadius, const float ptSize /*= 2.0f*/ ) const { POINT ptPoint.. 더보기
[C언어] rand 함수를 이용한 로또 프로그램 ※설명 아래는 C언어로 만든 로또 번호 생성 예제이자 중복 없는 난수 생성 예제다. 본인이 배포하는 로또 프로그램에서 일부 가져와 군더더기를 제거하고 예제에 맞게 수정했다. 중복을 방지하기 위해 생성 여부에 대한 일종의 인덱스를 둬서 따로 검사하지 않아도 중복을 방지할 수 있게 했다. 흔히 사용하는 배열 요소를 처음부터 끝까지 조사 방식은 배열 개수에 따라 속도가 엄청 느려지므로 추천하지 않으며 이렇게 인덱스를 두는 방법은 에라토스테네스의 체를 구할 때도 이용되고 데이터를 캐싱할 때 이미 불러들인 데이터인지 판별할 때도 사용된다. C++로 구현한 로또 프로그램도 있으니 비교해보니 바란다. ※예제#include #include //srand #include //time //#define _MAX 6 con.. 더보기
[C언어] 재귀 함수 - 10진수 -> 2진수 변환 ※요약 재귀함수를 통해 10진수를 2진수로 변환한다. ※특징 10진수 n을 Dec2Binary함수에 넣으면 2진수로 출력해준다. int형으로 값을 받으므로 2,147,483,647의 수까지 변환이 되며, 더 큰 수를 변환하고 싶으면 unsigned int나 unsigned __int64로 하면 된다. unsigned __int64의 경우 18446744073709551615의 수를 2진수로 변환 할 수 있다. ※예제 #include void Dec2Binary( unsigned __int64 nNum ); int main( ) { unsigned __int64 nNum = 0; printf( "-1 입력시 종료 됩니다.\n" ); while( nNum != -1 ) { printf( "숫자를 입력하세요 .. 더보기
[C언어] 소수점 특정 자릿수 반올림하기 - ROUND 함수 ※요약C언어나 C++ 등에서 소수점 특정 자릿수 반올림하는 방법입니다. 매크로 함수와 일반 함수 2가지로 구현되어 있으며, 다른 곳에서 사용할 땐 원하는 함수만 복사해서 쓰면 됩니다. ※예제 #include #include #define ROUNDING(x, dig)( floor((x) * pow(float(10), dig) + 0.5f) / pow(float(10), dig) ) double Rounding( double x, int digit ) { return ( floor( (x) * pow( float(10), digit ) + 0.5f ) / pow( float(10), digit ) ); } int main( ) { printf( "%g\n", ROUNDING( 9.3453456, 3 ) ).. 더보기
[C언어] 어떤 수 x가 2의 n승인지 판별하는 함수 ※요약어떤 수가 있을 때, 이 수가 2의 n승인지 판별하는 방법입니다. ※특징비트 연산을 이용해 속도가 빠름 ※함수 설명2의 3승인 8을 2진수로 표현하면 아래와 같습니다.(편의상 8비트로 표현)0000 1000여기서 1을 빼주면0000 0111이 되고, 0000 1000와 & 연산을 하게 되면 0이 나옵니다. 0000 10000000 0111-------------&연산 (& 연산자는 두 개의 비트가 모두 1일 때 1이 됨, 고로 여기서는 0이 됨)0000 0000 비트 연산 보기 ※예제 #include bool CheckPowerOfTwo( int nNum ); int main( ) { int x = 0; bool bState = false; printf( "-1 입력시 종료 됩니다.\n" ); wh.. 더보기
[C언어] 재귀 함수 - 이진 탐색 (Binary Search) ※요약C언어에서 재귀 호출을 이용한 이진 탐색이다. 이진 탐색이란 이름 그대로 탐색할 데이터를 반으로 나눠 나머지 반만 탐색하는 방식을 반복하는 알고리즘이며 빠른 속도로 원하는 값을 찾을 수 있다. 이진 검색, 이분 검색 등으로도 불린다. ※특징 - 각 요소의 값들은 정렬되어 있어야 한다. - 각 요소의 값들은 모두 달라야 한다. ※예제 #include int RecusiveBinSearch( int nArr[], int nBegin, int nEnd, int nTarget ) { int nMid = 0; if( nBegin > nEnd ) { return -1;//탈출 조건 및 탐색 실패 } nMid = (nBegin+nEnd) / 2; if( nArr[nMid] == nTarget ) { return.. 더보기
[C언어] 재귀 함수 - 거듭제곱 (power) ※요약 C언어에서 재귀 호출을 이용한 거듭제곱 구하는 함수다. 어떤 수 a에 대하여 n개 곱한 것을 a^n( an )이라 표시하고 a의 n제곱이라 하며, n을 거듭제곱의 지수라고 한다. a = 3, n = 5일때 3^5 = 243 = 3 * 3 * 3 * 3 * 3 다. ※예제 #include double power( double a, int num ); int main( ) { printf( "%.10lf", power( 3.141592653589793238462643383279, 3 ) ); return 0; } double power( double a, int num ) { if( num == 0 ) return 1; return a * power( a, num-1 ); } ※결과 더보기
[C언어] 재귀 함수 - 팩토리얼 (Factorial) ※요약C언어에서 재귀 호출을 이용한 팩토리얼 구하는 함수이다.정수 n의 팩토리얼은 n! 이라고 표시하며, n! = n * (n-1) * (n-2) * (n-3) * . . * 2 * 1 이며5! 일 경우 5! = 120 = 5 * 4 * 3 * 2 * 1 다. ※예제 #include unsigned __int64 factorial( unsigned __int64 num ); int main( ) { int nNum = 5; printf( "%d! : %I64u", nNum, factorial(nNum) ); return 0; } unsigned __int64 factorial( unsigned __int64 num ) { if( num == 1 ) { return 1; } return num * fact.. 더보기
[C언어] 재귀 함수 - 함수의 재귀적 호출 ※요약재귀 함수란 자기 자신을 호출하는 함수다 일반적인 함수 호출 방법은 다음과 같다. 프로그램 실행 중 함수를 만나면 현재 위치를 저장 후, 호출할 함수의 주소로 점프해 함수 내용을 수행한다. 함수 실행이 끝나면 기억해뒀던 원래 위치로 복귀해 다음 코드를 수행한다. (일반적으로 잦은 함수 호출로 인한 점프의 반복은 속도를 느리게 한다.) 일반 함수나 재귀 함수나 위와 같은 방법으로 함수가 호출이 되는데 재귀 함수의 경우 함수의 실행이 채 끝나기도 전에 자기 자신을 호출한다. 이게 가능한 이유는 호출된 각 함수에 대한 복귀 번지, 인수, 지역 변수 등이 스택 프레임에 저장되기 때문에 기존의 작업 내용들이 서로 방해하지 않고 잘 동작할 수 있는 것이다. ※재귀 함수 특징 - 무한 루프에 빠지지 않기 위해 .. 더보기
[C언어] 위경도 좌표계 거리 구하기 C언어나 C++에서 사용할 수 있는 함수입니다. 두 지점의 위경도 값을 정해서 함수에 대입하면 Meter로 값을 반환합니다. km로 값을 받고 싶으면 dDistance*=1000; 부분 주석치면 됩니다. double GetDistance( tagPT pt1, tagPT pt2 ) { int radius = 6371; double dLat = rad( (pt2.y-pt1.y) ); double dLon = rad( (pt2.x-pt1.x) ); pt1.y = rad( pt1.y ); pt2.y = rad( pt2.y ); double a = sin(dLat⁄2) * sin(dLat⁄2) + sin(dLon⁄2) * sin(dLon⁄2) * cos(pt1.y) * cos(pt2.y); double c = 2.. 더보기