중간고사 핵심 정리 (C++)
PDF 강의자료(형광펜 표시 부분) + 녹음본 교수님 지시사항 완전 통합 정리
📘 PART 1. 제어문 (Chapter 3~4)
1. if ~ else if ~ else 복합문 (예제 3_3.cpp)
#include<iostream>
using namespace std;
int main() {
int a;
cout<<"a=>?";
cin>>a;
if(a>0)
cout<<a<<"=>양수"<<endl; // 단문 (블록 생략 가능)
else if(a<0)
cout<<a<<"=>음수"<<endl;
else
cout<<a<<"=>영"<<endl;
}
- 단문이면
{}생략 가능 - 조건이 여러 개면
else if로 연쇄
2. switch ~ case (예제 3_5.cpp) ⭐ 교수님: "최소한 이 정도는 짜야 함"
switch(num) {
case 1: cout<<"one"<<endl;
break;
case 2: cout<<"two"<<endl;
break;
case 3: cout<<"three"<<endl;
break;
default: cout<<"3이상의 값"<<endl;
}
break없으면 다음 case로 떨어짐 (fall-through)default는 어떤 case에도 안 걸릴 때
3. for문 (예제 3_7.cpp) — 1~10 합
int i, sum;
for(i=1, sum=0; i<=10; i++)
sum += i;
cout<<"total_sum:"<<sum<<endl; // 55
형식: for(초기식; 조건식; 증감식)
4. while문 (예제 3_10.cpp)
int counter;
cin>>counter;
while(counter>0) {
cout<<"Hello!"<<endl;
counter--;
}
cout<<"counter is output:"<<counter; // 0
- 조건 먼저 검사 → 0회 실행 가능
5. do ~ while문 (예제 3_11.cpp)
int num = 1, sum = 0;
do {
sum += num;
cout<<"num:"<<num<<"\t"<<"sum:"<<sum<<endl;
} while(num++ < 10);
- 최소 1회는 반드시 실행
- 조건 뒤에
;필수 num++ < 10: 비교 먼저, 그 다음 증가
6. break문 (예제 3_12.cpp)
- 반복문/switch를 빠져나감 (현재 속해있는 문장만)
- for, while, do~while, switch에서 사용
for(num=1, sum=0; num<=10; num++) {
sum += num;
if(num == 8) break; // num==8일 때 for문 탈출
}
// 결과: num=8, sum=36
7. continue문 (예제 3_14.cpp)
- 이후 문장은 건너뛰고 조건식 재평가 (반복문 전용)
for(num=1, sum=0; num<11; num++) {
if((num==4) || (num==5))
continue; // 4, 5는 더하지 않음
sum += num;
}
// 결과: num=11, sum=46 (1+2+3+6+7+8+9+10)
📍 제어문 실습문제 Q.1 ~ Q.8 (11~12p)
Q.1 — 두 정수 교환 (q_1.cpp)
int num_1, num_2, temp;
cin >> num_1 >> num_2;
temp = num_1;
num_1 = num_2;
num_2 = temp;
Q.2 — 실행결과 예측
int a=1, b=1, c;
if (c = (a - b)) // c = 0 → 거짓
cout << "The value of c is : " << c;
// 출력 안 됨 (대입문 결과 0이 조건식이 됨)
Q.3 — 입력값의 배수를 0~100까지 출력 (for문)
int num; cin >> num;
for(int i=0; i<=100; i+=num)
cout << i << endl;
Q.4 — 구구단 (한 줄에 3개씩, q_4.cpp)
for(int i=1; i<=9; i++) {
cout << num << "*" << i << "=" << num*i << "\t";
if((i%3) == 0) cout << endl; // 3개마다 줄바꿈
}
Q.5 — while 이중문 1단~9단 가로 배열 (q_5.cpp)
int i, j = 0;
while(++j <= 9) {
i = 0;
while(i++ < 9)
cout << i << "*" << j << "=" << i*j << "\t";
cout << endl;
}
Q.6 — 1~30 홀수, 5의 배수 제외, 한 행에 4개 (q_6.cpp)
int num = 0;
for(int i=1; i<=30; i+=2) {
if((i%5) == 0) continue;
else {
num++;
if((num%4) == 0) {
cout << i << endl; // 4번째면 줄바꿈
num = 0;
}
else cout << i << "\t";
}
}
Q.7 — do~while로 입력값보다 작은 3의 배수 (q_7.cpp)
int a = 0, num;
cin >> num;
do {
a++;
if((a%3) == 0) cout << a << "\t";
} while(a < num);
Q.8 — do~while로 1+2+...+n=합 출력 (q_8.cpp)
int sum=0, i=0, num;
cin >> num;
do {
i++;
sum += i;
} while(i < num);
cout << "1+2+...+" << num << "=" << sum << endl;
📍 중첩 반복문 (33p) ⭐⭐
교수님: "포문으로 이렇게도 해보고 이렇게도 해보고 — 너네 시험문제야. 파일(for)운영에서 이렇게도 해보고, while문에서 이렇게도 해보자"
출력 형태 1 (한 단씩 가로):
2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12
3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18
...
출력 형태 2 (같은 번째끼리 가로):
2*1=2 3*1=3 4*1=4 5*1=5 6*1=6 7*1=7 8*1=8 9*1=9
2*2=4 3*2=6 4*2=8 5*2=10 ...
...
→ 이중 for / 이중 while 둘 다로 각 형태를 짤 수 있어야 함
📗 PART 2. 함수 (Chapter 5~6)
1. 함수 사용의 장점
- 모듈화 가능 → 이해 용이
- 잘못된 부분 수정·변경 용이
- 자주 쓰는 기능을 재사용 → 반복 프로그램 회피
2. 함수의 종류
- 표준 C++ 라이브러리 함수 (시스템 표준함수, 내장함수)
- 컴파일러가 자체 제공,
#include로 포함 - 예:
strlen()(문자열 길이)
- 컴파일러가 자체 제공,
- 사용자 정의 함수: 사용자가 필요에 따라 코딩
3. 함수 작성 3요소 (Main Point!) ⭐
- 함수 정의: 실제 기능 작성부
- void형 함수 (리턴값 없음)
- 리턴값 있는 함수
- 함수 원형 (prototype): 컴파일러에게 함수 인터페이스 알려줌 (세미콜론
;필수) - 함수 호출: 작성된 함수 호출
📍 인수 있고 리턴값 없는 함수 (ex4.cpp)
교수님: "리턴값 있게도, 없게도 둘 다 짜보세요"
#include<iostream>
using namespace std;
void add(int, int); // 프로토타입
void main() {
int a, b;
cout<<"정수1,2 입력 :";
cin>>a>>b;
add(a, b); // 호출
}
void add(int a, int b) { // 정의
cout<<"a+b="<<a+b<<endl;
}
📍 리턴값 있는 함수 — 절대값 (ex6.cpp)
int abst(int x); // 세미콜론 주의
int main() {
int num, result;
cin >> num;
result = abst(num);
cout<<"입력된 수의 절대값:"<<result<<endl;
}
int abst(int x) {
if (x >= 0) return (x);
else return (-x);
}
📍 Call by Address — swap (ex10.cpp)
void swap(int *a, int *b);
int main() {
int a, b;
a = 100; b = 200;
cout<<"Before:"<<a<<"\t"<<b<<endl;
swap(&a, &b); // 주소 전달
cout<<"After:"<<a<<"\t"<<b<<endl;
}
void swap(int *x, int *y) {
int z;
z = *x;
*x = *y;
*y = z;
}
// Before: 100 200 → After: 200 100
📍 재귀적 호출 함수 (ex11.cpp, 14p) ⭐⭐
정의: 한 함수가 자기 자신을 호출하는 형태
- 장점: 프로그램 단순화 (변수 수 적음)
- 단점: 값 보관용 스택 필요 → 메모리 낭비
int factorial(int p) {
if (p==1) return 1;
else return (p * factorial(p-1));
}
// 5! = 120
🎯 시험 응용 (교수님 구두 예고):
입력 5 →
입력 3 →
→ factorial이 아닌 "다른 계산"을 재귀로 짜게 할 것
입력 5 →
1 + (1+2) + (1+2+3) + (1+2+3+4) + (1+2+3+4+5)입력 3 →
1 + (1+2) + (1+2+3)→ factorial이 아닌 "다른 계산"을 재귀로 짜게 할 것
📍 구구단 함수 — 한 번에 2단씩 묶어 출력 (ex13.cpp)
출력: 2단+3단 묶어 → 4단+5단 묶어 → 6단+7단 → 8단+9단
void gugudan(int);
int main() {
for(int dan=2; dan<=9; dan+=2) {
gugudan(dan);
cout<<endl;
}
}
void gugudan(int i) {
for(int k=1; k<=9; k++) {
for(int a=i; a<=i+1; a++) {
cout<<a<<"*"<<k<<"="<<a*k<<"\t";
}
cout<<endl;
}
}
📍 함수 오버로딩 (Overloading, 16p) ⭐⭐
정의: 같은 이름의 함수를 여러 개 사용
조건: 이름은 같고 매개변수의 타입이나 개수가 달라야 함
✅ 올바른 사용 예
// 타입이 다름
int func(int a) { /* 함수 몸체 */ }
int func(float b) { /* 함수 몸체 */ }
// 개수가 다름
int func2() { /* 함수 몸체 */ }
int func2(char *str, int x) { /* 함수 몸체 */ }
❌ 틀린 사용 예 (시험 단골 함정)
int func(int a) { /* 함수 몸체 */ }
void func(int b) { /* 함수 몸체 */ }
→ 매개변수가 같으면 리턴타입이 달라도 오버로딩 X
📍 선행처리기 (Pre-processor, 20p~)
컴파일 이전에 먼저 실행되는 것
종류: #define, #include, #undef 등
5.1 #include
#include <iostream.h> // 기본 include 폴더
#include "myheader.h" // 현재 폴더
#include "c:\Cplus\header\myheader.h" // 경로 지정
5.2 #define 매크로
#define EOF (-1)
#define TRUE 1
#define FALSE 0
#define PI 3.141592
#define SIZE 10
5.2.3 const 상수
- 프로그래머에게 변경할 것/하지 말 것을 구분
- C++ 프로젝트에 안전성과 제어 제공
📊 매크로 상수 vs const 상수 비교
| 매크로 상수 | const 상수 |
|---|---|
#define PI 3.141592 | const double PI=3.141592; |
#define EOF (-1) | const int EOF=-1; |
#define TRUE 1 | const int TRUE=1; |
#define FALSE 0 | const int FALSE=0; |
#define SIZE 10 | const int SIZE=10; |
🎯 시험 예상 문제 (교수님 명시)
"PI 값 3.141592로 정의 후, 원의 면적과 둘레를 구하는 프로그램을 두 가지로 작성"
"PI 값 3.141592로 정의 후, 원의 면적과 둘레를 구하는 프로그램을 두 가지로 작성"
- ① 매크로 상수 이용
- ② const 상수 이용
녹음본: "매크로 다음에 상수 오면 → 매크로 상수",
"매크로 다음에 함수 오면 → 매크로 함수"
📕 PART 3. 배열과 포인터 (Chapter 3.5, 4.5)
1. 배열 선언·초기화·순회
// 1차원 배열
int str[5] = {10, 20, 30, 40, 50};
int i;
for(i=0; i<5; i++)
cout << "str[" << i << "]:" << str[i];
// 입력받는 1차원 배열
int str[10];
for(i=0; i<10; i++)
cin >> str[i];
2. 2차원 배열 (a[3][4])
메모리 구조 (12칸):
| 인덱스 | 값 |
|---|---|
| a[0][0]~a[0][3] | 1, 2, 3, 4 |
| a[1][0]~a[1][3] | 5, 6, 7, 8 |
| a[2][0]~a[2][3] | 9, 10, 11, 12 |
// 초기화 + 출력
int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int i, j;
for(i=0; i<3; i++)
for(j=0; j<3; j++) // ※ PDF 원본에 j<3으로 적혀있음
cout<<"a["<<i<<"]["<<j<<"]:"<<a[i][j];
// 입력받는 2차원 배열
int a[3][4];
for(i=0; i<3; i++)
for(j=0; j<3; j++)
cin >> a[i][j];
🎯 시험 응용: "2개로 출력하던 걸 4개로 출력해보세요"
→ 같은 배열을 한 행 2개씩 / 4개씩 둘 다 출력할 수 있어야 함
→ 같은 배열을 한 행 2개씩 / 4개씩 둘 다 출력할 수 있어야 함
3. 3차원 배열 (a[2][3][2])
메모리 구조 (24칸):
a[0][0][0]=1 a[0][0][1]=2 a[0][0][2]=3 a[0][0][3]=4
a[0][1][0]=5 a[0][1][1]=6 ...
...
a[1][2][3]=24
int a[2][3][2] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int i, j, k;
for(i=0; i<2; i++)
for(j=0; j<3; j++)
for(k=0; k<2; k++) {
cout<<"a["<<i<<"]["<<j<<"]["<<k<<"]:"<<a[i][j][k];
cin >> a[i][j][k];
}
4. char 배열과 문자열 (ex4_4.cpp)
char buffer[10];
cout << "Enter the string: ";
cin >> buffer; // 공백 전까지만 입력
cout << "Here's the buffer: " << buffer << endl;
// "Seoul University" 입력 → "Seoul"만 저장 (공백 무시)
// "ABCDEFGHI" 입력 → "ABCDEFGHI" 그대로
5. 1차원 배열과 포인터의 관계 (12p)
주소 값 배열 포인터
1000 10 a[0] ←─ *a (= *(a+0))
1004 20 a[1] ←─ *(a+1)
1008 30 a[2] ←─ *(a+2)
1012 40 a[3] ←─ *(a+3)
1016 50 a[4] ←─ *(a+4)
🔑 핵심 등식 (반드시 암기)
| 배열 표기 | 포인터 표기 |
|---|---|
a[i] | *(a+i) |
&a[i] | (a+i) |
a (배열명) | 첫 원소의 주소 = 포인터 |
int a[5] = {10, 20, 30, 40, 50};
int i;
cout<<"a["<<i<<"]:"<<a[i]<<endl;
cout<<"*(a+"<<i<<"):"<<*(a+i)<<endl; // 같은 결과
녹음본: "A라는 배열은 원래 A라는 포인터였어요"
6. 동적 메모리 (ex4_10.cpp)
교수님: "동적 메모리 빼고는 (변수명) 바꿔놓으세요"
→ 동적 메모리 문제는 거의 원본 그대로 나올 가능성
→ 동적 메모리 문제는 거의 원본 그대로 나올 가능성
#include<iostream>
using namespace std;
int main() {
char *str;
str = new char[10]; // 동적 할당
if(str != NULL) {
cout<<"str=>?";
cin>>str;
}
else {
cout<<"Memory is lack!."<<endl;
exit(1); // 메모리 부족 시 종료
}
cout<<"str="<<str<<endl;
delete str; // 해제 필수
}
키워드: new로 할당, delete로 해제, NULL 체크, exit(1)
🎯 시험 범위 요약표
| 영역 | 시험 | 비고 |
|---|---|---|
| switch~case | ⭕ | 10p, 최소한 짜야 함 |
| for / while / do~while | ⭕ | 각각 구별해서 사용 |
| break / continue | ⭕ | 차이 정확히 |
| 이중 for / 이중 while 구구단 | ⭕⭐ | 33p, 두 형태 둘 다 |
| 재귀 호출 | ⭕⭐ | 14p, factorial 변형 |
| 함수 오버로딩 | ⭕⭐ | 16p, 정의·예시 |
| 매크로 상수 vs const 상수 | ⭕⭐ | 원 면적·둘레 |
| Call by Address (swap) | ⭕ | 포인터 활용 |
| 1차원 배열 (대입/입력/출력) | ⭕ | |
| 2차원 배열 (대입/입력/출력) | ⭕ | 2개/4개씩 출력 |
| 3차원 배열 (대입/입력/출력) | ⭕ | |
| 3차원 포인터 | ❌ | "나가거든(=빼고) 내고요" |
배열 ↔ 포인터 (a[i] = *(a+i)) | ⭕ | |
| 동적 메모리 (new/delete) | ⭕ | 거의 원본 그대로 |
| 함수 프로토타입·종류·작성 3요소 | ⭕ | 개념 설명 |
⚠️ 시험 직전 최종 당부 (녹음본 직접 인용)
"한두 문제는 조금 바꿔서 낼게요, 한두 문제는 똑같이 낼게요"
"이 문제보다 다른 사람이 짤 수 있어야 돼요. 정확히 이 문제를 여러분이 알고..."
"심볼(변수명)은 바꿔야 돼요. 안 바꾸고 (카톡 예제 그대로) 그거는 죽을 줄 알아"
"이거 못 짜면 바보야" (1/2/3차원 배열 입출력)
"나는 기말 나쁜 사람들 점수 올려주는데 사용한다고 해서요" (오버로딩 정의 등 이론 문제)
핵심 전략
- 예제 코드는 변수명 바꿔서 재작성 연습
- 같은 결과를 다른 반복문(for↔while)으로 옮겨 짜는 연습
- 개념 문제 대비: 오버로딩 정의, 함수 3요소, 매크로 vs const, 재귀 장단점
시험 잘 보세요! 💪
No cross, no crown.