본문 바로가기
카테고리 없음

임베디드 프로그래밍을 고려한 C강의 -4

by 팁텍북 2018. 7. 5.

임베디드 프로그래밍을 고려한 C강의 -4


C(4)


Int arr[3]={5,6,7};

배열선언/초기화


Int arr[]; =>불가능하다.

Int arr[] = {1,2,3} =>가능하다


Char buf[100]=”embedded”

문자배열


sizeof(arr) =>배열의 크기

sizeof(arr)/sizeof(데이터타입)=>배열의 수


배열명은 배열의 시작주소이다.

&arr[0] == 0x500


scanf(“%d”,&arr[0]);


-포인터 연산

&arr[0]==arr+0

&arr[1]==arr+1

&arr[2]==arr+2


Arr+1의 포인터 연산시, 자료형 크기만큼 주소를 건너뜀.


포인터 서식문자 %p



-함수

하나의 main을 사용하는 것이 아니라 쪼개서 함수를 사용함.

유지보수하기에 좋고, 새로운 내용을 작성할 때, 다음에도 가져다 쓸 수 있기 편리함.



라이브러리함수

함수의 동작이 이미 구현되어 있음. ex) printf(), scanf(), strcpy()


사용자정의

엔지니어가 직접 구현한 함수.


함수

1.함수원형. 뼈대와 같다.

2.함수호출. 정의부분으로 점프시키는 역할을 한다.

3.함수정의. 함수의 동작(기능)을 구현하는 역할을 한다.


.h 함수의 원형을 저장함.

.c 일반적으로 함수의 정의, 함수의 동작을 저장함.

Main에서 함수를 호출함.


링커-라이브러리를 연결. 컴파일 이후 구동.


Link에러. 함수명이 틀리거나 main이 두 개 등일 때,  link할 수 없다는 link에러가 난다.


함수의 형태


//함수원형

#include<stdio.h>

컴파일 전에 stdio.h에 있는 함수의 원형들을 불러온다.

앞으로 사용할 함수를 미리 알려준다. prototype.


main()

{

함수호출;

}


함수정의

{


}



CPU내의 pc(프로그램 카운터)는 주소를 받아서 한 줄 씩 실행함.

함수명은 시작주소를 의미한다. 매칭하여 맞는 주소로 이동함. 함수정의와 연결.

나중에 함수포인터를 이용한다.


복귀주소를 stack메모리에 저장.


-스택과 큐의 자료구조

Stack - last input first out(LIFO), 뷔페에서 쌓여있는 접시를 꺼내가기.

Queue - First input first out(FIFO), 은행에서 순번대로 작업.

C에서는 직접 만들어주어야하고, c++에서는 가져다 사용하면 된다.



함수의 호출과 정의가 일치해야한다.

기능을 구현.


함수 호출시 전달인자에는 자료형을 넣지 않는다.

ex) Example(1,2);


함수 정의에서는 매개변수의 선언이 필요하여 데이터형을 적어준다.

ex)

Int Example(int a, int b)

{

Int sum=0;


Return sum;

}


원래는 호출과 정의를 하기전에 원형을 작성해주나, 호출과 정의가 완벽히 수정이 끝나면 정의의 한 줄을 맨 위로 올리고 ;(세미콜론)을 추가해주는 방법이 편리하다.



#include<stdio.h>

int Add(int a, int b);//함수 원형 - prototype


int main(void)

{

int tmp=5;

int val = 8;

int res = 0;


res = Add(tmp, val); //함수 호출(전달인자: 변수의 사용) -> 정의 부분으로 점프한다.

//리턴값을 res에 저장한다.


printf("res : %d\n", res);


return 0;

}


//int a=tmp;

//int b=val;


int Add(int a, int b) //함수 정의(매개변수 선언 : 변수의 선언) ->동작을 구현하는 부분이다.

//변수의 이름을 일치시키지 말 것. 헷갈리기 때문에.

{

int sum = 0;

sum = a+b;


return sum;//return의 반환타입을 함수 정의 앞에 적어준다.

}

#include<stdio.h>


char input_data(void);

int main(void)

{

char ch;


//input_data(); //함수 호출 - 전달할 파라미터가 없을 때는 파라미터를 넣지 않으면 된다.

printf("ch : %c\n", input_data());


return 0;

}


char input_data(void) //함수 정의

{

char inputChar;

printf("하나의 문자를 입력하세요.>");

scanf("%c", &inputChar);


return inputChar;

}

주의.return타입을 제대로 처리하지 않아서 그대로 5의 값을 출력함.


#include<stdio.h>


void input_data(int a);

int main(void)

{

int tmp = 5;


input_data(tmp); //함수호출


printf("tmp : %d\n", tmp);

return 0;

}


void input_data(int a) //함수 정의

{

a = a+2;


return a;

}



해결하기 위해서는 Main함수 내에서 input_data(tmp);의 값을 변수에 저장해서 처리해야한다.

자동변수(지역변수) - Automatic 변수 자동으로 저장되었다가 함수가 끝나면 삭제되는 변수.


전달인자와 매개변수의 이름은 다르게 해준다. 같게하면 간혹 헷갈려서 실수하는 문제가 발생함.



호출되면서 값이 바뀐다 call by value

매개변수의 값에 전달인자의 값을 복사, 전달한 것.

전달인자에 따라

전달인자가 주소면 주소를 받을 수 있는, 저장할 수 있는 변수가 와야한다.

포인터변수


pVal == &tmp

(pVal) == (&tmp)

*(pVal) == *(&tmp)

*(pVal) == tmp

*pVal == tmp



*연산자 - 메모리 참조 연산(포인터 변수가 가리키는 위치의 내용물을 들여다보는 연산자.)


32bit체계 시스템에서는 모든 포인터 변수는 size가 4byte이다.


pV==0x2000

&pV=0x5000

*pV=5==tmp


-직접접근과 간접접근

tmp=8; //직접접근

*pV=8 //간접접근

#include<stdio.h>


void input_data(int a);

int main(void)

{

int tmp = 5; //일반변수 선언

tmp = 5; //변수 사용

//포인터변수: 메모리의 주소값을 저장하는 변수로서 해당위치를 가리키는 변수

//일반변수: 데이터를 저장하는 변수

int* pVal; //포인터변수 선언. int *pVal; 둘다 가능함. 보통 좌측에 표현함.

 pVal = &tmp;

//선언과 동시 초기화도 가능함. / int* pVal = &tmp;



printf("tmp : %d\n", tmp);

printf("&tmp : 0x%p\n", &tmp);


return 0;

}


예제)

#include<stdio.h>

int disp_menu(void);


int main(void)

{

int sel;


while(1){


sel = disp_menu(); //함수호출

printf("선택된 메뉴는 %d 입니다. \n",sel);

switch(sel)

{

case 1:

printf("돈까스는 790kcal입니다.\n");

break;

case 2:

printf("닭갈비는 1300kcal입니다.\n");

break;

case 3:

printf("치킨은 1150kcal입니다.\n");

break;

case 4:

printf("프로그램이 종료됩니다.\n");

break;

}

if(sel==4) break;


}

return 0;

}


int disp_menu(void) // 함수정의

{

int num;


printf("************** 메뉴 리스트 **************\n");

printf("1. 돈까스 \n");

printf("2. 닭갈비 \n");

printf("3. 치킨 \n");

printf("4. 종료 \n");


printf("#   메뉴를 선택하세요 : >");

scanf("%d", &num);


return num;

}


아래는 실행결과입니다. 1,2,3을 입력해봤고, 4를 입력시 종료가 됩니다.


예제)반지름 구하기



#include<stdio.h>

double area(double halfDiameter);


int main(void)

{

double radius;

double result;


printf("원의 반지름 입력 : ");

scanf("%lf", &radius);

result = area(radius);

printf("반지름에 따른 원의 넓이 : %.3lf\n", result);


return 0;


}


double area(double halfDiameter)

{

return halfDiameter*halfDiameter*3.14159265359;

}



출력결과는 아래와 같다.


결과값은 의도한 값대로 나왔는지 검증도 해야한다.

예제) 두 수를 입력받고 그 사이의 값을 모두 더한 뒤 결과를 출력하는 함수. 합계는 함수에서 처리 되도록 하자.(call-by-value)


#include<stdio.h>


int sumofvalue(int lowNum, int highNum);


int main(void)

{

while(1)

{

int sum =0;

int a =0,b=0;


printf("\n두 수를 입력하세요.(종료는 control+c)>");

scanf("%d %d", &a, &b);

sum=sumofvalue(a, b);


printf("sum : %d\n", sum);


return 0;

}

}


int sumofvalue(int lowNum, int highNum)

{

int total=0;


for(;lowNum<=highNum;lowNum++)

{

total=total+lowNum;

}


return total;

}


예제 //함수를 호출하여 Call by Address방법으로 a,b 값을 바꾸어주기


#include<stdio.h>

void reverse(int* first, int* second);


int main(void)

{

int a=5; //초기값설정. a=5, b=7

int b=7;

printf("a : %d, b: %d\n", a, b); //결과는 5,7


reverse(&a, &b); //함수를 호출하여 Call by Address방법으로 a,b 값을 바꾸어주기

//reverse 함수의 포인트변수에 줄 a와 b의 주소값을 전달인자로 보낸다.


printf("a : %d, b: %d\n", a,b); //7,5

//reverse에서 a와 b의 값을 바꾼 것을 확인한다.


return 0;

}


void reverse(int* first, int* second) //포인터변수 first와 second에 a와 b의 주소값을 불러온다.

{

int temp=*first; //temp변수에 임시로 first가 가르키는 a의 값을 보관한다.

*first = *second;//first가 가르키는 a에는 second가 가르키는 b의 값을 저장한다.

*second=temp; //second가 가르키는 b에 잠시 temp에 보관했던 first가 가르키는 b의 값을 넣는다.

}


출력결과는 아래와 같다.

#include <stdio.h>

void Input_Data(int* scanVar);

int main(void)

{

int tmp = 0;

printf("데이터를 입력해주세요.\n");

Input_Data(&tmp);


printf("입력된 값은 다음과 같습니다.(tmp) : %d \n", tmp);

return 0;

}


void Input_Data(int* scanVar) //매개변수

//main에 선언된 tmp변수에 데이터를 입력

{

/*1번방법

int temp;

scanf("%d", &temp);

*scanVar=temp;*/


//#2번방법

scanf("%d", scanVar);

}


출력결과는 아래와 같다.

arr[0]==pA[0]==*(pA+0)

직접    간접

arr[1]==pA[1]==*(pA+1)


#include<stdio.h>

int SumofArr(int* pA);


int main(void)

{

int arr[5]={5,6,7,8,9};

//arr(배열명): 배열의 시작주소 : 포인터 상수


int res=0;

res=SumofArr(arr);


printf("res : %d\n",res);


return 0;

}


int SumofArr(int* pA)

{

int iteration;

int sum=0;

for(iteration=0;iteration<=sizeof(pA);iteration++)

sum=sum+pA[iteration]; //sum+=*(pA+iteration);


return sum;

}



댓글