[C언어] 데이터의 표현과 연산

이가영·2023년 8월 8일
0

C언어

목록 보기
4/16

숫자상수

  • 숫자 데이터를 프로그램 안에서 직접 표현한 것
  • 정수형 상수의 표현
    -일반적인 정수값 표현방식과 같다.
  • 실수형 상수의 표현
    -정수값 표현방법에 소수점을 붙인다.
3.14   0.05   .9(=0.9)   165.(=165.0)
  • 정수형 상수와 실수형 상수는 다른 형태로 번역된다.

정수형 변수와 실수형 변수

  • 상수의 형태에 따라 적절한 자료형의 변수를 사용해야 함
  • 정수형 변수는 int, 실수형 변수는 double로 선언한다.

    정수형 변수 선언 -> int -> 크기: 4byte
    실수형 변수 선언 -> double -> 크기: 8byte

  • 월급의 실 입금액 계산을 위한 변수 선언의 예
int bonbong, bonus, total;  //본봉, 보너스, 총수입액
double tax, real_income;  //세금, 실수입액

bonbong = 150;  //본봉 = 150
bonus = 60;  // 보너스 = 60

total = bonbong + bonus;  //총수입액 = 본봉 + 보너스
tax = total * 0.09;  //세금 = 총수익액의 9%
real_income - total - tax;  //실수입액 = 총수입액 - 세금

기본적인 연산과 연산과정

  • 피연산자는 상수 또는 변수가 된다.
    상수 + 상수(150 + 60)
    변수 + 변수(bonbong + bonus)
    변수 상수(total 0.9)
  • 덧셈, 뺄셈, 곱셈 연산자
    덧셈: +
    뺼셈: -
    곱셈: *
  • 연산 결과는 일단 임시 기억공간에 저장된다.
    150 + 60; -> 기억공간에 잠시 저장 -> 사라짐
    total = 150 + 60; -> 기억공간에 잠시 저장 -> total 변수에 저장
    printf("%d", 150+60); -> 기억공간에 잠시 저장 -> printf함수에 전달

자동 형변환

  • 연산과정에서 피연산자의 형태는 하나로 통일된다.
    -정수형과 실수형 값이 연산될 때는 정수형이 실수형으로 자동 형변환 되어 연산된다 -> 그 결과값 또한 실수형

    정수형 10 -> 형변환 -> 10.0
    실수형 20.0 -> 변화없음 -> 20.0
    정수형 + 실수형 -> 10.0 + 20.0 = 30.0

※변수 type에서 사이즈가 큰 쪽으로 변환


실수형 데이터의 입출력

  • 실수형 값을 입출력 할 때는 %lf 변환문자열을 사용
    -실수형 값의 출력
double real_income;  //실수형 변수 선언
...
printf("실 수입액은 %lf입니다.", real_income);

-실수형 값의 입력

double tax_rate;  //세율을 저장할 실수형 변수
scanf("%lf", &tax_rate);  //키보드로 세율 입력
  • 숫자 데이터 정리
데이터형   상수의 표현법  변수의 자료형  데이터의 크기  입출력변환문자열
정수형         10           int        4바이트          %d
실수형        10.0         double      8바이트          %lf

문자상수

  • 문자상수는 문자를 작은따옴표로 묶어서 표현한다.
문자상수의 표현 -> 'A'

-문자상수의 크기는 1바이트이다.
-아스키코드값으로 변역되므로 실제로는 정수형 상수와 같이 처리된다.

printf("정수형 상수값 : %d\n", 65);   -> 정수형 상수값 : 65
printf("문자형 상수값 : %d\n", 'A');  -> 실수형 상수값 : 65

문자변수

  • 문자상수는 1바이트의 크기의 char형 변수에 저장한다.
문자형 변수 선언 -> 예약어 char -> 크기는 1바이트
char A;    //A는 char형 변수명 
A = 'A';  //변수 A에 문자상수 'A'를 저장
  • char형 변수는 작은 범위의 정수값도 저장할 수 있다.
  • 문자상수 자체가 정수값으로 변역되므로 char형 변수도 당연히 정수값을 저장할 수 있다. 단, 크기가 1바이트이므로 값의 범위가 제한적이다.
char ch;   //ch는 char형 변수명
ch = 123;  //char형 변수에 정수값 저장

문자의 입출력

  • 문자를 입출력 할 때는 %c 변환문자열을 사용
  • 혈액형을 입력 받아 그대로 출력하는 코드(ab형 빼고)
char blood_type;  //문자 변수의 선언
printf("혈액형을 입력 : ");  //입력 안내 메세지 출력
scanf("%c", &blood_type);  //혈액형 입력
printf("당신의 혈액형은 %c형입니다.\n", blood_type); // 혈액형 출력

-> (출력)

혈액형을 입력 : O (엔터)
당신의 혈액형은 O형입니다.
  • char형 변수라도 정수값을 입출력 할 때는 %d를 사용

문자열상수

  • 문자열상수는 문자열을 큰따옴표로 묶어서 표현
  • 문자열상수: 연속적인 문자상수들의 집합
  • 문자열상수의 마지막에는 널문자가 포함되어 번역
  • 널문자(null)는 '\0'으로 표현하며 아스키코드값은 0이다.
문자상수    번역된 형태    아스키코드값
'\0'   ->  0000 0000 -> 숫자 0과 일치
'0'    ->  0011 0000 -> 숫자 48과 일치

문자열의 저장

  • 문자열은 char형 변수들을 모아 놓은 배열에 저장
    -널문자를 포함한 문자열의 길이에 맞게 char 배열을 선언
    -문자열 "gayeong"을 저장하기 위한 char 배열
char string[8];
자료형/ 이름 /  몇 개를 모을 것인가?
  • 문자열상수는 배열의 선언과 동시에 대입(초기화만 가능)
char string[8] = "gayeong";  //배열의 선언과 동시에 문자열을 저장
char string[8];
string = "gayeong";  

-> 

컴파일 에러! (string이 변수의 이름이 아니라 상수라서)

문자열의 입출력

  • 문자열을 입출력 할 때는 %s변환문자열을 사용
    -배열은 입력되는 문자열이 모두 저장될 수 있도록 넉넉하게 선언
    -입력할 때 배열명 앞에는 &를 붙이지 않는다.
char string[80];  //80바이트면 넉넉하다
scanf("%s", string);

-지하철 역 이름을 입력 받아 출력하는 코드

char subway[80];
printf("역 이름을 입력 : ");
scanf("%s", subway);   //배열명 앞에 &이 없다!
printf("이번에 정차할 역은 %s역입니다.\n", subway);
  • 문자열을 입력할 때 중간에 빈칸을 두지 않는다.
    -scanf함수는 "화이트 스페이스(빈칸, 탭, 엔터)"를 입력 데이터를 구분하는 문자로 활용하므로 문자열의 중간에 빈칸이 들어가면 빈칸의 앞부분만 입력이 된다.
역 이름을 입력하세요 : 을지로 3(엔터)  //문자열 중간에 빈칸 입력
이번에 정차할 역은 을지로입니다.  //을지로만 출력
  • 중간에 빈칸이 있는 문자열 처리 -> 문자열 전용 입력 함수( gets() )
  • 문자 데이터 정리
데이터형   상수의 표현법   변수의 자료형   데이터의 크기   입출력 변환문자열
문자형        'A'         char          1바이트            %c
문자열     "gayeong"     char 배열      가변적임            %s

형변환 규칙

  • 서로 다른 형태의 값이 연산될 때는 형태가 하나로 통일된다.
  • 형변환은 데이터의 손실을 최소화하는 방향으로 수행된다.
문자 op 정수 -> 정수 op 정수
정수 op 실수 -> 실수 op 실수
문자 op 실수 -> 실수 op 실수
  • 문자 데이터끼리 연산 할 때는 둘 다 정수형으로 변환된다.
문자 op 문자 -> 정수 op 정수
  • 대입문에서는 횐쪽 변수의 형태에 따라 변환된다.
int result!
result = 2.5;  -> 소수부분은 버려지고 정수값만 저장된다.
  • 연산의 결과값은 피연산자의 형태와 같다. 따라서 두 정수값으로 나눗셈 연산을 수행하면 결과값은 정수가 된다.
result = 10 / 4.0;  //result = 2.000000이다.
  • 나눗셈 결과가 실수값이 되려면 피연산자 중의 하나는 실수값이여야 한다.
result = 10 / 4.0;  //연산시 정수값 10은 10.0으로 자동 형변환된다. result = 2.500000이다.
  • 나눗셈 연산자(/)의 피연산자가 모두 정수형이면 몫을 구한다.
  • 나머지 연산자(%)의 피연산자는 모두 정수형이어야 한다.
(몫 연산자)        (나머지 연산자)
정수형 / 정수형     정수형 % 정수형
  • 몫과 나머지 연산자는 어떤 값을 일정한 단위로 걸러낼 때 유용하다.
    -거스름돈 850원에 필요한 동전의 최소 개수를 구하는 예
    거스름돈 850원 / 500원 -> 몫 1은 500원 동전의 개수
    거스름돈 850원 % 500원 -> 나머지 350원은 다른 동전으로 계산할 값
  • 형변환 연산자는 피연산자의 형태를 명시적으로 변환시킨다.
(double) 정수형 데이터 -> 실수형으로 형변환 

-취업자 수와 졸업생 수를 입력 받아서 취업률을 계산하는 예

int employed, graduation;  //취업자수와 졸업생 수를 저장할 변수
double percentage;  //취업률을 저장할 변수
scanf("%d%d", &employed, &graduation);  //취업자수와 졸업생수 입력
percentage = (employed / (double)graduation) * 100;
//(double)graduation -> 나눗셈 연산이 수행되기 직전에 실수형으로 변환된다.

※형변환하지 않는다면 취업률은 항상 0%이다.

  • 실수를 정수형으로 형변환하면 정수값만 계산된다.
(int)3.69 -> 3

예시 문제

  • 32767초는 몇 시간, 몇 분, 몇 초 인지를 계산하는 프로그램

진법 변환

  • 진법은 값을 표현할 때 단위기호를 몇 개 사용하느냐이다.

    10진법, 8진법, 2진법, 16진법
    -10진법 : 0~9까지 10개
    -8진법 : 0~7까지 8개
    -2진법 : 0과 1
    -16진법 : 0~9, a, b, c, d, e, f

10진법 -> 10(10)
8진법 -> 12(8)
2진법 -> 1010(2)

다른 진법의 수를 10진수로

  • 각 자릿수에 2, 8, 16의 거듭제곱을 차례로 곱해서 모두 더한다.
  • 2진수 1010을 10진수로 바꾸는 예
0 : 0 x 2의 0제곱 = 0
1 : 1 x 2의 1제곱 = 2
0 : 0 x 2의 2제곱 = 0
1 : 0 x 2의 3제곱 = 8

-> 0 + 2 + 0 + 8 = 10
  • 16진수 4b를 10진수로 바꾸는 예
4b(16) -> (4x16의 1제곱) + (11x16의 0제곱) = 75

2진수를 8진수와 16진수로

  • 2진수
    -> 3자리는 8진수 1자리로
    -> 4자리는 16진수 1자리로 바꾼다.
(2진수 8자리)
01100111 <- 오른쪽을 기준으로 끊음

(세 자리씩 끊는다) 8진수
01/100/111
1   4   7

(네 자리씩 끊는다) 16진수
0110 / 0111
 6      7

10진수를 다른 진법으로

  • 10진수를 각 진법의 수로 나누면서 나머지를 차례로 적어준다.
  • 큰 수는 8진수를 먼저 구하고 2진수와 16진수로 바꾸면 편하다
73(8) -> 111011(2) -> 3b(16)

정수형 상수를 다른 진법으로 표현

  • 정수형 상수는 10진법, 8진법, 16진법으로 표현할 수 있다.
  • 8진수와 16진수로 표현할 때는 10진수와의 구별을 위해서 각각 접두어 0과 0x를 붙인다.
12(10진수)   014(8진수)   0xc(16진수) -> 모두 같은 값이다
  • 표현법만 다를 뿐 같은 값임

정수를 다른 진법으로 출력

  • 정수를 각 진법에 맞게 입출력 할 때는 적절한 변환문자열을 사용한다.
출력형태     10진수    8진수    16진수
변환문자열     %d      %o       %x
의미      decimal   octal   hexa-decimal
  • 같은 값 12를 각 진법으로 출력하는 예
printf("10진수 12를 10진수로 출력 : %d\n", 12);
printf("10진수 12를 8진수로 출력 : %d\n", 12);
printf("10진수 12를 16진수로 출력 : %x\n", 12);

-> 

10진수 1210진수로 출력 : 12
10진수 128진수로 출력 : 14
10진수 1216진수로 출력 : c

진법에 맞게 접두어 붙여서 출력

  • 변환문자열에 '#'플래그를 사용하면 -> 접두어를 붙여서 출력
printf("10진수 12를 8진수로 출력 : %#o\n", 12);
printf("10진수 12를 16진수로 출력 : %#x\n", 12);

-> 

10진수 128진수로 출력 : 014
10진수 1216진수로 출력 : 0xc

정수를 다른 진법으로 입력

  • 키보드입력 14를 각 진법으로 입력 받을 때 실제 입력되는 값
int val;
printf("정수값을 입력하세요 : ");
scanf("%o", &val);  // 키보드로 입력되는 값을 8진수로 해석한다.
printf("입력된 값을 10진수로 출력하면 %d입니다.\n", val);
정수값을 입력하세요 : 14
입력된 값을 10진수로 출력하면 12입니다.

※진법 변환 프로그램


여러 가지 정수형 자료형

  • 정수형 자료형에는 int형 외에도 여러 가지가 있으며, 크기는 컴파일러에 따라 차이가 있다.
  • 특별한 경우가 아니면 정수형 자료형으로 int형을 사용한다.
    -> int형은 현재의 시스템에서 가장 빠르게 처리될 수 있도록 구현되므로 int형을 사용하는 것이 좋다.

정수값의 비트표현

  • 정수값은 2진수로 저장된다.
15(10진수) -> 1111(2진수)
  • 2진수 비트열에서 가장 왼쪽의 비트는 MSB(most significant Bit), 가장 오른쪽의 비트는 LSB(least significant bit)가 된다.

정수형 변수를 양수값 전용으로 사용

  • 양수값 전용으로 사용할 때는 unsigned 예약어를 사용
unsigned int val;
양수값 전용으로 사용 / 자료형 / 변수명
  • unsigned 변수로 입출력할 때는 %u변환문자열을 사용한다.
unsigned char uch;  //uch는 unsigned형으로 선언
printf("unsigned char형에 최대값을 입력 : ");
scanf("%u", &uch);  // %u변환문자열 사용하여 입력
printf("unsigned char형에 저장된 값은 : %u\n", uch);  //%u로 출력
unsigned char형에 최대값을 입력 : 255
unsigned char형에 저장된 값은 : 255

정수값은 모듈러 연산에 의해 저장

  • 자료형의 최대값을 넘는 값을 입력하면 -> 범위를 넘어선 나머지 값만 저장된다.
unsigned char형에 최대값을 입력하세요 : 257
unsigned char형에 저장된 값은 : 1

예시 문제

※나이까지의 총 일 수 계산

몇 살까지 살고 싶습니까? 95
27375일, 657000시간, 39420000분, 2365200000초입니다.
계속하려면 아무 키나 누르십시오...

※거리와 속력

거리<km>와 속력<km/h>을 입력하세요 : 38.6
38<km>를 6<km/h>의 속력으로 달리면...
6시간 걸리고 2<km>가 남습니다.
계속하려면 아무 키나 누르십시오...

※거리와 속력2


실수값의 비트 표현

  • 실수값은 IEEE754표준에 따라 저장된다.
    -한정된 크기의 기억공간에 최대한 효율적으로 실수값을 저장하기 위해서는 특별한 약속에 따라 저장
  • double형 변수(8바이트)에 실수값을 저장하는 예
    -> 가장 왼쪽의 비트(MSB)는 부호비트이며 양수는 0, 음수는 1을 저장
    -> 부호비트 다음부터 11비트는 지수값을 저장한다.
    -> 나머지 52비트에 소수값을 저장한다.
  • 실수형 자료형은 signed와 unsigned를 사용하지 않는다.
    -실수형 자료형은 항상 signed형태로 사용되는 것이다.

저장 범위와 유효숫자

  • double형 변수의 저장값의 범위는 다음과 같다.
    -> 최대값은 지수 부분과 소수 부분이 모두 가장 큰 값을 가질 때이며 최소값은 부호가 반대인 경우
-1.79 x 10의 308승 ~ 1.79 x 10의 308승
  • double형 값의 유효숫자는 15자리이다.
    -> 실수값은 값의 크기와는 별도로 정확한 값을 표현하는 데에는 한계가 있다.
double exact;
exact = 0.1234567890123456789; //유효숫자가 많아서 정밀한 값
printf("유효숫자가 많은 값 : %.20lf\n", exact);
유효숫자가 많은 값 : 0.123456789012345678000 //뒷부분에 오차가 생김
  • 오차의 이유
    -소수 부분은 나타내는 비트가 정확한 값을 표현하지 못하기 때문

문자 데이터의 저장

문자 데이터는 아스키코드값으로 저장

  • 아스키코드값은 컴퓨터에서 사용되는 각 문자들을 어떤 비트열로 표현할 것인지에 때한 약속
  • 128개의 문자에 대해 각각 1바이트(8비트)의 비트열로 표현하도록 약속한다.
  • 아스키코드값의 몇 가지 예(괄호는 각각 16진수와 10진수)
A -> 0100 0001 (41, 65)
7 -> 0011 0111 (37, 55)
; -> 0011 1011 (3b, 59)
  • 문자상수는 아스키코드값에 해당하는 정수형 상수와 같다.
    -문자상수를 연산하여 대문자를 소문자로 바꾸는 예
'Q' + 32 -> 'q'  //코드값의 차이를 직접 더함
'Q' + ('a'-'A') -> 'q'  //코드값의 차이를 계산해서 더함 
'Q' + ' ' -> 'q'  //스페이스 문자의 코드값을 더함

자료형의 크기 확인

  • 자료형의 크기를 확힌할 때는 sizeof연산자를 사용
    ->sizeof연산자는 피연산자의 데이터 크기를 바이트 단위로 계산해준다.
sizeof(int) -> 연산결과는 4
  • 다양한 데이터의 크기를 확인하는데 사용할 수 있다.
printf("%d바이트\n", sizeof('V'));  //1바이트, 문자 상수의 크기
printf("%d바이트\n", sizeof(35));  //4바이트, 정수형 상수의 크기
printf("%d바이트\n", sizeof(1.65)); //8바이트, 실수형 상수의 크기
printf("%d바이트\n", sizeof(10/4)); //4바이트, 수식의 결과값의 크기
printf("%d바이트\n", sizeof("abc")); //4바이트, 문자열 상수의 크기
profile
gy’s portfolio

0개의 댓글