C & C++/디딤돌 C언어

Part 9. 산술, 논리, 비교 연산자

언휴 2024. 1. 9. 08:54

 

[C언어] 산술, 논리, 비교 연산자
00:19 산술 연산
00:35 [실습] 부호 연산
01:35 [실습] 사칙 연산
04:05 [실습] 나머지 연산
05:32 논리 연산자
05:46 [실습] 논리 연산
07:18 [실습] 논리 연산에서 주의할 점
09:03 비교연산자
09:18 [실습] 비교 연산자
10:01 비교 연신에서 주의할 점

29. 산술 연산자

프로그래밍 언어는 관리해야 할 데이터를 위한 문법도 제공하지만 수행해야  할 코드를 작성하는 문법도 제공하죠.
이번에는 C언어에서 수행할 코드를 작성하는 가장 기본적인 문법인 연산자를 다룰게요.

C언어에서는 사칙 연산이나 논리 연산, 비트 연산을 비롯하여 30여 가지의 연산자를 제공하고 있어요.
여러분은 책에 나온 예제 코드를 직접 작성하여 하나 하나 확인하세요.
프로그래밍은 머리로 이해하는 것으로 그치면 실력이 늘지 않아요.
이해한 것을 직접 프로그램으로 작성하면서 몸으로 숙련시키세요.

가장 먼저 산술 연산자를 살펴봅시다.

C언어의 산술 연산자는 부호 연산자와 사칙 연산자, 나머지 연산자를 제공하고 있어요.

29.1 부호 연산자

+
-

부호 연산자는 피 연산자가 하나인 단항 연산자예요.
+ 부호 연산의 연산 결과는 피 연산자 값이어서 표시하지 않은 것과 결과가 같아서 거의 사용하지 않아요.
그리고 – 부호 연산자는 피 연산자의 값에 -1을 곱한 값이 연산 결과예요.

◈ 부호 연산자

#include <stdio.h>
int main()
{
    printf("%d %d \n", +5, -5);
    return 0;
}

◈ 실행 결과

5 -5

29.2 사칙 연산자

+
-
*
/

사칙 연산은 두 개의 피 연산자가 오는 이항 연산자죠.
만약 두 개의 피 연산자가 모두 정수형이면 연산 결과는 정수예요.

하지만 피 연산자 중에 하나라도 실수형이 오면 연산 결과는 실수라는 것을 기억하세요.

특히 C언어에서 나누기 연산은 나머지 값을 버리는 내림 법칙을 사용해요.
그리고 나머지 연산의 우항이 0이면 나누기 연산을 할 수 없어 예외가 발생하죠.
이러한 예외를 흔히 divide zero라고 불러요.

◈ 사칙 연산

#include <stdio.h>
int main()
{
    int a = 8;
    int b = 3;
    printf("%d \n", a+b);
    printf("%d \n", a-b);
    printf("%d \n", a*b);
    printf("%d \n", a/b);
    printf("%f \n", a/b);
    printf("\n");
    
    printf("%d \n", 2+3);
    printf("%f \n", 2+3.0f);
    printf("%f \n", 2.0+3.0);
    printf("%f \n", 8/3.);
    return 0;
}

◈ 실행 결과

11
5
24
2
0.000000

5
5.000000
5.000000
2.666667

29.3 나머지 연산자

%

나머지 연산은 피연산자로 정수가 와야 하며 연산 결과는 나눈 나머지예요.
좌항의 값이 양수일 때는 언제나 연산 결과는 0 이상이고 음수일 때는 0 이하예요.

◈ 나머지 연산

#include <stdio.h>
int main()
{
    printf("7을 3으로 나눈 나머지: %d \n",7%3);
    printf("7을 -3으로 나눈 나머지 %d \n",7%-3);
    printf("-7을 3으로 나눈 나머지 %d \n",-7%3);
    printf("-7을 -3으로 나눈 나머지 %d \n",-7%-3);
    return 0;
}

◈ 실행 결과

7을 3으로 나눈 나머지: 1
7을 -3으로 나눈 나머지: 1
-7을 3으로 나눈 나머지: -1
-7을 3으로 나눈 나머지: -1

◈ 기본 연습
1. 두 개의 정수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램을 작성하세요.

더보기

답:

//두 개의 정수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램
#include <stdio.h>
int main(void)
{
    int a,b;
    printf("두 개의 정수 입력:");
    scanf_s("%d%d",&a,&b);
    printf("합:%d 차:%d 곱:%d 몫:%d\n",a+b,a-b,a*b,a/b);
    return 0;
}

2. 두 개의 실수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램을 작성하세요.

더보기

답:

//두 개의 실수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램
#include <stdio.h>
int main(void)
{
    double a,b;
    printf("두 개의 실수 입력:");
    scanf_s("%lf%lf",&a,&b);
    printf("합:%f 차:%f 곱:%f 몫:%f\n",a+b,a-b,a*b,a/b);
    return 0;
}

3. 한 개의 정수와 한 개의 실수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램을 작성하세요.

더보기

답:

//한 개의 정수와 한 개의 실수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램
//한 개의 정수와 한 개의 실수를 입력받아 합, 차, 곱, 몫을 출력하는 프로그램
#include <stdio.h>
int main(void)
{
    int a ;
    double b;
    printf("정수: ");
    scanf_s("%d",&a);
    printf("실수: ");
    scanf_s("%lf",&b);
    printf("합:%f 차:%f 곱:%f 몫:%f\n",a+b,a-b,a*b,a/b);
    return 0;
}

4. 다음 프로그램의 출력 결과를 예측하고 출력 결과를 확인하시오. 그리고 출력 결과가 서로 다른 이유를 설명하시오.

#include <stdio.h>
int main()
{
    printf("%d \n", 3*2/3);
    printf("%d \n", 2/3*3);
    return 0;
}
더보기

답:
2
0
3*2/3 은 3*2를 먼저 수행한 후에 6/3 을 수행하여 결과가 2
2/3*3 은 2/3을 먼저 수행한 후에 0*3 을 수행하여 결과가 0

4. 두 개의 정수를 입력받아 나머지를 출력하는 프로그램을 작성하세요.

더보기

답:

//두 개의 정수를 입력받아 나머지 출력
#include <stdio.h>
int main(void)
{
    int a,b;
    printf("두 개의 정수 입력:");
    scanf_s("%d%d",&a,&b);
    printf("나머지:%d\n",a%b);
    return 0;
}

30. 논리 연산자

&&
||
!

C언어에서는 논리 연산자로 논리곱(&&) 연산자와 논리합(||) 연산자, 논리 부정(!) 연산자를 제공해요.

C언어에서 피 연산자의 값이 0이면 거짓이며 그 외의 값은 참이예요.
그리고 연산식이 참일 때 연산 결과는 1이고 거짓일 때 연산 결과는 0이랍니다.

논리곱 연산은 피 연산자가 모두 참일 때만 연산 결과가 참이고 그 외에는 모두 거짓이예요.
논리합 연산은 피 연산자 중에 하나라도 참이면 연산 결과는 참이고 둘 다 거짓일 때만 거짓이죠.
논리 부정은 단항 연산자로 피 연산자가 참이면 연산 결과는 거짓이고 피 연산자가 거짓이면 연산 결과는 참이예요.

◈ 논리 연산

#include <stdio.h>
int main()
{
    printf("%d %d %d \n", 3&&2, 0&&2, 0&&0);
    printf("%d %d %d \n", 3||2, 0||2, 0||0);
    printf("%d %d \n", !3, !0);
    return 0;
}

◈ 실행 결과


1 0 0
1 1 0
1 0

그리고 C언어에서 논리곱 연산에서는 하나의 항만 거짓이어도 연산 결과는 거짓이죠.
따라서 좌항이 거짓일 때는 우항을 확인하지 않아요.
또한 논리합 연산에서는 좌항이 참이면 우항을 확인하지 않아도 참이므로 우항을 확인하지 않아요.

◈ 논리 연산에서 주의할 점

#include <stdio.h>
int main()
{
    int a = 0, b = 0, re = 0;
    re = (a=3)||(b=b+3);
    printf("a:%d b:%d re:%d\n",a,b,re);
 
    re = (a=0)&&(b=4);
    printf("a:%d b:%d re:%d\n",a,b,re);
    return 0;
}

◈ 실행 결과

a:3 b:0 re:1
a:0 b:0 re:0

위 예를 보면 (a=3)||(b=b+3)의 연산 결과는 참이예요.
좌항인 (a=3)은 a 변수에 3을 대입하는 것이며 연산 결과는 대입 연산 이후의 a 값인 3이예요.
논리합 연산에서 좌항이 참이면 우항을 수행하지 않죠.
따라서 (b=b+3) 부분은 수행하지 않아요.
결과적으로 출력 내용을 보면 a는 3으로 변한 것을 알 수 있지만 b는 변하지 않았죠.

그리고 (a=0)&&(b=4)의 연산 결과를 보면 거짓이예요.
좌항인 (a=0) 부분은 0인 값을 a 변수에 대입하고 연산 결과는 대입 연산 이후의 a 값인 0이예요.
논리곱 연산에서는 좌항이 거짓이면 우항을 수행하지 않죠.
따라서 (b=4)를 수행하지 않아요.
결과적으로 출력 내용을 보면 a는 0으로 변하였지만 b는 변하지 않았어요.

31. 비교 연산자

<
< =
>
>=
==
!=

C언어에서 비교 연산은 이항 연산자로 피연산자의 값의 크기를 비교하며 연산 결과는 참일 때 1, 거짓일 때 0이예요.

연산자를 보면 쉽게 알 수 있듯이 < 는 우항이 작은지 비교, <= 우항이 작거나 같은지 비교, > 우항이 큰지 비교, >= 우항이 크거나 같은지 비교, == 서로 같은지 비교, != 다른지 비교하는 연산자예요.
그리고 <=, >=, ==, != 연산자를 사용할 때 중간에 공백은 올 수 없어요.

◈ 비교 연산

#include <stdio.h>
int main()
{
    printf("1<2  연산 결과:%d \n", 1<2);
    printf("1<=2 연산 결과:%d \n", 1<=2);
    printf("1>2  연산 결과:%d \n", 1>2);
    printf("1>=2 연산 결과:%d \n", 1>=2);
    printf("1==2 연산 결과:%d \n", 1==2);
    printf("1!=2 연산 결과:%d \n", 1!=2);
    return 0;
}

1<2 연산 결과:1
1<=2 연산 결과:1
1>2 연산 결과:0
1>=2 연산 결과:0
1==2 연산 결과:0
1!=2 연산 결과:1

비교 연산에서 주의할 점은 2<1<3 처럼 비교 연산하면 결과는 수학과 다를 수 있어요.
C언어에서 2<1<3을 계산할 때는 2<1을 먼저 계산한 후에 1과 비교 연산을 수행해요.
2<1의 연산 결과는 거짓이므로 0 이고, 0(2<1의 연산 결과)<3은 참이므로 연산 결과는 1이예요.

따라서 수학에서 2<1<3 계산을 C언어로 작성할 때는 (2<1)&&(1<3)처럼 논리곱 연산을 사용하세요.

◈ 비교 연산을 사용할 때 주의할 점

#include <stdio.h>
int main()
{
    printf("2<1<3 연산 결과: %d \n", 2<1<3);
    printf("(2<1) && (1<3) 연산 결과: %d \n", (2<1) && (1<3) );
    return 0;
}

◈ 실행 결과

2<1<3 연산 결과: 1
(2<1) && (1<3) 연산 결과: 0

◈ 기본 연습
다음 프로그램의 출력 결과를 예측하고 이유를 설명하시오.

#include <stdio.h>
int main()
{
    printf("%d \n", 5<2<4);
    printf("%d \n", (5<2)&&(2<4));
    return 0;
}
더보기

답:
1
0
▷ 이유
5<2<4는 5<2를 먼저 수행하고 수행 결과인 0과 4를 비교, 0<4를 수행하므로 결과는 참인 1
(5<2)&&(2<4)는 5<2를 먼저 수행하고 수행 결과가 0입니다.
&&은 앞이 0이면 뒤는 수행하지 않으므로 결과는 거짓인 0