#include <iostream>
using std::cout;
using std::endl;
int Max(int i, int j)
{
return i>j ?i:j;
}
double Max(double i, double j)
{
return i>j ?i:j;
}
char Max(char i, char j)
{
return i>j ?i:j;
}
int main()
{
cout<< "Max값은=" << Max(1,2)<<endl;
cout<< "Max값은=" << Max(7.5,3.6)<<endl;
cout<< "Max값은=" << Max('A','B');
return 0;
}
을 템플렛 사용으로 바꿈 V
#include <iostream>
using std::cout;
using std::endl;
template <class T >T Max(T i, T j)
{
return i > j ? i : j;
}
int main()
{
cout << "Max값은=" << Max(1, 2) << endl;
cout << "Max값은=" << Max(7.5, 3.6) << endl;
cout << "Max값은=" << Max('A', 'B');
return 0;
}
눈에 보이는 소스는 줄어들지만 샐행 파일는 변화 없다.
제네릭 프로그래밍은 데이터 타입에 독립적인 알고리즘과 구조를 작성하여 코드의 재사용성을 높이는 프로그래밍 패러다임입니다. (자료형 나중에 걸정하는 방법)
template <typename T >T Max(T i, T j)
{}
template <class T >T Max(T i, T j)
{}
C++에서 템플릿을 만들 때 `typename`과 `class`는 거의 동일한 기능을 수행하지만, 일반적으로 다음과 같은 차이점이 있습니다:
1. **의미적 차이**: `typename`은 타입을 명시할 때 사용되며, 보다 명확하게 "타입"이라는 의미를 전달합니다. 반면, `class`는 클래스 타입을 나타내는 데 사용되며, 일반적으로 클래스에 대한 제너릭 타입을 정의할 때 사용됩니다.
2. **관습**: 템플릿 인자를 정의할 때는 `typename`을 사용하는 것이 더 일반적입니다. 특히, 여러 타입 인자를 사용하는 경우 `typename`을 선호하는 경향이 있습니다.
3. **특정 상황**: 특정 상황에서는 `class`를 사용해야 하는 경우도 있습니다. 예를 들어, 템플릿 특수화(template specialization)에서는 `class`만 사용 가능합니다.
결론적으로, 일반적인 경우에는 `typename`을 사용하는 것이 더 좋고, 코드의 의미를 명확히 할 수 있습니다. 그러나 두 키워드 모두 동일하게 작동하므로, 개인의 취향이나 팀의 코딩 스타일에 따라 선택할 수 있습니다.
typename(함수), class(클래스)를 사용할때 주로 사용<시험에 매년 나옴>
#include <iostream>
using std::cout;
using std::endl;
template <class T1, class T2, class T3> void fun(T1 x, T2 y, T3 z)
{ // 두 개의 매개변수 자료형이 T1과 T2로 다르다.
cout << x << " " << y <<" "<<z<< endl;
}
int main()
{
fun("Han", 30, 30.5); // T1은 문자열(const char *),T2는 정수형(int)
fun(25, 50.5, 'a'); // T1은 정수형(int), T2는 double형
return 0;
}//재작년 시험 문제
#include <iostream>
using std::cout;
using std::endl;
class CCC1
{
int x;
int y;
public:
CCC1(int xx, int yy) { x = xx; y = yy; }
void Print() { cout << x << ',' << y << endl; }
};
class CCC2
{
double x;
double y;
public:
CCC2(double xx, double yy) { x = xx; y = yy; }
void Print() { cout << x << ',' << y << endl; }
};
class CCC3
{
char x;
const char* y;
public:
CCC3(char xx, const char* yy) { x = xx; y = yy; }
void Print() { cout << x << ',' << y << endl; }
};
int main()
{
CCC1 c1(10, 20);
CCC2 c2(3.5, 5.5);
CCC3 c3('I', "Love You!");
c1.Print();
c2.Print();
c3.Print();
return 0;
}
을 템플렛 class 사용하여 바뀜V
1단계. 비슷한 코드가 있다면 단 1나 빼고 다 지운다
2단계. 앞에 template 작성
3단계. 함수 변형
class 자리에 typename을 사용해도 되나 class을 사용시에는 class를 주로 쓴다.<시험에 냄 배점높음>
#include <iostream>
using std::cout;
using std::endl;
template <class T1, class T2>class CCC
{
T1 x;
T2 y;
public:
CCC(T1 xx, T2 yy) { x = xx; y = yy; }
void Print() { cout << x << ',' << y << endl; }
};
int main()
{
CCC <int, int> c1(10, 20);
CCC <double, double> c2(3.5, 5.5);
CCC <char, const char*> c3('I', "Love You!");
c1.Print();
c2.Print();
c3.Print();
return 0;
}
이 C++ 코드는 제네릭 클래스를 정의하고 사용하는 예제입니다. 아래는 코드의 각 부분에 대한 설명입니다.
### 코드 설명
1. **헤더 파일 포함**:
```cpp
#include <iostream>
```
이 줄은 C++의 입출력 스트림 라이브러리를 포함하여, `cout`과 `endl`을 사용할 수 있게 합니다.
2. **네임스페이스 사용**:
```cpp
using std::cout;
using std::endl;
```
`std` 네임스페이스에서 `cout`과 `endl`을 직접 사용할 수 있도록 합니다.
3. **제네릭 클래스 정의**:
```cpp
template <class T1, class T2> class CCC
```
`CCC`라는 이름의 클래스 템플릿을 정의합니다. `T1`과 `T2`는 클래스에서 사용할 두 개의 타입 매개변수입니다.
4. **멤버 변수**:
```cpp
T1 x;
T2 y;
```
클래스 `CCC`는 두 개의 멤버 변수 `x`와 `y`를 가지고 있으며, 각각 `T1`과 `T2` 타입입니다.
5. **생성자**:
```cpp
CCC(T1 xx, T2 yy) { x = xx; y = yy; }
```
생성자는 두 개의 매개변수 `xx`와 `yy`를 받아서 멤버 변수 `x`와 `y`에 각각 할당합니다.
6. **Print 메서드**:
```cpp
void Print() { cout << x << ',' << y << endl; }
```
`Print` 메서드는 멤버 변수 `x`와 `y`의 값을 출력합니다. `cout`을 사용하여 값들을 출력하고, `endl`로 줄바꿈을 합니다.
7. **main 함수**:
```cpp
int main()
{
CCC <int, int> c1(10, 20);
CCC <double, double> c2(3.5, 5.5);
CCC <char, const char*> c3('I', "Love You!");
c1.Print();
c2.Print();
c3.Print();
return 0;
}
```
- `CCC<int, int> c1(10, 20);`: `int` 타입의 두 값을 저장하는 `CCC` 객체 `c1`을 생성합니다.
- `CCC<double, double> c2(3.5, 5.5);`: `double` 타입의 두 값을 저장하는 `CCC` 객체 `c2`를 생성합니다.
- `CCC<char, const char*> c3('I', "Love You!");`: `char`와 `const char*` 타입을 저장하는 `CCC` 객체 `c3`를 생성합니다.
각 객체에 대해 `Print` 메서드를 호출하여 값을 출력합니다.
### 출력 결과
위 코드를 실행하면 다음과 같은 출력이 생성됩니다:
```
10,20
3.5,5.5
I,Love You!
```
이 코드는 제네릭 프로그래밍을 통해 다양한 데이터 타입을 처리할 수 있는 클래스를 정의하고, 이를 통해 객체를 생성하고 메서드를 호출하여 데이터를 출력하는 예제를 보여줍니다.
아래는 자료구조에서 사용하는 자료구조와 C++ STL(Standard Template Library)에서 제공하는 자료구조를 비교한 표입니다. `벡터`, `스택`, `큐`를 포함하여 각 특성을 정리했습니다.
| **특징** | **자료구조** | **STL** |
|----------------- --|-------------------------------|-------------------------------------|
| **정의** | 데이터를 저장하고 관리하는 구조 | STL에서 제공하는 템플릿 기반 자료구조 |
| **구조** | 동적 배열, 연결 리스트 등 | `vector`, `stack`, `queue` |
| **메모리 관리** | 프로그래머가 직접 관리 | 자동으로 메모리 관리 |
| **접근 방식** | 배열: 인덱스 접근, 연결 리스트: 포인터 접근 | `vector`: 인덱스 접근<br>`stack`, `queue`: 제한된 접근
| **삽입/삭제 속도**| 배열: O(n), 연결 리스트: O(1) | `vector`: O(n) (중간 삽입 시)<br>`stack`: O(1)<br>`queue`: O(1) |
| **검색 속도** | 배열: O(1), 연결 리스트: O(n) | `vector`: O(n)<br>`stack`: O(n)<br>`queue`: O(n) |
| **사용 편의성** | 직접 구현 시 복잡함 | 간단하고 직관적인 인터페이스 제공 |
| **기능** | 기본적인 데이터 조작 기능 제공 | `vector`: 동적 크기 조정, 정렬 등<br>`stack`: 푸시, 팝<br>`queue`: 인큐, 디큐 |
| **예외 처리** | 직접 처리해야 함 | STL에서 예외 처리 기능 제공 |
| **성능** | 직접 구현 시 성능 최적화 가능 | 일반적으로 최적화된 성능 제공 |
| **범용성** | 특정 문제에 맞춤형으로 설계 | 범용적으로 사용 가능 |
이 표는 `벡터`, `스택`, `큐` 각각의 특징을 자료구조와 STL에서 제공하는 구조로 비교하여 각자의 장점과 단점을 이해하는 데 도움이 됩니다. STL은 사용하기 편리하고, 다양한 기능과 최적화된 성능을 제공하는 반면, 직접 구현한 자료구조는 특정 요구사항에 맞춤형으로 최적화할 수 있는 장점이 있습니다.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector <int> x; //int x[10]와 차이
// 여러 개 int형을 가지고 노는 배열 공간을 만들고 싶어요
x.push_back(1);
x.push_back(2);
x.push_back(5);
for (int i = 0; i < x.size(); i++)//.size 배열의 크기
cout << x[i] << endl;
return 0;
}
//작년 시험문제
//1
//2
//5
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector <char> x; //int x[10]와 차이
// 여러 개 int형을 가지고 노는 배열 공간을 만들고 싶어요
x.push_back('a');
x.push_back('t');
x.push_back('l');
for (int i = 0; i < x.size(); i++)//.size 배열의 크기
cout << x[i] << endl;
return 0;
}
프로그래밍 언어에서 예외 처리(Exception handling)는 프로그램 실행 중 발생할 수 있는 오류나
예외적인 상황을 관리하는 메커니즘입니다. 예외 처리를 통해 프로그램이 예기치 않은 상황에서도
정상적으로 동작하거나, 적절한 오류 메시지를 출력하고 종료할 수 있도록 도와줍니다.
### 주요 개념
1. **예외(Exception)**: 프로그램 실행 중 발생하는 오류나 비정상적인 상황을 의미합니다. 예를 들어,
파일을 열 수 없거나, 배열의 범위를 초과하여 접근하는 경우 등이 있습니다.
2. **예외 발생(Throwing an Exception)**: 예외가 발생했을 때, 해당 예외를 "던진다"는 의미로,
프로그램이 오류 상태에 도달했음을 알리는 것입니다.
3. **예외 처리(Handling an Exception)**: 발생한 예외를 처리하는 과정입니다. 이를 통해 프로그램이
중단되지 않고, 적절한 조치를 취할 수 있습니다.
4. **try-catch 블록**: 대부분의 프로그래밍 언어에서 예외 처리를 구현하는 기본 구조입니다.
- **try**: 예외가 발생할 수 있는 코드를 포함합니다.
- **catch**: 발생한 예외를 처리하는 코드를 포함합니다.
### 예시 (C++)
```cpp
#include <iostream>
#include <stdexcept>
int main() {
try {
throw std::runtime_error("예외가 발생했습니다!");
} catch (const std::runtime_error& e) {
std::cout << "Caught: " << e.what() << std::endl;
}
return 0;
}
```
### 장점
- **안정성**: 프로그램이 예외적인 상황에서도 종료되지 않고, 적절하게 대응할 수 있게 해줍니다.
- **코드 가독성**: 예외 처리를 통해 오류 처리를 명확하게 구분할 수 있어 코드의 가독성이 높아집니다.
- **유지보수성**: 예외 처리 구조를 통해 오류 발생 시의 처리 방법을 쉽게 수정할 수 있습니다.
예외 처리는 프로그램의 안정성과 신뢰성을 높이는 데 중요한 역할을 합니다.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
void Div(double ja, double mo)
{
try { //1
if(mo==0)throw mo;//2
cout << "결과:" << ja / mo << endl;
}
catch (double) {//3 //던지는 값에 자료형을 ()안에 넣음 //매년 시험냄
cout << "오류 분모가 0이기 때문에 나눌수 없음." << endl;
}//catch는 여러개 사용가능 자료형이 맞는 catch가 사용됨
}
int main()
{
double x, y;
cout << "분자를 입력하세요=";
cin >> x;
cout << "분모를 입력하세요=";
cin >> y;
Div(x, y);
return 0;
}
뤼튼 주석
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
// 나눗셈을 수행하는 함수
void Div(double ja, double mo)
{
try { // 1. 예외 처리를 시작하는 블록
if(mo == 0) throw mo; // 2. 분모가 0인 경우 예외를 던짐
cout << "결과: " << ja / mo << endl; // 나눗셈 결과 출력
}
catch (double) { // 3. double 타입 예외를 처리하는 catch 블록
cout << "오류: 분모가 0이기 때문에 나눌 수 없음." << endl; // 예외 발생 시 오류 메시지 출력
}
}
int main()
{
double x, y; // 분자와 분모를 저장할 변수 선언
cout << "분자를 입력하세요 = "; // 사용자에게 분자 입력 요청
cin >> x; // 사용자로부터 분자 입력 받기
cout << "분모를 입력하세요 = "; // 사용자에게 분모 입력 요청
cin >> y; // 사용자로부터 분모 입력 받기
Div(x, y); // 입력받은 값으로 Div 함수 호출
return 0; // 프로그램 종료
}
| **프로그래밍 언어** | **예외 처리 키워드** | **설명** |
|---------------------|--------------------------|--------------------------------------------|
| C++ | `try`, `catch`, `throw` | `try` 블록 내에서 예외 발생 시 `catch`로 처리하며, `throw`로 예외를 던진다. |
| Java | `try`, `catch`, `throw`, `throws`, `finally` | `try` 블록 내에서 예외 발생 시 `catch`로 처리, `throws`는 메서드에서 예외를 선언, `finally`는 예외 발생 여부와 관계없이 실행됨. |
| Python | `try`, `except`, `raise`, `finally` | `try` 블록 내에서 발생한 예외를 `except`로 처리하며, `raise`로 예외를 던진다. `finally`는 항상 실행됨. |
| C# | `try`, `catch`, `throw`, `finally`, `using` | `try` 블록 내에서 발생한 예외를 `catch`로 처리하며, `using`은 IDisposable 객체의 자동 해제를 위해 사용됨. |
| JavaScript | `try`, `catch`, `throw`, `finally` | `try` 블록 내에서 예외 발생 시 `catch`로 처리하며, `finally`는 항상 실행됨. |
| Ruby | `begin`, `rescue`, `raise`, `ensure` | `begin` 블록 내에서 발생한 예외를 `rescue`로 처리하며, `raise`로 예외를 던진다. `ensure`는 항상 실행됨. |
| PHP | `try`, `catch`, `throw`, `finally` | `try` 블록 내에서 예외 발생 시 `catch`로 처리하며, `finally`는 항상 실행됨. |
| Swift | `do`, `try`, `catch`, `throw` | `do` 블록 내에서 발생한 예외를 `catch`로 처리하며, `throw`로 예외를 던진다. |
이 표는 다양한 프로그래밍 언어에서 예외 처리를 위한 키워드를 정리하여 각 언어의 예외 처리 메커니즘을 이해하는 데 도움이 됩니다.
#include <iostream>
using namespace std;
int main() {
cout << "디폴트\n"; // 기본 출력
cout.width(10); // 다음 출력의 너비를 10으로 설정
cout << -50 << endl; // 너비 설정 후 -50 출력
cout << "[ * fill ]\n"; // 출력 구분을 위한 메시지
cout.fill('A'); // 빈 공간을 'A'로 채움
cout.width(10); // 다음 출력의 너비를 10으로 다시 설정
cout << -50 << endl; // 'A'로 채워진 너비 10에 -50 출력
cout.width(10); // 다음 출력의 너비를 10으로 설정
cout << 100.25 << endl; // 너비 10에 100.25 출력
cout.width(10); // 다음 출력의 너비를 10으로 설정
cout << "HanSH" << endl; // 너비 10에 문자열 "HanSH" 출력
cout.fill(' '); // 빈 공간을 공백으로 채움 (기본값 복원)
cout.precision(6); // 전체 자리수를 6자리로 설정 (소수점 제외)
cout << 12.34567 << endl; // 6자리로 설정된 12.34567 출력
cout << fixed; // 소수점 이하의 자리수만 다루게 설정
cout.precision(3); // 소수점 이하 3자리로 설정
cout << 12.34567 << endl; // 소수점 이하 3자리로 설정된 12.34567 출력
return 0; // 프로그램 종료
}
#include <iostream>
#include <iomanip> // 입출력 조작을 위한 헤더 파일
using namespace std;
int main() {
cout << "abcdefg\n"; // 문자열 출력
cout << 12345 << endl; // 정수 12345 출력
cout << 123.45 << endl; // 실수 123.45 출력
cout << "10칸\n"; // 출력 구분을 위한 메시지
cout << setfill('*'); // 빈 공간을 '*'로 채우도록 설정
cout << setw(10) << "abcdefg" << endl; // 너비 10에 'abcdefg' 출력, 부족한 부분은 '*'로 채워짐
cout << setw(10) << 12345 << endl; // 너비 10에 12345 출력, 부족한 부분은 '*'로 채워짐
cout << setw(10) << 123.45 << endl; // 너비 10에 123.45 출력, 부족한 부분은 '*'로 채워짐
return 0; // 프로그램 종료
}
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream hout("www.txt");
hout << "ananana";
cout << "Smile";
return 0;
}
이 C++ 코드는 파일 입출력을 사용하여 텍스트 파일에 데이터를 작성하는 간단한 프로그램입니다. 각 부분을 설명하겠습니다.
### 코드 설명
1. **헤더 파일 포함**:
```cpp
#include <iostream>
#include <fstream>
```
- `iostream`: 표준 입력 및 출력을 위한 라이브러리입니다.
- `fstream`: 파일 입출력을 위한 라이브러리입니다. 파일을 읽거나 쓰는 데 사용됩니다.
2. **네임스페이스 사용**:
```cpp
using namespace std;
```
- `std` 네임스페이스의 모든 요소를 사용할 수 있게 해줍니다. 이를 통해 `cout`, `ofstream` 등을 직접 사용할 수 있습니다.
3. **main 함수**:
```cpp
int main()
{
ofstream hout("www.txt");
```
- `ofstream`: 파일에 데이터를 쓰기 위한 스트림 객체입니다.
- `hout("www.txt")`: `"www.txt"`라는 이름의 파일을 생성하거나 열고, 그 파일에 데이터를 쓸 준비를 합니다. 파일이 이미 존재하면 기존 파일을 덮어씁니다.
4. **파일에 데이터 쓰기**:
```cpp
hout << "ananana";
```
- `hout` 스트림을 사용하여 `"ananana"`라는 문자열을 `www.txt` 파일에 씁니다.
5. **콘솔 출력**:
```cpp
cout << "Smile";
```
- 콘솔에 `"Smile"`이라는 문자열을 출력합니다.
6. **프로그램 종료**:
```cpp
return 0;
```
- 프로그램을 정상적으로 종료합니다.
### 요약
이 프로그램은 `www.txt`라는 텍스트 파일을 생성하고, 그 파일에 `"ananana"`라는 문자열을 기록한 후, 콘솔에 `"Smile"`이라는 메시지를 출력합니다. 프로그램이 실행된 후, `www.txt` 파일에는 `"ananana"`라는 내용이 저장되어 있게 됩니다.
파일 만들때 ofstream
파일 불어올때 ifstream
파일을만든 다음ㅇ[ .close을 해야 파일이 닫아지고 저데로 저장된다.
#include <iostream>
#include <fstream> // 파일 입출력을 위한 헤더 파일 포함
using namespace std;
int main()
{
int x; // 정수를 저장할 변수 x 선언
ofstream hout("a1.txt"); // "a1.txt"라는 이름의 파일을 생성하거나 연다.
hout << "100"; // 파일에 문자열 "100"을 기록
hout.close(); // 파일 쓰기를 마치고 파일을 닫음
//cout << "Smile"; // 주석 처리된 코드: 콘솔에 "Smile"을 출력하는 코드 (현재는 실행되지 않음)
ifstream hin("a1.txt"); // "a1.txt" 파일을 열어 읽기 위한 입력 스트림 hin 생성
hin >> x; // 파일에서 데이터를 읽어 변수 x에 저장
cout << x; // 변수 x의 값을 콘솔에 출력 (이 경우 100이 출력됨)
return 0; // 프로그램 종료
}
주석 요약
헤더 파일 포함: iostream은 표준 입출력을 위한 라이브러리이고,
fstream은 파일 입출력을 위한 라이브러리입니다.
변수 선언: 정수를 저장할 변수 x를 선언합니다.
파일 쓰기:
ofstream을 사용하여 파일에 데이터를 쓸 준비를 합니다.
"a1.txt" 파일에 "100"이라는 문자열을 기록합니다.
파일을 닫아 리소스를 해제합니다.
파일 읽기:
ifstream을 사용하여 파일을 읽기 위해 열고, 파일에서 값을 읽어 x에 저장합니다.
읽은 값 x를 콘솔에 출력합니다.
프로그램 종료: 프로그램이 정상적으로 종료됩니다.
이 주석은 코드의 각 부분이 어떤 역할을 하는지 설명하여, 코드를 이해하는 데 도움이 됩니다.
각 단계에서 어떤 작업이 수행되는지를 명확히 알 수 있습니다.
#include <iostream>
using std::cout;
using std::endl;
int main(void)
{
int x = 10;
int& rx = x;//rx는 x의 참조자
cout << x << " " << rx << endl;
rx = rx + 10;
cout << x << " " << rx << endl; //참조자(rx)에 변화를 주면 그 타켓(x)도 변함
x = x + 10;
cout << x << " " << rx << endl; //타켓(x)에 변화를 주면 그 참조자(rx)도 변함
return 0;
}
//10 10
//20 20
//30 30
이번 학기에 뭘 학습했나?