연산자

Updated:

연산자

저번 Chapter 2. 타입에서는 변수와 상수, 타입의 종류와 변환에 대해서 알아보았다. 이번에는 C 언어에서 사용되는 연산자에 대해서 정리하고자 한다.
이 글은 Chapter 3. 연산자을 정리한 내용이다.
참고한 사이트 : TCLSchool

산술 연산자

연산자(operator)란 프로그램의 산술식이나 연산식을 표현하고 처리하기 위한 기호를 의미한다.

  1. 산술 연산자(arithemetic operator)
    산술 연산자는 사칙연산을 다루는 가장 기본적인 연산자이다. 산술 연산자는 두 개의 피연산자를 가지는 이항 연산자이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽이다.

    산술 연산자 설명
    + 왼쪽의 피연산자에 오른쪽의 피연사자를 더함.
    - 왼쪽의 피연산자에서 오픈쪽의 피연사자를 뺌.
    * 왼쪽의 피연산자에 오른쪽의 피연산자를 곱함.
    / 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 몫을 반환함.
    % 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 그 나머지를 반환함.
    int num01 = 10;
    int num02 = 4;
       
    printf("+ 연산자에 의한 결과값은 %d입니다.\n", num01 + num02);
    printf("- 연산자에 의한 결과값은 %d입니다.\n", num01 - num02);
    printf("* 연산자에 의한 결과값은 %d입니다.\n", num01 * num02);
    printf("/ 연산자에 의한 결과값은 %d입니다.\n", num01 / num02);
    printf("% 연산자에 의한 결과값은 %d입니다.\n", num01 % num02);
       
    // 실행 결과
    + 연산자에 의한 결과값은 14입니다.
    - 연산자에 의한 결과값은 6입니다.
    * 연산자에 의한 결과값은 40입니다.
    / 연산자에 의한 결과값은 2입니다.
    % 연산자에 의한 결과값은 2입니다.
    
  2. 연산자의 우선순위(operator precedence)와 결합 방향(associativity)
    수식 내에 여러 연산자가 동시에 존재한다면, 정해진 우선순위와 결합 방향에 의해 처리된다. 괄호(()) 연산자를 사용하여 처리 순서를 수동으로 변경할 수도 있다.

    우선 순위 연산자 설명 결합방향
    1 ++ 후위 증가 연산자 왼쪽에서 오른쪽으로
      후위 감소 연산자 왼쪽에서 오른쪽으로
      () 함수 호출 왼쪽에서 오른쪽으로
      [] 첨자 연산자 왼쪽에서 오른쪽으로
      . 참조에 의한 선택 왼쪽에서 오른쪽으로
      -> 포인터를 통한 선택 왼쪽에서 오른쪽으로
    2 ! 논리 NOT 연산자 오른쪽에서 왼쪽으로
      ~ 비트 NOT 연산자 오른쪽에서 왼쪽으로
      + 양의 부호 (단항 연산자) 오른쪽에서 왼쪽으로
      - 음의 부호(단항 연산자) 오른쪽에서 왼쪽으로
      ++ 전위 증가 연산자 오른쪽에서 왼쪽으로
      전위 감소 연산자 오른쪽에서 왼쪽으로
      (타입) 타입 캐스트 연산자 오른쪽에서 왼쪽으로
      * 참조 연산자 (단항 연산자) 오른쪽에서 왼쪽으로
      & 주소 연산자 (단항 연산자) 오른쪽에서 왼쪽으로
      sizeof 크기 오른쪽에서 왼쪽으로
    3 * 곱셈 연산자 왼쪽에서 오른쪽으로
      / 나눗셈 연산자 왼쪽에서 오른쪽으로
      % 나머지 연산자 왼쪽에서 오른쪽으로
    4 + 덧셈 연산자 (이항 연산자) 왼쪽에서 오른쪽으로
      - 뺄셈 연산자 (이항 연산자) 왼쪽에서 오른쪽으로
    5 « 비트 왼쪽 시프트 연산자 왼쪽에서 오른쪽으로
      » 부호 비트를 확장 및 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
    6 < 관계 연산자(보다 작은) 왼쪽에서 오른쪽으로
      <= 관계 연산자(보다 작거나 같은) 왼쪽에서 오른쪽으로
      > 관계 연산자(보다 큰) 왼쪽에서 오른쪽으로
      >= 관계 연산자(보다 크거나 같은) 왼쪽에서 오른쪽으로
    7 == 관계 연산자(와 같은) 왼쪽에서 오른쪽으로
      != 관계 연산자(와 같지 않은) 왼쪽에서 오른쪽으로
    8 & 비트 AND 연산자 왼쪽에서 오른쪽으로
    9 ^ 비트 XOR 연산자 왼쪽에서 오른쪽으로
    10 | 비트 OR 연산자 왼쪽에서 오른쪽으로
    11 && 논리 AND 연산자 왼쪽에서 오른쪽으로
    12 || 논리 OR 연산자 왼쪽에서 오른쪽으로
    13 ? : 삼항 조건 연산자 오른쪽에서 왼쪽으로
    14 = 대입 연산자 및 복합 대입 연산자 오른쪽에서 왼쪽으로
    15 , 쉼표 연산자 왼쪽에서 오른쪽으로

    위의 표를 보면, 우선순위가 높은 연산자가 먼저 실행되고, 우선순위가 같다면 결합 순서에 따라 실행된다. 위의 표는 외우는 것이 아닌, 직접해보면서 필요할 때 참조해가며 활용하자.

대입 연산자

  1. 대입 연산자(assignment operator)
    대입 연산자는 변수에 값을 대입할 때 사용하는 이항 연산자이다. 피연산자들의 결합 방향은 오른쪽에서 왼쪽입니다. 산술 연산자와 결합한 다양한 복합 대입 연산자가 존재한다.

    대입 연산자 설명
    = 왼쪽의 피연산자에 오른쪽의 피연산자를 대입
    += 왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후, 왼쪽의 피연산자에 대입
    -= 왼쪽의 피연산자에서 오른쪽의 피연산자를 뺀 후, 왼쪽의 피연산자에 대입
    *= 왼쪽의 피연산자에 오른쪽의 피연산자를 곱한 후, 왼쪽의 피연산자에 대입
    /= 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 왼쪽의 피연산자에 대입
    %= 왼쪽의 피연산자를 오른쪽의 피연산자로 나눈 후, 왼쪽의 피연산자에 대입
    int num01 = 7;
    int num02 = 7;
    int num03 = 7;
       
    num01 = num01 - 5;
    num02 -= 5;
    num03 =- 5;
       
    printf("- 연산자에 의한 결과값은 %d입니다.\n", num01);
    printf("-= 연산자에 의한 결과값은 %d입니다.\n", num02);
    printf("=- 연산자에 의한 결과값은 %d입니다.\n", num03);
       
    // 실행 결과
    - 연산자에 의한 결과값은 2입니다. // num01 = 7 - 5
    -= 연산자에 의한 결과값은 2입니다. // num02 = 7 - 5 (num02 -= 5)
    =- 연산자에 의한 결과값은 -5입니다. // num03 = -5 
    

​ ‘-‘와 ‘=’의 위치를 주의하면서 코드를 작성하자.

증감 연산자

  1. 증감 연산자(increment and decrement operator)
    증감 연산자란 1씩 증가 혹은 1씩 감소시킬 때 사용하는 연산자로, 피연산자가 하나뿐인 단항 연산자이다. 증감 연산자에서 피연산자의 위치로 연산 순서, 결과가 달라지기에 주의해야 한다.

    증감 연산자 설명
    ++x 먼저 피연산자의 값을 1 증가시킨 후에 해당 연산을 진행함.
    x++ 먼저 해당 연산을 수행하고 나서, 피연산자의 값을 1 증가시킴.
    –x 먼저 피연산자의 값을 1 감소시킨 후에 해당 연산을 진행함.
    x– 먼저 해당 연산을 수행하고 나서, 피연산자의 값을 1 감소시킴.
    int num01 = 7;
    int num02 = 7;
    int result01, result02;
       
    result01 = (++num01) - 5;
    result02 = (num02++) - 5;
       
    printf("전위 증가 연산자에 의한 결과값은 %d이고, 변수의 값은 %d로 변했다.\n", result01, num01);
    printf("후위 증가 연산자에 의한 결과값은 %d이고, 변수의 값은 %d로 변했다.\n", result02, num02);
       
    // 실행 결과
    전위 증가 연산자에 의한 결과값은 3이고, 변수의 값은 8 변했다. // 7 + 1 - 5
    전위 증가 연산자에 의한 결과값은 2이고, 변수의 값은 8 변했다. // 7 - 5 + 1
    
  2. 증감 연산자의 연산 순서

    int x = 10;
    int y = x-- + 5 + --x;
       
    printf("변수 x의 값은 %d이고, 변수 y의 값은 %d입니다.\n", x, y);
       
    // 실행 결과
    변수 x 값은 8이고, 변수 y 값은 23입니다.
    

    위의 연산 순서를 보자면,

    ch3_operation_order
    연산 순서, TCL

    ① : 감소 연산자가 피연산자 뒤에 있기 때문에 x + 5이 먼저 수행.
    ② : 이후 감소 연산자. (x의 값 : 9)
    ③ : 두 번째 감소 연산자는 피연산자 앞에 있기 때문에 –x 먼저 수행. (x의 값: 8)
    ④ : 이후 덧셈 연산자.
    ⑤ : 이후 대입 (y의 값 : 23)
    (10 + 5)(①) +(④) 10 - 1(②) - 1(③) = 23(⑤)

비교 연산자

  1. 비교 연산자(comparison operator)
    비교 연산자는 피연산자들의 상대적인 크기를 판단하는 연산자로, 두 개의 피연산자를 가지는 이항 연산자이며, 결합 방향은 왼쪽에서 오른쪽이다.

    비교 연산자 설명
    == 왼쪽의 피연산자와 오른쪽의 피연산자가 같으면 1을 반환함.
    != 왼쪽의 피연산자와 오른쪽의 피연산자가 같지 않으면 1을 반환함.
    > 왼쪽의 피연산자가 오른쪽의 피연산자보다 크면 1을 반환함.
    >= 왼쪽의 피연산자가 오른쪽의 피연산자보다 크거나 같으면 1을 반환함.
    < 왼쪽의 피연산자가 오른쪽의 피연산자보다 작으면 1을 반환함.
    <= 왼쪽의 피연산자가 오른쪽의 피연산자보다 작거나 같으면 1을 반환함.

    C 언어에서 거짓(false)은 0이며, 0이 아닌 모든 것은 참(true)으로 인식한다. 즉, 1을 반환하는 것은 참을 반환하는 것이다.

논리 연산자

  1. 논리 연산자(logical operator)
    논리 연산자는 주어진 논리식을 판단하여 참, 거짓을 결정하는 연산자이다. AND, OR, NOT 연산자가 있다. AND, OR은 이항 연산자, 결합 방향은 왼쪽에서 오른쪽이다. NOT 연산자는 단항 연산자, 결합 방향은 오른쪽에서 왼쪽이다.

    논리 연산자 설명
    && 논리식이 모두 참이면 1을 반환함. (논리 AND 연산)
    || 논리식 중에서 하나라도 참이면 1을 반환함. (논리 OR 연산)
    ! 논리식의 결과가 참이면 0을, 거짓이면 1을 반환함. (논리 NOT 연산)

    A와 B 그리고 A와 B에 대한 논리 연산자에 대한 표는 다음과 같다.

    A B A && B A || B !A
    1 (true) 1 (true) 1 (true) 1 (true) 0 (false)
    1 (true) 0 (false) 0 (false) 1 (true) 0 (false)
    0 (false) 1 (true) 0 (false) 1 (true) 1 (true)
    0 (false) 0 (false) 0 (false) 0 (false) 1 (true)
    int num01 = 3;
    int num02 = -7;
    int result01, result02;
       
    result01 = (num01 > 0) && (num01 < 5);
    result02 = (num02 < 0) || (num02 > 10);
       
    printf("&& 연산자에 의한 결과값은 %d입니다.\n", result01);
    printf("|| 연산자에 의한 결과값은 %d입니다.\n", result02);
    printf("! 연산자에 의한 결과값은 %d입니다.\n", !result02);
       
    // 실행 결과
    && 연산자에 의한 결과값은 1입니다.
    || 연산자에 의한 결과값은 1입니다.
    ! 연산자에 의한 결과값은 0입니다.
    

비트 연산자

  1. 비트 연산자(bitwise operator)
    비트 연산자는 비트(bit) 단위의 논리 연산을 할 때 사용하는 연산자이다. 비트 단위로 비트를 이동시킬 때도 사용한다.

    비트 연산자 설명
    & 대응되는 비트가 모두 1이면 1을 반환함. (비트 AND 연산)
    | 대응되는 비트 중에서 하나라도 1이면 1을 반환함. (비트 OR 연산)
    ^ 대응되는 비트가 서로 다르면 1을 반환함. (비트 XOR 연산)
    ~ 비트를 1이면 0으로, 0이면 1로 반전시킴. (비트 NOT 연산)
    « 지정한 수만큼 비트들을 전부 왼쪽으로 이동시킴.
    » 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴.

    bitwise_and
    비트 AND 연산 과정, TCL

    비트 AND 연산은 두개의 비트가 필요한 이항 연산자이며, 두 비트 모두 1일 때만 1을 반환한다. 그림에서는 6번째, 8번째 비트만 1로 반환한다.

    bitwise_or
    비트 OR 연산 과정, TCL

    비트 OR 연산도 마찬가지로 이항 연산자이며, 두 비트 중 하나라도 1이면 1을 반환, 모두 0이라면 0을 반환한다.

    bitwise_xor
    비트 XOR 연산 과정, TCL

    비트 XOR 연산도 이항 연산자이며, 두 비트가 서로 다르면 1을 반환, 같으면 0을 반환한다. 그림에서는 비트의 값이 다른 4번째, 5번째, 7번째 비트만 1로 반환한다.

    bitwise_not
    비트 NOT 연산 과정, TCL

    비트 NOT 연산자는 한개의 비트가 필요한 단항 연산자이며, 해당 비트가 1이면 0, 0이면 1을 반환한다.즉, 반전시켜주는 연산자이다.

    int num01 = 15;
    int num02 = 8;
       
    printf("~ 연산자에 의한 결과값은 %d입니다.\n", ~num01); // 1의 보수
    printf("<< 연산자에 의한 결과값은 %d입니다.\n", num02 << 1); // 곱하기 2
    printf(">> 연산자에 의한 결과값은 %d입니다.\n", num02 >> 1); // 나누기 2
       
    // 실행 결과
    ~ 연산자에 의한 결괏값은 -16입니다.
    << 연산자에 의한 결괏값은 16입니다.
    >> 연산자에 의한 결괏값은 4입니다.
    

    비트 연산자에 대한 더 자세한 내용은 비트 단위 연산에서 다룬다.

기타 연산자

  1. 삼항 연산자(ternary operator)
    삼항 연산자는 C 언어만의 독특한 연산자이며, 피연산자를 세 개 가지는 조건 연산자이다. 삼항 연산자의 문법은 다음과 같다.

    조건식 ? 반환값1 : 반환값2;
    

    물음표(?) 앞의 조건식이 true이면 반환값1을 반환, false이면 반환값2를 반환한다. 반환값에는 값뿐만 아니라 수식, 함수 호출 등 명령문이 올 수도 있다.

    int num01 = 15;
    int num02 = 8;
    int result;
       
    result = (num01 > num02) ? num01 : num02; // 15 > 8 : true -> 15 반환
    printf("둘 중에 더 큰수는 %d입니다.\n", result);
       
    // 실행 결과
     중에  큰수는 15입니다.
    

    삼항 연산자는 if / else 문 대신에 사용할 수 있다. if / else 문에 대한 자세한 내용은 조건문에서 다룬다.

  2. 쉼표 연산자
    연산을 수행하는 것이 아니라 다음과 같은 상황에서 사용되는 연산자이다.

    • 두 연산식을 하나의 연산식으로 나타내고자 할 때
    • 둘 이상의 인수를 함수로 전달하고자 할 때
    int num01 = 15, num02 = 8; // 하나의 연산식으로 연결
    printf("첫 번째 수는 %d이고, 두 번째 수는 %d입니다.\n", num01, num02); // 두 개의 인수를 함수로 전달
       
    // 실행 결과
     번째 수는 15이고,  번째 수는 8입니다.
    
  3. sizeof 연산자
    sizeof 연산자는 단항 연산자로 피연산자의 크기를 바이트 단위로 반환하는 연산자이다. 피연산자로 타입뿐만 아니라 변수, 상수를 받을 수도 있다.

    int num01 = 0;
    int size;
       
    size = sizeof num01;
       
    printf("num01의 크기: %d\n", size);
       
    // 실행 결과
    num01 크기: 4 // 0이 int형이기 때문에
    

    sizeof에 대한 자세한 내용은 자료형 크기 구하기에서 다룬다. 참고하자.

  4. 포인터 연산자
    포인터 연산자는 메모리에 할당된 주소와 관련된 연산자로 주소 연산자(&)와 참조 연산자(*)가 있다.
    주소 연산자(&)는 변수의 이름 앞에 사용하며, 해당 변수의 주소값을 반환한다. 번지 연산자라고도 불린다.
    참조 연산자(*)는 포인터의 이름이나 주소 앞에 사용하여, 포인터에 가리키는 주소에 저장된 값을 반환한다. 위치에 따라 다양한 용도로 사용되기 때문에 주의하여 사용해야 한다.
    포인터 연산자에 대한 자세한 내용은 포인터에서 다룬다.

추가 및 수정

  • 정리할 주제
    • 증감 연산자에 대한 다양한 예제
    • 변수의 값을 서로 교체하는 방식 (대입 연산자와 관련하여)
  • 관련 문제 및 오류

Tags:

Categories:

Updated:

Leave a comment