수식: 피연산자들과 연산자들의 조합
연산자: 어떤 연산을 나타내는 기호
피연산자: 연산의 대상이 되는것.
연산자의 분류
산술 연산자
산술 연산자는 기본적인 산술 연산인 덧셈, 뺄셈 , 곱셈, 나눗셈, 나머지 연산을 실행하는 연산자이다.
덧셈 +
뺄셈 -
곱셈 *
나눗셈 /
나머지 %
나눗셈 연산에 대해서 주의하여야 한다.
사람한테 7/4를 계산해보라고 하면 답이 1.75 라고 한다.
하지만 컴퓨터에서는 정수 계산과 실수 계산은 서로 다른 하드웨어를 사용하기 때문에 정수 연산은 1이 나오고 실수는 1.75가 나온다.
나머지 연산자 %는 생각보다 많이 사용되는 중요한 연산자이다.
x%y는 x를 y로 나누어서 남은 나머지를 반환한다.
ex) 10%3 은 1이다.
나머지 연산자를 이용하면 짝수와 홀수를 쉽게 구분할 수 있다.
부호 연산자
부호 연산자는 변수나 상수의 부호를 나타내거나 변경하는 연산자이다. 예를 들어서 어떤 값앞에 마이너스 기호인 -를 붙이면 그 값의 부호가 음수로 변경된다.
x = -10;
y = -x; // 변수 y의 값은 10이 된다.
증감 연산자
증감 연산자는 ++기호나 -- 기호를 사용하여 변수의 값을 1만큼 증가시키거나 감소시키는 연산자이다.
++x; // x = x + 1; 과 같은 의미
--x; // x = x -1; 과 같은 의미
증감 연산자는 피연산자의 앞이나 뒤에 올 수 있다. 만약 변수 x를 증가시킬 목적으로만 증감 연산자를 사용한다면 x++나 ++x는 동일하다.
그러나 증감 연산자를 적용한 후에 그 연산의 값을 사용할 목적이라면 두 가지를 구분하여야 한다. ++x는 x의 값을 먼저 증가시키고 증가된 x의 값을 수식에 사용한다. x++는 x의 이전 값을 수식에 사용한 후에 x의 값을 증가시키게 된다.
// x의 값이 10
y = ++x ; // 증가된 값이 y에 대입된다. y는 11이 된다.
y = x++ // x의 이전 값이 y에 대입되고 이후에 증가된다. y는 10
y = ( 1 + x++) + 10; // 괄호가 있어도 x값의 증가는 맨 나중에 실행된다.
거스름돈 계산하기
편의점에서 물건을 구입하고 만 원을 냈을 때, 거스름돈의 액수와 점원이 지급해야 할 거스름돈을 화폐와 동전수를 계산하는 프로그램을 작성해보자
1. 사용자로부터 물건값을 입력받는다.
2. 점원이 내줘야 할 오천원권 , 천원권 , 오백원짜리 동전, 백원짜리 동전 개수를 출력한다.
#include <stdio.h>
int main()
{
int price , change = 0 ;
int c5000 , c1000, c500 , c100 ;
int x = 0;
printf("물건값:");
scanf("%d", &price);
printf("사용자가 낸돈");
scanf("%d", &x);
change = x - price;
c5000 = change / 5000;
change = change % 5000;
c1000 = change / 1000;
change = change % 1000;
c500 = change / 500;
change = change % 500;
c100 = change / 100;
change = change % 100;
printf(" 5000 : %d\n", c5000);
printf(" 1000 : %d\n", c1000);
printf(" 500 : %d\n", c500);
printf(" 100 : %d\n", c100);
}
대입 연산자
대입 연산자는 변수에 수식의 값을 계산하여 저장하는 연산자이다.
등호의 왼쪽은 반드시 변수이어야하고 등호의 오른쪽은 어떠한 수식이라도 가능하다.
+=처럼 대입 연산자와 산술 연산자를 합쳐 놓은 연산자이다. x += y의 의미는 x = x + y와 같다.
복합 대입 연산자는 오른쪽에 있는 식을 먼저 계산하여 그 결과를 왼쪽에 있는 변수의 현재 값에 지정된 산술 연산을 한 후에 대입한다 .
x += 1; // x = x + 1
x *= y + 1; // x = x * (y +1)
x %= x + y; // x = x % (x + y)
오류 주의 :
x *= y + 1 에서 먼저 y + 1이 계산된다는 것을 유의하자 .
x += 1 을 x =+ 1 이라고 쓰면 완전히 다른 개념이 된다. x =+ 1 은 x = +1과 같은 의미로 해석된다. 즉 x에 1을 대입한다.
관계 연산자
관계 연산자는 두 개의 피연산자를 비교하는 데 사용된다.
관계 수식은 참이나 거짓이라는 값을 생성한다. C 에서 참과 거짓은 1과 0으로 표시되기 때문에 참(1) 거짓 (0) 정수 값을 생성한다 .
주의사항 !!!!
1.많이 저지르는 실수 중의 하나는 x==y 인데 x = y 사용하는 것이다 .
2. 2< x < 5
예를 들어 x 의 값이 8이라고 해도 위의 시근 참이 된다 .
(2< x) < 5 와 같이 계산되고 만약 x 가 8이라면 (2<8) < 5 같이 된다 . (2<8)은 참이므로 최종적으로 1<5로 되고 수식의 값은 참이 된다.
올바른 방법은 (2 < x) && < (x < 5) 이다. &&은 and를 의미한다.
3. 실수를 서로 비교하는 경우에도 예상치 못한 결과가 발생할 수 있다.
(1e32 + 0.01) > 1e32
이유는 double 형이라고 하더라도 유효숫자는 16자리다. 하지만 1e32 + 0.01과 같은 수를 맨 마지막 자리까지 다 가지고 있으려면 유효숫자가 30자리는 넘어야한다 .
(1e32 + 0.01) > 1e32는 같은 값으로 취급되어서 거짓이 된다.
올바른 방법은 (fabs(x-y) < 0.0001) 과 같이 비교를 해야한다. fabs()는 실수값이 절대값을 구하는 함수이다.
논리 연산자
여러 개의 조건을 조합하여 참인지 거짓인지를 따질 때 사용한다.
x && y AND연산 , x와 y가 모두 참이면 참 , 그렇지 않으면 거짓
x || y OR연산 , x나 y중에서 하나만 참이면 참 , 모두 거짓이면 거짓
!x NOT연산 , x가 참이면 거짓 , x가 거짓이면 참
AND 연산자인 &&은 두 개의 피연산자가 모두 참일 때만 연산 결과가 참이 된다 .
ex) (age <= 30) && (toeic >= 700)
위의 수식에서 age가 30이하이고 700이상인 경우에만 참이 된다.
(age <= 30) || (toeic >= 700)
OR 연산자인 ||은 하나의 피연산자만 참이면 연산 결과가 참이 된다,
나이가 30살 이하거나 토익 성적이 700점 이상이면 된다.
논리 연산자들은 여러 개가 동시에 사용될 수 있다.
x는 1,2,3중의 하나인가
ex) (x == 1) || (x == 2) || (x == 3)
NOT 연산자는 피연산자의 값이 참이면 연산의 결과값을 거짓으로 만들고 , 피연산자의 값이 거짓이면 연산의 결과값을 참으로 만든다.
ex)
!0 // 결과값은 1
!(x+y) // 수식 (x+y) 의 값이 0이면 1 , 1이면 0
NOT 연산자를 1의 값에 대해서만 0으로 만드는 것이 아니라 0이 아닌 값에 적용하면 0으로 만든다는 것에 유의해야 한다.
!100 // 100도 거짓으로 취급한다. 결과 0
!-3 // 음수도 거짓으로 취급한다. 결과 0
NOT 연산자는 논리적인 NOT과는 약간의 차이가 있다.
논리적인 NOT의 경우에는 NOT을 두 번 적용시키면 원래의 상태로 되지만 연산자 NOT은 두 번 적용시켜도 원래의 상태가 되지 않는 경우도 있다.
!!3 // 이 수식의 값은 1이 된다.
!!3 은 !(!3)으로 생각할수도 있고 !3은 앞에서 설명했듯이 0이다. 따라서 주어진 수식은 !0과 같고 결과적으로 1이 된다.
관계 수식이나 논리 수식이 거짓으로 계산되면 0을 생성하고 참으로 계산되면 1을 생성한다.
하지만 피연산자의 경우네는 0이면 거짓이고 0이 아닌값은 무조건 참으로 간주한다.
따라서 NOT 연산자의 경우와 같이 !100하면 100의 값을 참으로 간주하여 여기에 NOT을 적용하여 0값이 생성되는 것이다.
따라서 수식의 결과로는 항상 0 아니면 1만 생성되지만 피연산자로서 참과 거짓을 분류할 때는 0이면 거짓이고 나머지는 모두 참으로 간주한다.
논리 연산자를 포함한 수식을 작성할 떄 주의해야 할 점이 있다. &&연산자의 경우, 여러 개의 피연산자 중에서 처음 피연산자의 값이 거짓(0)이면 다른 피연산자들은 계산되지 않는다.
왜냐하면 첫 번째 피연산자의 값이 거짓(0)이면 나머지 피연산자들을 계산하지 않아도 전체 수식의 값은 거짓(0)이기 때문이다.
이것은 수식의 계산을 빼르게 하기 위하여 컴파일러에서 사용하는 기법이다.
이것은 || 연산자에서도 마찬가지이다. || 연산자의 경우는 첫 번째 피연산자의 값이 참(1)이면 나머지 피연산자들을 계산하지 않는다.
왜냐하면 전체의 수식은 이미 값이 참(1)이기 때문이다 .
이것을 단축 계산이라고 한다. 따라서 논리 연산에서 모든 피연산자가 계산되지 않을 수도 있다는 것을 명심하여야 한다.
윤년 판단 .
입력된 연도가 윤년인지 아닌지를 판단하는 조건을 만들어보자.
윤년의 조건
1 연도가 4로 나누어 떨어진다.
2 100으로 나누어 떨어지는 연도는 제외한다.
3 400으로 나누어 떨어지는 연도는 제외한다.
조건 분석)
연도가 4로 나누어지지만 100으로는 나누어 떨어지지 않는 연도
연도가 400으로 나누어 떨어지는 연도
#include <stdio.h>
int main()
{
int year = 0 , result = 0;
printf("연도를 입력하세요:");
scanf("%d", &year);
result = ((year % 4 == 0) && (year % 100) != 0)) || (year % 400 == 0);
printf ("result = %d", result);
return 0;
}