로보테크AI

융합_로보테크 AI 자율주행 로봇 개발자 과정-26/02/12

steezer 2026. 2. 12. 18:30

일반 변수: 값을 저장하는 변수

포인터 변수: 메모리 주소를 저장하는 변수

레퍼런스: 변수에 또 다른 이름, 별칭 부여

 

레퍼런스 변수는 이미 존재하는 변수를 다른 이름으로 참조하는 별칭

레퍼런스 변수는 & 연산자를 사용하여 선언

 

사용 이유

함수에서 값 복사 없이 원본을 직접 수정하기 위해
코드 가독성을 높이기 위해
불필요한 메모리 복사를 줄이기 위해

 

레퍼런스 사용시 주의할 것

1.레퍼런스 변수는 선언 후 반드시 참조할 원본 변수를 지정해야 함

2.참조할 대상이 지정된 레퍼런스 변수는 다른 변수를 참조하도록 변경할 수 없음

3.레퍼런스 변수는 상수를 참조할 수 없음

 

#include <iostream>

using namespace std;

int main() {
  int value = 10;
  int& ref_value = value; // 10이 저장된 메모리에 변수명 추가

  int value2 = 20;
  ref_value = value2;   // 레퍼런스 재지정, 의도와 다르게 동작

  cout << "value: " << value << endl;
  cout << "ref_value: " << ref_value << endl;

  return 0;
}

 

value: 20
ref_value: 20

 

Call by Value

함수 원형 void swap(int a, int b)
매개변수 값 복사본
코드 예 cpp\nvoid swap(int a, int b){\n int temp = a;\n a = b;\n b = temp;\n}\n
swap 이전 a = 5, b = 10
swap 이후 a = 5, b = 10 (변화 없음)
특징 원본이 복사되어 전달되므로 원본 값 변경 불가

 

Call by Reference

함수 원형 void swap(int& a, int& b)
매개변수 원본 변수의 별칭
코드 예 cpp\nvoid swap(int& a, int& b){\n int temp = a;\n a = b;\n b = temp;\n}\n
swap 이전 a = 5, b = 10
swap 이후 a = 10, b = 5
특징 원본과 같은 메모리를 공유하여 직접 변경 가능

 

Call by Address / Pointer

함수 원형 void swap(int* a, int* b)
매개변수 변수의 주소값
코드 예 cpp\nvoid swap(int* a, int* b){\n int temp = *a;\n *a = *b;\n *b = temp;\n}\n
호출 방법 swap(&a, &b);
swap 이전 a = 5, b = 10
swap 이후 a = 10, b = 5
특징 주소를 통해 간접적으로 원본 값 변경

 

핵심 차이

방식 원본 변경 메모리 전달 방식 문법 난이도
X 값 복사 가장 쉬움
참조 O 별칭 공유 간결함
주소 O 포인터 사용 비교적 복잡

 

 

조건문

 

구문 사용 목적 특징
if 단일 조건 가장 기본
if-else 두 가지 경우 참/거짓
else if 여러 조건 순차 검사
switch 정해진 값 비교 가독성 좋음
삼항 연산자 간단한 조건 한 줄 표현

 

if (조건식) {

    실행문;

}

 

switch (변수) {

    case 값1;

        실행문;

        break;

    case 값2;

        실행문;

        break;

    default:

        실행문;

}

 

if

#include <iostream>

using namespace std;

int main() {
  int input_number;

  cout << "정수 입력: ";
  cin >> input_number;

  if (input_number > 0) {
    cout << "입력한 수는 양수 입니다." << endl;
  }
  else if (input_number < 0) {
    cout << "입력한 수는 음수 입니다." << endl;
  }
  else {
    cout << "입력한 수는 0 입니다." << endl;
  }

  return 0;
}

정수 입력: 1
입력한 수는 양수 입니다.

 

중괄호 생략 ver

#include <iostream>

using namespace std;

int main() {
  int input_number;

  cout << "정수 입력: ";
  cin >> input_number;

  if (input_number > 0)
    cout << "입력한 수는 양수 입니다." << endl;
  else if (input_number < 0)
    cout << "입력한 수는 음수 입니다." << endl;
  else
    cout << "입력한 수는 0 입니다." << endl;

  return 0;
}

정수 입력: 1
입력한 수는 양수 입니다.

 

 

switch

여러 경우 중 하나 선택해 실행

#include <iostream>

using namespace std;

int main() {
  int input_number;

  cout << "1 ~ 5 정수 입력: ";
  cin >> input_number;

  switch (input_number) {
  case 1:
    cout << "입력한 수는 1 입니다." << endl;
    break;

  case 2:
    cout << "입력한 수는 2 입니다." << endl;
    break;

  case 3:
    cout << "입력한 수는 3 입니다." << endl;
    break;

  case 4:
    cout << "입력한 수는 4 입니다." << endl;
    break;

  case 5:
    cout << "입력한 수는 5 입니다." << endl;
    break;

  default:
    cout << "입력한 수는 1 ~ 5 범위 밖입니다." << endl;
    break;
  }

  return 0;
}

1 ~ 5 정수 입력: 1
입력한 수는 1 입니다.

 

break 없는 ver

#include <iostream>

using namespace std;

int main() {
  int input_number;

  cout << "1 ~ 5 정수 입력: ";
  cin >> input_number;

  switch (input_number) {
  case 1:
    cout << "입력한 수는 1 입니다." << endl;

  case 2:
    cout << "입력한 수는 2 입니다." << endl;

  case 3:
    cout << "입력한 수는 3 입니다." << endl;

  case 4:
    cout << "입력한 수는 4 입니다." << endl;

  case 5:
    cout << "입력한 수는 5 입니다." << endl;

  default:
    cout << "입력한 수는 1 ~ 5 범위 밖입니다." << endl;
  }

  return 0;
}

1 ~ 5 정수 입력: 1
입력한 수는 1 입니다.
입력한 수는 2 입니다.
입력한 수는 3 입니다.
입력한 수는 4 입니다.
입력한 수는 5 입니다.
입력한 수는 1 ~ 5 범위 밖입니다.

 

A customer wants to order Coffee.
The code in the editor is incomplete. Fix it by inserting the missing values so the program prints the correct order.

  1. Change choice to the correct number for Coffee (see the comments).
  2. Insert choice inside switch().
  3. Replace each case: with the correct number based on the comments above.
  4. Move cout << "Invalid choice" into a default: case.
#include <iostream>
using namespace std;

int main() {
  int choice = 1;

  // 1 = Coffee
  // 2 = Tea

  switch (choice) {
    case 1:
      cout << "You ordered Coffee";
      break;

    case 2:
      cout << "You ordered Tea";
      break;

    default:
      cout << "Invalid choice";
  }

  return 0;
}

 

 

반복문

 

while

 

while (조건식) {
    실행문;
}

 

조건이 true인 동안 계속 반복

반복 횟수가 명확하지 않을 때 사용

 

#include <iostream>

using namespace std;

int main() {
  int count = 0;
  while (count < 5) {
    cout << "count : " << count << endl;
    count++;
  }
  return 0;
}

 

count : 0
count : 1
count : 2
count : 3
count : 4

 

do-while

 

do {
    실행문;
} while (조건식);

 

최소 한 번은 반드시 실행
실행 후 조건 검사

 

#include <iostream>

using namespace std;

int main() {
  int count = 0;
  do {
    cout << count << endl;
    count++;
  } while (count < 5);
  return 0;
}

 

0
1
2
3
4

 

for

 

for (초기식; 조건식; 증감식) {
    실행문;
}

#include <iostream>

using namespace std;

int main() {
  for (int count = 0; count < 5; count++) {
    cout << " count : " << count << endl;
  }
  return 0;
}

 

 count : 0
 count : 1
 count : 2
 count : 3
 count : 4

 

동작 순서

초기식 실행
조건 검사
실행문 실행
증감식 실행
조건이 false가 될 때까지 반복

 

특징


반복 횟수가 정해져 있을 때 사용
가장 많이 사용되는 반복문

 

while vs dowhile

#include <iostream>

using namespace std;

int main() {
  int i = 0;
  while (i < 0) { // 조건식이 거짓이므로 반복문은 전혀 실행되지 않는다.
    cout << "i is less than 0" << endl;
    i++;
  }

  int j = 0;
  do {
    cout << "j is less than 0" << endl;
    j++;
  } while (j < 0); // 조건식이 거짓이지만 반복문은 1회 실행된다.


  return 0;
}

 

j is less than 0

 

비교 정리

반복문 조건 검사 시점 최소 실행 횟수 사용 상황
for 시작 전 0회 횟수 정해짐
while 시작 전 0회 조건 중심
do-while 실행 후 1회 최소 1회 필요

 

 

표현식

값을 만들어내는 코드 조각

 

구문

하나의 동작을 수행하거나 동작을 실행하는 명령문의 집합

 

구분 표현식 구문
결과 값이 나온다 동작을 수행한다
a + b a = a + b;

 

 

C++ 제어문 퀴즈

 

에디터는 자유

조건: 검색, LLM 금지

 

사용자로부터 1 또는 2를 입력 받아(cin)

1을 입력받으면 구구단 홀수단만 나열 출력

2를 입력받으면 구구단 짝수단만 나열 출력

#include <iostream>
using namespace std;

int main() {

	int input_number;

	cout << "1 or 2?: ";
	cin >> input_number;

	switch (input_number) {

	case 1:
		cout << "\n1 3 5 7 9 \n" << endl;

		for (int dan = 1; dan <= 9; dan += 2) {
			cout << "\n(" << dan << "dan)\n";

			for (int i = 1; i <= 9; i++) {
				cout << dan << "x" << i << "=" << dan * i << endl;
			}
		}
		break;

	case 2:
		cout << "\n2 4 6 8 \n" << endl;

		for (int dan = 2; dan <= 8; dan += 2) {
			cout << "\n(" << dan << "dan)\n";

			for (int i = 2; i <= 8; i++) {
				cout << dan << "x" << i << "=" << dan * i << endl;
			}
		}
		break;

	default:
		cout << "\n Error \n" << endl;

	}
	return 0;
}

 

프로그램에서 발생하는 문제의 오류

ㄴ문법적인 오류: 문법이 틀려서 빌드가 안됨

ㄴ논리적인 오류: 문법은 맞지만 실행했을 때 문제

 

문법적인 오류 -> 오류

논리적인 오류 -> 예외

 

#include <iostream>

using namespace std;

int main() {
  try {
    int input;
    cout << "정수 중 하나를 입력하세요 : ";
    cin >> input;

    // 입력받은 숫자가 양수이면
    if (input > 0) {
      cout << "throw 1" << endl;
      throw 1;      // 예외 1 발생(정수 형식 예외)
      cout << "after throw 1" << endl;
    }

    // 입력받은 숫자가 음수이면
    if (input < 0) {
      cout << "throw -1.0f" << endl;
      throw - 1.0f;   // 예외 1.0f 발생(부동소수점 형식 예외)
      cout << "after throw -1.0f" << endl;
    }

    // 입력받은 숫자가 0이면
    if (input == 0) {
      cout << "throw Z" << endl;
      throw 'Z';    // 예외 Z 발생(문자 형식 예외)
      cout << "after throw Z" << endl;
    }
  }
  catch (int a) {   // 정수 형식 예외 받기
    cout << "catch " << a << endl;
  }
  catch (float b) {   // 부동소수점 형식 예외 받기
    cout << "catch " << b << endl;
  }
  catch (char c) {   // 문자 형식 예외 받기
    cout << "catch " << c << endl;
  }

  return 0;
}

 

정수 중 하나를 입력하세요 : 0
throw Z
catch Z

 

#include <iostream>

using namespace std;

int main() {
  try {
    int input;
    cout << "정수 중 하나를 입력해보세요 : ";
    cin >> input;

    // 입력받은 숫자가 양수이면
    if (input > 0) {
      cout << "throw 1" << endl;
      throw 1;   // 예외 1 발생(정수 형식 예외)
    }

    // 입력받은 숫자가 음수이면
    if (input < 0) {
      cout << "throw -1.0f" << endl;
      throw - 1.0f;   // 예외 1.0f 발생(부동소수점 형식 예외)
    }

    // 입력받은 숫자가 0이면
    if (input == 0) {
      cout << "throw Z" << endl;
      throw 'Z';   // 예외 Z 발생 (문자 형식 예외)
    }
  }
  catch (int a) {   // 정수 형식 예외 받기
    cout << "catch " << a << endl;
  }
  catch (...) {   // 처리되지 않은 나머지 예외 모두 받기
    cout << "catch all" << endl;
  }

  return 0;
}

 

정수 중 하나를 입력해보세요 : 1
throw 1
catch 1

 

예외 전달 동작 확인

#include <iostream>

using namespace std;

void func_throw() {
  cout << "func_throw()" << endl;
  cout << "throw -1" << endl;
  throw - 1;   // 정수 형식 예외 던지기
  cout << "after throw -1" << endl;
}

int main() {
  try {
    func_throw();
  }
  catch (int exec) {   // 정수 형식 예외 받기
    cout << "catch " << exec << endl;
  }

  return 0;
}

 

func_throw()
throw -1
catch -1

 

예외가 발생하면(throw),

어딘가에서는 catch를 해줘야 함

 

스택 풀기: 함수에서 예외가 처리되지 않아서 함수를 호출한 쪽으로 전달되는 현상

 

#include <iostream>

using namespace std;

void func_throw() {
  cout << endl;
  cout << "func_throw() 함수 내부" << endl;
  cout << "throw -1" << endl;
  throw - 1;   // 정수 형식 예외 던지기
  cout << "after throw -1" << endl;
}

void func_2() {
  cout << endl;
  cout << "func_2() 함수 내부" << endl;
  cout << "func_throw() 호출" << endl;
  func_throw();
  cout << "after func_throw()" << endl;
}

void func_1() {
  cout << endl;
  cout << "func_1() 함수 내부" << endl;
  cout << "func_2() 호출" << endl;
  func_2();
  cout << "after func_2()" << endl;
}


int main() {
  cout << "main 내부" << endl;

  try {
    cout << "func_1() 호출" << endl;
    func_1();
  }
  catch (int exec) {   // 정수 형식 예외 받기
    cout << endl;
    cout << "catch " << exec << endl;
  }

  return 0;
}

 

main 내부
func_1() 호출

func_1() 함수 내부
func_2() 호출

func_2() 함수 내부
func_throw() 호출

func_throw() 함수 내부
throw -1

catch -1

 

함수 호출 순서: main -> func_1() -> func_2() -> func_throw()

 

 

어설션을 이용한 예외 처리

어설션: 코드를 검증하여 예상치 못한 상황에서 프로그램 동작을 중단 시키는 도구

안정성, 신뢰성 향상

 

#include <iostream>
#include <cassert>  

using namespace std;

void print_number(int* _pt_int) {
  assert(_pt_int != NULL);
  cout << *_pt_int << endl;
}

int main() {
  int a = 100;
  int* b = NULL; //아직 값이 없음, 이라고 명시한 것
  int* c = NULL; //Python의 None과 유사

  b = &a;
  print_number(b); // 주소를 전달

  // c는 NULL인 상태로 인자 전달
  print_number(c);

  return 0;
}

100
Assertion failed: _pt_int != NULL

 

assert를 이용해 프로그램의 특정 지점에서 true로 예상되는 조건을 지정

만약 지정한 조건이 true가 아니면 프로그램 실행이 중단

어셜선 실패 대화상자가 나타나 문제 발생을 알려줌

 

 

noexcept: 예외 처리 생략

ex) 함수가 예외를 던지지 않음을 명시

int func(0 noexcepy

ex) 함수가 예외를 던지는지 확인

bool does_not_throw = noexcept(my_function());

 

set_terminate:  예외 처리 실패 대응

ex) 종료 처리 함수 설정

set_terminate(종료_처리_함수);

#include <iostream>
#include <cstdlib>  // exit와 set_terminate 함수 사용을 위해 추가

using namespace std;

// 종료 처리 함수 
void myterminate() {
  cout << "myterminate called" << endl;
  exit(-1);      // 프로그램을 비정상적으로 종료
}

int main(void) {
  set_terminate(myterminate);    // 종료 처리 함수를 myterminate로 지정

  throw 1;    // 처리되지 않는 예외를 던짐

  return 0;   // 이 줄은 실행되지 않음, 위에서 예외가 던져졌기 때문
}

 

 

 

객체지향과 클래스

 

프로그램 패러다임: 프로그램을 어떤 절차와 구조로 만들 것인지에 대한 스타일이나 접근 방법을 나타냄

비구조적 프로그래밍: 코드를 구조화하지 않고 작성하는 방법

절차적 프로그래밍: 소스 코드를 여러 부분으로 나눠서 활용하는 패러다임, 프로시저를 이용해 구조화하는 방식(모듈화)

 

하향식: 절차적 프로그래밍은 프로그래밍이 수행할 기능을 프로시저 단위로 쪼개 문제를 해결하는 방법

상향식: 객체지향 프로그래밍은 객체라는 논리적 단위를 먼저 정의 후 이를 조합해 프로그램이 수행할 기능을 만드는 방법

 

객체지향 프로그래밍: 객체라는 논리적인 개념으로 코드를 구성하는 것

ㄴ현실 모델링

ㄴ논리적 계층 관계 표현

ㄴ접근 제어

 

객체지향 프로그래밍 특징

ㄴ추상화: 어떤 부류에서 불필요한 요소는 배제하고 공통된 특징만 추출하는 것

ㄴ캡슐화: 복잡한 내부 기능을 묶어 외부에서 불필요한 정보를 감춘느 것

ㄴ상속성: 부모 객체의 특성을 이어받는 것

ㄴ다형성: 상속 관계의 객체에서 같은 기능(함수)이 다르게 동작하는 특성