20140416 (LED 실습, #if #ifdef #ifndef #endif #else, 분할 컴파일)
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 if( 7 > (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(10, 00) ); // 1000 이 들어와 %d에 들어감
printf("%d \n", _hap(22, 00) ); // 2200 이 들어와 %d에 들어감
printf("%d \n", iNum);
return 0;
}