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

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

by 팁텍북 2018. 7. 3.

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


프로그램(Program)은 가공되지 않은 데이터를 가지고 원하는 결과물을 도출되도록 알고리즘을 접목한 것이다.

알고리즘(Algorithm)은 명령어들의 집합이라고 말할 수 있다. 요리로 비유하면 recipe에 해당한다.



CPU의 핵심은 ALU.

CPU는 사칙연산과 참, 거짓을 판별 한다. 0은 거짓, 1이외의 정수는 참으로 판단한다.

ALU(Arithmetic Logic Unit) 산술 논리 연산장치


SoC(System On chip) 하나의 집적회로에 집적된 컴퓨터나 전자 시스템 부품을 가리킨다.(출처: 위키백과 https://ko.wikipedia.org/wiki/%EB%8B%A8%EC%9D%BC_%EC%B9%A9_%EC%B2%B4%EC%A0%9C)



메모리: 냉장고(재료를 보관하는 장소.)

레지스터: 도마(임시 저장장치)


작업순서

메모리->레지스터->ALU

시스템에서 작업을 처리하기전에 항상 데이터는 메모리에 보관되어야한다.


대입(Assignment)

= 대입연산자, == 같다, 관계비교연산(주의)

메모리에서 데이터를 레지스터에 가져온 뒤 CPU의 ALU에서 처리하고, 이후 처리한 값을 버리지 않고 저장하는 것이다.


대입시 주의 할 것

1. 대입 시 양쪽의 자료형이 일치해야한다.

차후 형변환에서 다룰 수 있다. 컴파일에서, 혹은 Cast연산 문법을 추가하여 처리한다.

2. 대입 시 양쪽의 크기를 일치시켜야한다.

Overflow를 주의해야한다.

데이터를 담을 그릇 크기는 작은데 데이터가 크면, 흘러 넘친다는 의미로 overflow라고 한다.

근접한 메모리 데이터를 깨뜨린다.

반대로 낭비의 상황도 주의해야한다. 4byte의 크기가 필요한데 그 이상의 그릇은 필요없을 것이다. 이때는 낭비는 되지만 데이터가 깨지 지는 않는다.

3.

  • 자료형(Data Type)

정수는 양의 정수와 음의 정수, 그리고 0이 있다.

문자는 ‘A’, ‘B’

실수는 3.14와 같이 소수점(.)이 있다.


부호비트

+는 0, -는


1의 보수는 각 비트의 역을 취함(0을 1로 바꿔준다.)

1000 0001

2의 보수는 각 비트의 역을 취함(0을 1로 바꿔준다.)

1000 0001    => 앞의 부호비트가 1이라 -1임을 알 수 있다.

0111 1110 역

0111 1111 +1 => 따라서 -127을 의미한다.


1byte의 표현범위는 -128~127(0을 포함)

0111 1111 => +127

1000 0000 => -128

0000 0000 => 0


Unsigned에서는 0~255(256가지)

8bit = 1byte는 2^8=256가지의 데이터를 담을 수 있음.


-int(자료형) integer, 4byte(최근에는 승격됨)

정수

실수 문자

문자열


Type

자료형

크기

정수Integer

int

4byte

실수Float

double

8byte

문자Character

char

1byte

문자열String

char배열

문자열의 길이에 따라 가변적


그밖에 short는 정수형의 축소형태로, 2byte임.

시스템에 따라 크기는 가변적이다.

sizeof(연산자)를 이용하여 자료형의 크기를 반환해서, 현재 시스템의 자료형 크기를 파악해야한다.


#include <stdio.h>


int main(void)

{

printf("int size : %d\n", sizeof(int));

return 0;

}


출력결과


#include <stdio.h>


int main(void)

{

printf("int size : %d\n", sizeof(int));

printf("char size : %d\n", sizeof(char));

return 0;

}



#include <stdio.h>


int main(void)

{

printf("int size : %d\n", sizeof(int));

printf("char size : %d\n", sizeof(char));

printf("double size : %d\n", sizeof(double));

return 0;

}


Int temp; //변수 선언

Int는 자료형, temp는 변수명


변수명을 갖고 찾아가는 것 - 직접접근

메모리 주소를 갖고 찾아가는 것 - 간접접근, 포인터


메모리는 사용하면 사용한 흔적이 남는다. 이를 쓰레기 값이라고 부른다.


temp=30; //변수 사용

변수 사용시에는 자료형이 들어가지 않는다.


정수상수는 4byte, 문자상수는 1byte, 실수상수는 8byte


Int val;

val=90;

=> Int val=90; //동시에 할 수 있음.


Int temp; //변수선언

temp=0; //초기화

=> int temp=0; //변수 선언과 초기화를 동시에



주석처리하고 싶은 범위를 블록 선택 후  Control + K+ C를 누르면 손 쉽게 주석 처리를 할 수 있다.

#include <stdio.h>


int main(void)

{

int temp=0;

temp = 9;

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


return 0;

}




#include <stdio.h>


int main(void)

{

int temp=0;

int val = 0;

int sum = 0;


temp = 9;

val = 7;


printf("temp : %d\n", temp+val);

return 0;

}


#include <stdio.h>


int main(void)

{

int temp=0;

int val = 0;

int sum = 0;


temp = 9;

val = 7;


sum=temp+val;

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


return 0;

}


오버플로의 예이다.

의도된 결과는 16.5가 나와야하지만 여기서는 16이 출력된다.

이를 해결하기 위해서는 변수 선언시, Sum을 실수형으로 바꾸어주면 해결된다.

변수의 사용 규칙




#include <stdio.h>


int main(void)

{

int korean=70;

int english = 80;

int math = 90;


int sum = 0;

float average = 0;


sum = korean+english+math;

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


average = sum/3;

printf("평균: %f\n", average);


return 0;

}


이번에는 소수점도 제대로 출력될 수 있도록 하였다. 소수점은 2째자리까지 표현될 수 있도록 하였다.(%.2f)


#include <stdio.h>


int main(void)

{

int korean=68;

int english = 78;

int math = 98;


float sum = 0;

float average = 0;


sum = korean+english+math;

printf("총점 : %.2f\n",sum);


average = sum/3;

printf("평균: %.2f\n", average);


return 0;

}



자동형변환: 대입연산자를 기준으로 형을 바꿔준다.

자료형: 강제형변환 문법(Casting)


#include <stdio.h>


int main(void)

{

int korean = 68;

int english = 78;

int math = 98;


int sum = 0;

float average = 0;


sum = korean+english+math;

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


average = (float) sum / 3.00; //자료형: 강제형변환 문법(Casting)

printf("평균: %.2f\n", average);


return 0;

}



현장에서는 포인터변수의 형변환을 많이 사용한다. 아직 이해하지 않아도 된다.

Void *ptr, 몇 byte를 할당할 지 모르기 때문에.

동적할당 *((int *)ptr)=80;


-scanf

scanf(“%d”, &변수);

%d의 형태로 메모리주소에 값을 입력한다.


&주소연산자, [앰퍼샌드]라고 읽는다.


*ptr

C에서는 사용하지 않으나 Oop(객체지향 프로그래밍)에서 사용함.

연산자의 오버로딩(overloading) 과적의 의미를 담음. 연산자에 여러가지 기능을 함.


객체지향의 특징(정보은닉, 캡슐화, 다형성, 상속)



32bit에서는 32bit-4byte


#include <stdio.h>


int main(void)

{

int temp=3;

int var = 5;


printf("temp addr : 0x%p\n", &temp); //&: 주소연산자

printf("var addr : 0x%p\n", &var); //&: 주소연산자

return 0;

}

위와같이 변수의 시작주소를 반환한다.


-포인트의 연산

다음주소까지 4바이트를 건너뛴다. 자료형의 크기만큼 건너뛰는 것이다.

#include <stdio.h>


int main(void)

{

int temp=3;

printf("temp addr : 0x%p\n", &temp); //&: 주소연산자

printf("temp+1 addr : 0x%p\n", &temp+1); //&: 주소연산자

return 0;

}



#include <stdio.h>


int main(void)

{

double temp=0;

printf("실수 데이터 하나 입력=>");

scanf("%lf", temp);

printf("temp : %lf\n", temp);


return 0;

}


-연산자

+

-

*

/ 몪을 구하는 연산자

% 나머지를 구하는 연산자


-관계연산자

관계연산자의 종류

a>b

a>=b

a<b

a<=b

a==b

a!=b


관계 비교연산자는 참, 거짓 반환한다.


-비트연산자

비트연산자는 관계연산자와 다르게 연산에 대한 값이 나온다.


-비트연산자의 종류

&

|

~

<< 쉬프트 연산shift

>>

^ exclusive



비트연산으로 곱하거나 나눌 수 있다.

0x38 << 2


2번 곱한다.

5<<2 5를 2번 곱한다.


-논리연산자

&& 논리 and

|| 논리 or

! 논리 not


&는 앞에 항이 있느냐에 따라 주소연산자와 비트연산자가 구분됨.

ex) Val & Temp 비트연산자, &Temp 주소연산자

-연산자의 우선순위

연산자의 우선순위는 아래와 같다. 괄호 연산자가 가장 우선순위가 높다. 여러 연산자를 쓸 때는 괄호를 쓰는 습관을 갖자.

(출처: 우선 순위 및 식 평가 순서,https://msdn.microsoft.com/ko-kr/library/2bxt6kc4.aspx)

아래에서는 비트연산자 <<의 우선순위가 더욱 높기 때문에 2D의 결과값이 나온다.



괄호를 넣어 다시 계산해본다.


#include <stdio.h>


int main(void)

{

int temp = 0x05;

int val =0x0A;

int res = 0;


res =(temp | val) <<2;


printf("res : 0x%X \n",res);


return 0;

}

#include <stdio.h>


int main(void)

{

int temp = 5; //증감연산(증가연산 + 감소연산)

//++증가 연산

//--감소 연산

temp++; // temp = temp +1;


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


return 0;

}

조건연산자. 3항연산자라고도 한다. 간단한 수식에서는 3항연산을 사용하고, 복잡해질때는 사용하지 않는다.

#include <stdio.h>


int main(void)

{

int temp =5;

int val =3;

int res =0;


res = (temp > val)?temp:val; // res=val;

// res=temp;

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


return 0;

}


#include <stdio.h>


int main(void)

{

int temp =5;

int val =3;

int res =0;


printf("size: %d\n", sizeof(5.2));

return 0;

}


복합대입 연산자

&=

^=

|=

<<=

>>=


&=, |=의 예

#include <stdio.h>


int main(void)

{

int temp =10;

int res =0;


temp &=0x80;//temp = 1011 0000 & 0x80;

temp |= 0x80;//temp = 0110 0000 | 0x80;

return 0;

}

If 조건문




참고. 논리.

binary

switch

TTL

논리

Level

Bit control

0

off

0v

False

Low

Clear

1

on

5v

True

High

Set



문제

1.Ascii 코드를 이용하여 소문자는 대문자로, 대문자는 소문자로 변환하기

참고로, 소문자는 97~122, 대문자는 65~90의 Ascii코드 값을 갖는다.


(풀이)

#include <stdio.h>


int main(void)

{

char c;

printf("한 문자 입력");

scanf("%c",&c);


printf("%d",c);

if((c>='a')&&(c<='z'))

{

c=c-32;

}else

{

c=c+32;

}

printf("%c",c);


return 0;


}


2. 정수를 세 번입력받고, 가장 큰 수를 출력한다.


(풀이)

#include <stdio.h>


int main(void)

{

int i;

int j;

int k;

int temp;


scanf("%d %d %d",&i,&j,&k);


temp = i;


if(j>i){

temp = j;

}

if(k>temp){

temp = k;

}


printf("%d",temp);

return 0;

}


3. 정수를 두 번 입력 받고 그 합을 구한 뒤, 이것이 2와 3의 공배수인지 판별하기


(풀이)

#include <stdio.h>


int main(void)

{

int i=0;

int j=0;

int sum=0;


scanf("%d %d",&i, &j);


sum=i+j;


if(sum%2!=0)

{

printf("거짓");

}else if(sum%3!=0){

printf("거짓");

}else{

printf("참");

}

return 0;

}


- 사칙연산예제


#include <stdio.h>


int main(void)

{

int num = 0;

char oper = 0;

int value = 0;

while(1){

printf("사칙계산할 수식 입력 : ");

scanf("%d%c%d", &num,&oper,&value);


if (oper == '+')

printf("%d+%d = %d", num, value, num + value);

else if (oper == '-')

printf("%d-%d = %d", num, value, num - value);

else if (oper == '*')

printf("%d*%d = %d", num, value, num * value);

else if (oper == '/')

printf("%d/%d = %d", num, value, num / value);

}

return 0;

}



댓글