[P4C] C언어 코딩 도장 : UNIT 12 ~ UNIT 16
Unit 12. 덧셈, 뺄셈하기
#include <stdio.h>
int main()
{
int num1;
int num2;
num1 = 1 + 2; // 1에 2를 더해서 num1에 저장
num2 = 1 - 2; // 1에서 2를 빼서 num2에 저장
printf("%d\n", num1); // 3
printf("%d\n", num2); // -1
return 0;
}
다음과 같이 덧셈은 + 연산자, 뺄셈은 - 연산자를 사용한다.
* 변수 하나에서 값을 더하거나 빼기
C 언어에서는 num1 = num1 + 2;와 같이 num1을 두 번 입력하지 않도록 덧셈 후 할당 +=, 뺄셈 후 할당 -= 연산자를 제공한다.
- 변수 += 값
- 변수 -= 값
#include <stdio.h>
int main()
{
int num1 = 1;
int num2 = 1;
num1 += 2; // num1에 2를 더한 뒤 다시 num1에 저장(2를 증가시킴)
num2 -= 2; // num2에서 2를 뺀 뒤 다시 num2에 저장(2를 감소시킴)
printf("%d\n", num1); // 3
printf("%d\n", num2); // -1
return 0;
}
num1 += 2은 num1 = num1 + 2;의 축약형이다.
num2 -= 2은 num2 = num2 - 2;의 축약형이다.
Unit 13. 증가, 감소 연산자 사용하기
++ : 값을 1 증가시키는 증가 연산자
-- : 값을 1 감소시키는 감소 연산자
13.1 변수의 값을 1 증가, 감소시키기
증가 연산은 ++ 연산자를 사용하며 변수 앞과 뒤에 붙일 수 있다.
- 변수++;
- ++변수;
#include <stdio.h>
int main()
{
int num1 = 1;
num1++; // 정수형 변수의 값을 1 증가시킴
printf("%d\n", num1); // 2
return 0;
}
이 코드의 실행 결과는 2이다.
따라서 증가 연산자는 num1 = num1 + 1;와 같고 num1 += 1;도 같은 효과를 낸다.
감소 연산의 경우, --연산자를 사용하며 변수 앞과 뒤에 붙일 수 있다.
13.2 실수 자료형에 증감 연산자 사용하기
#include <stdio.h>
int main()
{
float num1 = 2.1f;
float num2 = 2.1f;
num1++; // 실수형 변수의 값을 1 증가시킴
num2--; // 실수형 변수의 값을 1 감소시킴
printf("%f %f\n", num1, num2); // 3.100000 1.100000
return 0;
}
실수에서도 ++, -- 연산자를 사용할 수 있으며 1을 증가시키거나 감소시킨다. 따라서 정수 부분만 바뀌며 소수점 이하 자리에는 영향을 미치지 않는다.
13.3 문자 자료형에 증감 연산자 사용하기
#include <stdio.h>
int main()
{
char c1 = 'b';
char c2 = 'b';
c1++; // 문자 자료형 변수의 값을 1 증가시킴, 'c'로 바뀜
c2--; // 문자 자료형 변수의 값을 1 감소시킴, 'a'로 바뀜
printf("%c %c\n", c1, c2); // c a: b에서 1 증가시켰으므로 c, b에서 1 감소시켰으므로 a
return 0;
}
문자 자료형도 실제로는 정수이므로 증감 연산자를 사용하면 1을 증가시키거나, 감소시킨다. 따라서 b를 1 증가시키면 ASCII 코드대로 c가 되고, 1 감소시키면 a가 된다.
13.4 증감 연산자의 위치에 따른 차이점 알아보기
증감 연산자를 변수 뒤에 사용한 것을 후위(postfix) 연산자라고 한다.
#include <stdio.h>
int main()
{
int num1 = 2;
int num2 = 2;
int num3;
int num4;
num3 = num1++; // num1의 값을 num3에 할당한 뒤 num1의 값을 1 증가시킴
num4 = num2--; // num2의 값을 num4에 할당한 뒤 num2의 값을 1 감소시킴
printf("%d %d\n", num3, num4); // 2 2
return 0;
}
실행 결과는 다음과 같다.
2 2
2가 들어있는 num1, num2 뒤에 ++, -- 연산자를 사용한 다음 다른 변수에 할당하였다. 그런데 printf로 값을 출력해보면 값이 바뀌지 않고 2가 출력된다.
-> 후위 연산자는 할당 이후에 연산을 하게 되므로 바뀌기 전의 값이 다른 변수에 할당된다.
증감 연산자를 변수 앞에 사용한 것은 전위(prefix) 연산자라고 한다.
#include <stdio.h>
int main()
{
int num1 = 2;
int num2 = 2;
int num3;
int num4;
num3 = ++num1; // num1의 값을 1 증가시킨 뒤 num3에 할당
num4 = --num2; // num2의 값을 1 감소시킨 뒤 num4에 할당
printf("%d %d\n", num3, num4); // 3 1
return 0;
}
실행 결과는 다음과 같다.
3 1
2가 들어있는 num1, num2 앞에 ++, -- 연산자를 사용한 다음 다른 변수에 할당하였다. 그리고 printf로 값을 출력해보면 증감 연산자가 동작하여 3, 1이 출력된다.
전위 연산자는 할당 전에 연산을 하게 되므로 바뀐 값이 다른 변수에 할당된다.
※ 파이썬과의 차이점 : C와는 달리 파이썬의 경우 증감 연산자(++/--)가 존재하지 않는다.
Unit 14. 곱셈, 나눗셈하기
곱셈은 * 연산자, 나눗셈은 / 연산자를 사용한다.
- a * b
- a / b
#include <stdio.h>
int main()
{
int num1;
int num2;
num1 = 2 * 3; // 2에 3를 곱해서 num1에 저장
num2 = 7 / 2; // 7에서 2를 나누어서 num2에 저장
printf("%d\n", num1); // 6
printf("%d\n", num2); // 3: 소수점을 사용하지 않고 최대한 나눌 수 있는 값이 3
return 0;
}
실행 결과는 다음과 같다.
6
3
그런데, 나눗셈은 결과를 보면 3.5가 아니라 3이 나온다. 왜냐하면 C 언어에서는 정수끼리 나눗셈을 하면 결과도 정수가 나오기 때문이다.
나눗셈에서 또 한가지 주의해야 할 점은 컴퓨터에서 정수를 0으로 나눌 수 없다는 점이다. 정수를 0으로 직접 나누면 컴파일 에러가 발생한다.
다음은 실수의 곱셈과 나눗셈이다.
#include <stdio.h>
int main()
{
float num1;
float num2;
num1 = 2.73f * 3.81f; // 2.73에 3.81f을 곱해서 num1에 저장
num2 = 7.0f / 2.0f; // 7.0에서 2.0을 나누어서 num2에 저장
printf("%f\n", num1); // 10.401299
printf("%f\n", num2); // 3.500000
return 0;
}
앞의 정수끼리 나눗셈과는 달리 실수끼리 나눗셈을 하면 소수점 이하 자리까지 계산이 된다. 즉, 7.0에서 2.0을 나누었으므로 3.5가 나온다.
실수 계산에서 한가지 특이한 점은 계산 결과에서 오차가 발생한다는 점이다. 다음과 같이 2.73에 3.81을 곱하면 10.4013이 나와야 하는데 10.401299가 나온다. 실수의 계산 오차는 곱셈뿐만 아니라 덧셈, 뺄셈, 나눗셈에서도 나타난다.
* 변수 하나에서 값을 곱하거나 나누기
곱셈과 나눗셈도 변수를 두 번 입력하지 않도록 곱셈 후 할당 *=, 나눗셈 후 할당 /= 연산자를 제공한다.
- 변수 *= 값
- 변수 /= 값
#include <stdio.h>
int main()
{
int num1 = 2;
int num2 = 7;
num1 *= 3; // num1에 3을 곱한 뒤 다시 num1에 저장
num2 /= 2; // num2에서 2를 나눈 뒤 다시 num2에 저장
printf("%d\n", num1); // 6
printf("%d\n", num2); // 3
return 0;
}
num1 *= 3;은 num1 = num1 * 3;의 축약형이다.
num2 /= 2;는 num2 = num2 / 2;의 축약형이다.
※ 파이썬과의 차이점 : C언어에서는 정수끼리 나누면 결과값으로 정수가 반환되지만, 파이썬에서는 정수로 나눠도 소수점 이하 자리까지 계산된다. 즉, 실수값이 반환된다.
Unit 15. 나머지 연산하기
% 연산자 : 정수 a에서 b를 나눈 뒤 나머지를 구한다.
- a % b
#include <stdio.h>
int main()
{
printf("%d\n", 1 % 3); // 1: 1을 3으로 나누면 몫은 0 나머지는 1
printf("%d\n", 2 % 3); // 2: 2를 3으로 나누면 몫은 0 나머지는 2
printf("%d\n", 3 % 3); // 0: 3을 3으로 나누면 몫은 1 나머지는 0
printf("%d\n", 4 % 3); // 1: 4를 3으로 나누면 몫은 1 나머지는 1
printf("%d\n", 5 % 3); // 2: 5를 3으로 나누면 몫은 1 나머지는 2
printf("%d\n", 6 % 3); // 0: 6을 3으로 나누면 몫은 2 나머지는 0
return 0;
}
다음과 같이 나머지 연산 %는 앞의 숫자를 뒤의 숫자로 나눈 뒤 나머지만 구한다.
% 연산자의 특징
1. 나머지 연산은 특정 수의 배수인지 확인할 때 자주 사용한다(특정 수로 나누었을 때 나머지가 0이면 배수).
2. 그리고 어떤 수이든 0, 1, 2의 3가지 상태로 강제할 때도 사용할 수 있다(x % 3일 때).
3. 나머지 연산은 정수에서만 사용할 수 있고 실수에서는 사용할 수 없다(컴파일 에러 발생).
4. 또한, 7 % 0처럼 0으로 나눈 결과의 나머지는 구할 수 없다.
* 변수 하나에서 나머지 연산하기
나머지 연산도 변수를 두 번 입력하지 않도록 나머지를 구한 후 할당 %= 연산자를 제공한다.
- 변수 %= 값
#include <stdio.h>
int main()
{
int num1 = 7;
num1 %= 2; // num1에 2를 나눈 뒤 나머지를 구하여 다시 num1에 저장
printf("%d\n", num1); // 1
return 0;
}
num1 %= 2는 num1 = num1 % 2;의 축약형이다.
Unit 16. 자료형의 확장과 축소 알아보기
16.1 자료형의 확장
실제로 프로그래밍을 할 때는 서로 다른 자료형으로 연산을 할 때가 많다.
이렇게 서로 다른 자료형끼리 연산을 할 때 나타나는 형변환에 대해 알아보겠다.
먼저 정수와 실수를 함께 연산했을 때이다.
#include <stdio.h>
int main()
{
int num1 = 11;
float num2 = 4.4f;
printf("%f\n", num1 + num2); // 15.400000: 정수와 실수 덧셈. 정수는 실수로 변환됨
printf("%f\n", num1 - num2); // 6.600000: 정수와 실수 뺄셈. 정수는 실수로 변환됨
printf("%f\n", num1 * num2); // 48.400002: 정수와 실수 곱셈. 정수는 실수로 변환됨
printf("%f\n", num1 / num2); // 2.500000: 정수와 실수 나눗셈. 정수는 실수로 변환됨
return 0;
}
실행 결과는 다음과 같다.
15.400000
6.600000
48.400002
2.500000
정수와 실수를 함께 연산하면 결괏값은 실수로 나온다. 왜냐하면 실수가 정수보다 표현 범위가 넓기 때문이다.
C 언어에서는 자료형을 섞어서 쓰면 컴파일러에서 암시적 형 변환(implicit type conversion)을 하게 되는데 자료형의 크기가 큰 쪽, 표현 범위가 넓은 쪽으로 자동 변환된다. 이를 형 확장(type promotion)이라고 하며 값이 버려지지 않고 그대로 보전된다.
이번에는 크기가 다른 정수끼리 연산을 해보겠다.
#include <stdio.h>
int main()
{
long long num1 = 123456789000;
int num2 = 10;
// int보다 long long이 자료형 크기가 크므로 long long으로 변환됨
printf("%lld\n", num1 + num2); // 123456789010
printf("%lld\n", num1 - num2); // 123456788990
printf("%lld\n", num1 * num2); // 1234567890000
printf("%lld\n", num1 / num2); // 12345678900
return 0;
}
실행 결과는 다음과 같다.
123456789010
123456788990
1234567890000
12345678900
long long형 num1과 int형 num2를 함께 연산하면 long long으로 변환된다. int는 4바이트, long long은 8바이트이므로 int보다 long long이 크기 때문이다.
16.2 자료형의 축소
다음과 같이 실수에서 정수로 표현 범위가 좁은 쪽으로 변환하게 되면 값의 손실이 생긴다.
#include <stdio.h>
int main()
{
float num1 = 11.0f;
float num2 = 5.0f;
int num3 = num1 / num2; // 실수에서 실수를 나누어 2.2가 나왔지만
// 정수 자료형에는 2만 저장되고 0.2는 버려짐
printf("%d\n", num3); // 2
return 0;
}
11.0에서 5.0을 나누면 2.2가 되어야 하지만 정수 자료형에서는 소수점 이하 자리를 표현할 수 없으므로 2만 저장된다. 따라서 0.2가 버려지게 되므로 주의해야한다. 이렇게 자료형의 크기가 작은 쪽, 표현 범위가 좁은 쪽으로 변환 되는 것을 형 축소(type demotion)라고 한다.
형 축소가 일어나면 컴파일할 때 값의 손실이 일어날 수 있다고 경고가 나온다.
-> 컴파일 경고가 나오지 않게 하려면 형 변환(type conversion, type casting, 타입 캐스팅)을 해야 한다.
지금까지 알아본 형 확장과 축소를 그림으로 나타내면 다음과 같다.
오른쪽으로 갈수록 크기가 크고 표현 범위가 넓은 자료형이다. 그리고 같은 자료형 안에서도 숫자가 높을수록 크기가 크다.
※ 파이썬과의 차이점 : 파이썬의 경우 정수와 실수 간에는 암시적 형변환이 일어날 수 있지만, C언어와 달리 정수 자료형이나 실수자료형이 하나씩이기 때문에 자료형 안에서의 암시적 형변환은 존재하지 않는다.