수업일: 2025-09-08
학습목표: C++의 기본 타입과 초기화, 포인터·레퍼런스 차이, string 기본 인터페이스를 이해하고 전형적인 함정을 피한다.
🎯 학습 목표 (Exam Scope)
- [ ] 객체/이름/주소 개념을 설명할 수 있다.
- [ ] 레퍼런스와 포인터의 차이를 표와 코드로 설명할 수 있다.
- [ ] 초기화 4종(=, (), {}, 디폴트) 차이를 말할 수 있다.
- [ ] const/constexpr와 포인터-상수 조합을 읽고 쓸 수 있다.
- [ ] auto/decltype의 추론 규칙(특히 decltype((x)))을 구분할 수 있다.
- [ ] string의 생성/길이/비교/입력(>> vs getline)을 다룰 수 있다.
- [ ] 부호 혼합 연산의 함정을 예로 설명할 수 있다.
🧠 큰 그림 요약
- 객체(object)=상자, 이름(identifier)=이름표, 주소(address)=좌표
- 레퍼런스=별명, 포인터=리모컨(주소 저장)
- 초기화는 복사(=)/직접(())/리스트({})/디폴트 구분
- const/constexpr: 읽기 전용 vs 컴파일타임 상수
- *auto*는 편의 추론(보통 const 제거), **decltype*은 표현식 타입 그대로
- string: 안전한 문자열, >>(단어) vs getline(한 줄)
1) 객체·이름·주소 (기초)
// 객체(object)=값을 담는 메모리 칸, 이름(identifier)=그 칸의 라벨, 주소(address)=칸의 좌표
int x = 10; // x라는 이름표가 붙은 정수 상자에 10 저장
int* px = &x; // &x: x의 주소(좌표)를 구함
std::cout << *px; // *px: 주소를 따라가 x의 '값'을 읽음 (10)
- [ ] &x는 주소, *px는 역참조(값 접근) 이라는 점을 혼동하지 않는다.
2) 레퍼런스 vs 포인터 (시험 단골)
✅ 한 장 요약 표
항목 레퍼런스(reference) 포인터(pointer)
| 정체 | 객체 아님(별도 저장공간 X), 기존 변수의 별명 | 객체(주소를 저장하는 변수) |
| 초기화 | 즉시 바인딩 필수 (int& r=a;) | 선언만 가능, 나중에 대입 가능 |
| 재바인딩 | 불가 (항상 같은 대상) | 가능 (p=&b; 로 대상 변경) |
| 널 | 없음 | nullptr 가능 |
| 연산 | 특별한 연산 거의 없음 | *(역참조), &(주소), 산술/비교 가능 |
| 용도 | 안전한 별칭(복사비용 없이 전달) | 저수준 제어(재지정/널/배열과 호환) |
예제
int a = 10;
// 레퍼런스: a의 '다른 이름'
int& r = a; // 반드시 즉시 초기화
r = 20; // a가 20으로 변함
// 포인터: a의 주소를 들고 다니는 '리모컨'
int* p = &a; // p 안에 a의 주소 저장
*p = 30; // a가 30으로 변함
p = nullptr; // 이제 아무 것도 가리키지 않음(null)
- [ ] int& r; 처럼 레퍼런스를 비워둘 수 없다(컴파일 에러).
- [ ] p 사용 전 p가 무엇의 주소인지를 확인하자
3) 초기화 4종 ( =, (), {}, default )
유형 예시 특징
| default | int x; | 지역변수는 미정의값(주의!), 전역/정적은 0 |
| 복사 | int x = 3; | 대입 형태 |
| 직접 | int x(3); | 생성자/형변환과 연계(클래스에서 중요) |
| 리스트 | int x{3}; | 좁은 변환 금지로 안전, 컨테이너 초기화에 좋음 |
int a; // (지역) 미정의 값 → 사용 금지!
int b = 0; // 복사 초기화
int c(0); // 직접 초기화
int d{0}; // 리스트 초기화(권장)
- [ ] 지역변수 디폴트 초기화의 미정의값을 시험에서 주의할 것.
4) const / constexpr & 포인터-상수 조합
int x = 1, y = 2;
const int* p1 = &x; // '가리키는 값'이 상수(읽기만), 포인터는 변경 가능
// *p1 = 3; // ❌ but, x = 3; 은 OK / x가 const int 가 되는 것은 아님
p1 = &y; // OK (*p1 = 2)
int* const p2 = &x; // '포인터 자체'가 상수(변경 불가), 값은 수정 가능
*p2 = 4; // OK
// p2 = &y; // ❌
const int* const p3 = &x; // 둘 다 상수
- [ ] const가 별(*) 오른쪽이면 대상이 상수, 식별자 옆이면 포인터 자체 상수
- [ ] constexpr int N = 10; 은 컴파일타임 상수로 배열 크기 등 정적 문맥에 사용.
5) auto / decltype (타입 추론 규칙)
const int ci = 42;
auto a = ci; // a는 int (보통 const 제거)
decltype(ci) b = 0; // b는 const int
int v = 0;
decltype((v)) r = v; // r은 int& ← 괄호로 '좌값 표현식'이 되어 참조 타입
- [ ] auto는 주로 상수성 제거, decltype은 표현식 그대로 보존.
- [ ] 함정: decltype((x))는 거의 항상 참조.
6) 부호/크기/형변환 (혼합 연산 주의)
unsigned u = 1;
int i = -2;
std::cout << (u > i) << "\\n"; // 보통 1(true): i가 unsigned로 승격되어 큰 값으로 비교됨
- [ ] 부호 있는/없는 정수 혼합 연산 금지(명시 캐스트로 타입을 맞추자).
- [ ] sizeof(T)로 타입 크기는 구현 의존임을 기억.
7) string 기본기 (>> vs getline)
#include <string>
#include <iostream>
using namespace std;
int main() {
string s1; // ""
string s2 = "hi"; // 복사 초기화
string s3("hi"); // 직접 초기화
string s4{5, 'x'}; // "xxxxx"
cout << s2.size() << "\\n"; // 길이(부호 없는 정수)
cout << boolalpha << s1.empty() << "\\n"; // true
string token, line;
cin >> token; // 공백 전까지 읽음
cin.ignore(numeric_limits<streamsize>::max(), '\\n'); // 남은 줄 비우기
getline(cin, line); // 공백 포함 한 줄 전체
}
- [ ] "text"는 const char[] 리터럴, string과 구분 (필요 시 암시 변환).
- [ ] >>는 토큰 단위, getline은 줄 단위.
8) 배열 ↔ 포인터 연결감 (기초)
int arr[3] = {10, 20, 30};
int* p = arr; // &arr[0]로 decay
std::cout << *(p + 1); // 20
- [ ] nullptr 역참조는 미정의 동작(금지).
9) 미니 실습 스니펫
(A) 레퍼런스/포인터 동작 감각 익히기
#include <iostream>
using namespace std;
int main() {
int a = 10;
int& r = a; // a의 별명
int* p = &a; // a의 주소
r = 20; // a=20
*p = 30; // a=30
int b = 99;
// r = b; // r을 b에 다시 붙이는 게 아님! (a=b와 동일 효과)
p = &b; // 포인터는 재지정 가능
cout << a << " " << *p << "\\n"; // 30 99
}
(B) 한 줄 입력 안전 패턴
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main() {
string token, line;
cout << "단어 하나: ";
cin >> token;
cin.ignore(numeric_limits<streamsize>::max(), '\\n'); // 버퍼 비우기
cout << "한 줄: ";
getline(cin, line);
cout << "[" << token << "] / [" << line << "]\\n";
}
🔎 예상문제 (Self-Check)
Q1. const int* p; vs int* const p; 차이?
정답: 전자는 대상 상수, 후자는 포인터 자체 상수.
Q2. 아래 출력이 true(1)인 이유?
unsigned u=1; int i=-2; cout << (u > i);
정답: i가 unsigned로 승격되어 큰 값으로 비교됨.
Q3. 컴파일 에러는?
int a=10;
int& r; // (A)
int* p; p=&a; // (B)
int& r2=a; // (C)
정답: (A) — 레퍼런스는 즉시 초기화 필요.
Q4. 공백 포함 한 줄 입력은?
정답: getline(cin, s).
Q5. 타입 추론 결과?
const int ci=0;
auto x=ci; // x: int
decltype(ci) y=1; // y: const int
int v=0; decltype((v)) z=v; // z: int& (괄호 때문에 참조)
🧪 한 화면 요약 (암기 포인트)
- 레퍼런스=별명(객체X), 포인터=리모컨(객체)
- (역참조)/&(주소)/nullptr 구분
- 초기화: 디폴트(미정의), 복사(=), 직접(()), 리스트({}=안전)
- const 위치로 의미 판별(대상 vs 포인터 자체)
- auto는 보통 const 제거, decltype은 그대로
- string: size(), empty(), 비교, +=, >> vs getline
- 부호 혼합 연산 주의(특히 unsigned ↔ int)
✅ 복습 체크리스트 (To-Do)
- [ ] 레퍼런스/포인터 표를 빈칸 없이 암기한다.
- [ ] {} 리스트 초기화 예시를 직접 타이핑해 본다.
- [ ] const+포인터 조합 3종을 스스로 선언/설명해 본다.
- [ ] decltype((x))가 참조가 되는 이유를 문장으로 설명해 본다.
- [ ] >> 뒤 getline 사용 시 ignore 패턴을 적용해 본다.
- [ ] unsigned/int 혼합 비교의 반례를 하나 만들고 설명한다.
'시험공부' 카테고리의 다른 글
| (2025-2) Introduction to programming(2) 3. Strings, Vectors, and Arrays (0) | 2025.12.18 |
|---|---|
| (2025-2) Introduction to programming(2) 4. Expressions & Statements (0) | 2025.12.18 |
| (2025-2) Introduction to programming (2) 1. Introcudtion (0) | 2025.12.18 |
| (2025-2) 서울과기대 현대사회와 철학 중간고사 정리 (0) | 2025.10.18 |
| (2025 - 1) 서울과기대 삶의 윤리학 중간고사 서술형 (0) | 2025.04.26 |