C 언어

[Unreal Engine 8기] C언어 3일차

조현묵 2026. 2. 25. 21:30
  • 비트 논리 연산자, 비트 이동 연산자
더보기
  •  (1) 비트 연산자

비트(Bit-wise)라는 말이 붙으면 피연산자를 모두 2진수로 평가한 후에 연산을 수행해야합니다.

 

  • 비트 논리 연산자(Bit-wise Logical Operator)

비트별로 논리 연산을 수행하는 연산자.

꿀팁은 역시나 비트 논리 보다는 곱/합/반전/베타합 글자에 집중해봅시다.

 

  • 비트 논리 연산자의 종류

비트 논리 곱 연산자(&)

비트 논리 합 연산자(|)

비트 논리 반전 연산자(~): 전체 비트를 반전

비트 논리 베타합 연산자(^): 비트별로 1의 개수가 홀수개면 그 결과는 1, 짝수개면 0.

 

  • 비트 연산자

int 자료형 num1과 num2를 선언. 각각 11과 9로 초기화합니다.

그리고 num1과 num2에 대해 위에 나온 4개의 비트 논리 연산자 결과를 줄마다 출력해봅시다.

 

비트 연산자
  • 비트 이동 연산자(Bit-Shift Operator)

마찬가지로 피연산자를 2진수로 모두 평가 한 후에

2진수 기준 왼쪽 혹은 오른쪽으로 n 칸씩 이동시키는 연산자.

  • Bit Left Shift Operator

피연산자의 이진패턴을 왼쪽으로 n칸 이동.

ex) 7(10) << 2 == 0000 0111(2) << 2 == 0001 1100(2) == 28(10)

      3(10) << 3 == 0000 0011(2) << 3 == 0001 1000(2) == 24(10)

  • 비트를 왼쪽으로 n번 이동하는 것은 2를 n번 곱한것과 같습니다.

2를 3번 곱한것과 3번 비트 왼쪽 시프트 한 것의 속도 차이가 있을까요?

최신 컴파일러들은 없습니다. 최적화에 너무 목매지 맙시다. 그런 개념이 있었음만 기억하면 됩니다.

  • Bit Right Shift Operator

피연산자의 이진패턴을 오른쪽으로 n칸 이동.

ex) 3(10) >> 1 == 0011(2) >> 1 == 0001(2)

     -4(10) >> 2 == 1111 1100(2) >> 2 == 1111 1111(2)

  • 들어가기 전에 (2)
더보기
  • “천천히 읽기”

앞으로는 명령어 하나하나의 실행에 신경써야합니다.

마치 컴퓨터가 되었다고 생각하고 실습하는 것이 중요합니다.

이는 소스코드라는 글을 “정독”하는 방법을 익히고자 하는 것입니다.

정독이 되어야 속독이 가능해집니다. 섣부른 암산은 폐사 지름길입니다. 절대 금지.

 

  • “천천히 읽기” 방법
  1. 프로그램의 시작점은 main() 함수. main() 함수의 첫 줄부터 읽습니다.
  2. 위에서 아래로, 좌에서 우로 읽습니다.
  3. 단위는 하나의 문. 명령어 단위로 읽습니다.
  • C언어는 절차지향 언어입니다.

마치 라면 끓이는 방법처럼, 실행 순서가 아주 중요한 언어입니다.

그렇기에 “천천히 읽기”를 하는 것이 아주 중요해집니다.

ex) 대충 읽고, 서두르다가 물을 먼저 안넣고, 면만 넣고 가스불 올리면 큰일납니다.

  • 단순 if문 (2)
더보기
  • 단순 if문

 

if (조건식)

{

명령어1;

명령어2;

...

}

  • if(조건식);의 의미

세미콜론은 문장의 끝을 의미한다고 했습니다.

if(조건식) 뒤에 ;을 달면 뒤에 중괄호 내용은 if문과 관련 없어집니다. 즉, 무조건 실행됩니다.

if (조건식);

{

명령어1;

명령어2;

...

}

  • 단순 if문
단순 if
  • if-else문 (2)
더보기
  • if-else문

조건식이 참 혹은 거짓, 모든 경우를 처리 할 수 있습니다.

 

if (조건식)

{

명령어1; // 조건식이 참이면 여기가 실행됩니다.

...

}

else

{

명령어2; // 조건식이 거짓이면 여기가 실행됩니다.

...

}

  • else문만 단독으로 쓸 수 있을까요?

당연히 쓸 수 없습니다.

else

{

명령어1;

...

}

  • if-else문과 삼항연산자

간단한 if-else문은 삼항 연산자로 대체가 가능합니다. 이후에 알아볼 예정입니다.

 

  • if-else문
if-else문
  • if-else if-else문 (2)
더보기
  • if-else if-else문

if (조건식1)

{

명령어1; // 조건식1이 참이라면 명령어1부터 수행.

...

}

else if (조건식2) // 조건식1이 거짓이라면 조건식2 검사.

{

명령어2; // 조건식2가 참이라면 명령어2부터 수행.

...

}

else

{

명령어3; // 조건식1도 거짓이고, 조건식2도 거짓이라면 명령어3 수행.

...

}

  • if-else if-else문 Vs. 단순 if문

위의 if-else if-else문과 아래 코드의 차이는 뭘까요?

if (조건식1)

{

명령어1

...

}

if (조건식2)

{ 명령어2

...

}

if (조건식3)

{

명령어3

...

}

  • if-else if-else문
if-else if-else문
  • if ifelse문
if ifelse 문
  • 중첩 if문 (2)
더보기
  • 중첩 if문(Nested-if statement)

if (조건식1)

{

명령어1;

...

if (조건식2)

{

명령어2;

...

}

else

{

명령어3;

...

}

}

  • 조건문의 스코프 속 명령어가 한 줄이어도 스코프는 꼭 적습니다.

중괄호를 생략하는 사람이 정말 많습니다.

그러나 초보자에겐 너무나도 안좋은 습관입니다. 우리는 무조건 적어서 명시적으로 표현해주도록 합시다.

if (x < 10)

{

printf("x < 10");

}

 

// if (x < 10) printf("x < 10"); worst.

  • 조건문 꿀팁

조건문에는 조건식이 나옵니다.

조건식은 보통 부등식으로 표현이 되는데, 머리속에 수평선을 그려서 해석하면 쉽습니다.

  • 값의 범위를 조건식에 적을때 아래와 같이 적어봅시다.

확실히 x가 10과 15 사이에 있음을 알 수 있습니다.

// if (x >= 10 && x >= 15) worst

if (10 <= x && x <= 15) // best. 그럼 이 조건식의 역은 어떻게 적으면 될까요?

  • 중첩 if문
중첩 if문
  • switch-case문 (2)
더보기
  • switch-case문

switch (Num)

{

case 값1:

명령어1; // "Num == 값1"인 경우엔 명령어1

...

break;

case 값2: 명령어2; // "Num == 값2"인 경우엔 명령어2

...

break;

default: 명령어3; // "Num이 값1도 값2도 아닌 경우"(Num이 어떤 케이스에도 속하지 않는 경우)엔 명령어3

...

break;

}

  • switch-case문은 if-else if-else문으로 치환 가능합니다.

그럼에도 switch-case문을 사용하는 이유는 가독성 때문입니다.

반대로 if-else if-else문은 switch-case문으로 치환 불가능할 때가 있습니다.

특히 if-else if-else문의 조건식이 범위를 다루는 경우 불가능합니다.

  • Intentional-Fallthrough

고의적으로 case 내부에 break 구문을 적지 않은 경우입니다.

아래와 같이 코드를 작성한다면 Num이 값1과 같으면, case 값2 부분까지도 수행하게 됩니다.

switch (Num)

{ case 값1: 명령어1;

/*Intentional-Fallthrough*/

case 값2:

명령어2; // Num == 값1인 경우엔 명령어1과 명령어2 모두 실행

...

break;

default: 명령어3;

...

break;

}

  • 만약 case 내에서 변수를 선언하려면 아래와 같이 중괄호를 쳐주면 됩니다.

switch (Num)

{ case 값1:

명령어1;

...

break;

case 값2:

{

int Var = 10;

printf("%d", Var);

}

break;

default:

작은 명령어3

...

break;

}

  • switch-case문
switch-case
  • while문 (2)
더보기
  • 반복문에서도 “천천히 읽기”가 중요합니다.

처음에는 답답하고 힘들겠지만, 정독 횟수가 누적되어야 정확한 속독이 가능해집니다.

  • while문

while (조건식)

{

명령어1;

...

}

  • while문
while문
  • 누적합
누적합
  • 누적곱
누적곱
  • 최대값
최대값
  • 최소값
최소값

 

  • 반복문의 순회 변수로는 i를 자주 씁니다.

iterate의 약자이기도 하지만, 이후에 배울 배열 + 반복문에서 index의 약자이기도 합니다.

되도록이면 i를 사용하는 것이 국룰입니다.

  • for문 (2)
더보기
  • for문

for (초기식; 조건식; 증감식)

{

명령어1;

...

}

  • for문
for문
  • 누적합
누적합
  • 누적곱
누적곱
  • 최대값
최대값
  • 최소값
최소값
  • do-while문 (2)
더보기
  • do-while문

일단 조건식 검사 없이 1회 순회(do) 후에 조건식 검사 후 다음 순회 진행합니다.

do

{

명령어1;

...

} while (조건식)

  • do-while문은 왜 필요할까요?

아주 가끔 요긴하게 쓰일때가 있습니다. ex) 자료구조 구현할 때, …

대부분의 경우에는 for문, 순회하는 변수가 필요 없는 경우엔 while을 씁니다.

  • do-while문

다음의 소스코드를 “천천히 읽기”로 출력 결과를 예측해봅시다.

예측 결과와 실행 결과와 비교해봅시다.

do-while문
  • 무한 반복문, break, continue (2)
더보기
  • 무한 반복문

무한 반복문은 for문보다는 while문으로 구현하는 경우가 많습니다.

while (1) // 1은 true일까 false일까요?

{

명령어1;

...

}

 

int i;

for (i = 1; 1; ++i) // 조건식을 1이 아닌 그냥 비워두어도 참으로 간주됩니다.

{

명령어1;

...

}

  • falsy와 while의 조건문

while (-9) // -9는 true일까요 false일까요?

{

명령어1;

...

}

 

while (0) // 0은 true일까요 false일까요?

{

명령어1;

...

}

  • 무엇이든지 무한하게 도는 것은 아주 위험합니다.

막연하게 무한히 돈다는 것은 다시는 그 장치를 쓸 수 없다는 뜻과 같습니다.

멈추는 코드가 없기 때문입니다. 그렇기 때문에 break 구문이 필요합니다.

  • break

반복문이나 switch-case문에서 탈출 할 때 break 구문을 사용합니다.

해당 스코프에서만 탈출됩니다. 다중 반복문 전체를 다 탈출하는게 아님에 주의합시다.

while (1)

{

while (2)

{ break; // while (2)

반복문만 탈출됨.

}

}

  • continue

반복문에서 continue 구문을 만나면 해당 회차는 건너뛰고 다음 회차 진행합니다.

반복문을 아에 탈출하는 게 아닌 특정 순회 번째만 무시합니다.

특정 순회에서는 아무 일도 안하고 다음 순회로 가고 싶을 수 있기 때문입니다.

  • 무한반복문과 break, continue
무한반복문과 break,continue

 

'C 언어' 카테고리의 다른 글

[Unreal Engine 8기] C언어 6일차  (0) 2026.03.03
[Unreal Engine 8기] C언어 5일차  (0) 2026.02.27
[Unreal Engine 8기] C언어 4일차  (0) 2026.02.26
[Unreal Engine 8기] C언어 2일차  (0) 2026.02.24
[Unreal Engine 8기] C 언어 1일차  (0) 2026.02.23