1998.7.31 조경민

        C & C++ Tip 1001

      C 언어 기초
=======================================================================
c15  컴파일 작업 속토 향상
      만일 램드라이브  D:가 있다면

      SET TEMP=D:

C42 래지스터 변수의 사용
     만일 자주쓰는 간단한 인덱싱을 위한 변수라면 ( for문의 인덱스변수)
     래지스터 변수로 선언 함으로써 속도를 높일수 있다.
     register int a;
    
C43 short 타입
     int형은 16bit컴퓨터에서는 16bit이지만 32비트컴퓨터에선  32bit이다.
     만일 어떤 컴퓨터에서나 2바이트의 크기를 보장받고 싶으면
     int에 short 형을 붙이면 된다.  
     short int a;

c50 오버플로우
     int형에서
     32,767     0111 1111 1111 1111
     +    1     0000 0000 0000 0001
     ------------------------------
    -32,768     1000 0000 0000 0000     (2의 보수형태)

    -32,768-1 = 32,767

c52 여러 문자지정
     char quote = '\'';
     이렇게 지정할수 있다.
     \a   신호음을 발생하는 문자
     \b   백스페이스 문자
     \f   폼피드(From Feed)문자
     \n   새줄(New Line)문자
     \r   캐리지 리턴 문자
     \t   수평탭
     \v   수직탭
     \\   백 슬레쉬
     \nnn  8진으로 된 ASCII 값 ex) \012
     \xnnn 16진으로 된 ASCII값 ex) \x01f

printf에서.................
c56 printf에서 unsigned int 표시 플래그 %u

c57 printf에서 long int 표시 플래그 %ld

c60 지수형식으로 부동 소수점 숫자 출력 %e, %E

c61 10진수나 지수형식으로 부동 소수점 출력 &g

c63 포인터 어드레스 출력 %p

c64 부호가 있는 값 +       ex) %+d, %+f

c64 형식을 갖춘 출력  플래그 에 숫자 붙임
    ex)   printf("%1d\n", val);         5
          printf("%4d\n", val);             5

c66 채우기 출력 zero padding 플래그에 0을 붙임
    ex)   printf("%03d\n",val);         005

c67 8진 16진에 접두사 붙이기 플래그에 #
    ex)   printf("%#x %#x %#o,255,255,255);  0xFF  0xff  0377

c68 부동 소수점 숫자 형식화 수.소수부
    ex)   printf("%7,2f\n", 1.23456);   1.23

c70 죄측 정렬 출력   -
    ex)   printf("%5d\n",5);            5
          printf("%-5d\n",5);     5

c73 Near, Far 문자열 출력
    ex)   printf("%Fs %Ns\n",far_string,near_string);

c75 출력시킬 문자 개수의 결정
    ex)   int cnt;
          printf("I'm a bo%ny\n",&cnt);    c == 8

c76 출력에 에러가 나면 printf는 EOF를 리턴한다.
    ex)  if( EOF == printf("hi")) fprintf(stderr,"Error with printf");

c77 ANSI 디바이스 드라이버 사용
     CONFIG.SYS 에서 DEVICE=C:\DOS\ANSI.SYS 를 설치한다.

c78 ANSI 드라이버를 사용하여 printf에서 ANSI 쓰기
     printf("\033[sJ");         // 033 은 ESC키이다.
  
c95 비트 Rotation
     stdlib.h에 _rotl()와 _rotr() 이 있다. 각각 비트 죄측, 우측 회전이다.
     long 형인경우는 _lrotl(), _lrotr()을 쓴다.
     비트 회전 -> 0011 을 왼쪽 회전1회 0110 -> 1회 회전 1100 1001... 이렇게 된다.

c110 부동 소수점 숫자 올바르게 처리 하기
     부동 소수점은 0.065 을 0.649999 으로 처리한다. 따라서
     if(fabs( f - 0.065) <= 0.0001 ) // 이렇게 처리해야 한다.

c113 지정(Assignment)
     if( (score = 100) == MAX)  score에 100을 넣고 MAX와 비교한다.
     if( score = 100 == MAX) 100과 MAX를 비교하여 참거짓(1,0)을 score에 넣는다.


                매크로와 상수
==============================================================================

  C135  전처리기 매크로 __FILE__
        현재 컴파일 하고 있는 파일의 이름에 대한 문자열 상수
        printf(" This File is %s",__FILE__);

  C136  __LINE__ 현재 진행중인 컴파일 라인
        
  C137  전처리기 줄번호의 변경 #line
         #line 100 //컴파일 줄번호를 100으로 변경
         #line 1 "FILENAME.C" // 소스 코드 화일 이름 변경
        
  C138  무조건적인 컴파일 에러 내기 #error
        컴파일 도중 #error 매크로를 만나면 컴파일러는 무조건 지정된 에러메세지
        를 띄운다.
        #error It's Error!!!
  
  C140  전처리기 날짜, 시각 상수 (문자열)
        현재 컴파일중의 날짜, 시각 __DATE__, __TIME__
        마지막으로 컴파일한 정보를 제공하는데 쓰면 유용하다.

  C141  ANSI C 준수 여부 체크
        __STDC__ 가 정의되어 있으면 안시 C를 쓰는 컴파일러이다.
        #ifdef __STDC__
          printf("ANSI C");
        #else
          printf(" Not ANSI C");
        #endif
  
  C142   C++ 사용 여부
         __cplusplus가 정의 되어 있으면 C++을 쓰는 컴파일러다.
        
  C143  매크로나 상수 정의 해제 , 재정의
         #define X  100
         #undef  X
         #define X  200
  
  C144  매크로와 함수를 쓰는 경우
         매크로는 매크로가 있는 코드에서 매크로 코드를 그대로 덮어 쓰게 되므로
         매크로를 쓴 만큼 코드양이 더 늘어 나게 된다. 그러나 함수는 함수를 호출
         한 부분에서 함수가 정의된 코드로 넘어가므로 코드 량이 커지진 않는다.
         그러나 함수 호출을 위한 오버헤드로 인해 속도가 느려진다. 그러나 매크로는
         속도가 빠르다.

  C145  컴파일러의 pragma
        #define, #include, #undef 같은 매크로 말고 현재 사용중인 컴파일러에 따라
        컴파일러마다 정의된 매크로가 있는데 이런것을 #pragma라고 한다.
        볼랜드 C++인 경우 프로그램이 시작되고 종료될때  자동으로 함수를 지정할수
        있도록 startup과 exit 플라그마가 있다.
        #pragma startup  load_data    // 프로그램 시작시 load_data함수 호출
        #pragma exit     out          //      "   종료   out         "

  C148  #include <> #include ""
        <>로 정의된 헤더파일은 먼저 /INCLUDE/ 디렉토리를 검색해보고 없다면
        현재 디렉토리를 검색해 본다. 그러나 ""는 현재 디렉토리만 검색한다.

  C149  심벌 정의 여부 테스트
        다음은 XX가 정의되었다면 명령문을 수행한다.
        #ifdef XX
           // 명령문
        #endif
        컴파일시 한번만 헤더 포함하고 싶을때 쓰면 편리하다.

        다음 test.h 헤더 파일은 여러번 포함을 해도 단 한번 포함된다.
        test.h
        #ifndef __TEST__
           #define __TEST__
             :              명령문
        #endif

  C150  If-Else 구문의 사용
        #ifdef MY_FILE
            // 명령문 1
        #else
            // 아닐때 명령문 2
        #endif

  C152  Else-If  구문의 사용
        아닐때 다시 조건 검사를 하는 매크로 #elif    
        또한 #if defined() 은 #ifdef와 같은 역활을 한다.
  
        #if defined(MY_FILE)
           // 명령문 1
        #elif defiend(MY_ROUTINES)
           // 명령문 2
        #else
           // 명령문 3
        #endif

  C153  여러줄의 매크로
        여러줄의 매크로가 될경우 백슬레쉬 \ 를 붙여서 컴파일러에게
        다음줄로 무조건 내려가게 한다.
        #define very_long  " long long chuk ket chi ....\
                             yes  yes  chuk ket chi ....\
                             -__; hurl                  "
        
  C158  매크로 정의에서의 빈 공간 사용
        #define SQUARE (x) ((x) * (x))
        이렇게 정의하면 SQUARE만 나오면 (x) ((x) * (x)) 로 코드를 바꾼다.
        따라서 에러가 난다. SQUARE(x) ((x) * (x)) 로 해주어야 한다.

  C159  괄호의 사용
        #define SUM(x,y)  ((x)+(y))
        매개변수에 대해서는 (x) 처럼 괄호를 해주어야 옳치 않은 결과를 피할
        수 있다.

  C160  매크로에는 타입이 없다.
        매크로 매개변수가 float이든 char이든 int이든 다를것이 없다.
        그러나 함수는 int add(int a, int b) 로 자료형을 정해 주어야 한다.
  
  

                함수
=======================================================

C219 함수가 스택을 사용하는 기법

스택의 주요 목적은 함수의 발동을 지원하는 것이다. 프로그램이

함수를 작동시킬 때에는 우선 스택에 함수를 작동시키게 하는 명령어

어드레스(리턴어드레스) 를 위치시키게 되며 그 다음 변수의 매개변수들을

우측부터 좌츶에 있는 것까지 스택에 위치시킨다. 마지막으로 함수에 지역변

수들이 선언되어 있으면 그 지역 변수들의 값을 저장하기 위해 스택공간을

할당하는 것이다.


some_function(1,2,3)  

   ------------
  |지역변수들  |
  |------------|
  |     1      |
  |------------|
  |     2      |
  |------------|
  |     3      |
  |------------|
  |리턴어드레스|
   ------------ <--- Stack base

   <  스택 >

C컴파일러는 함수의 작동이 끝나면 지역변수들과 매개변수들을 가지고 있는

스택공간은 버리게 되고 리턴 어드레스를 사용하여 다음에 실행될 명령어를

결정한다. 그 다음 스택으로 부터 리턴 어드레스를 제거한 후

그 어드레스를 IP(명령어 포인터;Instruction Pointer)래지스터에 위치 시킨다.


C220 함수의 오버헤드

함수의 오버해드란 프로그램이 함수를 사용할때에 리턴 어드레스,매개변수들,

그리고 지역변수들을 스택에 넣는 push와 끝날때 pop하는것을 의미한다.

16비트 컴퓨터에서는 일반 작업을 함수화 시켰을때 속도 상에 2배정도 속도가

더 느렸다.


C221 지역 변수들이 위치되는 장소

지역변수는 C에서는 함수의 시작부에서 선언된다.


C224 전역변수와 지역변수가 충돌하는 경우

전역변수와 어떤 함수내의 지역변수의 이름이 같을 경우 그 지역변수가 선언된

함수내에서의 변수 이름은 지역변수의 이름으로 간주한다.


C225 전역변수의 번위 정의

만일 전역변수를 쓰는 함수가 전역변수가 선언된 곳보다 먼저 위치해 있으면

변수가 선언되어 있지 않다고 에러가 난다. 전역변수를 앞으로 끌어 올리던지

컴파일러에게 변수가 선언되어 있다고 보장하는 extern 키워드를 함수 앞에

써주면 된다.


C233 Call By Reference는 아직도 스택을 사용한다.


         -------
1000    |   0   |  a
        |-------|
1002    |   5   |  b
         -------
어드레스 메모리   변수


->>> change_value(&a,b)   우측부터 좌측으로 스택에 push

------------
|  1000      |    <-- &a
|------------|  
|    5       |    <-- b의 값
|------------|
|리턴어드레스|
------------
   스택

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

[tc] tc 사용하기  (0) 2004.03.19
bc 버그 중 하나..  (0) 2004.03.19
비트찍기  (0) 2004.03.19
[djgpp] class 라이브러리만들기  (0) 2004.03.19
class에 대한 잡담  (0) 2004.03.19

+ Recent posts