부산IT학원/스마트컨트롤러

20140416 (LED 실습, #if #ifdef #ifndef #endif #else, 분할 컴파일)

EHOzlO 2014. 4. 16. 14:21

43일차




-------------

실        습

-------------


--- LED 왔다리 갔다리

ex) 소스


- main.c

#include "smart.h"

int main(void)
{
      volatile unsigned int uiCnt;
      unsigned int  uiSign = 0x00;
      unsigned int  uiNum = 0x01;

      DDRA = 0xFF;


      while(1)
      {
            PORTA = uiNum;
            DELAY(65000);
            DELAY(65000);
            DELAY(65000);
            DELAY(65000);
            DELAY(65000);
            DELAY(65000);
            PORTA = 0x00;
            DELAY(65000);

            if(7 == (uiSign%16|| 15 == (uiSign%16) )
            { // 아무기능도 하지 않음. 그냥 잠깐 LED 위치 머물기용
            }
            else if7 > (uiSign%16) )
            {
                  uiNum = uiNum << 1;
            }
                else
            {
                  uiNum = uiNum >> 1;
            }
            ++uiSign;
      }
      return 0;
}


- smart.h

#ifndef _SMART_H_
#define _SMART_H_

#define DDRA (*((volatile unsigned char *)0x3A))
#define PORTA (*((volatile unsigned char *)0x3B))
#define DELAY(x) for(uiCnt = 0; (x) > uiCnt; ++uiCnt)

#endif //_SMART_H_


결과물





--- 위의 소스를 보면 헤더파일을 "smart.h"라고 include 돼있는데.

#include <xxxxxx.h> 는 환경변수 include에 저장된 위치에 헤더파일을 찾고

#include "xxxxxx.h"  는 현재폴더(상대경로) 내에 xxxxxx.h를 포함한다는 뜻이다.








- C

----------------------------------

C Language

----------------------------------



--- #if    #endif

if문과 똑같다.

#define ADD 1

#if ADD

명령

#endif

ADD의 값이 참이면 명령을 실행한다는 코드이다.




--- #ifdef    #endif

이건 쬐금 다른데 매크로가 define 돼있나 확인이다.

#define ADD 0

#ifdef ADD

명령

#endif

ADD의 값과 상관없이 ADD라는 매크로가 정의 되어 있으면 참.




--- #ifndef    #endif

이건 위에 것과 반대 뜻.

실습 헤더파일을 보면

#ifndef _SMART_H_
#define _SMART_H_
(명령)
#endif //_SMART_H_

이런 코드가 있는데 _SMART_H_가 정의 되어 있지 않으면

정의한다라는 뜻인데

헤더파일이 여러번 include 되어도 중복을 피하게 하는 코드이다.

따라서 헤더파일을 만들때 항상 있어야 할 코드.




--- #else

#else도 제어문 if문과 마찬가지로 똑같이 동작한다



--- #elif

#elif 같은 경우 #if 문에서만 사용이 가능하다는 것만 기억할 것.





------------------

--- 분할 컴파일



분할 작업을 했을 시 얻는 이점이 많다.

여러명이서 작업이 더 손쉽고, 처음 컴파일 했을 때에는 둘다 느리겠지만

수정 후엔 분할 컴파일이 더 빠르다.


main.c    ->    main.obj

???.c      ->    ???.obj

###.c     ->    ###.obj

수정된 c소스만 다시 obj(기계어) 파일로 만들어

obj 파일들만 link를 걸면 exe 파일이 나오므로

훨씬 속도가 향상된다.




- 분할 하는 요령



- 분할 후


- LinkedList.h

#ifndef _LinkedList_h_
#define _LinkedList_h_


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

typedef struct _node
{
      char  data;
      struct _node * next;
}Node;

void Node_Print(Node *);
void Node_Free(Node *);


#endif  // _LinkedList_h_




- Node.c (LinkedList.c 라고 하든 제목은 프로그래머 재량)

#include "LinkedList.h"  // 선언된 헤더파일을 include 해줘야함.

void Node_Print(Node * npHead)
{
      Node *  temp;

      for(temp = npHead; 0 != temp; temp = temp->next)
      {
            printf("%c -> ", temp->data);
      }
      printf("NULL \n");
}

void Node_Free(Node * npHead)
{
      Node * temp;

      for(temp = npHead; 0 != temp; temp = npHead)
      {
            npHead = npHead->next;
            free(temp);
      }
}


- main.c

#include "LinkedList.h"

int main()
{
      Node *  Head;
      Node *  temp;

      Head = malloc(sizeof(Node));

      Head->data = 'a';
      Head->next = malloc(sizeof(Node));

      Head->next->data = 'b';
      Head->next->next = malloc(sizeof(Node));

      Head->next->next->data = 'c';
      Head->next->next->next = NULL;

      Node_Print(Head);

      Node_Free(Head);

      return 0;
}


이런식으로 분할한다.





-----------------------

--- 매크로 문자열 치환

문자열 내에서는 매크로의 매개변수가 치환되지 않는다

그래서 #을 매개변수 앞에 붙여 사용한다.

ex)

#include <stdio.h>

#define  _hap(A, B)  #A "는 지금 " #B "한다"

int main()
{
      printf("%s \n", _hap(나, 퇴근) );

      return 0;
}


출력 화면

나는 지금 퇴근한다



--- 필요한 형태대로 결합하기

예제를 보자

ex)

#include <stdio.h>

#define  _hap(A, B)  A##B


int main()
{
      int _hap(i, Num) = 5 // iNum = 5 이렇게 치환됨.
      printf("%d \n", _hap(1000) );   // 1000 이 들어와 %d에 들어감
      printf("%d \n", _hap(2200) );   // 2200 이 들어와 %d에 들어감

      printf("%d \n", iNum);

      return 0;
}