Core Programming/C for Systems Engineering

C언어 연산자 총정리: 산술, 논리, 삼항 연산자부터 비트 연산까지

임베디드 친구 2024. 12. 12. 15:33
반응형

컴퓨터(Computer)의 어원이 '계산하다(Compute)'라는 사실, 알고 계셨나요? 결국 컴퓨터는 우리가 지시한 명령에 따라 엄청난 속도로 연산을 수행하는 기계입니다. 소스 코드 안에서 컴퓨터에게 "이 데이터를 더해라", "저 데이터가 더 큰지 비교해라" 하고 구체적인 계산 명령을 내리는 기호들을 바로 연산자(Operator)라고 부릅니다. C 언어는 하드웨어를 세밀하게 다루는 언어답게 단순한 사칙연산부터 메모리 크기를 재고 비트 단위를 쪼개는 연산자까지 아주 강력하고 다양한 도구들을 제공합니다. 오늘 글을 통해 C 언어의 연산자들을 내 손과 발처럼 자유자재로 다루는 방법을 알아보겠습니다.

Generated by Gemini AI.

📌 핵심 요약 3줄

  • 수학적·논리적 제어의 기초: 산술, 관계, 논리 연산자는 프로그램의 조건과 흐름을 결정짓는 가장 핵심적인 연산 기호입니다.
  • C 언어만의 특수 연산자: 메모리 공간의 크기를 바이트 단위로 알려주는 sizeof나 주소를 다루는 연산자 등 저수준 제어를 위한 강력한 기호를 지원합니다.
  • 우선순위와 작동 원리 이해: 연산자마다 먼저 계산되는 우선순위가 정해져 있으며, 증감 연산자의 위치에 따라 연산 시점이 달라지므로 정확한 개념 이해가 필요합니다.

1. 산술 연산자 (Arithmetic Operators)

가장 기본이 되는 사칙연산과 나머지를 구하는 연산자입니다. 우리가 수학 시간에 배운 기호와 거의 같아서 이해하기 아주 쉽습니다.

연산자 기능 설명 예제 코드 계산 결과 (a=10, b=3 기준)
+ 두 값을 더합니다. a + b 13
- 앞의 값에서 뒤의 값을 뺍니다. a - b 7
* 두 값을 곱합니다. a * b 30
/ 앞의 값을 뒤의 값으로 나눕니다. (정수끼리는 몫만 반환) a / b 3 (소수점은 버려짐)
% 나눗셈을 한 뒤 남은 나머지를 구합니다. a % b 1
  • 나눗셈(/) 팁: int형 정수끼리 나누면 소수점은 완전히 증발하고 '몫'만 남습니다. 만약 3.333... 같은 실수 결과를 얻고 싶다면 변수 중 하나를 float나 double로 형변환(casting)해 주어야 합니다.

2. 대입(할당) 연산자 (Assignment Operators)

우측에 있는 값을 좌측 변수에 집어넣는 연산자입니다. 코드를 더 짧게 줄여 쓸 수 있는 '복합 대입 연산자'도 자주 쓰입니다.

연산자 기능 설명 일반적인 표현 줄여 쓴 표현 (복합 대입)
= 우변의 값을 좌변의 변수에 대입합니다. a = b; -
+= 좌변의 값에 우변의 값을 더한 후 다시 대입합니다. a = a + b; a += b;
-= 좌변의 값에서 우변의 값을 뺀 후 다시 대입합니다. a = a - b; a -= b;
*= 좌변의 값에 우변의 값을 곱한 후 다시 대입합니다. a = a * b; a *= b;
/= 좌변의 값을 우변의 값으로 나눈 몫을 대입합니다. a = a / b; a /= b;
%= 좌변의 값을 우변의 값으로 나눈 나머지를 대입합니다. a = a % b; a %= b;

3. 증감 연산자 (Increment/Decrement Operators)

변수의 값을 딱 1씩 증가시키거나 감소시키는 독특한 연산자입니다. 연산자가 변수의 앞에 붙느냐(전위), 뒤에 붙느냐(후위)에 따라 실행 순서가 완전히 달라지니 눈여겨보셔야 합니다.

연산자 종류 표기법 작동 원리
전위 증가 (Prefix) ++a 값을 먼저 1 증가시킨 후, 해당 라인의 나머지 코드를 실행합니다.
후위 증가 (Postfix) a++ 현재 값으로 코드를 먼저 실행한 후, 라인이 끝나면 값을 1 증가시킵니다.
전위 감소 (Prefix) --a 값을 먼저 1 감소시킨 후, 해당 라인의 나머지 코드를 실행합니다.
후위 감소 (Postfix) a-- 현재 값으로 코드를 먼저 실행한 후, 라인이 끝나면 값을 1 감소시킵니다.
C
 
#include <stdio.h>

int main() {
    int a = 5;
    printf("++a (전위): %d\n", ++a);  // 1이 먼저 더해져서 6이 출력됩니다.
    printf("a++ (후위): %d\n", a++);  // 현재 값인 6이 먼저 출력된 후, a는 7이 됩니다.
    printf("현재 a의 값: %d\n", a);   // 최종적으로 반영된 7이 출력됩니다.
    return 0;
}

4. 관계 연산자 및 논리 연산자

두 값을 비교하거나 여러 조건을 엮을 때 사용합니다. C 언어에는 참/거짓을 뜻하는 별도의 불리언 타입이 기본적으로 없기 때문에, 참은 정수 1, 거짓은 정수 0으로 표현합니다.

관계 연산자 (비교)

연산자 의미 예시 (a=10, b=20 기준) 결과 (참/거짓)
== 두 값이 같은가? a == b 0 (거짓)
!= 두 값이 다른가? a != b 1 (참)
< / > 왼쪽이 작은가 / 큰가? a < b 1 (참)
<= / >= 왼쪽이 작거나 같은가 / 크거나 같은가? a >= b 0 (거짓)

논리 연산자 (조건 결합)

연산자 기능 설명 의미 예시 구문
&& 논리 AND (그리고) 두 조건이 모두 참이어야 최종 참(1)이 됩니다. (a > 5) && (b < 30)
|| 논리 OR (또는) 두 조건 중 하나만 참이어도 최종 참(1)이 됩니다. (a > 5) || (b < 10)
! 논리 NOT (반대) 참은 거짓으로, 거짓은 참으로 뒤집습니다. !(a == b)

5. 비트 연산자 (Bitwise Operators)

하드웨어 제어나 임베디드 프로그래밍에서 정말 자주 쓰이는 연산자입니다. 메모리의 최소 단위인 '비트(0과 1)'를 직접 제어합니다.

연산자 이름 작동 방식
& 비트 AND 두 비트가 모두 1일 때만 1을 반환
| 비트 OR 두 비트 중 하나라도 1이면 1을 반환
^ 비트 XOR 두 비트의 값이 서로 다를 때만 1을 반환
~ 비트 NOT 0은 1로, 1은 0으로 반전
<< 왼쪽 시프트 비트들을 왼쪽으로 지정한 칸만큼 이동 (값에 $2^n$을 곱한 효과)
>> 오른쪽 시프트 비트들을 오른쪽으로 지정한 칸만큼 이동 (값을 $2^n$으로 나눈 효과)

6. 조건부 삼항 연산자 및 기타 특수 연산자

C 언어에는 코드를 획기적으로 줄여주는 매력적인 연산자들이 숨어있습니다.

삼항 연산자 (? :)

조건식 ? 참일_때_값 : 거짓일_때_값 형태로 사용하며, if문을 한 줄로 축약한 형태입니다.

C
 
int a = 10, b = 20;
int max = (a > b) ? a : b; // a가 b보다 크면 a를, 아니면 b를 max에 대입합니다.

크기 및 주소 관련 연산자

  • sizeof: 데이터 타입이나 변수가 메모리에서 차지하는 크기를 바이트(Byte) 단위로 계산해 줍니다.
  • & (주소 연산자): 변수가 할당된 실제 메모리 주소값을 찾아냅니다. (scanf에서 보았던 그 기호입니다!)
C
 
printf("int 자료형의 크기: %lu 바이트\n", sizeof(int)); // 출력: 4 바이트

💡 C 언어 연산자 사용을 위한 꿀팁 (Tip)

  1. 복잡한 조건식에는 무조건 괄호 ()를 감싸세요: 연산자 우선순위를 다 외우고 코딩하는 개발자는 드뭅니다. a == b && c > d || e < f 처럼 적으면 가독성도 떨어지고 컴퓨터가 내 의도와 다르게 계산할 수 있습니다. ((a == b) && (c > d)) || (e < f) 처럼 괄호로 명확하게 묶어주세요.
  2. 비트 시프트 연산으로 고속 곱셈/나눗셈을 수행하세요: 임베디드 환경처럼 연산 성능이 제한된 곳에서는 a * 4 대신 a << 2를, a / 2 대신 a >> 1을 쓰면 내부적으로 훨씬 빠른 속도로 연산이 처리됩니다.
  3. 나머지 연산자(%)는 패턴 주기에 최고입니다: 어떤 정수든 % 3을 하면 결과는 항상 0, 1, 2 중 하나만 나옵니다. 짝수/홀수를 판별하거나(num % 2 == 0), 특정 사이클을 반복하는 로직을 짤 때 치트키처럼 활용할 수 있습니다.

⚠️ 초보자가 흔히 하는 실수 (Mistakes)

  • 대입 연산자 =와 비교 연산자 == 혼동하기: "만약 a가 10이라면"을 코드로 적을 때 if (a = 10)이라고 적는 대참사가 자주 일어납니다. 이렇게 적으면 비교를 하는 게 아니라 a에 10이 대입되어 항상 '참'으로 인식됩니다. 반드시 == 기호를 두 번 적어주세요.
  • 한 줄에 증감 연산자 과도하게 겹쳐 쓰기: int result = ++a + a++; 같은 코드는 작성하지 마세요. 컴파일러 종류에 따라 전위 연산과 후위 연산의 계산 순서가 달라질 수 있어서 버그의 원인이 되며, 사람이 읽기에도 최악의 코드입니다. 증감 연산은 가급적 한 라인에 독단으로 분리해서 쓰는 것이 깔끔합니다.
  • 정수 나눗셈의 데이터 손실: int 타입 변수끼리 나누면 결과값도 무조건 int가 됩니다. float result = 5 / 2; 라고 적으면 2.5가 담길 것 같지만, 5 / 2가 이미 정수 2로 계산된 뒤에 float에 담기므로 2.0이 저장됩니다. 제대로 쓰려면 5.0 / 2.0으로 적거나 형변환을 꼭 거쳐주세요.

🔚 마무리하며

오늘 살펴본 다양한 연산자들은 소스 코드 안에서 데이터를 이리저리 요리하는 훌륭한 조리도구들입니다. 특히 비트 연산자나 포인터 관련 특수 연산자들은 다른 최신 고수준 언어에서는 쉽게 맛볼 수 없는 C 언어만의 강력한 매력이자 핵심 무기입니다. 오늘 배운 예제들을 콘솔 창에 직접 입력해 보시면서 컴퓨터가 계산하는 흐름을 손 끝으로 익혀보세요.

오늘도 소프트웨어 공장을 찾아주셔서 감사합니다. 코딩하다 궁금한 점은 언제든 댓글로 소통해요!

반응형