'Programming/C / C++'에 해당되는 글 47건

  1. 2015.02.07 가변 인수
  2. 2015.02.07 STL without warnings
  3. 2015.02.07 구조체 초기화
  4. 2015.02.07 자료형의 종류와 범위
  5. 2015.02.07 __IN & __OUT
  6. 2015.02.07 strncpy 의 함정
  7. 2015.02.07 XOR Swap
  8. 2015.02.07 struct tm
  9. 2015.02.07 Lotto
  10. 2015.02.07 Quick Cast
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

15-3.가변 인수

15-3-가.가변 인수 함수

여기서는 가변 인수 함수에 대해서 알아 본다. 가변 인수의 함수를 만드는 방법에 대해서는 물론이고 가변 인수 함수가 동작하는 원리에 대해서도 자세하게 분석해 볼 것이다. 조금 어렵기는 하지만 포인터를 적절하게 활용하는 예를 볼 수 있으며 포인터로 어떤 일이 가능한지를 경험할 수 있는 좋은 기회가 될 것이다. 가변 인수 함수가 어떻게 동작하는지를 설명할 수 있다면 포인터를 정복했다고 생각해도 좋다. 가변 인수를 읽어내는 포인터 연산식을 해석할 수 있다는 것은 포인터를 충분히 이해했다는 증거이다. 이 절의 내용은 다소 어렵고 함수에 대한 이해가 필요하므로 다음 장의 스택 프레임을 먼저 읽어 본 후 공부하는 것이 효율적이다.

가변 인수란 말 뜻 그대로 인수의 개수와 타입이 미리 정해져 있지 않다는 뜻이며 그런 인수를 사용하는 함수를 가변 인수 함수라고 한다. 가변 인수 함수의 가장 좋은 예는 C언어의 가장 기초 함수인 printf이다. C언어를 배우는 사람이 가장 먼저 배우는 친근한 함수이므로 이 함수를 통해 가변 인수 함수를 어떻게 사용하는지 연구해 보자. 이 함수는 서식 문자열과 서식에 대응되는 임의 타입의 인수들을 개수에 상관없이 전달받을 수 있다. 다음이 printf 함수의 호출 예이다.

 

printf("정수는 %d이고 실수는 %f이다.", i, d);

printf("이름 = %s, 나이 = %d, 키 = %f", "김상형", 25,178.8);

printf("%d + %f = %f", 123, 3.14, 123 + 3.14);

 

 printf 함수로 전달되는 인수의 개수와 타입이 모두 다르지만 정상적으로 컴파일되고 실행된다. 반면 gotoxy(10, 15, "quickly")나 strcpy(src, dest, 3) 따위의 호출은 당장 컴파일 에러로 처리된다. 이런 함수들은 가변 인수를 받아들이지 않기 때문에 헤더 파일에 적힌 원형대로 정확하게 인수의 개수와 타입을 맞춰서 호출해야 한다. 인수가 남아서도 안되며 모자라도 안되고 타입이 틀려도 에러로 처리된다. 그렇다면 printf 함수의 원형은 어떻게 선언되어 있길레 가변 인수를 처리할 수 있을까? 다음이 printf 함수의 원형이다.

 

int printf( const char *format, ... );

 

이 함수의 첫 번째 인수는 format이라는 이름의 문자열 상수인데 흔히 서식 문자열이라고 부른다. 두 번째 이후의 인수에는 타입과 인수 이름이 명시되어 있지 않으며 대신 생략 기호(ellipsis)인 ...이 적혀 있다. 생략 기호는 컴파일러에게 이후의 인수에 대해서는 개수와 타입을 점검하지 않도록 하는데 이 기호에 의해 가변 인수가 가능해진다.

컴파일러는 ... 이후의 인수에 대해서는 개수가 몇개든지 어떤 타입이든지 상관하지 않고 있는 그대로 함수에게 넘기므로 임의 타입의 인수들을 개수에 상관없이 전달할 수 있다. 대신 전달된 인수의 정확한 타입을 판별하여 꺼내쓰는 것은 함수가 알아서 해야 한다. 컴파일러는 인수를 마음대로 취할 수 있도록 허락은 해 주지만(사실은 허락이 아니라 무관심이다) 뒷일에 대해서는 절대로 책임지지 않는다.

생략 기호 이전에 전달되는 인수를 고정 인수라고 하는데 printf 함수의 경우 format 인수가 바로 고정 인수이다. 고정 인수는 원형에 타입과 개수가 분명히 명시되어 있으므로 원형대로 정확하게 전달해야 한다. printf가 아무리 가변 인수를 지원한다고 하더라도 printf(1, 2)나 printf(3.14) 따위의 호출은 안된다. printf의 첫 번째 인수는 반드시 const char * 타입의 서식 문자열이어야 하며 두 번째 인수부터 가변 인수이다. 그래서 정수 하나를 출력할 때는 printf(i)가 아니라 printf("%d", i)로 호출해야 한다.

가변 인수 함수를 사용하는 것은 별로 어렵지 않다. printf 함수의 경우 고정 인수인 서식 문자열을 먼저 전달하고 서식의 개수와 타입에 맞는 인수들을 순서대로 전달하기만 하면 된다. 그렇다면 이런 가변 인수를 취할 수 있는 함수는 어떻게 만드는지 알아보자. 관건은 자신에게 전달된 임의 타입의 인수들을 순서대로 꺼내서 정확한 값을 읽는 것이다. 가변 인수 함수의 개략적인 구조는 다음과 같다.

 

void VarFunc(int Fix, ...)

{

    va_list ap;

    va_start(ap, Fix);

    while (모든 인수를 다 읽을 때까지)

{

va_arg(ap, 인수타입);

}

    va_end(ap);

}

 

물론 함수의 이름이나 원형, 고정 인수의 개수 등은 필요에 따라 마음대로 작성할 수 있다. 마지막 인수 자리에 ...만 있으면 가변 인수 함수가 된다. 가변 인수 함수 내부에서는 인수를 읽기 위해 이상한 모양의 매크로 함수들을 많이 사용하는데 이 문장들을 각각 분석해 보자.

 

va_list ap

함수로 전달되는 인수들은 스택(Stack)이라는 기억 장소에 저장되며 함수는 스택에서 인수를 꺼내 쓴다. 스택에 있는 인수를 읽을 때 포인터 연산을 해야 하는데 현재 읽고 있는 번지를 기억하기 위해 va_list형의 포인터 변수 하나가 필요하다. 변수 이름은 ap로 되어 있는데 아마도 Argument Pointer의 약자일 것이다. ap는 어디까지나 지역변수일 뿐이므로 이름은 마음대로 정할 수 있되 관습적으로 가변 인수를 다루는 매크로에서는 ap라는 이름을 사용한다. va_list 타입은 char *형으로 정의되어 있다. 가변 인수를 읽기 위한 포인터 변수를 선언했다고 생각하면 된다.

va_start(ap,마지막고정인수)

이 명령은 가변 인수를 읽기 위한 준비를 하는데 ap 포인터 변수가 첫 번째 가변 인수를 가리키도록 초기화한다. 첫 번째 가변 인수의 번지를 조사하기 위해서 마지막 고정 인수를 전달 한다. va_start 내부에서는 ap가 마지막 고정 인수 다음 번지를 가리키도록 해 주므로 이후부터 ap 번지를 읽으면 순서대로 가변 인수를 읽을 수 있다.

va_arg(ap,인수타입)

가변 인수를 실제로 읽는 명령이다. va_start가 ap를 첫 번째 가변 인수 번지로 맞추어 주므로 ap 위치에 있는 값을 읽기만 하면 된다. 단, ap 번지에 있는 값이 어떤 타입인지를 지정해야 이 매크로가 값을 제대로 읽을 수 있으므로 두 번째 인수로 읽고자 하는 값의 타입을 지정 한다. 예를 들어 ap 위치에 있는 정수값을 읽고자 한다면 va_arg(ap, int)를 호출하고 실수값을 읽고자 한다면 va_arg(ap, double)이라고 호출하면 된다. 물론 리턴되는 값은 인수타입에 맞는 변수로 대입받아야 한다. 이 명령은 ap위치에서 타입에 맞는 값을 읽어 리턴하며 또한 ap를 다음 가변 인수 위치로 옮겨준다. 그래서 va_arg를 반복적으로 호출하면 전달된 가변 인수를 순서대로 읽을 수 있다.

그런데 이 명령에서 조금 이상한 점을 발견할 수 있는데 int나 double같은 타입 이름이 어떻게 함수의 인수로 전달될 수 있는가 하는 점이다. 함수의 인수로는 값이 전달되는 것이 정상인데 타입명이 어떻게 함수의 인수가 될 수 있는가 말이다. 타입명은 분명히 함수의 인수가 될 수 없다. 그럼에도 불구하고 va_arg가 타입명을 인수로 받아들일 수 있는 이유는 va_arg가 진짜 함수가 아니라 매크로 함수이기 때문이다. va_arg의 두 번째 인수는 내부적으로 sizeof 연산자와 캐스트 연산자로 전달되기 때문에 타입명이 될 수 있다.

va_end(ap)

이 명령은 가변 인수를 다 읽은 후 뒷정리를 하는데 별다른 동작은 하지 않으며 실제로 없어도 전혀 지장이 없다. 이 명령이 필요한 이유는 호환성 때문인데 플랫폼에 따라서는 가변 인수를 읽은 후에 뒷처리를 해야 하는 경우도 있기 때문이다. 적어도 인텔 계열의 CPU에서는 va_end가 아무 일도 하지 않는다. 그러나 다른 플랫폼이나 미래의 환경에서는 va_end가 중요한 역할을 할 수도 있으므로 호환성을 위해서는 관례적으로 넣어 주는 것이 좋다.

 

여기까지 설명을 읽고 "음, 그렇군, 가변 인수 함수 만들기 무지 쉽군"이라고 한 번에 이해할 수 있는 사람은 많지 않을 것이다. 이 매크로들을 사용하는 방법과 정확한 동작 원리는 좀 더 연구해 봐야 할 과제이다. 일단 실제로 동작하는 가변 인수 함수를 하나 만들어 보자. 다음 예제의 GetSum 함수는 첫 번째 인수로 전달된 num 개수만큼의 정수 인수들의 합계를 구해 리턴한다.

 

  : GetSum

#include <Turboc.h>

 

int GetSum(int num, ...)

{

     int sum=0;

     int i;

     va_list ap;

     int arg;

 

     va_start(ap, num);

     for (i = 0; i < num; ++i)

     {

          arg = va_arg(ap, int);

          sum += arg;

     }

     va_end(ap);

     return sum;

}

 

void main()

{

     printf("1 + 2 = %d\n", GetSum(2, 1, 2));

     printf("3 + 4 + 5 + 6 = %d\n", GetSum(4, 3, 4, 5, 6));

     printf("10 ~ 15 = %d\n", GetSum(6, 10, 11, 12, 13, 14, 15));

}

 

GetSum 함수의 첫 번째 인수 num은 전달될 정수 인수의 개수를 가지는 고정 인수이며 이 인수 다음에 합계를 구하고 싶은 num개의 정수값을 나열하면 된다. 인수의 개수가 몇개이든간에 전달된 모든 값의 합계를 구해 리턴할 것이다. 실행 결과는 다음과 같다.

 

1 + 2 = 3

3 + 4 + 5 + 6 = 18

10 ~ 15 = 75

 

GetSum 함수에서 가변 인수들을 어떻게 읽는지 분석해 보자. va_list형의 포인터 ap를 선언하고 va_start(ap, num) 호출로 ap가 마지막 고정 인수 num 다음의 위치, 그러니까 첫 번째 가변 인수를 가리키도록 초기화했다. 그리고 num만큼 루프를 돌면서 va_arg(ap,int) 호출로 ap 위치에 있는 int값을 계속 읽어 sum에 누적시킨다. 모든 가변 인수를 다 읽었으면 va_end(ap)로 뒷정리를 하고 계산된 sum값을 리턴하였다. 앞에서 보인 기본 형식대로 va_ 매크로를 사용하여 가변 인수를 읽어 처리하기만 하면 되므로 사용만을 목적으로 한다면 그리 어렵지 않다.

'Programming > C / C++' 카테고리의 다른 글

override, abstract, __interface, sealed  (0) 2015.02.07
switch 분할 호출  (0) 2015.02.07
STL without warnings  (0) 2015.02.07
구조체 초기화  (0) 2015.02.07
자료형의 종류와 범위  (0) 2015.02.07
Posted by 역시인생한방
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

#pragma warning(disable: 4018)  // signed/unsigned mismatch
#pragma warning(disable: 4100)  // unreferenced formal parameter
#pragma warning(disable: 4146)  // unary minus operator applied to unsigned type, result still unsigned
#pragma warning(disable: 4244)  // 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4245)  // conversion from 'type1' to 'type2', signed/unsigned mismatch
#pragma warning(disable: 4511)  // 'class' : copy constructor could not be generated
#pragma warning(disable: 4512)  // 'class' : assignment operator could not be generated
#pragma warning(disable: 4663)  // C++ language change: to explicitly specialize class template 'vector'
#pragma warning(disable: 4710)  // 'function' : function not inlined
#pragma warning(disable: 4786)  // identifier was truncated to 'number' characters in the debug information

 

STL의 vector<vector<POINT> > 을 쓰면서 한가지 주의해야 할 사항은

>> 부분을 겹쳐쓰면 안된다는 것이다 컴파일러는 이것을 비트연산자로 처리하기 때문이다.

그래서 꼭 띄어쓰기를 해야한다.


출처 : http://www.codeproject.com/vcpp/stl/stl_without_warnings.asp

'Programming > C / C++' 카테고리의 다른 글

switch 분할 호출  (0) 2015.02.07
가변 인수  (0) 2015.02.07
구조체 초기화  (0) 2015.02.07
자료형의 종류와 범위  (0) 2015.02.07
__IN & __OUT  (0) 2015.02.07
Posted by 역시인생한방
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MS의 구조체 중에는 첫번째 인자가 구조체의 사이즈인 경우가 많습니다. 
흔히 사용하는 CreateProcess의 STARTUPINFO구조체를 예로 들자면... 

STARTUPINFO StartupInfo; 
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); 
StartupInfo.cb = sizeof(STARTUPINFO);
 

이런 식의 코드로 초기화하는 경우가 많죠. 
이걸 한 줄로 쓸 수 있습니다. 

STARTUPINFO StartupInfo = { sizeof(STARTUPINFO) }; 
이렇게 쓰면 되죠. 멋있죠? 

STARTUPINFO si = { sizeof(si) }; 
이렇게 써도 됩니다. 

왜 이게 가능하냐면... 
C나 C++이 배열이나 구조체를 초기화하는 것이 가능합니다. 
그런데 중간까지만 초기화를 하면 나머지는 자동으로 0으로 됩니다. 
물론 위의 코드는 첫번째 인자가 cbSize인 경우에만 가능하겠죠. 
(그러니까... MS의 사이즈 쓰는 구조체는 거의 다 될겁니다.) 
위처럼 구조체에 사용하셔도 되고, 배열도 마찬가지로 일부만 초기화하면 나머지가 0이 됩니다. 

참고로 CHARFORMAT2에 대해서 사용했더니 안되더군요. 

struct CHARFORMAT2A : _charformat 

  WORD wWeight; 
  SHORT sSpacing; 
  COLORREF crBackColor; 
  LCID lcid; 
  DWORD dwReserved; 
  SHORT sStyle; 
  WORD wKerning; 
  BYTE bUnderlineType; 
  BYTE bAnimation; 
  BYTE bRevAuthor; 
};
 

CHARFORMAT2가 c++에서는 CHARFORMAT를 계승한 클래스로 정의되기 때문입니다. 다음과 같은 에러가 나죠. 
error C2552: cf : non-aggregates cannot be initialized with initializer list 

ps. 또는 구조체를 계승하고 생성자에서 첫번째 인자를 채워주는 클래스를 만들기도 하지요. 이것도 꽤 폼납니다. ^^

'Programming > C / C++' 카테고리의 다른 글

가변 인수  (0) 2015.02.07
STL without warnings  (0) 2015.02.07
자료형의 종류와 범위  (0) 2015.02.07
__IN & __OUT  (0) 2015.02.07
strncpy 의 함정  (0) 2015.02.07
Posted by 역시인생한방
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
자료형의 종류와 범위
구분자료형크기(byte)범위
문자형

char

1 byte

   -128 ~ 127

unsigned char

1 byte

   0 ~ 255
정수형

__int8

1 byte

   -128 ~ 127

__int16

2 byte

   -32,768 to 32,767

unsigned int

2 byte

   -32,768 to 32,767

short (int)

2 byte

   -32,768 to 32,767

unsigned short (int)

2 byte

   0 ~ 65,535

__int32

4 byte

   -2,147,483,648 ~ 2,147,483,647

int

4 byte

   -2,147,483,648 ~ 2,147,483,647

unsigned int

4 byte

   0 ~ 4,294,967,295

long (int)

4 byte

   -2,147,483,648 ~ 2,147,483,647

unsigned long (int)

4 byte

   -2,147,483,648 ~ 2,147,483,647

__int64

8 byte

   -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
실수형

float

4 byte

   3.4E +/- 38 (7 digits)

double

8 byte

   1.7E +/- 308 (15 digits)

long double

8 byte

   1.2E +/- 4932 (19 digits)


참고 : limits.h

'Programming > C / C++' 카테고리의 다른 글

STL without warnings  (0) 2015.02.07
구조체 초기화  (0) 2015.02.07
__IN & __OUT  (0) 2015.02.07
strncpy 의 함정  (0) 2015.02.07
XOR Swap  (0) 2015.02.07
Posted by 역시인생한방
,

__IN & __OUT

Programming/C / C++ 2015. 2. 7. 19:07
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


출처 : http://msdn.microsoft.com/en-us/library/aa383701(VS.85).aspx

'Programming > C / C++' 카테고리의 다른 글

구조체 초기화  (0) 2015.02.07
자료형의 종류와 범위  (0) 2015.02.07
strncpy 의 함정  (0) 2015.02.07
XOR Swap  (0) 2015.02.07
struct tm  (0) 2015.02.07
Posted by 역시인생한방
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

코딩을 하다보면 발생하는 버그중 가장 악질적인 것중 하나가 디버그 버전에서는 나타나지 않고 릴리즈 버전에서만 나타나는 버그다. 그것도 랜덤하게....

랜덤하게 나타나는 버그 중에서도 자신이 만든 루틴에서 나는 버그는 그나마도 괜찮다고 할 수 있다. 악질 중에 악질은 아무 생각 없이 쓴 표준 함수에서 나타나는 경우다. 특히 표준 함수를 쓸 때는 대부분이 아무런 문제가 없다는 확신을 가지고 쓰기 때문에 더욱 찾기가 힘들다.

DJ Max때도 그런 악질 적인 버그를 한번 만난 적이 있다. 릴리즈모드에서만 가끔씩 랜덤으로 유저가 튕겨져 나간다는 것이었다. 디버그 모드에서는 아무리 해도 찾을 수 없는 그 버그의 원흉은 아무런 생각 없이 썼던 strncpy() 함수에 있었다. 물론 코드를 검사할 때 strncpy()함수에 큰 주의를 기울이지 않기 마련이기 때문에 더 찾기가 힘들었다.

아마도 코드는 이랬던 것 같다.


char szDst[256];

// szStc 는 인수로 넘어온 const char* 형 변수다.
strncpy(szDst, szSrc, 2);

// 이하 이어지는 코드...


아마도 고수분이라면 이 코드의 문제점을 바로 알아봤을 것이다. 따로 놓으면 보이지만 이 코드가 수만줄 사이에 끼여져 있다면 참으로 찾기 힘든 코드다.

이 코드 발생 원인에는
첫번 째로 초기화에 충실하지 않았다는 점이고 두번 째로 strncpy()의 정의를 확실히 몰랐다는 점을 들 수 있겠다.

보통은 문자열을 주어진 길이만큼 복사한다고만 알고 있는 strncpy()의 확실한 정의는 이렇다.

"문자열을 정해진 길이만큼 복사한다. 소스 문자열의 길이와는 별개로 무조건 정해진 길이만큼 복사되기 때문에 문자열이 짤릴 수도 있고 뒷부분이 NULL문자로 채워질 수도 있다. 채워넣을 문자열 크기는 주어진 길이보다 커야 한다. 그렇지 않으면 인접 데이터가 파괴된다."

여기서 주의해야 할 것은 주어진 길이만큼 복사한다는 내용 이외의 것이다. 다시 위의 코드로 돌아가보면

szSrc로부터 szDst로 2개의 문자가 복사된다. 이 경우 문자열중 앞쪽 2개만 사용할 때는 문제가 없지만 2개를 넘어갈 때는 세번째 멤버부터는 데이터를 보장할 수 없기 때문에 문제가 된다.

이 코드를 고칠려면


char szDst[256] = { 0 };
을 해주던가

strncpy(szDst, szSrc, 2);
이후에

szDst[2] = 0;


을 붙여주어 채워지지 않은 나머지 부분에 널문자임을 확실히 해 주어야 한다.


출처 : http://trapping.egloos.com/2509570

'Programming > C / C++' 카테고리의 다른 글

자료형의 종류와 범위  (0) 2015.02.07
__IN & __OUT  (0) 2015.02.07
XOR Swap  (0) 2015.02.07
struct tm  (0) 2015.02.07
Lotto  (0) 2015.02.07
Posted by 역시인생한방
,

XOR Swap

Programming/C / C++ 2015. 2. 7. 19:04
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

이것은 XOR 이라는 비트연산의 특성을 이용한 방법
XOR은 같은 값으로 연산을 두번 시켜주면 다시 원래대로 돌아오는 특성을 가지고 있다
예를 들어 두 값 A, B 가 있고 처음 XOR을 했을 때의 값을 X 라 한다면

 

A ^ B = X
X ^ B = A
X ^ A = B

 

그래서 XOR연산은 데이타 암호화의 가장 기본이 되는 연산으로 쓰이고 있다
A가 암호화할 문장, B가 암호 키, X가 암호문으로
자세한 것은 데이타 암호화를 찾아보시라

 

#define SWAP( a, b ) a ^= b; b ^= a; a ^= b;

 

이것을 부분별로 나눠보면 다음과 같다

1) 초기값 : a(A), b(B) 
2) a ^= b 가 실행된 후 : a(X), b(B) (a = a ^ b = A ^ B = X)
3) b ^= a 가 실행된 후 : a(X), b(A) (b = a ^ b = X ^ A = B)
4) a ^= b 가 실행된 후 : a(B), b(A) (a = b ^ a = X ^ B = A)

 

* XOR은 순서가 바뀌어도 상관없다 A ^ B = B ^ A

하지만 위와 같이 데이타 타입이 없는 경우 조금 위험하게 쓰일 수도 있으니 차라리 inline을 쓰는 것이 좋다
#define은 타입체킹을 하지 않으니 서로 다른 두 타입이 들어오면 문제가 발생할 수 있다

 

template<class A, class B>
inline void Swap( A &a, B &b ) { a ^= b; b ^= a; a ^= b; }

 

* 단, 이것은 C++에서나 사용가능
   C에서는 어쩔 수 없이 위의 #define 방법을 사용해야된다.

'Programming > C / C++' 카테고리의 다른 글

__IN & __OUT  (0) 2015.02.07
strncpy 의 함정  (0) 2015.02.07
struct tm  (0) 2015.02.07
Lotto  (0) 2015.02.07
Quick Cast  (0) 2015.02.07
Posted by 역시인생한방
,

struct tm

Programming/C / C++ 2015. 2. 7. 19:03
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

#include <time.h>

 

struct tm
{
        // seconds after the minute - [0,59]
        int tm_sec;

        // minutes after the hour - [0,59]
        int tm_min;

        // hours since midnight - [0,23]
        int tm_hour;

        // day of the month - [1,31]
        int tm_mday;

        // months since January - [0,11]
        int tm_mon;

        // years since 1900
        int tm_year;

        // days since Sunday - [0,6]
        int tm_wday;

        // days since January 1 - [0,365]
        int tm_yday;

        // daylight savings time flag
        int tm_isdst;
};

 

Convert from a struct tm to a time_t function : time_t mktime( struct tm* ptm )


사용 예)

time_t t;
time(&t);
tm* tstruct;
tstruct = localtime(&t);

tstruct->tm_sec = 현재시간 중 초

'Programming > C / C++' 카테고리의 다른 글

strncpy 의 함정  (0) 2015.02.07
XOR Swap  (0) 2015.02.07
Lotto  (0) 2015.02.07
Quick Cast  (0) 2015.02.07
_strtime  (0) 2015.02.07
Posted by 역시인생한방
,

Lotto

Programming/C / C++ 2015. 2. 7. 19:02
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

////////////////////////////////////////////////////////////////////////////////
// Title : 로또 프로그램
// Author : 최민혁
// Revision : 2006. 5. 30 First implementation
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main( void )
{
    int number[45] = {  1,  2,  3,  4,  5,  6,  7,  8,  9,

                          10, 11, 12, 13, 14, 15, 16, 17, 18,

                          19, 20, 21, 22, 23, 24, 25, 26, 27,

                          28, 29, 30, 31, 32, 33, 34, 35, 36,
                          37, 38, 39, 40, 41, 42, 43, 44, 45 };
    int result[6] = { 0 };
    int i, temp;
    int count = 0;

 

    srand( time(NULL) );

 

    while( count < 6 )
    {
         temp = rand() % 45 + 1;
         for( i = 0; i < 45; i++ )
         {
             if( number[i] == temp )
             {
                 result[count] = temp;
                 number[i] = 0;
                 count++;
             }
         }  
    }

 

    for( i = 0; i < 6; i++ )
        printf( "Making Number %d : %d\n", i + 1, result[i] );

 

    printf( "Enter 키를 누르면 종료됩니다" );

 

    while( getchar() != '\n' )
        continue;

 

    return 0;
}

 

대학시절 강의시간에 심심해서 수업 안듣고 짜본거 ㅋ

이걸로 5등 몇번 당첨됐었다 ㅋㅋ

'Programming > C / C++' 카테고리의 다른 글

XOR Swap  (0) 2015.02.07
struct tm  (0) 2015.02.07
Quick Cast  (0) 2015.02.07
_strtime  (0) 2015.02.07
소수점 둘째자리이하 자르기  (0) 2015.02.07
Posted by 역시인생한방
,

Quick Cast

Programming/C / C++ 2015. 2. 7. 18:59
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

이건 보통 게임제작할 때 많이 쓰이는 기법인데
간단하면서도 빠른속도를 내주는 방법이다
 
보통 float 형을 int 형으로 cast 할때 (int)로 cast 하는데
이렇게 하는 것보다 다음과 같이 해주면 훨씬 빠르게 된다

 

num 이란 float 형 변수가 있을 때


int temp = *(int*)num;
 
라고 해주면 훨씬 빠른 프로그램을 작성할 수 있다

'Programming > C / C++' 카테고리의 다른 글

struct tm  (0) 2015.02.07
Lotto  (0) 2015.02.07
_strtime  (0) 2015.02.07
소수점 둘째자리이하 자르기  (0) 2015.02.07
비트 연산자들의 진리표  (0) 2015.02.07
Posted by 역시인생한방
,