C++ 요약
C++ 기초
임포트. 입출력
#include <iostream> //iostream 헤더를 임포트
#include <stdio.h>
using namespace std; //네임스페이스 선언
int main() {
//방법 1
string s;
scanf_s("%s", &s);
printf("지역변수 : %s", s);
//방법 2
string a; //
cin >> a; //입력 getline(cin,a)가 띄어쓰기도 포함해줌
std::cout << a; //출력. 네임스페이스를 명시적 선언
return 0;
}
- 독자적인 파일은 <> 대신, “주소”로 불러올수 있음
네임스페이스
using namespace name;
namespace name {
class cls {
};
void func() {
cout << "call name function";
}
}//네임스페이스 선언
int main(){
name::fun();//사용 방법 1. 명시적 방법
fun(); //사용방법 2. using 구문 이용
}
자료형
int main() {
//기본자료형
int i= 1; //선언하는 방법
string s="안녕";
//배열
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
arr[0] //arr 접근방법
//다차원 배열
int arr[10][10]={0} //배열의 형태를 확실히 입력시 첫 인자 스킵가능
arr[0][0]=1
}
- c++은 주소가 따로 있으므로 대입시 값이 (얕은) 복사
int | 약 절대값 약 21억의 정수(32비트) |
---|---|
float | 유효자리 15의 약 절대값 10^38(32비트) |
char, wchar_t | 문자. 1바이트, 2바이트(unsigned) |
bool | 참 거짓(1바이트) |
string | 인스턴스지만 대입시 값복사 |
class, struct | 클래스와 구조체 |
그외 | double(8바이트), longlong, unsigned |
자료형 이름[크기] | 배열은 선언후 다시 대입 불가 |
- 주소
자료형 * | 자료형의 주소 |
---|
연산
int a=10
int b=4
int result=0
//가감승제
result=a + b # 14
result=a - b # 6
result=a * b # 40
result=a / b # 2 (버림)
//나머지
result=a%b # 2
//비트 연산 (&,|,^,~)
result= a&b # 0
//연산하고 대입
b+=a # b=b+a 와 동일
//문자열 연산(널문자를 자동 처리해줌)
string a = "안녕 ";
string b = " 반가워";
cout << a + b; //안녕 반가워
- 정수와 소수자료형끼리 연산하면 자동 형변환
- 정수끼리 연산에는 형변환 없음
- string 끼리는 연산 가능(char[]는 안됨)
조건문
//비교
1<1.1 //True
1>1.1 //False
1<=1 //True
1>=1 //True
1==1 //True
1==1.0 #True
//if문
int main() {
int a = 1;
if (a < 10) {
cout << "a는 10보다 작습니다. "<<a;
}
else if(a==10){
cout << "a는 10입니다 " << a;
}
else {
cout << "a는 10보다 큽니다. " << a;
}
//switch문(숫자형만 가능)
int num=0;
switch (num) {
case 0:
printf("입력값은 0입니다");
break;//호출 안하면 아래도 실행해버림
case 20:
printf("입력값은 20입니다");
break;
default:
printf("입력값은 어찌돼도 좋습니다.");
break;
}
return 0;
}
반복문
//0~9까지 출력하는 반복문
int main(){
int i = 0;
//while 문
while (i < 10) {
cout << i << endl;
i++;
}
//for문
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
}
- do~while문 역시 있으나 잘 쓰지 않음
C++ 심화
메서드
int a=10;
void met(int input=2){
int a=1; //전역변수 a와는 별개
int b=2;
return a+b;
}
int main(){
met(1) // 2
return 0;
}
- 반환형 이름(파라미터){ return 반환값 형식 }
- 디폴트 입력값 가능
- 파라미터에 넣은 값은 원본의 데이터의 값을 복사한 값임을 유의
- 원본값을 조작하려면 주소를 넘기는 방식을 쓸것 (*)
구조체
struct stu
{
private:
int id;
string name;
public:
stu(int id, string name) : id(id),name(name){}//생성자
~stu() {
cout << "구조체 소멸" << endl;
}// 소멸자
void show() {
cout << id << name;
}
void set(int id, string name) {
this->id = id;//this를 써서 자신의 구조체(클래스)주소를 반환
this->name = name;
}
}; //c와 다르게 typedef가 필요없다.
int main(){
stu a={10,"name"};//a(10,"name")과 동일
a.show();
return 0;
}
- 기본적으로 public
클래스
class parent {
public:
int id;
string name;
parent() {
id = 10;
name = "name";
cout << id << name<<endl;
}
parent(int id, string name) : id(id), name(name) {
cout << id << " " << name<<endl;
}
void show() {
}
};
class cls : public parent{
public:
cls() :parent() {}
cls(int id, string name) :parent(id, name) {}//생성자.
~cls() {
cout << "클래스 소멸" << endl;
}// 소멸자
void show() {
cout << id << name<<endl;
}
void set(int id, string name) {
this->id = id;//this를 써서 자신의 구조체(클래스)주소를 반환
this->name = name;
}
}; //c와 다르게 typedef가 필요없다.
int main() {
//방법 1(대입시 내부의 값이 얕은 복사)
cls a(1, "name");
a.show();
//방법 2(대입시 주소값만 복사)
cls * b = new cls();
b->show(); //(*b).show()를 간단하게 표현가능
return 0;
}
- 기본적으로 private
- 구조체처럼 { } 할당 불가
- 딴언어랑 다르게 대입연산시 내부 내용 얕은 복사
- 복사말고 주소를 넘기려면 주소값을 사용해야함(*)
- (*인스턴스)는 인스턴스→ 구문으로 바꿀수 있음
- 부모 생성자를 자동으로 부르기 때문에 { }안에 생성자를 명시적으로 부르면 안됨(두번 부르게 됨)
주소와 동적할당(point, refference)
void point(int* ref1, int* ref2) {
int temp = *ref1;
*ref1 = *ref2;
*ref2 = temp;
}
void reff(int& ref1, int& ref2) { //레퍼런스
int temp = ref1;
ref1 = ref2;
ref2 = temp;
}
void main() {
int* ptr1 = new int(3);
int* ptr2 = new int[3] {0, 1, 2};
int* ptr3=new int();
*ptr3 = 10; //주소에 접속해서 참조
int temp=5;
ptr3 =&temp; //기존의 값의 주소추출
cout<<*ptr1<<" "<<*ptr2<<" "<<*ptr3;
point(ptr1,ptr3);
cout<<*ptr1<<" "<<*ptr2<<" "<<*ptr3;
delete ptr1;
delete[]ptr2; //객체 배열은 이렇게 해제
//이중 배열이면 안에 있는 배열들부터 해제요망
delete ptr3;
int ref1 = 1;
int ref2 = 2;
int& ref3 = ref1; //ref1의 분신체
reff(ref1, ref2);
cout << ref1 << " " << ref2;
}
- 주소를 넘기는 방식은
- 일차원 배열은 주소를 가르킴을 알 수 있다.
- 레퍼런스는 그 자체를 그대로 쓰는거고, 주소는 주소를 복사해 같은 곳을 가르킨다는 차이점이 있음
예외처리
void main() {
try
{
int a=10;
int b=0;
if (b == 0) throw "0 이";
cout << a << "를 " << b << "로 나눈 몫은 " << a / b << "입니다." << endl;
}
catch (string & excep)//오류를 던지는 자료형과 자료형이 일치해야함
{
cout << "예외 발생, 나누는 수는 " << excep << " 될 수 없습니다." << endl;
}
}
- c++의 예외처리는 받을 때 자료형을 따진다.
템플릿
template<typename T>
void swapping(T& num1, T& num2)
{
T temp = num1;
num1 = num2;
num2 = temp;
}
void useTemp() {
int num1 = 0, num2 = 1;
swapping<int>(num1, num2); //꼭 명시적일 필욘 없으나 명시적인게 좋다
cout << num1 << " " << num2;
}
- 템플릿으로 자료형을 자유롭게 설정가능한 코드 생성가능
Ghost