물 한 잔을 따르거나, 휴대폰에서 사진을 찾는 것처럼 우리가 일상에서 당연히 여기는 행동 뒤에는 수많은 문제 해결의 논리가 숨어 있습니다. 프로그래밍도 마찬가지입니다. 단순히 코드를 줄줄 쓰는 게 아니라, 무엇을, 어떻게 해결할 것인가를 고민하는 일이죠.
이때 프로그래머의 가장 강력한 도구가 바로 자료구조와 알고리즘입니다.
자료구조란? 데이터를 저장하고 정리하는 방식을 의미합니다.
전화번호부처럼 순서대로 정렬된 배열
브라우저 ‘뒤로가기’처럼 마지막부터 꺼내는 스택
지하철 노선도처럼 연결된 그래프
이처럼 자료구조는 데이터를 빠르고 효율적으로 꺼내 쓰기 위한 정리 방법입니다.
알고리즘이란? 문제를 해결하기 위한 절차, 단계의 집합을 의미합니다. 예를 들어
가장 저렴한 항공권을 찾을 때?
장바구니에서 총 금액을 계산할 때?
모두 정해진 규칙에 따라 계산되고 정렬됩니다. 이 규칙이 바로 알고리즘입니다.
그럼 우리는 좋은 프로그래밍을 하기 위해 왜 자료구조와 알고리즘을 배워야할까요?
첫째로, 이는 수십 년간 쌓인 모범 사례이기 때문입니다. 우리가 겪는 대부분의 문제는 이미 누군가 비슷한 문제를 만나 효율적으로 푼 경험이 있습니다. 자료구조와 알고리즘은 그 정리된 해법입니다.
둘째로, 문제를 해결하는 시야를 키울 수 있기 때문입니다. 처음 보는 문제도 어떤 구조로 풀면 좋을지 감이 생기고 해결 실마리를 빠르게 떠올릴 수 있게 됩니다.
세번째로, 프로그래머의 기본 체력이 되기 때문입니다. 아무리 도구나 언어가 바뀌어도 결국 성능과 확장성을 좌우하는 건 기초 실력입니다.
자료구조와 알고리즘을 공부하려면 당연히 이것들을 코드로 구현할 수 있어야 합니다. 그때 필요한 게 바로 프로그래밍 언어, 그리고 그중 하나가 C++입니다.
C++은 직접 메모리를 다룰 수 있는 저수준의 언어로 배열, 포인터, 동적 할당 같은 개념을 통해 데이터가 어떻게 저장되고 이동하는지 이해할 수 있습니다. 이런 저수준 개념을 알면, 자료구조를 더 깊이 있게 공부할 수 있습니다.
알고리즘은 이론이 아니라 실행 가능한 절차입니다. 알고리즘은 단지 머릿속 아이디어에 머물지 않고 프로그래밍 언어로 구현되어야 실제로 동작합니다. 이를 통해 시간 복잡도, 공간 복잡도 같은 성능 분석도 가능해지죠.
영어로 글을 쓰기위해서는 알파벳과 문법을 알아야 하듯이, 프로그래밍을 위해선 프로그래밍 언어의 기초 문법을 충분히 숙지할 수 있어야합니다.
변수: 데이터를 저장하는 이름이 붙은 메모리 공간
자료형: 해당 공간에 무슨 종류의 데이터를 담을지를 정함
int age = 20; // 정수형 변수
double height = 172.5; // 실수형 변수
char grade = 'A'; // 문자형 변수
bool isPassed = true; // 참거짓 값 저장
여기서 특히 주의해야할 점은 C++에선 변수를 선언하고 초기값을 넣지 않으면 메모리의 쓰레기값이 들어가게 됩니다.
int a; // 초기화하지 않은 변수는 위험 → 예측 불가한 동작 초래
nt a = 0; // 항상 초기화 습관 들이기 → 안정적인 코드 작성의 기본!
변수명은 숫자로 시작 ❌, 공백 포함 ❌
의미 없는 변수명 ❌, 명확한 의미의 이름 사용 ✅
자료형(type)에 따라 계산 방식 다름 → 타입 혼동 주의 필요 ✅
추가적으로, 다음과 같은 성격의 자료형도 C++에선 구현할 수 있습니다.
const int maxScore = 100; // 절대 바뀌지 않는 점수 한도
auto price = 19.99; // 자료형은 double로 자동 추론됨
const: 한 번 값이 들어가면 변경 불가한 상자 (즉, 상수)
auto: 컴파일러가 자료형을 자동으로 추론
입력(Input): 사용자가 컴퓨터에 값을 전달하는 것
→ 우리가 키보드로 숫자나 글자를 입력하면, 컴퓨터는 그걸 변수에 저장함
cin >> 변수명;
출력(Output): 컴퓨터가 결과나 메시지를 화면에 보여주는 것
→ 계산 결과나 메시지를 화면에 출력하는 것
cout << 출력할_내용;
줄바꿈의 경우 다음과 같은 두가지 문법이 사용됩니다.
구분 | 설명 | 예시 |
---|---|---|
endl | 줄을 바꿈 + 출력 버퍼를 비움 (느림) | cout << "Hello" << endl; |
\n | 줄을 바꿈만 함 (빠름) | cout << "Hello\n"; |
아래와 같이 한 줄에 여러 값을 입력받을 수도 있습니다.
int a, b;
cin >> a >> b;
또한 cin은 공백을 기준으로 끊게 되는데 공백을 포함해서 입력받고 싶다면 getline() 함수를 사용하면 됩니다.
string sentence;
getline(cin, sentence);
조건문은 상황에 따라 다르게 동작하도록 코드를 제어하는 구조입니다.
int score;
cin >> score;
if (score >= 90) {
cout << "A학점입니다.";
} else if (score >= 80) {
cout << "B학점입니다.";
} else {
cout << "C학점입니다.";
}
if (조건)에서 괄호 { } 생략 ❌ → 복잡한 코드에서 실수 발생
코드 블록이 여러 줄일 땐 반드시 { } 사용 ✅
할당 연산자 = vs 비교 연산자 == 혼동 ❌ → 논리 오류 발생
int menu;
cin >> menu;
switch (menu) {
case 1:
cout << "커피를 선택했습니다.";
break;
case 2:
cout << "녹차를 선택했습니다.";
break;
default:
cout << "잘못된 선택입니다.";
}
switch는 정수, 문자, 열거형 등 정해진 값 비교에 적합하며 break를 써야 선택한 case만 실행하고 종료됩니다.
조건을 잘못 쓰면 무한 루프 발생 ❌ → 무한 루프 위험
인덱스 범위 초과 주의 ❌ → 배열 사용 시 유효 범위 벗어나면 오류
반복문은 같은 작업을 여러 번 반복할 때 사용합니다.
for (int i = 0; i < 5; i++) {
cout << i << " ";
}
조건을 잘못 쓰면 무한 루프 발생 ❌
인덱스 범위 초과 주의 ❌
int i = 0;
while (i < 5) {
cout << i << " ";
i++;
}
조건을 잘못 쓰면 무한 루프 발생 ❌
조건을 항상 참으로 설정하면 무한 루프 발생 ❌ → 종료 조건 반드시 넣기! ✅
i++ 누락 시 무한 루프 발생 ❌
인덱스 범위 초과 주의 ❌
int i = 0;
do {
cout << i << " ";
i++;
} while (i < 5);
break과 continue를 활용하면 더 복잡한 반복문을 만들 수 있습니다.
키워드 | 설명 | 예시 |
---|---|---|
break | 반복문을 즉시 종료 | if (조건) break; |
continue | 이번 반복만 건너뛰고 다음으로 | if (조건) continue; |