연산은 우리가 알고있는 +, -, *, /, % 등을 표현하며 C언어에서도 그 연산식을 다룹니다. 그 기호로 표현한 코드들을 연산자라 표현한다. 이번 글은 그 연산자와 짧게 배운 형변환에 대해 알아보겠습니다. 아래는 사용할 코드 정리입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include <stdio.h>
void main()
{
//연산자(Operators)
const int lhs = 3, rhs = 5;
printf("lhs + rhs: %d\n", lhs + rhs);
printf("lhs - rhs: %d\n", lhs - rhs);
printf("lhs * rhs: %d\n", lhs * rhs);
printf("lhs / rhs: %d\n", lhs / rhs); //%d를 쓰면 10진수의 정수만 표현하라는 뜻이기 때문에 소수점을 제외한 값 0이 출력
//printf("lhs / rhs: %f\n", lhs / rhs); //%f를 쓰면 정수형 int를 float 실수형으로 표현하라는 뜻이기 때문에 유효한 함수가 아님
//형변환(Type Casting, Type Conversion): 자료형을 바꿔주는 것
//자료형의 승격
printf("lhs / rhs: %f\n", lhs / rhs); //변수의 자료형 int를 float값으로 바꾸지 않고 %f로 표현해달라하니 0.000000으로 표현함.
printf("lhs / rhs: %f\n", (float)lhs / rhs); //int lhs를 float lhs로 변환하여 3을 3.000000으로 변환해 계산함 //이 순간만 변환
printf("lhs / rhs: %f\n", lhs / (float)rhs); //위와 같은 출력값 //정수보다 실수가 더 정확도가 높기 때문에 컴퓨터는 계산할 때 실수가 포함되있다면 그걸 따라 계산함.
printf("lhs %% rhs: %d\n", lhs % rhs); //Debug를 하면 % r을 %r로 읽어서 이런 용어 잘 모른다고 알려준다. 때문에 %%라고 붙여야함.
float f = 3.14f;
//묵시적 형변환 (Implicit Type Casting)
//명시적 형변환 (Explicit Type Casting)
int i = (int)f; //(int)를 빼면 묵시적 형변환인데 잘못하면 관련 데이터 잃을 수 있음,(int)를 붙이면 명시적 형변환 //Debug할 때 "야, 너 f를 int로 형 변환하는 거 알아? 라고 얘기하는것.
printf("i: %d\n", i); //%d이기 때문에 3.14의 소수 0.14를 제외하고 '3' 출력
//float result = 3.14f % 0.5f; //나머지 연산(%)은 정수만 가능
//단항연산자 ++, --은 1씩 증가, 감소를 얘기함.
int value = 0;
//후증가 연산자(Post-Increment)
printf("value++ %d\n", value++); //%d\n처리를 먼저한 후, 후연산 출력값 0;
//선증가 연산자(Pre-Increment)
printf("++value: %d\n", ++value); //먼저 선연산 후 %d\n처리 진행 출력값 2;
//후감소 연산자(Post-Decrement)
printf("value--: %d\n", value--); //%d\n처리를 먼저한 후, 후연산 출력값 2;
//선감소 연산자(Pre-Decrement)
printf("--value: %d\n", --value); //먼저 선연산 후 %d\n처리 진행 출력값 0;
//이러한 문제로 같은 조건과 결과라면 선연산이 속도가 빠르기 때문에 더 좋다.
//대입연산자
int result = lhs + rhs;
//삼항연산자(조건 ?, 참: 거짓)
result = lhs < rhs ? 0 : 1; // > < 비교연산자 조건 ? 참 : 거짓으로 lhs가 rhs보다 작으면 result값을 0으로 크면 1로 넣어라.
printf("result: %d\n", result);
//복합대입연산자
long double val = 1.5L;
val += 0.5L; //val = val + 0.5L;
val -= 0.5L; //val = val - 0.5L;
val *= 0.5L; //val = val * 0.5L;
val /= 0.5L; //val = val / 0.5L;
result %= 3; // result 변수는 자료형이 int기 때문에 따로 표현. %나머지 연산은 정수로만 가능 3.3f이런거 안됨
printf("Q1: 3 + 2 * 2 = %d\n", 3 + 2 * 2);
printf("Q2: ++result / result-- * ++result = %d\n", ++result / result-- * ++result);
printf("Q3: value = 3 + 2 / result-- = %f\n", value = 3 + 2 / (float)(result--));
return;
}
|
cs |
<연산자> (Operators)
앞 글에서 다뤘던 상수 선언으로 시작합니다.
void main()
{
//연산자(Operators)
const int lhs = 3, rhs = 5;
printf("lhs + rhs: %d\n", lhs + rhs); // lhs + rhs: 8
printf("lhs - rhs: %d\n", lhs - rhs); // lhs - rhs: -2
printf("lhs * rhs: %d\n", lhs * rhs); // lhs * rhs: 15
printf("lhs / rhs: %d\n", lhs / rhs); // lhs / rhs: 0
printf("lhs / rhs: %f\n", lhs / rhs); // lhs / rhs: 0.000000
printf("lhs / rhs: %f\n", (float)lhs / rhs); // lhs + rhs: 0.600000
printf("lhs / rhs: %f\n", lhs / (float)rhs); // lhs + rhs: 0.600000
printf("lhs %% rhs: %d\n", lhs % rhs); // lhs % rhs: 3
float result = 3.14f % 0.5f; // %는 나머지 연산으로 정수만 가능하기 때문에 오류가 발생한다.
return;
}
const는 초기값이 고정된 상수로 lhs = 3과 rhs = 5가 선언되었습니다. 각 코드별 오른쪽 주석은 결과값입니다. +, -, *는 정수값에서 변화가 없으니 넘어가고 / 부터 보겠습니다.
printf("lhs / rhs: %d\n", lhs / rhs); // lhs / rhs: 0 // %d는 정수로 출력하라는 뜻, 소수 출력 X
printf("lhs / rhs: %f\n", lhs / rhs); // lhs / rhs: 0.000000 // 정수 자료형인 int에 %f로 출력해달라하면 컴퓨터가 이해할 수 없어서 그냥 0.000000으로 표기하며 오류 발생
printf("lhs / rhs: %f\n", (float)lhs / rhs); // lhs + rhs: 0.600000 // 정수 상수인 lhs 값을 이 코드에선 임의로 실수형으로 바꿔 연산해달라는 뜻입니다. 그렇기 때문에 %f를 해도 오류가 없습니다.
printf("lhs / rhs: %f\n", lhs / (float)rhs); // lhs + rhs: 0.600000 // 정수 상수인 rhs 값을 이 코드에선 임의로 실수형으로 바꿔 연산해달라는 뜻입니다. 그렇기 때문에 %f를 해도 오류가 없습니다.
printf("lhs %% rhs: %d\n", lhs % rhs); // lhs % rhs: 3 // %%를 한 이유는 Debug 시 %만 존재하면 % r로 읽어 해석할 수 없다고 경고가 발생하며 오류가 발생할 수 있습니다.
여기서 확인해야할 사항 3가지입니다.
- 실수 자료형을 정수로 출력해달라하면 소수값을 제외한 정수값만 출력합니다.
- 정수 자료형을 실수로 출력해달라하면 오류가 발생합니다. (컴퓨터가 이해 못함.)
- 정수 자료형을 실수형으로 변환시켜 실수로 출력해달라하면 가능합니다.
위의 3번에 대한 설명을 위해 잠시 형변환에 대해 설명하겠습니다.
<형변환> (Type Casting)
형변환의 종류는 두 가지로 묵시적(Implicit)과 명시적(Explicit)으로 나뉩니다.
float f = 3.14f;
int i = (int)f;
printf("i: %d\n", i);
위 코드에서 f 변수는 실수로 선언되며 3.14f의 초기값을 가지고 있습니다. 그리고 다음 줄에서 int i = (int)f 라는 코드가 붙여지는데 그 뜻은 정수 i 변수의 초기값은 f 변수의 초기값의 정수 부분을 뜻합니다. 여기서 (int)가 붙은 상태를 명시적 형변환이라고 하고 붙이지 않으면 묵시적 형변환이라고 합니다.
위의 표대로라면 묵시적 형변환을 하여도 되지만 Debug시 경고해주며 잘못하면 관련 데이터를 잃을 수 있습니다. 때문에 웬만해선 명시적 형변환을 사용하는걸 생활화합시다.
<단항(증감) 연산자> (++, -- 1씩 증가, 감소)
단항 연산자는 특정 변수, 상수끼리의 연산이 아니라 기존의 변수, 상수에 지속적인 특정값을 더하거나 빼는 것을 뜻합니다. 관련 코드를 위에서 가져옵니다.
int value = 0;
printf("value++ %d\n", value++); //후증가 연산자(Post-Increment), %d\n처리를 먼저한 후, 후연산 출력값 0;
printf("++value: %d\n", ++value); //선증가 연산자(Pre-Increment), 먼저 선연산 후 %d\n처리 진행 출력값 2;
printf("value--: %d\n", value--); //후감소 연산자(Post-Decrement), %d\n처리를 먼저한 후, 후연산 출력값 2;
printf("--value: %d\n", --value); //선감소 연산자(Pre-Decrement), 먼저 선연산 후 %d\n처리 진행 출력값 0;
코드 우측 주석 설명대로 ++, --가 앞에 붙으면 선, 뒤에 붙으면 후라는 이름이 붙습니다. 순서에 따라 연산 순서도 달라집니다. 만약 같은 조건과 결과라면 선연산이 속도가 빠르기 때문에 더 활용하기 좋습니다.
위의 출력 순서는 %d 출력0 -> ++ -> ++ -> %d 출력2 -> %d 출력2 -> -- -> -- -> %d 출력0
<대입연산자>
대입 연산자는 = 등호에 관한 것으로 변수에 값, 변수, 수식 등을 대입한다라는 개념입니다. 밑의 코드에 주석 설명입니다.
d = e = 1; // 다중대입(변수 a와 b에 정수 1 저장)
}
<삼항연산자> (조건 ?, 참 : 거짓)
비교 연산자 > <와 조건 ? 참 : 거짓을 다루는 연산자입니다. 위의 코드와 주석으로 설명합니다.
result = lhs < rhs ? 0 : 1; // lhs = 3, rhs = 5라는 상수
printf("result: %d\n", result); // lhs가 rhs보다 작으면 result값을 0으로 크면 1로 넣어라.
결과값은 0이 나옵니다.
<복합대입연산자>
복합대입연산자는 대입 연산자 = 등호에 여러 연산자를 붙여 사용하는 것을 의미합니다. 위의 코드를 가져옵니다.
const int lhs = 3, rhs =5;
int result = lhs + rhs;
long double val = 1.5L;
val += 0.5L; //val = val + 0.5L;
val -= 0.5L; //val = val - 0.5L;
val *= 0.5L; //val = val * 0.5L;
val /= 0.5L; //val = val / 0.5L;
result %= 3; //result = result % 3; (result = result / 3의 나머지값) result 변수는 자료형이 int기 때문에 따로 표현. %나머지 연산은 정수로만 가능하기 때문에 실수형인 val 대신 정수형 변수인 result로 표현함, 출력값에 3.3f 이런거 나올 수 없습니다.
코드 우측 주석의 설명대로 복합대입연산자의 코드는 <변수명 - 복합대입연산자 - 식>으로 구성되어있으며 있습니다. 이제 val과 result 코드들을 출력해보겠습니다.
printf("val += %lf\n", val += 0.5L); //출력값 val += 2.000000
printf("val -= %lf\n", val -= 0.5L); //출력값 val -= 1.500000
printf("val *= %lf\n", val *= 0.5L); //출력값 val *= 0.750000
printf("val /= %lf\n", val /= 0.5L); //출력값 val /= 1.500000
printf("result %= %d\n", result %= 3); //출력값 result %= 2
여기서 기억해야할건 val의 값은 상수가 아닌 변수이기 때문에 위에서 아래로 코드가 내려가며 var의 값은 항시 변하게됩니다. 즉, += 연산 출력값인 2.000000이 -= 연산에 대입되어 출력되고 그 값이 *=에 출력되고 이러한 방식으로 진행되어 주석에 나온 출력값이 나오게 된다. %=는 나머지값을 나타내는 것이기 때문에 2가 나오게된다.
끝
'프로그래밍 C언어' 카테고리의 다른 글
반복문(Loop) (1) | 2024.08.11 |
---|---|
분기문(Branch)과 조건문(Condition) (0) | 2024.08.09 |
변수(Variable)와 상수(Constant) (0) | 2024.08.08 |
고정소수점과 부동소수점의 이해 (0) | 2024.08.08 |
변수와 자료형(Data Type) (0) | 2024.08.07 |