20140312 (리터럴 상수, 접미사, 아스키코드, 캐스팅, 서식문자, 특수문자)

18일차

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

리터럴(Literal) 상수

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

 

- 변수가 아닌 것 상수를 리터럴 상수라 함.

ex) int iNum = 3;    // 여기서 3이 리터럴 상수.

- int형으로 저장 가능한 것은 int형으로 약속하고

- double형으로 저장 가능한 것은 double형으로 저장하기로 약속했다.

 

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

접     미     사

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

- (리터럴) 상수 뒤에 써주는 것으로 상수의 자료형을 바꿀 수 있음.

확인 예제 소스

#include <stdio.h>

int main()
{
  printf("3 \t: %d \n"sizeof 3);
  printf("3LL \t: %d \n"sizeof 3LL);
  printf("3.14 \t: %d \n"sizeof 3.14);
  printf("3.14F \t: %d \n"sizeof 3.14F);

  return 0;
}
 

출력 화면

 

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

아스키코드 (ASCII)

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

- 영문자를 표기하기 위해 아스키코드 표를 만들어 그에 상응하는

숫자를 글자 형태로 출력시 영문자가 출력된다.

예제 소스코드

#include <stdio.h>

int main()
{
  char cCh1 = 'A';
  char cCh2 = 65;
  char cCh3 = 'Z';
  char cCh4 = 90;

  printf("%c %d \n", cCh1, cCh1);
  printf("%c %d \n", cCh2, cCh2);
  printf("%c %d \n", cCh3, cCh3);
  printf("%c %d \n", cCh4, cCh4);

  return 0;
}

출력 화면

따라서 문자도 컴퓨터 내에선 숫자로 취급한다.

- 0부터 31까지는 제어문자

- 65 = 'A'      - 90 = 'Z'       - 97 = 'a'     - 122 = 'z'

 

- 문자열이 아닌 문자 하나만 쓸 경우 char 형 말고 int 형으로 쓰는 것이

더 빠르다. 왜냐하면

 

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

캐 스 팅 Casting

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

- 묵시적 형변환

컴파일러가 어떠한 언급도 없이 형변환

두 가지로 나뉜다.

 

- down casting(하향식 형변환)

서로 크기가 안 맞을 경우 맞지 않는 부분 만큼 버림.

ex)

int iNum;

char cNum;

iNum = 257.9;

cNum = iNum;

이와 같이 소스를 짜면 iNum에는 257, cNum에는 1이 들어간다.

iNum에서는 뒤에 소수를 버리고 cNum은 257이 이진수로 1 0000 0001인데

1byte만 가져가므로 0000 0001 만 들어감.

 

- up casting(상향식 형변환)

데이터의 손실을 막기 위해 범위가 더 큰쪽으로 맞춘다.

ex)

dNum = 1 + 1.4;

1도 double형으로 바뀌어 1.4와 연산되어 dNum에 들어간다.

 

- 명시적 형변환

프로그래머가 알려서 바뀌는 것

ex)

int iNum1 = 3;

int iNum2 = 4;

double dNum;

dNum = (double)iNum1 / iNum2;

() 괄호는 casting 연산자라 부르고

결국 iNum1이 double형으로 승격하고

묵시적 변환으로 iNum2도 double형으로 승격되어 계산됨.

 

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

printf 서식 문자와 특수 문자

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

 

추가로 %출력은 %%이다.

 

 

 

 

 

 

 

 

설정

트랙백

댓글

20140311 (비트연산자, 상수, 변수, const, sizeof)

17일차

 

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

비트연산자

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

비트 연산자 종류는

|     OR  조건 하나가 참일 때 참

&   AND  조건 둘 다 참일 때 참

^   XOR  두 조건이 서로 반대일 때 참

~ TILDE 비트 반전

<< LEFT SHIFT 왼쪽으로 비트 이동

 >> RIGHT SHIFT 오른쪽으로 비트 이동

가 있다.

아래 예제 소스코드를 보자.

#include <stdio.h>

int main()
{
  int iNum1;
  int iNum2;
  int iNum3;

// OR
  iNum1 = 0xB;
  iNum2 = 0x4;
  iNum3 = iNum1 | iNum2;

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

// AND
  iNum1 = 0xB;
  iNum2 = 0x4;
  iNum3 = iNum1 & iNum2;

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

// TILDE
  iNum1 = 0xFFFFFFF0;
  iNum2 = !iNum1;
  iNum3 = ~iNum1;

  printf("iNum1 : 0x%08X\n", iNum1);
  printf("iNum2 : 0x%08X\n", iNum2);
  printf("iNum3 : 0x%08X\n\n", iNum3);

// XOR
  iNum1 = 0xB;
  iNum2 = 0x6;
  iNum3 = iNum1 ^ iNum2;

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

// right SHIFT
  iNum1 = 0x18 >> 1;
  iNum2 = iNum1 >> 1;
  iNum3 = iNum2 >> 2;

  printf("iNum1  : 0x%X\n", iNum1);
  printf("iNum2  : 0x%X\n", iNum2);
  printf("iNum3  : 0x%X\n\n", iNum3);

// left SHIFT
  iNum3 = iNum3 << 3;

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

  return 0;
}

실행 결과

결과물에 위에 iNum2 : 0x00000000은 ~와 !가 헷갈려서

넣어서 비교해 보았다.

 

여기서 SHIFT 연산자를 좀 자세히 보기로 하였다.

아래 소스코드

#include <stdio.h>

int main()
{
  signed int iNum;
  unsigned int uiNum;

//
  iNum = 0xFFFFFFFF;
  uiNum = 0xFFFFFFFF;

  printf("1\n");
  printf("iNum  : 0x%X\n", iNum);
  printf("uiNum : 0x%X\n", uiNum);
  printf(>> 1\n");

  iNum = iNum >> 1;
  uiNum = uiNum >> 1;

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

//
  iNum = 0x82345678;
  uiNum = 0x82345678;

  printf("\n2\n");
  printf("iNum  : 0x%X\n", iNum);
  printf("uiNum : 0x%X\n", uiNum);
  printf(>> 1\n");

  iNum = iNum >> 1;
  uiNum = uiNum >> 1;

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

//
  iNum = 0x72345678;
  uiNum = 0x72345678;

  printf("\n3\n");
  printf("iNum  : 0x%X\n", iNum);
  printf("uiNum : 0x%X\n", uiNum);
  printf(>> 1\n");

  iNum = iNum >> 1;
  uiNum = uiNum >> 1;

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

//
  iNum = 0x72345678;
  uiNum = 0x72345678;

  printf("\n4\n");
  printf("iNum  : 0x%X\n", iNum);
  printf("uiNum : 0x%X\n", uiNum);
  printf(<< 1\n");

  iNum = iNum << 1;
  uiNum = uiNum << 1;

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

//
  iNum = 0x82345678;
  uiNum = 0x82345678;

  printf("\n5\n");
  printf("iNum  : 0x%X\n", iNum);
  printf("uiNum : 0x%X\n", uiNum);
  printf(<< 1\n");

  iNum = iNum << 1;
  uiNum = uiNum << 1;

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

  return 0;
}

 실행 결과

여기서 변수 앞에 signed, unsigned를 붙여서 연산한 결과가

다르게 나온다는 것을 볼 수 있다.

>> 오른쪽 SHIFT로 비트를 움직일 경우

1번과 2번의 결과를 통해

signed는 맨 앞에 부호비트로 인식?해서 맨 앞자리는 계속 1(음수)을 채워 넣고

unsigned는 명령하는 대로 움직이는 것을 볼 수 있다.

하지만 3번과 4번, 5번을 통해

signed의 맨 앞자리가 0일 경우(양수) unsigned와 같은 결과를 보고

<< 왼쪽 SHIFT로 비트를 움직일 경우

둘 다 명령처럼 움직이는 것을 볼 수 있다.

 

* 따라서 SHIFT연산을 할 경우 원하는 값대로 나오게 하려면

unsigned를 붙여야 한다. 또 컴퓨터 내에서 unsigned가 더 빠르다

 

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

상수와 변수, const

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

const는 변수를 상수화 시키는 것이다.

오직 읽기만 가능하기에 반드시 선언시에 초기화를 해야한다.

아래는 const상수 실습 소스코드.

#include <stdio.h>

int main()
{
  int iNum = 3;
  const int ciNum = 100;

  iNum = 100;
//  ciNum = 1000;
  printf("%d\n", ciNum);

  return 0;
}

위에 ciNum = 1000;을 넣으면 l-value Error가 뜬다.

iNum = 100;

=을 중심으로 왼쪽은 l-value (Left Value),

오른쪽은 r-value (Right Value)라고 부른다.

 

 

-------

sizeof

-------

 

변수나 상수 등 크기를 측량하는 연산자.

지금까지 sizeof()가 뒤에 괄호가 붙으니 함수인지 알았는데

연산자였다.... 괄호는 우선순위만 정해주는 역할이었다.. 충격..

아래는 실습 소스코드

#include <stdio.h>

int main()
{
  int iNum;

  printf("char : %d\n"sizeof(char));
  printf("short : %d\n"sizeof(short));
  printf("int : %d\n"sizeof(int));
  printf("long : %d\n"sizeof(long));
  printf("long long : %d\n"sizeof(long long));
  printf("float : %d\n"sizeof(float));
  printf("double : %d\n"sizeof(double));
  printf("long double : %d\n"sizeof(long double));
//  printf("sizeof 3.5 : %d\n", sizeof 3.5 );
//  printf("sizeof iNum + 3 : %d\n", sizeof iNum + 3);

  return 0;
}

출력 화면

왼쪽은 MS-DOS VC++로 실행한 결과이고

오른쪽은 Linux gcc에서 실행한 결과이다.

변수의 크기는 컴파일러 마다 다르기 때문에

새로운 컴파일러를 사용시 꼭 확인해야 한다.

 

그리고 아래는 sizeof가 함수가 아니라 연산자라는 것을 확인한 것이다

위에 소스에서 주석 처리한 부분을 실행한 결과다. 

결과 화면과 같이 sizeof 는 연산자였다.......

그리고 실수를 넣었을 때에 컴파일러 마다 float일지 double형일지는

이것도 확인해 봐야 한다고 한다.

 

 

 

 

설정

트랙백

댓글

20140310 (scanf, 16진수 10진수, 실수)

16일차

 

-----------

scanf 함수

-----------

scanf("서식문자", &변수);

여기서 &기호는 나중에 포인터 나올 때에 다시 배우기로 하고

우선 scanf 함수 내에 변수 앞에는 무조건 붙인다.

 

 

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

16진수와 10진수

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

보통 프로그램 만들 때에는 10진수를 사용하지만

임베디드는 주로 16진수를 사용한다고 한다.

위에 그림과 같이 LED에  불을 킨다면 한 자리당 그 해당하는 LED 스위치를

담당한다고 한다. 0이 켜지는 것이라고 하셨다.

그래서 소스에

int iSwitch = 0x05; // 0101 (2) == 0x05 (16)

이런 식으로 표현될 것이라고 하심.

 

----------

실       수

----------

 

실수 구조 ( IEEE 754 )

 

- 오늘 알게된 것 중 주관적으로 가장 중요한 것이라고 생각하는 것이

cpu내에서 실수는 정수보다 훨씬 느리다. 가급적이면 정수를 사용할 것.

정수가 메모리에 저장되는 구조와 실수가 저장되는 구조가 다르고 실수가 훨씬 어렵다

 

-실수 변수 사용 예

#include <stdio.h>

int main()
{
  float fNum;

  fNum = 3.0/2;  /* 여기서 잿수와 피잿수 중 하나라도 실수가 아니면

                           정수로 계산하여 실수형태로 저장하기 때문에 둘 중 하나는

                           반드시 실수형태여야 한다. */

  printf("%f\n", fNum);   // 실수는 %f 로 사용.

  return 0;
}

 

설정

트랙백

댓글