본문 바로가기
C언어 공부

04. 산술연산자, 대입연산자, 비트연산자, 오버플로우

by 나노다 2024. 10. 13.

산술 연산자 

  • +,  - ,  * ,  / ,  % 
  • a % b : a를 b로 나눈 나머지를 구해주는 연산자. 정수형 데이터에서만 연산이 가능.
  • "" 안에서 문자 %를 출력하고 싶다면 붙여서 두 번 써줘야함. 한번만 쓰면 "%d"같은 변환문자로 먼저 인식하기 때문.
int a = 10;
int b = 3;
// 문자 %를 출력하고 싶다면 두 번 써줘야 함
printf("a %% b : %d \n", a % b);

 

[나눗셈 오류]

int a = 10;
int b = 3;
printf("a / b : %f", a / b);
  • 정수형 간 연산의 결과값은 무조건 정수형이기 때문에,
    모두 정수형인 a와 b의 연산 결과가 실수형 변환문자인 "%f"와 만나 오류
double a = 10;
double b = 3;
printf("a / b : %d", a / b);
  • 반대로 실수형 간의 연산인데 정수형 변환문자인 "%d"와 실수형 연산 결과가 만나 오류

[산술 변환]

int a = 10;
double b = 3;
printf("a / b : %f", a / b);
// 정수보다 실수의 범위가 크기 때문에 a가 double형으로 변환돼 연산
  • 자료형이 다른 두 변수를 연산할 때, 숫자의 범위가 더 큰 자료형으로 자료형들이 바뀌는 것.
  • int형인 a가 산술 변환되면서 실수형 변수와 실수형 변수의 연산이 됐고, 결과도 실수형으로 오류 없이 출력됨.

 

대입 연산자

  • a = b : 오른쪽의 값을 왼쪽에 대입한다는 의미. 양쪽이 같다는 뜻이 절대 아님!

[복합 대입 연산]

// a = a + x; 와 같음
a += x;
// a = a - x; 와 같음
a -= x;
// a = a * x; 와 같음
a *= x;
// a = a / x; 와 같음
a /= x;

 

[증감 연산자]

// 전위형
++a;
--a;
// 후위형
a++;
a--;
  • ++a : 변수 a의 값을 1씩 증가시킴
  • --a : 변수 a의 값을 1씩 감소시킴
  • 전위형 : 증감을 먼저 하고 결과 출력
  • 후위형 : 결과를 먼저 출력하고 증감

 

비트 연산자

  • 비트 하나 하나에 대해 연산. 1 비트는 0 또는 1을 나타내는 최소 단위.
  • 두 숫자를 자리수 대로 비교해 결과를 출력함.
  • 만약 두 숫자의 자리수가 맞지 않는다면 부족한 숫자의 빈 자리수에 0을 추가해 맞춤.
    11001과 101을 비교한다면, 101을 00101로 맞춰 줌.

[AND 연산]

1010 & 0010
// 0010 출력
  • a & b : 각 자리를 비교했을 때 양쪽 다 1일 경우에만 1을, 나머지 경우는 0을 출력함

[OR 연산]

1010 | 0011
// 1011 출력
  • a | b : 각 자리를 비교했을 때 어느 한 쪽이라도 1이라면 1을, 양쪽 다 0이면 0을 출력함

[XOR 연산]

1011 ^ 0010
// 1001 출력
  • a ^ b : 각 자리를 비교했을 때 양 쪽이 달라야 1을, 같으면 0을 출력함

[반전 연산]

~1011
// 0100 출력
  • ~a : 0을 1로, 1을 0으로 반전시킴

[쉬프트 연산]

101011 << 1
// 010110 출력
101010 >> 1
// 110101 출력
  • a << b , a >> b : a를 기호 방향대로 b만큼 밀어냄.
  • << 쉬프트 시 결과 값에서 맨 앞 숫자가 이동될 자리가 없다면 버려지고, 맨 뒤에서 새로 채워지는 부분은 무조건 0
  • >> 쉬프트 시 결과 값에서 맨 뒤 숫자가 이동될 자리가 없다면 버려지고,
    앞에서 새로 채워지는 부분은 원래 맨 앞에 있던 수 (무조건 0을 채우는 시스템도 있음)

[비트 연산 주의사항]

  • in형 변수는 4바이트 = 32비트기 때문에, 자리수가 총 32임.
  • int a = 10101111; // 실제 a의 값은 00000000 00000000 00000000 10101111
  • 아래 코드블럭처럼, 반전 연산과 쉬프트 연산에서 이 점을 주의해야 함.
int a = 10101111;
printf("%x", ~a);
// 11111111 11111111 11111111 01010000 출력됨.
printf("%x", a << 3);
// 10101111000 출력됨. 사실 쉬프트 결과가 00000000 00000000 00000101 01111000 라서.
printf("%x", a >> 3);
// 00010101 출력됨. 사실 쉬프트 결과가 00000000 00000000 00000000 00010101라서.

 

오버플로우

  • 자료형의 최대 범위보다 큰 수를 대입하면 발생.
  • 양수에 양수를 더했는데 음수가 나오거나 값이 작아지거나 하는 등의 일.
  • 따로 알려주지 않기 때문에 항상 자료형의 크기를 신경 써야함.