2026-03-04 TIL (7일차)
C++ 강의 (1주차)
1주차 강의
● Visual Studio의 파일의 의미구분 기능 리소스 파일 코드를 구현할 때 필요한 외부파일 소스 파일 코드 구현 및 main 함수 헤더 파일 클래스,함수의 선언 ● string 입력 출력 차이
cin » name: 공백(Space), 탭(Tab), 엔터(Enter)를 모두 데이터를 나누는 벽으로 봅니다. 중요한 건, 이 벽을 만나면 데이터만 쏙 가져가고 벽(\n 등)은 버퍼에 그대로 남겨둡니다.
getline(cin, name): 엔터(Enter, \n)만 유일한 벽으로 인정합니다. 얘는 벽을 만나면 벽까지 같이 치워버립니다. 즉, 버퍼에서 엔터 문자까지 싹 비우지만, 변수(name)에는 엔터를 제외한 내용만 담습니다.
비교항목 cin » name getline(cin, name) 종료 조건 공백, 탭, 엔터 중 하나라도 만나면 종료 엔터(\n)를 만날 때만 종료 버퍼의 엔터(\n) 버퍼에 그대로 남겨둠 버퍼에서 읽어서 버림 (소모함) 선행 공백 데이터 앞의 공백/엔터는 무시하고 건너뜀 앞의 공백/엔터도 데이터로 간주하여 읽음 주요 용도 단어나 숫자 위주의 간단한 입력 문장 전체(공백 포함)를 입력받을 때 1 2 3 4 5
int age; string name; cin >> age; // 25 입력 후 엔터! -> 버퍼에는 [25][\n]이 있음. 25만 가져가고 [\n] 남음. getline(cin, name); // 버퍼에 남은 [\n]을 보고 "어? 엔터네? 입력 끝!"이라며 빈 문자열을 가져감.
1 2 3 4 5 6
string name, city; cout << "이름 입력: "; cin >> name; // "kim tae young" 입력 cout << "도시 입력: "; cin >> city; // 사용자가 입력할 기회도 없이 "tae"가 들어가 버림!
★혼자 과제: for문을 이용하여 다양한 별 찍기 구현해보기
● char포인터의 주소값 출력시 문자가 나오는 이유
cout 기능 때문에 들어오는 데이터의 타입에 따라 행동을 바꿉니다.
char* (문자 포인터) 받으면 “오! 이건 문자열의 시작점으로 인지해서 끝(\0)이 나올 때까지 글자들을 다 화면 출력하게 됩니다.
즉, 주소값으로 강제 변환해줘야 합니다.1 2
// (void*)로 형변환(Casting)을 해주면 주소값이 나옵니다! cout << "ptr2 주소: " << (void*)ptr2 << endl;
● 반복 내용: 배열은 buf[k] == *(buf+k) 이렇게 표현가능하다
배열 첨자는 배열만 사용할 수 있는게 아니라 포인터도 사용가능하다 (자료형 만큼 주소를 이동을 할 수 있어서)● 중복정의
1) 한 파일 내에서 똑같이 두 번 만들 때
문제점: 컴파일러가 함수를 호출할 때 결정을 못합니다.1 2
void Attack() { cout << "칼 휘두르기"; } void Attack() { cout << "마법 쏘기"; } // ❌ 에러: 'Attack' 이미 정의됨
2) 헤더에 있는데 파일에서 또 만들 때
문제점: #include는 단순히 그 파일의 내용을 복사해서 붙여넣는거라서 1번 케이스와 똑같은 상황이 됩니다.1 2 3 4 5 6
// MyHeader.h void Move() { ... } // main.cpp #include "MyHeader.h" // 여기서 Move()가 이미 한 번 들어옴 void Move() { ... } // ❌ 에러: 위에서 들어온 Move와 중복됨
3) 헤더에 구현하고 여러 CPP에서 부를 때
문제점: LNK2005 각각의 .cpp 파일을 컴파일할 때는 문제가 없지만, 나중에 하나로 합칠 때 Log()가 두 개라서 어떤 걸 연결하는지 몰라서 링커가 멈춥
헤더 파일을 포함하면 내용을 똑같이 복붙을 하는 개념이라 각각 cpp파일에 같은 정의된 함수가 또 생성이 되는 개념이라서 이름이 같은 함수가 생성되서 링커 에러가 발생한다.1 2 3 4 5 6 7
// Common.h void Log() { ... } // 몸통(구현)을 헤더에 적음 //밑에 2개의 cpp에서 헤더파일을 포함하게되면 // Player.cpp void Log() { ... }가 생성됨 // Monster.cpp void Log() { ... }가 생성됨
● 헤더 가드 헤더 파일이 여러 번 포함 Include되어 소스 코드가 꼬이는 것을 방지
구분 #ifndef #pragma once 작성법 3줄 (#ifndef, #define, #endif) 1줄 (#pragma once) 표준 여부 C++ 공식 표준 (모든 곳에서 돌아감 비표준 (하지만 모든 현대 컴파일러 지원) 위험성 이름 중복 시 파일 실종 가능성 있음 위험 없음 컴파일 속도 상대적으로 느림 상대적으로 빠름 알고리즘 기초 강의
● 시간 복자도 입력 크기(n) 가 커질 때, 연산 횟수가 어떻게 증가하는가?
● 코딩 테스트 팁 입력 수가 1억이 넘거나 10억이 넘어가면 돌리는 시간이 1초가 넘어가서 보통 1초안에 코테 실행이 끝나야 하는거
ex) 문제마다 제공해주는 값 범위를 기준으로 사용해야하는 시간복잡도
N의 최대 범위 허용 시간 복잡도 사용 가능한 알고리즘 및 팁 N<=10~15 O(N!), O(2^N) 완전 탐색 (Brute Force): 순열, 조합, 모든 경우의 수 다 해보기 N<=20~25 O(2^N) 백트래킹, 비트마스킹 DP: 모든 경우를 따지되 가망 없는 건 쳐내기 N<=500 O(N^3)$ 플로이드-워셜: 모든 지점에서 모든 지점으로 가는 최단 경로, 3중 반복문 N<=2000~5000 O(N^2) 이중 반복문 가능: 단순 DP, 버블/선택 정렬, 브루트 포스(일부) N<=100,000 O(N log N) 가장 중요한 구간: 정렬(Sort), 힙(Priority Queue), 이진 탐색, 세그먼트 트리 N<=1,000,000 O(N) 또는 O(N log N) 선형 탐색: 단일 반복문, 스택/큐, 투 포인터, 슬라이딩 윈도우 N>=10,000,000 $O(log N) 또는 O(1) 로그 시간: 이진 탐색(Binary Search), 수학적 공식, 유클리드 호제법 ● 시간 복자도 vs 공간복잡도
구분 시간 복잡도 (Time) 공간 복잡도 (Space) 핵심 질문 얼마나 오래 걸리는가? 메모리를 얼마나 먹는가? 측정 기준 연산 횟수 (반복문 횟수 등) 변수/배열의 크기 성능 목표 보통 1초당 1억 번 이하 보통 128MB ~ 512MB 이하 표기법 Big-O (O(N) 등) Big-O (O(N) 등) 최적화 팁 불필요한 반복문 줄이기, 정렬 활용 큰 배열 선언 주의, 재귀 깊이 조절