'#define'에 해당되는 글 2건

Programming/C C++
보통 Program에서 다루는 Data는 변수와 상수로 구분됩니다. 변수는

int a;

라고 선언한 뒤에 a에 어떠한 값을 넣느냐에 따라 a값이 달라지므로(값이 변할 수 있으므로) 변수라고 합니다.

반면 상수는 이미 정해진 값으로 그 값 자체는 변할 수 없는 특징이 있습니다.

1. 수치표현

(1) 입력

종류 표현
8 진수 0으로 시작합니다. (011, 022)
10 진수 일반숫자를 나타냅니다. (123, 124)
 16 진수  0x(0X)로 시작합니다. (0xA1, 0XA2)
▶정수표현

 종류  표현
 일반 실수  소수점을 사용합니다. (1.234, 2.56)
 float형 실수  f(F)를 사용합니다. (1.23f, 1.23F)
 long double형 실수  l(L)를 사용합니다. (12.34l, 12.34L)
 지수  e(E)를 사용합니다. (5e3, 3E2)
▶실수표현

참고:
일반실수는 double형입니다.

(2) 출력

 변환문자열  설명
 %o  8진수 출력 - printf("%o\n", 011);
 %d  10진수 출력 - printf("%d\n", 123);
 %x  16진수 출력 - printf("%x\n", 0xA1);
▶정수출력

 변환문자열  설명
 %f  실수출력 - printf("%f\n", 1.234);
 %e  지수출력 - printf("%e\n", 3E2);
 %g  인수를 실수와 지수중 알맞은 형태로 출력합니다.
▶실수출력

참고:
%로 시작하는 문자를 변환문자열이라고 합니다. 이 문자열은 주어진 인수를 해당 형태에 맞는 값으로 Format하는 역활을 합니다.

#include <stdio.h>

main()
{
  printf("%o\n", 011);
  printf("%d\n", 123);
  printf("%x\n", 0xA1);
  printf("%f\n", 1.234);
  printf("%e\n", 3E2);
}


2. 문자표현

문자표현은 '(따옴표)로 둘러싸 표현하며 문자자체와 상수를 이용하는 두가지 방법이 있습니다.

문자 -> 'a' 또는 'A'
상수 -> '97' 또는 '64'

상수로 문자를 표현하고자 할때는 해당 문자에 맞는 Ascii code를 사용하면 됩니다. 단. 일부 System에는 이 값이 틀린경우도 있기 때문에 문자상수는 문자자체로만 표현하는 것이 상수를 사용할때 보다 더 안정적입니다.

(1) 문자출력

문자를 출력하기 위해서는 %c 변환문자열을 사용합니다.

#include <stdio.h>

main()
{
  printf("%c\n", 'a');
  printf("%c\n", 97);
}



3. 문자열표현

문자는 '(따옴표)를 사용했지만 문자열은 "(쌍따옴표)를 사용합니다.

"hello"
"korea"

(1) 문자열출력

문자열출력은 %s 변환문자열 사용합니다.

#include <stdio.h>

main()
{
  printf("%s\n", "hello");
}



4. 기호정수

년도를 표시하기 위해 2009 라고 하였습니다. 하지만 이렇게 숫자로만 2009를 쓰면 다른 사람이 보기에 이것이 년도를 나타내는지 아니면 2009라는 정수를 나타내는 것인지 구분하기 어려울 수도 있습니다.

따라서 단순히 숫자로만 표시하기 보다는 now_year등의 문자열로 표시하면 이것이 년도를 나타내는 것임을 좀더 명시적으로 알려줄 수 있을 것입니다.

기호정수를 사용하는 방법은 다음과 같습니다.

#define 표시어 수치정수

위 구문을 Source Code의 #include 다음에 추가하게 되면 이후 직접 수치를 사용하지 않고도 표시어만을 통해 Code를 작성할 수 있게 되는 것입니다.

#include <stdio.h>
#define now_year 2009

main()
{
  printf("올해 년도는 %d 입니다.\n", now_year);
}



5. 열거형

열거형은 간단히 '정수를 모아놓은 값이다.'라고 할 수 있습니다. 열거형의 선언은 다음과 같이 할 수 있으며

enum 열거형이름 {정수값1, 정수값2, ...}

이때 정수값은 0부터 차례로 부여됩니다.

#include <stdio.h>

main()
{
  enum sequence {first, second, third, fourth, fifth};
 
  printf("%d\n%d\n%d\n%d\n%d\n", first, second, third, fourth, fifth);
}



열거형에서 정수값을 명시적으로 지정하면 해당 값부터 1씩 증가된 값으로 지정됩니다.

#include <stdio.h>

main()
{
  enum sequence {first = 100, second, third, fourth, fifth};
 
  printf("%d\n%d\n%d\n%d\n%d\n", first, second, third, fourth, fifth);
}


first에 100을 지정


필요에 따라 값은 중간부터라도 바꿀 수 있습니다.

#include <stdio.h>

main()
{
  enum sequence {first, second, third = 100, fourth, fifth};
 
  printf("%d\n%d\n%d\n%d\n%d\n", first, second, third, fourth, fifth);
}



열거형은 선언할때 변수를 지정해 해당 변수가 열겨형으로 사용됨을 명시할 수도 있습니다.

#include <stdio.h>

main()
{
  enum sequence {first, second, third, fourth, fifth} sort;
 
  sort = third;
 
  printf("sort의 값 %d\n", sort);
}


sequence를 형으로 한 sort변수를 선언합니다.


이때 enum자체는 int형이므로 선언된 변수도 int형의 크기를 가지게 됩니다. 따라서 열거형의 Data가 아닌 일반적인 int형 정수값도 다음 경우처럼 가질 수 있는 것입니다.

enum sequence {first, second, third, fourth, fifth};
int sort;


열거형 변수는 필요하다면 일반변수와 마찬가지로 몇개든 선언할 수 있으며

enum sequence {first, second, third, fourth, fifth} sort1, sort2, sort3;

enum을 정의한뒤 해당 enum을 Data형으로 한 변수를 따로 선언할 수도 있습니다.

enum sequence {first, second, third, fourth, fifth};
enum sequence sort;

이때 열거형명은 생략할 수도 있습니다.

enum {first, second, third, fourth, fifth} sort;

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

[C, C++] 표준 Library 함수 - 문자 판단 함수  (0) 2011.03.29
[C, C++] Object(obj)와 Link  (0) 2011.02.10
[C, C++] 상수(숫자, 문자, 문자열, 열거형) 정의및 사용  (0) 2011.02.09
[C, C++] 연산자  (0) 2011.02.08
[C, C++] 제어문  (0) 2011.02.01
[C, C++] 공용체  (0) 2010.09.27
0 0
Programming/C C++
C Program이 Compile시에는 실제 Source의 내용을 바로 Compile하는 것이 아니라 일단 개발자가 작성한 Source를 분석하여 필요시 일부 Source를 수정하는 작업을 진행 하게됩니다. 이처럼 Compile하기전에 미리 어떠한 작업이 이루어지는 것을 흔히 '전처리'라고 부릅니다.(전처리 과정은 대게 Source File과 include File을 결합한 직후 발생합니다.)

참고:
C언어는 일반적으로 ; 문자까지를 하나의 행으로 보지만 예외적으로 #로 시작하는 내용은 그 행의 끝까지를 하나의 행으로 간주합니다.

1. #include

Source Code의 처음부분에 #include <header file> 형식으로 선언되어 지정된 Header File을 Program의 Source Code에 포함되도록 합니다. 그러면 전처리를 통해 실제 Header File의 내용을 추가하는 작업이 이루어 지게 되는것입니다.

#include <stdio.h>

main()
{
  printf("hello\n");
}

▶Source 작성

/***
*stdio.h - definitions/declarations for standard I/O routines
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       This file defines the structures, values, macros, and functions
*       used by the level 2 I/O ("standard I/O") routines.
*       [ANSI/System V]
*
*       [Public]
*
****/

#if     _MSC_VER > 1000
#pragma once
#endif
#ifndef _INC_STDIO
#define _INC_STDIO
#if     !defined(_WIN32)
#error ERROR: Only Win32 target supported!
#endif
--이하생략... 위 부분이 stdio.h의 실제 내용

main()
{
  printf("hello\n");
}


전처리에 의해 stdio.h Header File이 Program에 추가됩니다.

C에는 많은 Library의 Header File이 존재하지만 이 Header File을 개발자가 직접 작성여여 사용할 수도 있습니다. 이럴때는 #include를 통해 <와 >대신 "문자를 통해 사용자 Header File을 추가하면 됩니다.

#include "header file"

이때 해당 Header File은 현재 작업중인 경로에서 찾게 되는데 지정된 Hearder File이 없는 경우 다시 원래의 표준경로를 찾아가 Header File을 찾게 됩니다. 또한 사용자가 직접 작성한 Hearder File이라 하더라도 현재작업중인 경로가 아닌 표준경로에 저장된 경우 ""대신 <>로 Header File을 지정하여도 정상적으로 동작하게 됩니다.

myprint(char s[])
{
  printf("%s <- 문자열 출력\n", s);
}
▶'myheader.h' 라는 이름으로 Header File작성

#include <stdio.h>
#include "myheader.h"

main()
{
  myprint("hello");
}


myheader.h Header File을 현재 위치에 저장한 후 "로 myheader.h File을 포함합니다.


2. #define

전처리과정에서 #define로 정의된 문자열을 Source상에서 치환되도록 Macro를 정의합니다.

#include <stdio.h>
#define Count 10

main()
{
  int i;
 
  for (i=0;i<=Count;i++)
  {
    printf("i의 값 %d\n", i);
  }
}

▶ #define을 통해 Count라는 문자열을 정수 10으로 인식합니다.

#include <stdio.h>

main()
{
  int i;
 
  for (i=0;i<=10;i++)
  {
    printf("i의 값 %d\n", i);
  }
}


전처리를 통해 Source Code에 있는 Count라는 문자열을 10으로 치환한후 Compile합니다.


또한 #define를 사용하면 인수를 가져야 하는 함수자체를 정의할 수도 있어서 특정 함수를 간단히 활용할 수 있습니다.

#include <stdio.h>
#define prnt(s) printf("%s\n", s)

main()
{
  prnt("문자열 출력");
}


printf("%s\n", s)함수를 printf(s)로 Macro정의합니다. 이때 s는 화면에 출력할 문자열의 인수입니다.


Macro는 사용자가 정의할 수도 있지만 편의상 미리 마련된 Macro도 있습니다.

다음은 해당 Macro종류및 사용 예제입니다.

 macro  설명
 __DATE__  현재 날짜를 나타냅니다.(Computer설정 기준)
 __LINE__  _LINE_가 위치한 행의 번호를 나타냅니다.
 __TIME__  현재 시간을 나타냅니다.(Computer설정 기준)
 __FILE__  _FILE_이 있는 Source File의 이름을 나타냅니다.
 __STDC__  현재 C Program이 완벽히 ANSI C 표준만을 따를때 이 Macro가 정의됩니다.(값1)
만일 표준을 따르지 않고 현재 사용중인 개별 Compiler의 확장기능을 이용했을 경우 이 Macro는 정의되지 않습니다.

#include <stdio.h>

main()
{
  printf("현재 날짜는 %s 이며 시간은 %s 입니다.\n", __DATE__, __TIME__);
  printf("이 program file의 이름은 %s 입니다.\n", __FILE__);
  printf("이 행의 번호는 %d 입니다.\n", __LINE__);
  printf("ANSI C 표준입니까?%d\n", __STDC__);
}



Compile할때 /Za 를 지정하였습니다. ANSI C에 맞춰야 __STDC__ Macro를 확인할 수 있기 때문입니다. Microsoft C/C++ Compiler는 Compil시 /Za 가 있을때 해당 Source를 ANSI C에 맞게 Compile합니다.

3. #undef

#define를 통해서는 Macro를 정의하는 반면 #undef는 정의된 Macro를 해제하는 역활을 합니다.(#undef로 해제된 Macro는 #define로 다시 재정의 될 수 있습니다.)

#include <stdio.h>
#define line 500

main()
{
  int i;
  i = line;
  printf("현재 macro : %d\n", i);
 
  #undef line
  #define line 1000
 
  i = line;
 
  printf("재정의된 macro : %d\n", i);
}


main함수에서 #undef를 통해 미리 정의된 Macro를 해제하고 다시 #define로 Macro를 정의합니다.

주의:
#으로 시작하는 전처리는 끝에 ;문자를 붙이지 않습니다.


4. #if ~ #elif / #else ~ #endif

특정 조건을 만족할때만 개발자가 직접 작성한 Source Code의 일부분을 Compil하거나 또는 하지 않을 수 있습니다.(이것을 조건부 Compile이라고 합니다.)

#include <stdio.h>
#define error 0

main()
{
  #if (error == 0)
    printf("error는 0\n");
  #elif (error == 1)
    printf("error는 1\n");
  #else
    printf("이도저도 아님...\n");
  #endif
}


전처리에 의해 error가 정의된 값을 판단하여 해당 값에 따라 Compil하도록 합니다. 이것은 본래 if문과 작동은 비슷한 형태인데 error가 0이면 #if이하의 내용만, error가 1이면 #elif이하의 내용만 Compile하며 error가 0도 1도 아니면 #else이하 Code만을 Compile하도록 합니다.

실제 작동은 보통 if문을 쓸때와 별 다를바가 없지만 여기서는 Compile되는 Program에 어떤 Code의 내용만이 들어가는가가 중요합니다. 만일 #if를 쓰지않고 일반 if문을 쓰게되면 error가 무엇인지에 상관없이 모든 Code가 Compile될 것입니다.

#if는 전처리를 행한다는 특징때문에 Program이 실행되고 있다는 가정하에서는 아무런 소용이 없으며 일반적으로 Program Debug시에만 사용하곤 합니다.

5. #ifdef / #ifndef

Macro는 #define을 통해서 정의합니다. 이때 해당 Macro가 정의되었는가 또는 정의되지않았는가에 따라 별도의 처리를 하고자 한다면 #ifdef / #ifndef를 사용하도록 합니다.

#include <stdio.h>
#define error 10

main()
{
 #ifdef error
  printf("error가 10으로 정의됨\n");
 #endif
 #undef error
 #ifndef error
  printf("error가 정의되지 않음\n");
 #endif
}


#ifdef에 의해 error가 정의되어 있다고 판단되면 printf("error가 10으로 정의됨\n"); 부분을 Compile하게 되고 #undef에 의해 해당 Macro가 취소됩니다. 또한 #ifndef로 Macro미정의가 판단되어 printf("error가 정의되지 않음\n"); 부분이 Compile되는 것입니다.


6. #if ~ defined / !defined

앞서 살펴본 #ifdef는 단일 Macro만을 판단하지만 #if ~ defined(!defined)는 조건지시시자 개념으로 #ifdef를 보다 확장한 것이며 defined는 참일경우 !defined는 거짓일 경우 처리됩니다.

#include <stdio.h>
#define a 1
#define b 2

main()
{
  #if defined(a)
    printf("a 정의됨!\n");
  #endif
 
  #if !defined(c)
    printf("c 정의안됨!\n");
  #endif
 
  #if defined(b)
    printf("b 정의됨!\n");
  #endif
 
  #if defined(a) && defined(b)
    printf("a와 b둘다 정의됨.\n");
  #endif
}


#if ~ defined/!defined 는 위와같이 if조건연산자인 &&이나 ||등을 지정할 수 있습니다.


7. #error

조건에 따라 compile시에 Error Message를 표시하도록 합니다.

#include <stdio.h>
#define a 1

#if a == 1
#error a error...
#endif

main()
{
  printf("aaa\n");
}


#if ~ #endif 에 따라 a가 1이면 #error에 정의된 Message를 출력하도록 하였습니다.


8. ##

##은 이 ##을 기준으로 양쪽의 내용을 결합니다.

#include <stdio.h>
#include <string.h>

#define prnt(a, b) a ## b

main()
{
  printf("%s\n", prnt("hello", "world"));
}


prnt에 두개의 문자열을 , 로 분리하여 전달하지만 #define에서 a ## b문으로 "helloworld"내용으로 결합됩니다.

1 0
1
블로그 이미지

클리엘