∙ C언어와 C++ 그리고 C#이 무엇인가?
- C언어 : 아주 먼 옛날 벨 연구소에서 Unix라는 운영체제(OS)를 개발 목적으로 탄생한 언어이다.
- C++ : 조금 먼 옛날 C언어에서 한단계 진화한 언어로 객체와 클래스라는 개념이 처음 도입이 되었다. 이후 템플릿이라는 기능이 추가되어 더욱더 강력해졌고 지금도 계속 꾸준히 발전중이다.
- C# : 마이크로소프트사에서 2000년대 개발한 언어인데, 사실 Java를 대항하기 위해 탄생한 언어이다 보니 C와 C++만큼 관련은 없다.
∙ C++ 의 장점
1. 속도가 빠르다. (python 보다 수십배에서 수백배정도!)
2. 사용자가 직접! 메모리를 관리할 수 있다.
3. cross-platform : 하나의 코드를 여기저기서 사용
-> C++으로 하나를 만들어 놓으면 안드로이드, 윈도우 등 여러 곳에서 가져올 수 가 있다.
∙ 함수
- 코드 뭉치로 자주 사용할 것 같은 코드를 한 군데 모아, 추후에도 사용하기 편하기 해주는 아주 좋은 기능이다.
- 자주 사용할 것 같은 코드를 하나의 함수로 모은다
> 똑같은 코드를 사용해야 할 때에는 작성한 함수를 사용한다.
> 작성하는 코드의 양이 줄어든다.
> 적은 코드로 많은 기능을 만들 수 있다.
따라서 함수를 작성하실 땐, 반복되는 코드의 재사용에 대해 생각해보는게 매우 중요하다.
#include <iostream>
using namespace std;
void sayHello(); // 함수 선언
int main()
{
cout << "main" << endl;
sayHello(); // 함수 호출
}
// 함수 작성
void sayHello()
{
cout << "Welcome" << endl;
}
- 함수 오버로딩 (Overloading)
> 함수 오버로딩은 같은 이름의 함수가 있어도 매개변수를 보고 c++이 알아서 찾아준다.
> 함수 오버로딩이 적용되기 위해서 아래조건이 중요
1. 함수 이름이 같아야한다.
2. 매개변수의 수가 다르거나, 자료형이 달라야한다.
3. 반환형의 차이는 함수 오버로딩에 적용이 안된다.
#include <iostream>
using namespace std;
// 인자의 개수를 통해 구별을 함
int add(int a, int b);
int add(int a, int b, int c);
int main()
{
cout << add(1,2) << endl;
cout << add(1, 2, 3) << endl;
}
int add(int a, int b)
{
cout << "addTwo" << endl;
return a + b;
}
int add(int a, int b, int c)
{
cout << "addThree" << endl;
return a + b + c;
}
∙ 포인터와 참조
∙ 포인터
- 포인터란 우리가 사용하는 변수가 실제로 담기는 주소를 의미한다.
- 우리가 만드는 변수는 분명 컴퓨터 어딘가 잘 보관이 될 테고, C++에서 우리는 그 주소를 확인해 볼 수 있다.
#include <iostream>
using namespace std;
int main()
{
int water = 10;
// * : 포인트 변수를 선언, & : 변수의 주소를 가져와라
int *p_water = &water;
cout << "water" << water << endl;
// p_water 주소에 들어 있는 값 출력
cout << "p_water" << *p_water << endl;
// water 주소 값 출력 (두개의 주소는 같다)
cout << "water location" << &water << endl;
cout << "p_water location" << p_water << endl;
// 10이 아닌 11이 나온다 -> 주소가 같기 때문에
*p_water = *p_water + 1;
cout << "Now count" << water << endl;
}
- call by value, call by reference
> main함수에서 사용한 변수를 참조하기 때문에 main에서 사용하던 변수의 값에 영향을 준다는게 중요하다.
cf)
- string 함수
int main()
{
string sparta = "Sparta";
string coding = "Coding";
string club = "Club";
// 문자열 합치기
string result = sparta + coding + club;
cout << result << endl;
// 문자열 길이 구하기
cout << result.size() << endl;
// 문자열 나누기
// 출력 결과 : CodingClub
cout << result.substr(sparta.size(), result.size()) << endl;
// 문자열 찾기
// 인덱스 위치 출력됨
cout << result.find(club) << endl;
}
∙ 구조체
- 다양한 자료형을 한데 묶어서 하나로 관리하고 싶을 때 C++에서는 이를 구조체를 사용하여 해결한다.
- struct 라는 키워드를 사용한다.
// struct.cpp
#include <iostream>
using namespace std;
struct Person
{
string name;
int age;
};
int main()
{
Person p1;
p1.name = "John Doe";
p1.age = 20;
Person p2 = {"Jane", 30};
cout << p1.name << endl;
cout << p2.name << endl;
return 0;
}
∙ 클래스와 객체
- C++에서 클래스는 중요한 의미를 가지고 있다. 가장 큰 역할을 하지만 지금은 클래스 외에도 많은 기능이 확장되어 더욱 편리하게 사용할 수 있다.
- 클래스(Class), 객체(Object), 인스턴스(Instance), 메소드(Method)
> 클래스 (Class)
과자 모형이다. 내가 원하는 모양의 과자를 만들기 위해 기본 틀을 제작하는거다.
> 객체 (Object)
과자 모형을 통해 실제로 만들어진 과자를 의미한다.
> 인스턴스 (Instance)
클래스의 인스턴스를 객체라 한다. 객체와 인스턴스는 같은 의미라고 생각하는게 좋다
> 메소드 (Method)
클래스에서 제공하는 기능이고, 함수와 생김새는 같다. 주로 멤버변수를 활용하는 메소드를 가지고 있다.
// class.cpp
#include <iostream>
using namespace std;
class Person
{
// 외부에서 접근할 수 없음
private:
int age;
// public으로 지정을 안해주면 기본적으로 private으로 설정됨
public:
string m_name;
void sayHello()
{
cout << "Hello" << endl;
}
};
int main()
{
Person p1;
p1.m_name = "Eric Clapton";
/*
//private에 있기 때문에 age에 접근이 불가능
p1.age = 10;
*/
cout << p1.m_name << endl;
p1.sayHello();
return 0;
}
∙ 생성자와 소멸자
∙ 생성자
- 클래스가 생성될 때 딱 한번 실행되는 메소드이다.
- C++에서 생성자는 클래스와 같은 이름으로 선언해준다.
- 다른 메소드와는 다르게 반환 타입이 없다
// constructor.cpp
#include <iostream>
using namespace std;
class Person
{
public:
string m_name;
Person(string name) // 생성자... 함수랑 똑같다고 생각하면됨
{
cout << "Constructing Person......" << endl;
m_name = name;
}
void sayHello()
{
cout << "Hello I'm " << m_name << endl;
}
};
int main()
{
Person *p1 = new Person("Eric Clapton");
// Person p1 = Person("Eric Clapton");
// Person p1("Eric Clapton");
p1->sayHello();
return 0;
}
∙ 소멸자
- 클래스가 소멸될 때 실행되는 메소드이다.
- 소멸자는 클래스 이름 앞에 ~를 붙여서 선언해준다.
- 반환형과 인자가 없다는게 특징이다.
- new로 선안한 객체는 반드시 delete를 통해 소멸시켜줘야한다.
// destructor.cpp
#include <iostream>
using namespace std;
class Person
{
public:
string m_name;
Person(string name)
{
cout << "Constructing Person..." << endl;
m_name = name;
}
// 소멸자
~Person()
{
cout << "Destructing Person..." << endl;
}
void sayHello()
{
cout << "Hello I'm " << m_name << endl;
}
};
int main()
{
Person *p1 = new Person("Eric Clapton");
// Person p1 = Person("Eric Clapton");
// Person p1("Eric Clapton");
p1->sayHello();
// 이 타이밍에 소멸자를 호출한다.
delete p1;
// cout << "Good bye " << endl;
return 0;
}
∙ 상속
- 자식이 부모로부터 물려받는 것을 상속이라고 하고, 자식은 부모와 여러가지로 비슷한 점을 많이 가지고 있지만, 완전하게 똑같지는 않다.
- C++에서는 상속을 이용해서 이전에 만든 클래스를 기반으로 비슷하면 서로 다른 클래스를 만들 수 있다.
// inheritance.cpp
#include <iostream>
using namespace std;
class Person
{
private:
string m_name;
public:
Person(string name)
{
cout << "Construting Person..." << endl;
m_name = name;
}
~Person()
{
cout << "Destructing Person..." << endl;
}
void sayHello()
{
cout << "Hello I'm " << m_name << endl;
}
string getName()
{
return m_name;
}
};
// 상속을 받겠다
class Musician : public Person
{
private:
string m_instrument;
public:
Musician(string m_name) : Person(m_name)
{
cout << "Constructing Musician..." << endl;
}
~Musician()
{
cout << "Destructing Musician..." << endl;
}
void setInstrument(string instrument)
{
m_instrument = instrument;
}
string getInstrument()
{
return m_instrument;
}
};
int main()
{
Musician m1 = Musician("Eric Clapton");
m1.setInstrument("guitar");
m1.sayHello();
cout << m1.getInstrument() << endl;
return 0;
}
- is-a 관계
> 상속 관계 (is a relationship : inheritance)를 의미한다.
> 뮤지션과 사람의 관계를 is-a관계라 말하며, 이는 상속의 가장 대표적인 관계이다.
> 뮤지선을 파생 클래스, 사람을 기본 클래스라고 한다.
∙ 함수 오버라이딩
- 함수 오버로딩 : 클래스 내에 이름이 동일한 함수가 여러 개 존재
- 함수 오버라이딩 : 부모 클래스에 이미 정의된 함수를 재정의해서 사용
// overriding.cpp
#include <iostream>
using namespace std;
class Person
{
// protected 선언을 하면 자식한테 넘겨줄수 있지만, 외부에서는 불가능하다
protected:
string m_name;
public:
Person(string name)
{
m_name = name;
}
void sayHello()
{
cout << "Hello I'm " << m_name << endl;
}
};
class Musician : public Person
{
private:
string m_instrument;
public:
Musician(string m_name) : Person(m_name) {}
// 함수 오버 라이딩
void sayHello()
{
cout << "Hi I'm " << m_name << endl;
cout << "I play the " << m_instrument << endl;
}
// 위와 같은 함수이지만 인자가 다르기 때문에 오버 로딩이라고한다.
void sayHello(string lang)
{
if (lang == "ENG")
{
cout << "Hello!" << endl;
}
else
{
cout << "I can only speak in English..." << endl;
}
}
void setInstrument(string instrument)
{
m_instrument = instrument;
}
};
int main()
{
Musician m1 = Musician("Eric Clapton");
m1.setInstrument("guitar");
m1.sayHello();
m1.sayHello("KOR");
// cout << m1.m_name << endl;
return 0;
}
∙가사함수
// virtual.cpp
#include <iostream>
using namespace std;
class Person
{
protected:
string m_name;
public:
Person(string name)
{
m_name = name;
}
virtual sayHello()
{
cout << "Hello I'm " << m_name << endl;
}
};
class Musician : public Person
{
public:
Musician(string m_name) : Person(m_name)
{
}
void sayHello()
{
cout << "Hi I'm " << m_name << endl;
cout << "I'm a musician!" << endl;
}
void playSomething()
{
cout << "lalala~" << endl;
}
};
class Baker : public Person
{
public:
Baker(string m_name) : Person(m_name)
{
}
void sayHello()
{
cout << "Hi I'm " << m_name << endl;
cout << "I like bread!" << endl;
}
};
int main()
{
// vrtual로 person 클래스가 안되어 있으면 Person sayHello ㅎ마수가 실행이 된다
Person *p1 = new Musician("Jeff");
p1->sayHello();
// p1->playSomething();
cout << endl;
Person *p2 = new Person("Jane");
p2->sayHello();
cout << endl;
p1 = new Baker("Yumi");
p1->sayHello();
delete p1;
delete p2;
return 0;
}
∙ 템플릿
- C++의 여러가지 특징 중 하나로, 일반화 프로그래밍이란 특징이 있다. 이전까지 배운 객체지향 프로그래밍(OOP)과는 전혀 다른 프로그래밍 기법이다.
- 일반화 프로그래밍에서는 데이터의 타입과 관련없는 코드를 작성하는 것인데, 이를 위해서 템플릿이 필요하다.
∙ 함수 템플릿
- 두 개의 숫자를 더해주는 함수를 만들 때, 원래는 자료형 별로 함수를 만들어줘야 한다. 하지만 템플릿을 사용하면 하나의 함수로 쉽게 구현이 가능하다.
// functiontemplate.cpp
#include <iostream>
using namespace std;
int sum(int a, int b)
{
return a + b;
}
double sum(double a, double b)
{
return a + b;
}
// 템플릿 생성
template <typename T>
T sum(T a, T b)
{
return a + b;
}
int main()
{
int s1 = sum(1, 2);
double s2 = sum(2.2, 2.0);
// 템플릿 함수 호출 <string> 형이라고 템플릿에 알려준다.
string s3 = sum<string>("Sparta", "CodingClub");
double s4 = sum<double>(2.2, 2.0);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
return 0;
}
∙ 템플릿 특수화
- 특정 데이터 타입 한해서 따로 처리를 하고 싶을때 사용 (예외처리)
//templatespecialization.cpp
#include <iostream>
using namespace std;
template <typename T>
T sum(T a, T b)
{
return a + b;
}
// 템플릿 예외 처리
template <>
char sum<char>(char a, char b)
{
cout << "Unable to sum char!" << endl;
return a;
}
int main()
{
cout << sum<int>(1, 2) << endl;
cout << sum<double>(2.0, 2.0) << endl;
cout << sum<string>("Sparta", "CodingClub") << endl;
char a = 'a';
char b = 'b';
cout << sum<char>(a, b) << endl;
return 0;
}
'코딩 및 기타 > 어서와! 자료구조와 알고리즘' 카테고리의 다른 글
투포인터, 슬라이딩 윈도우 알고리즘 (0) | 2023.09.30 |
---|---|
동적 계획법 응용 : 정수 삼각형 (0) | 2023.09.02 |
동적 계획법 응용 : 최소 비용 경로 (0) | 2023.09.01 |
동적 계획법 (0) | 2023.09.01 |
그래프 순회 응용 (네트워크) (0) | 2023.09.01 |