프로그래밍 언어/C

연산자(Operators) 와 형변환

gcreators 2024. 8. 8. 17:17

연산자 (위키피디아)

물리학과 수학에서 어떤 함수에 작용해 그 함수를 다른 함수로 변형시키는 함수를 말한다.

const int lhs = 3, rhs = 5;

LHS : Left-Hand Side
RHS : Right-Hand Side

 

등호 ( = )가 있을때 등호의 오른쪽을 RHS, 왼쪽을 LHS라고 합니다.

 

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); //(나누기 시)나머지
printf("lhs / rhs: %f\n", lhs / rhs); //나눗셈

 

연산자는 간단하게 말해 우리가 흔히 사용하는 사칙연산 입니다.(물론 다른 연산자들도 더 많습니다)

덧셈, 뺄셈, 곱셈, 나눗셈 그리고 나머지를 구하는 연산자가 보는 것 처럼 따로 있습니다.

 

하지만 정상적으로 나눗셈이 되었다면

3 / 5 = 0.6이 되어야 하는데 값이 이상한 것을 확인 할 수 있습니다.

 

저 기호들은 연산자가 맞지만

이 결과를 출력하는 것은 별개임을 알 수 있죠

printf("lhs / rhs: %f\n", lhs / rhs);
//형변환(Type Casting, Type Conversion)
printf("lhs / rhs: %f\n", (float)lhs / rhs); 
printf("lhs / rhs: %f\n", lhs / (double)rhs);
printf("lhs / rhs: %d\n", lhs / (float)rhs);

 

정확한 값을 출력하기 위해

내가 선언한 자료형을 확인해야 할 필요가 있습니다.

lhs rhs 모두 상수(const) 정수형(int)으로 선언했기에

그 값이 고정된 정수입니다

 

정수를 정수로 나눠서 나온 값은 실수 이지만 정수형을 할당 받은 메모리에는

실수형의 값을 넣을 공간이 없습니다

따라서 출력 자체는 실수형으로 출력한다고 한들

그 메모리에는 실수가 담기지 않았기에 0.0으로 출력이 되죠

 

이를 해결하기 위해 있는 것이 바로 형변환(Type Casting, Type Conversion) 입니다.

위에서 확인한 것과 같이

변수 옆에 필요한 (자료형)을 붙여주는 것으로 내가 선언한 자료형을 해당 (자료형) 으로 변환 할 수 있습니다

int로 선언 했지만 (float)이나 (double)을 붙여 다른 자료형으로 변환을 해주었고

그 결과 제대로된 실수 값이 담기게 되었죠

 

하지만 형변환을 통해 하나는 정수고 하나는 실수가 되었는데도 실수값이 모두 메모리에 담기네요

그 이유는 컴퓨터는 정밀도가 높은 값을 계산 하는 것이 기본이며 정수와 실수를 같이 계산하면 정밀도가 더 높은 실수 로 계산을 하기 때문입니다.

이를 '자료형의 승격' 이라고 합니다.

 

형변환에는 흔히 두가지 종류가 있는데

float f = 3.14f;

int i = f; // 묵시적 형변환(Implicit Type Casting)
printf("i : %d\n", i);
i = (int)f; // 명시적 형변환(Explicit Type Casting)
printf("i : %d\n", i);


묵시적 형변환(Implicit Type Casting), 명시적 형변환(Explicit Type Casting) 이라고 합니다.

해당 코드는 둘다 출력 값은 3으로 동일합니다.

하지만 묵시적 형변환을 통해 자동으로 자료형이 바뀐다고 한들

 

위에서 이미 설명했던 것 처럼 연산을 통해 값을 출력해야 할 경우 형변환을 통해 (자료형)을 붙여야 정확한 값을 얻을 수 있습니다.

이를 잘 알고 활용해야 하겠습니다.

 

단항연산자

int value = 0;
//후증가 연산자(Post-Increment)
printf("value++: %d\n", value++);
//선증가 연산자(Pre-Increment)
printf("++value: %d\n", ++value);
//후감소 연산자(Post-Decrement)
printf("value--: %d\n", value--);
//선감소 연산자(Pre-Decrement)
printf("--value: %d\n", --value);

++은 1을 더하고 --는 1을 빼는 것 입니다.

 

후 연산자의 경우에는 결과값을 출력 한 후 연산을 하는 것 이고

선 연산자의 경우에는 결과값을 출력하기 전에 연산을 하는 것 입니다.

 

나중에 설명을 하겠지만 for문과 같은 활용처에서 i++ 처럼 후 연산자를 활용하는 경우가 많지만

프로그램의 연산처리 속도에는 후 연산이 아닌 선 연산이 더 빠른 속도가 나오기에 이점을 참고하여 코딩을 진행해야 할 거 같습니다.

 

대입연산자 ( = )

int result = lhs + rhs;

대입 연산자는 말 그대로 대입하는 것 입니다

보통 = 표시는 같다 라는 의미로 일상에서 사용되지만

프로그래밍에서는 대입이라는 것을 기억해야 합니다

int a=3;
int b=4;

a = b;

printf("%d", a);

를 진행 할 경우 a의 값은 b의 값이 대입되어 4가 나옵니다

 

삼항연산자(조건 ? 참 : 거짓)

result = lhs < rhs ? 0 : 1;
printf("result: %d\n", result);

참이면 0, 거짓이면 1을 출력하게 했습니다

lhs는 3 rhs는 5 이니 0이 나오겠죠?

 

결과 값이 참과 거짓으로 나오기에 많이 활용하는 연산자 입니다.

 

복합대입연산자

long double val = 1.5L;
int result = 4;

val += 0.5L; // val = val + 0.5L;
printf("val+= : %lf\n", val);

val -= 0.5L;
printf("val-= : %lf\n", val);
val *= 0.5L;
printf("val*= : %lf\n", val);
val /= 0.5L;
printf("val/= : %lf\n", val);
result %= 3;
printf("result %= : %lf\n", (float)result);

대입 연산자 왼쪽에 다른 연산자가 있는 경우 왼쪽의 변수에 대입연산자 오른쪽의 숫자를 해당 변수에 연산하게 합니다. 

 

연산 우선 순위

int result = 1;

printf("Q: 3 + 2 * 2 = %d\n", 3 + 2 * 2);
printf("Q2: ++result / result-- * ++result = %d\n", ++result / result-- * ++result);
printf("result = %d\n", result);
printf("Q3: (value = 3 + 2) / reslut -- = %.2f\n", (value = 3 + 2) / (float)(result--));

Q 같은 경우 곱, 나눗셈의 연산이 먼저 진행되는 것이 기본입니다

 

Q2의 단항 연산자의 경우

선 연산과 후 연산에 의해 결정되는데요

result값은 1을 할당 받았으나

++result 2번으로 선증가 연산을 2번 받아 해당 연산에서 3으로 먼저 계산됩니다

3 / 3 * 3 이라서 3이라는 결과가 나오게 됩니다

그리고 후감소 연산 result--를 받아 3에서 2가 되는지라

그 바로 아래 printf 코드에서는 2로 결과값이 나오게 되는 것 입니다. 

 

Q3의 경우에는

value값 5가 나오고

result값은 후감소 연산이라 연산 후 감소이므로 아직 2입니다.

그래서 5/2 = 2.5가 결과값으로 나오고

여기서 result 값은 1로 줄어들게 되죠

'프로그래밍 언어 > C' 카테고리의 다른 글

조건문  (0) 2024.08.09
비교 연산자와 논리 연산자  (0) 2024.08.09
변수(Variables)  (0) 2024.08.08
컴퓨터의 음수와 MSB / LSB  (0) 2024.08.07
자료형(Data Types)  (0) 2024.08.07