[C] TIL 6. 연산자(operator) - 기본


  1. 형 승격의 규칙을 나열하시오.
  2. 성성정수형과 부동소수점형을 혼합해서 나누기를 하면 어떻게 되는지를 설명하시오.


inflearn독하게 시작하는 C프로그래밍강의와 C기초 플러스 6판을 기초로하여 정리한 필기입니다. 😀


C언어는 코드 덩어리를 블록스코프(scpe, {...})를 이용해서 표현하며, 이 블록스코프는 1개 이상의 구문(statement)으로 이루어져 있다. 구문의 형태는 항(item)들의 연속이고, 이 항들은 세미콜론(;)으로 끝이 난다. 이런 구조로 되어있는 코드 덩어리가 1개 이상이 모여서 함수가 되는 것이고, 이러한 함수들을 연결(Bind)해서 프로그램을 이룬다.

3+4;

이런 구조들 중에서 주의 깊게 봐야하는 것은 항이다. 위와 같은 식을 C언어로 된 프로그램에 입력한다고 치면 3, +, 4 모두 항에 해당한다. 3과 4는 피연사라고 하고, +는 2항 연산자라고 한다. 로고, 위 식은 피연산자(operand) 2개와 2항연산자 1개로 구성되었으며, 항은 총 3개이다. 그리고 마지막에 세미콜론(;)이 찍혀 있기 때문에 위 식은 구문이라 할 수 있다.

3+4;
5+6;
7+8;

위처럼 다수의 구문이 있을 때는 위에서부터 아래로 연산이 이루어진다. 이것을 절차적인 흐름(context, 문맥)이라고 한다.

1. 연산자 이론

1.1 연산자 우선순위

우리가 학교에서 산수를 배울 때, 덧셈과 뺄셈보다 나눗셈과 곱셈을 먼저 계산해야 하며 괄호가 있는 경우에는 괄호를 가장 먼저 계산해야 한다는 이론을 공부한 적이 있을 것이다. 이것을 연산자 우선순위라고 한다. C언어에도 연산이 중첩되었을 때 어떤 연산을 먼저 처리해야 하는지에 대한 순서가 있다.

title

표에서 보이는 경합성이란, 연산자 우선순위기 같을 때 어느 쪽을 먼저 연산할 것인지에 대한 것이다. 대부분은 결합성은 왼쪽에서 오른쪽방향 움직인다. 3 *4/ 5 + 6을 계산할 때 왼쪽에서부터 계산해 나가는 것과 같은 맥락이다. 그러나 C언어에는 오른쪽에서 왼쪽으로 계산하는 엿 난자도 있다. 따라서 우선순위와 계산 순위를 잘 알아야 의도하지 않은 연산을 피할 수 있다.

1.2 연산의 임시 결과

연산의 임시 결과는 산술 연산이 중첩될 경우에 나타나는 것이다. 우선순위가 낮은 순위일 경우 연산의 피연산자는 코드에 기술한 피연산자가 아니라 임신 결과가 된다.

title

3과 4를 더한 값인 7이 연산의 임시 결과이다. 이 7이란 값은 5과 더해진 후에 삭제될 것이다. 이것은 말 그대로 임시 결과이기 때문에 이 값을 따로 쓰고 싶다면 3과 4를 더한 값이 담긴 변수를 만들어야 한다.

1.3 형 변환

문장과 수식은 일반적으로 한가지의 자료형으로 사용해야하지만, 데이터를 혼합해서 사용하더라도 프로그램이 멈추는 일은 발생하지 않는다. 매우 편리한 일이라고 생각할 수 있지만, 자료형을 혼합해서 사용했을 때 위험해 질 수 있다. 때문에 그 변환 규칙을 몇가지 알아두는 편이 좋다.

1.3.1 규칙 4가지

  • char형과 short 형이 하나의 표현식에 사용될 경우 자동으로 int형이 된다. 필요에 따라 unsigned int형이 되기도 하는데, 이 경우는 unsigned short형가 char형과 함께 하나의 표현식에 사용되었을 때다. unsigned short형는 int형보다 크다. 때문에 unsigned short형 보다 크고, int보다 큰, unsigned int로 형 변환이 이루어진다.
  • 두 가지 데이터형이 사용되면 보통 현 변환은 등급이 더 높은 쪽으로 되기 마련이다. 이것을 형 올림 변환(Type Promotion)이라고 부른다.
  • 데이터형의 등급을 높은 순부터 낮은 순으로 나타내면 아래 표와 같다. char형과 short형은 이미 int 형이나, unsigned int형으로 변환되었을 게 분명하기 때문에 나타내지 않았다. 여기서 예외가 하나 있는데, long형과 int형의 크기가 같을 때 unsigned int형이 long형보다 등급이 높다.

title

  • 대입문에서, 최종 계산 결과는 그 값이 대입될 변수의 데이터형으로 변환된다. 이때는 형 올림 변환과 형 내림 변환(Type Demotion) 둘 다, 일어날 수 있다.

  • 함수 전달 인자로 전달될 때는, char형과 short형은 int형으로, float형은 double형으로 변환된다. 이러한 자동 올림 변화는 함수 프로포타입에 의해서 무시(Type Overried)될 수 있다.

1.3.2 코드로 알아보기

#include <stdio.h>

int main (void) {
    char ch = 'C';
    int i = 'C';
    double fl = 'C';
    
    printf("ch는 %c이다.\n", ch);    //=> 'C'
    printf("i는 %d이다.\n", i);      //=> 67
    printf("fl는 %.2f이다.\n", fl);  //=> 67.00
    
    printf("%f\n", fl - 3);         //=> '64.000000'
    printf("%d\n", fl + 3);         //=> '0'
    
    printf("%c\n", ch + 2);         //=> 'D'
    printf("%c\n", 'C' - 2);        //=> 'A'
}

이것을 하나하나 살펴보자.

printf("ch는 %c이다.\n", ch);    //=> 'C'
printf("i는 %d이다.\n", i);      //=> 67
printf("fl는 %.2f이다.\n", fl);  //=> 67.00

각 변수에는 char형인 ‘C’ 가 선언되었지만, 출력값을 보면 char형이 아니다. char형보다 int형과 double형의 등급이 더 높기 때문에, 문자인 ‘C’가 아니라 ‘C’에 해당하는 ASCII 코드 값이 각각 정수형과 부동소수점형으로 저장된 것이다.

printf("%f\n", fl - 3);         //=> '64.000000'
printf("%d\n", fl + 3);         //=> '0'

double형이 int형보다 등급이 더 높기 때문에 결괏값의 자료형은 double형이다. 때문에 정상적으로 출력된 첫째 줄과는 달리 %d형식을 사용한 두 번째 줄은 출력 결과가 0이 되는 것이다. (정상적인 출력이 일어나지 않는다.)

printf("%c\n", ch + 2);         //=> 'D'
printf("%c\n", 'C' - 2);        //=> 'A'

분명 char형보다 int형이 큰데도 불구하고 %c 형식으로 출력해보면 문자가 출력된다. 이것은 화면에서는 char 형처럼 보이더라도 int형에 해당한다. (Type Promotion)



2. 산술연산자

title

2.1 덧셈 연산자 : +

덧셈연사자(addition operator)은 자신의 좌우 양편에 있는 두 값을 더한다.

#include <stdio.h>

int main (void) {
    printf("%d", 4 + 20); // => 24
    
    int income;
    int salary = 3000;
    int bribes = 4000;
    
    income = salary + bribes;
    
    printf("%d", income);  // => 7000
    
    return 0;
}

printf("%d", 4 + 20);처럼 상수를 더해도 되지만, income = salary + bribes;처럼 변수 안에 저장된 상수들을 더하는 것도 가능하다.

2.2 뺄셈 연산자 : -

뺄셈 연사자(subtraction operator)은 - 기호 앞에 있는 수에서 뒤에 있는 수를 빼는 것이다. 자신의 좌우 양편에 있는 두 값을 더한다.

#include <stdio.h>

int main (void) {    
    int result;
    int price = 3000;
    int discount = 400;
    
    result = price + discount;
    
    printf("%d", result);  // => 2600
    
    return 0;
}

2.3 부호 연산자 : -+

마이너스 부호(minus sign)는 어떤 값의 부호를 나타내거나, 부호와 값 자체를 변경하데 이용할 수 있다.

#include <stdio.h>

int main (void) {
    int smoking = -12;
    int noSmoking = -smoking;
        
    printf("%d", noSmoking);  // => 12
    
    return 0;
}

플러스 부호(plus sign)는 C99 표준에 추가된 것이다. 이것은 마이너스 연산자와는 달리는 어떤 값의 부호와 값을 변경하지 않는다.

이항 : 35 - 12            // 두 개의 피연산자
단항 : -16                // 하나의 피연산자
단항과 이항 : -(12 - 20)   // 여는 괄호 앞에 붙어있는 -는 단항 연산자이며, 괄호 안에 있는 -는 이항 연산자이다.

부호 연산자와 모양이 같은 + 연산자와 - 연산자는 이항연산자(binary operator 또는 dyadic operator)이라고 하며, 마이너스 부호는 하나의 피연산자만을 요구하기 때문에 단항 연산자(unary operator)라고 부른다.

2.4 곱셈 연산자 : *

곱셈(multiplication)은 *(애스터리스크, asterisk)부호를 사용하며, 앞 뒤에 있는 수를 곱한다.

#include <stdio.h>

int main (void) {
    int salePrice;
    int price = 3000;
    int number = 10;
    
    salePrice = price * number
        
    printf("%d 가격의 티셔츠를 %d개 구매하면, 가격은 %d입니다.", price, number, salePrice);
    
    return 0;
}

2.5 나눗셈 연산자와 나머지 연산자

2.5.1 나눗셈 연산자: /

/ 기호를 이용항 왼쪽에 있는 값이 오른쪽에 있는 값에의해서 나누어진다.

#include <stdio.h>

int main (void) {
    printf("***정수형(int) 나눗셈***\n");
    printf("1. 8/4 = %d\n", 8/4);                //=> 2
    printf("2. 5/4 = %d\n", 5/4);                //=> 1
    printf("3. 7/4 = %d\n\n", 7/4);              //=> 1
    
    printf("***부동소수점(double) 나눗셈***\n");
    printf("1. 12.0/4.0 = %1.1f\n", 12.0/4.0);   //=> 3.0
    printf("2. 7./4. = %1.2f\n\n", 7.0/4.0);     //=> 1.75
    
    printf("***혼합형 나눗셈***\n");
    printf("1. 12.0/4 = %1.1f\n", 12.0/4.0);     //=> 3.0
    printf("2. 7/4. = %1.2f\n", 7.0/4.0);        //=> 1.75
    
    return 0;
}

위 코드의 결괏값을 보면 이상한 부분이 눈에 보일 것이다. 나눗셈은 기본적으로 정수형과 부동소수점에 대해 동작하는 게 다르다. 정수형의 나눗셈의 값은 정수형이 되고, 부동소수점 나눗셈 값은 부동소수점이 된다.

printf("***정수형 나눗셈***\n");
printf("1. 8/4 = %d\n", 8/4);              //=> 2
printf("2. 5/4 = %d\n", 5/4);              //=> 1
printf("3. 7/4 = %d\n\n", 7/4);            //=> 1

정수는 그 역할과 정의 때문에 소수부를 가질 수 없다. 그렇기 때문에 8/4처럼 똑 떨어지는 식이 아니면 버림(truncation)을 한다.

printf("***혼합형 나눗셈***\n");
printf("1. 12.0/4 = %1.1f\n", 12.0/4.0);   //=> 3.0
printf("2. 7/4. = %1.2f\n", 7.0/4.0);      //=> 1.75

혼합경같은 경우, 딱 떨어지든 아니든 모두 부동소수점으로 값이 도출된다. intdouble로 나누던, 그 반대던 출력 값의 자료형은 모두 double이다. 이것에 이론은 1.3 형 승격(Type Promotion)에서 언급된다.

2.5.2 나머지 연산자 : %

나머지 연산자(modulus operator)는 이름 그대로 몫은 버리고 나머지(remainder)를 구하는 연산자이다. 이 나머지 연산자는 정수 계산에 사용된다. 즉, 8%4을 하면 0이라는 값이 출력되지만, 8.%48.0%4.0처럼 피연산자 중 하나가 부동소수점일 경우 프로그램이 동작하지 않는다.

#include <stdio.h>

int main (void) {
    printf("1. 8/4의 나머지는 %d이다.\n", 8%4);              //=> 0
    printf("2. 5/4의 나머지는 %d이다.\n", 5%4);              //=> 1
    printf("3. 7/4의 나머지는 %d이다.\n\n", 7%4);            //=> 3
    
    return 0;
}

2.5.3 나누기의 원리(컴퓨터는 어떻게 나눌까?)

컴퓨터는 어떠한 수든 0으로 나눌 수 없다. 그 이유를 알기 위해서는 컴퓨터가 나누기하는 방법을 알아야 한다. title

위 그림처럼 나눠야 할 값이 나눌 값보다 작아질 때까지 빼서 나온 값을 나머지, 그리고 뺀 횟수를 더해 몫을 구한다. 때문에 0으로 나누게 될 경우 무한루프가 된다. CPU가 연산하면 전기를 사용하고, 전기를 사용하면 발열이 일어난다. 이것은 저항을 높이게 되는데, 이때부터 저항이 높아지기 때문에 발열이 되고, 발열되기 때문에 저항이 높아지는 루프에 빠지게 된다. 두 동작이 전자적인 속도로 반복되다 보면 스피커에서 ‘딱’ 소리가 나면서 프로그램이 강제 종료된다. 이것을 Divide by Zero Exception이 발생했다고 한다.

2.6 괄호 연산자 : ()

학교에서 산수를 공부했을 때처럼 괄호는 우선순위를 임의로 변경하고자 할 때 사용한다. 괄호 연산자를 사용하면 연산 순위를 가장 높게 할 수 있다.



3. 단순 대입 연산자 : =

title

대부분의 프로그래밍 언어에서 =는 같다를 의미하지 않는다. 대입(복사)한다는 의미이며, 그 의미답게 copy & overwrite 역할을 한다. 변수는 메모리에 이름을 붙이는 것이고, 대입은 그 메모리에 값을 저장하는 것이라는 걸 기억하자. 나중에 배우겠지만 어떤 기억장소(메모리)를 가리키기 위해 포인터(pointer)라는 것을 사용할 수 있다. (변수명을 선언하는 것은 객체를 확인하기 위한 방법 중 하나이다. 그리고 이런 식으로 데이터 객체를 만드는 것이 포인터 연산의 지정이라고 한다.(포인터는 뒤에서 배운다.))

int main (void) {
    int num;
    num = 1;      /* 라인 3 */
    num = 2;      /* 라인 4 */
}

대입 연산자(assignment operator)는 위와 같은 형태로 쓰이는데, 라인 3과 라인 4 모두 대입문이라고 한다. 라인 3을 보면 num이라는 좌변값 (lvalue)에 1이라는 우변값(rvalue)를 저장한다. 라인 4를 보면 num이라는 변수에 이미 데이터가 있을 텐데도 불구하고 다시 대입을 해줬다. 이렇듯, 메모리에 이미 저장된 값이 있다면 기존 값 위에 덮어쓰게 된다.

3.1 용어1 : 데이터 객체

title

데이터 객체(data object)란, 값을 저장하는 데 사용할 수 있는 데이터 영역을 지칭하는 용어이다. C 표준은 이 개념을 위해 객체(object)라는 용어만 사용한다. 대입문이란 메모리 위치에 값을 저장하는 것이 목적이다.

3.2 용어2 : 좌변값(lvalue)와 우변값(rvalue)

title

좌변값(lvalue)은 특정 데이터 객체를 구별하는 이름이나 표현 식을 지칭할 때 사용되는 용어고, 우변값(rvalue)은 변경할 수 있는 좌변값(lvalue)에 대입할 수 있는 수량(quantity)을 지칭할 때 사용된다.

객체는 실제 데이터 저장 공간을 참조하지만 좌변값(lvalue)은 그 저장공간을 위치하는 데 사용되는 레이블(label)이다. 때문에 lvalue의 l은 location과 left라는 두 개의 뜻이 있다. 반면 우변값(rvalue)의 r은 right라는 뜻 밖에 없다. 우변값에는 상수, 변수 또는 함수 호출 같은 값을 양보하는 어떤 다른 표현 식이 올 수 있다.

#include <stdio.h>

int main (void) {
    int a, b;
    b = 1;      /* 라인 3 */
    a = b;      /* 라인 4 */
    
    printf("A : %d\n", a);   // => 1
    printf("B : %d\n", b);   // => 1
    
    b = 2;
    
    printf("A : %d\n", a);   // => 1
    printf("B : %d\n", b);   // => 2
    
    return 0;
}

대입 연산자 =의 역할은 copy & overwite라고 한다. 기본적으로 이 연산은 왼쪽 피연산자의 정보에 오른쪽에 있는 정보를 덮어씌운다. 그리고 기존 정보는 유실된다. 라인 4는 변수 b의 값을 변수 a복사하여 저장시켰다. 즉, b의 값이 변해도 a의 값은 변하지 않는다는 것이다.



4. 비트 연산자

title

C에서 제공하는 비트 연산자는 위와 같다. 위와 같다. 4번째 줄에 있는 ~A를 제외하고는 모든 2항 연산자에 해당한다. 비트 연산자라 함은 메모리에 담긴 2진수를 해석한 정보가 아니라, 메모리에 담긴 2진수 자체를 비트 단위로 계산하는 연산자이다. 시스템 자체나 네트워크와 관련된 개발을 할 때 비트 단위 정보를 다뤄야 하는 일이 발생한다.

4.1 AND, OR, XOR, NOT

#include <stdio.h>

int main(void)
{
    printf("AND : %x\n", 0x41 & 0x33);    // => AND : 1
    printf("OR : %x\n", 0x41 | 0x33);     // => OR : 73
    printf("XOR : %x\n", 0x41 ^ 0x33);    // => XOR : 72
    printf("NOT : %x\n", ~ 0x33);         // => NOT : ffffffcc

    return 0;
}

title

AND연산은 비교하는 두 값이 모두 참(1)이여야 결과가 1이 된다. 때문에 0x41과 0x33을 and 연산 하게 되면 0x01이 된다.

title

OR 연산은 AND와 반대로 한쪽이 참(1)이면 결과는 1이 된다. 때문에 0x41과 0x33을 or 연산을 하게 되면 0x73이된다.

title

XOR 연산은 비교하는 두 값이 모두 참(1)이면 결과는 0이 되고, 두 값이 같지 않으면 결과는 1이 된다.

title

NOR 연산은 0와, 두 값이 같지 않으면 결과는 1이 된다. 때문에0x33을 NOT 연산하면 결괏값은 0xffffffcc가 된다. 여기서 cc가 0x33을 뒤집은 값이고 그 앞의 f 여섯 개가 붙은 이유는 int 자료형이 4byte(32bit)이기 때문이다.

여기서 추가로 알아야 할 것은 16진법은 0~9까지는 숫자로 표기하며 10~16까지는 A~F로 표기한다. 그 때문에 1byte가 모두 1로 이루어질 경우 ff로 표기한다. 0x33은 곧 0x00000033과 같기 때문에 결괏값이 0xffffffcc이 된다.

4.2 쉬프트 : <<, >>

#include <stdio.h>

int main(void) {
    printf("<< : %x\n", 0x33 << 3);        //=> << : 0x198
    printf(">> : %x\n", 0x33 >> 3);        //=> >> : 0x6
    printf(">> : %x\n", -0x33 >> 3);       //=> >> : 0xfffffff9
    printf(">> : %x\n", -0x00000033 >> 3); //=> >> : 0xfffffff9

    return 0;
}

<<>> 연산에는 쉬프트 (Shift)와 패딩(Padding)이라는 개념이 있다. Shift는 단어 뜻 대로 이동하는 것이고 Padding는 그의 원형과 같은 뜻을 가진다. Pad는 양복의 모양을 조정하기 위해 등에 넣는 심을 뜻한다. 즉, 정보를 옮길 경우 비는 공간에 새로운 정보를 채워 넣는 다는 뜻이다.

title

위 사진은 0x33 << 3에 대한 것이다. 왼쪽으로 3만큼 이동시켜주고 기존에 3bit가 있던 자리에는 0으로 이루어진 3bit를 채워 넣게 된다. 결괏값도 그에 따라 변하게 된다. title

위 사진은 0x33 >> 3에 대한 것이다. 오른쪽부터 3비트만큼 잘라서 없애준 다음, 3비트 만큼 이동하여 값이 변한다. 다만 오른쪽으로 시프트할 경우엔 왼쪽 부호비트 값에 따라 0이 아닌 1로 패딩하기 도한다. 이유는 부호를 유지하기 위함이다.

4.3 마스크 연산

#include <stdio.h>

int main(void) {
    printf("**Mask 연산**\n");
    printf("%x\n", 0x11223344 & 0xffff0000);  //=> 0x11220000
    printf("%x\n", 0x11223344 & 0x0000ffff);  //=> 0x00003344 
    printf("%x\n", 0x11223344 & 0x00ffff00);  //=> 0x00223300 
    printf("%x\n", 0x11223344 & 0xff0000ff);  //=> 0x11000044 

    return 0;
}

마스크 연산은 AND 연산을 함으로써 일정 구간의 메모리를 잘라내고, 그 자리를 0이 들어간 메모리로 채우는 연산이다. 여기에서 핵심은 AND 연산이다. AND 연산은 비교하는 값 모두가 1이어야 1을 뱉기 때문이다. 이 마스크 연산은 필요한 정보를 가려서 불필요한 정보를 거르는 역할을 한다. 물론 왼쪽 혹은 오른쪽 등 한쪽으로 편향된 정보를 잘라내야 한다면 쉬프트를 쓰면 되기 때문에 무조건 마스크 연산을 할 필요는 없다.



5. 복합 대입 연산자

title

복합 대입 연산자는 단순대입연산자와 산술 혹은 비트 연산자를 조합한 것이다. 실제로 연산을 두 번 한다.

#include <stdio.h>

int main(void)
{
    int num = 1;
    printf("처음 num에 저장된 수는 %d입니다.\n", num);
    // 처음 num에 저장된 수는 1입니다.
    
    num += 1;
    printf("num +=1 을 한 번 하면 값은 %d입니다.\n", num);
    // num +=1 을 한 번 하면 값은 2입니다.
    
    num += 1;
    printf("num +=1 을 두 번 하면 값은 %d입니다.\n", num);
    // num +=1 을 두 번 하면 값은 3입니다.

    return 0;
}

위 코드만을 보아도 충분히 이해가 가능할 것이다. 나머지 연산도 수행되는 형태는 마찬가지이다.



6. 단항증감 연산자

title

증가 연산자(increment operator)는 피연산자의 값을 1만큼 증가시키는 단순 작업을 수행한다.

#include <stdio.h>

int main(void)
{
    int num1 = 0, num2 = 0;
    printf("처음 num1와 num2에 저장된 수는 각각 %d, %d입니다.\n", num1, num2);
    // 처음 num1와 num2에 저장된 수는 각각 0, 0입니다.

    num1++;
    printf("num1++을 하면 num1은 %d입니다.\n", num1);
    // num1++을 하면 num은 1입니다.

    ++num2;
    printf("++num2을 하면 num2은 %d입니다.\n", num2);
    // ++num2을 하면 num은 1입니다.

    return 0;
}

이 연산자의 형태는 ++AA-- 두 형태 모두 사용한다. ++A처럼 부호를 피연산자 앞에 사용하는 것을 전위(prefix) 모드라고 하며, A--처럼 부호를 피연산자 뒤에 사용한 것을 후위(postfix) 모드라고 부른다. 결괏값은 같지만, 유사점도 존재하고 차이점도 존재한다.

#include <stdio.h>

int main(void)
{
    int num1 = 0, num2 = 0;
    int tmp1, tmp2;
    printf("처음 num1와 num2에 저장된 수는 각각 %d, %d입니다.\n", num1, num2);
    // 처음 num1와 num2에 저장된 수는 각각 0, 0입니다.

    tmp1= num1++;
    printf("tmp1= num1++을 하면 tmp1은 %d이고, num1은 %d입니다.\n", tmp1, num1);
    // tmp1= num1++을 하면 tmp1은 0이고, num1은 1입니다.

    tmp2 = ++num2;
    printf("tmp2 = ++num2을 하면 tmp2은 %d이고, num2은 %d입니다.\n", tmp2, num2);
    // tmp2 = ++num2을 하면 tmp2은 1이고, num2은 1입니다.

    return 0;
}

위 코드를 보면 둘의 차이를 명확하게 알 수 있다. 변수 tmp1에는 0이 저장되어있고, tmp2에는 1이 저장되어있다. num1++이나 --num2 처럼 단독으로 사용할 경우에는 어떤 것을 사용해도 문제가 되지 않는다. 하지만 연산자와 피연산자가 수식의 일부일 때는 둘 중 모드를 선택해야 한다.

전위 모드(++num2)는 증가시킨 다음에 새로운 변수에 대입하지만, 후위 모드(num1++)에는 새로운 변수에 대입한 다음에 그 값을 증가시키기 때문이다.

감소연산자(decrement operator)는 증가연산자에 대응하는 --AA--의 두 형태를 갖고 있다.



7. 형변환 연산자

title

형 변환 연산자(type cast)는 피연산자의 자료형을 강제로 바꾸는 단항 연산자이다. 덧셈이나 곱셈 같은 산술연산자보다 우선순위가 높아, 산술연산과 중첩될 경우 형 변환을 우선시한다.

#include <stdio.h>

int main(void)
{
    int intNum = 1;
    printf("%d\n", intNum);         //=> 1
    printf("%f\n", (double)intNum); //=> 1.000000

    return 0;
}

위 코드를 보면 형 변환 연산자를 사용하여 int인 자료형을 double형으로 바꾸어주었다.

#include <stdio.h>

int main(void)
{
    int intNum = 1;
    printf("%d\n", intNum);         //=> 1
    printf("%d\n", (double)intNum); //=> 0

    return 0;
}

형 변환 연산자는 강제로 이행된다. 즉, 문제가 생기든 말든, 적절하든 아니든 무조건 변환을 하기 때문이다. 적절한 변환이야 큰 문제가 되지 않지만, 그렇지 않을 때는 정보의 손실이 일어난다.

위의 경우가 그런 경우이다. printf("%d\n", (double)intNum);는 형식지정자와 자료형이 맞지 않아서 절사가 일어났고, 정보의 왜곡이 발생했다.







© 2020. by RIVER

Powered by RIVER