독고솜의 인생일지

Day - 1 본문

sbs게임아카데미 프로그래밍 수업/CPP

Day - 1

독고솜 2022. 10. 14. 13:12

 

CPP란?

CPP는 C++로 흔히 C의 개선판 또는 C의 상위 집합이라고 한다.


C++은 원래 객체 지항 프로그램을 만들기 위해 나온 언어로 클래스가 있는 C 라고도 불리기도 한다. 또 한 C++은 C언어의 문법을 상당 이상을 참고한다.

 

 

기본 지식.

 

1. Main 함수

프로그램은 어떠한 정말 매우 특이한 경우의 상황이 없다면 main() 함수에서 시작합니다.

int main은 마지막 반환값인 return 0; 을 기준으로 0을 반환하는데 int main(void) 를 쓰시면 자동으로 0을 반환합니다.

int main(argc~~~~) 어찌고 이런거는 리눅스에서 명령어 쓰거나 그럴떄 인자값을 세탕해 주는 건데 ./run 인자1 인자2 이렇게 프로그램을 실행시킬때 인자값을 주는 것입니다.

 

 

2. 주석  //마지막에~~~~

을 연달아 달아 그 줄의 코드를 //주석 처리 하거나 ( 컴파일 되지 않는 상태를 의미함. 컴파일은 해당 부분은 완전히 무시 )  /* ~~~~~ */ 를 이용한 여러줄을 주석 처리를 할 수 있습니다. VS 단축키 : Ctrl + K , C   해제 C > U

 

 

입출력(cout, endl)
#include <iostream>

int main()
{

    std::cout << "HELLO WORDL!" << std::endl

    return 0;
}

위의 프로그램의 출력값은

HELLO WORLD!

 

먼저 #include <iostream> 은 전처리 지시자 iostream이라는 헤더파일을 불러온다.

iostream에는 cout, endl같은 기본 입 출력등 객체들을 정의한 헤더파일이다.

 

전처리 지시자란?

#include, #define 앞에 #을 붙인 얘들을 의미합니다.
#include : 해당 파일을 현재 위치에 포함 시키는 지시자
#define : 매크로를 생성하는 지시자
#error : 지정한 특정 오류를 발생시키는 지시자

 

iostream 헤더 파일에 있는 내용을 현재 파일에서 가져올 수 있도록 전처리기 해줍니다. 즉 우리 코드에 c++의 내용을 쓸 수 있도록 한 파일에 옮기는 거죠

실제 코드에서의 전처리 과정

만약 더 자세한 과정및 실행파일 과정을 알고 싶으시다면 https://blog.naver.com/pqlamz1020/222353807816 여기를 참고해주세요.

 

printf같은 함수가 아니다!

 

std::cout에서 std는 표준 라이브러리에 있는 변수나 함수 객체들을 사용할려고 했으니, std:: 접두어를 붙어야 한다.

 

std::cou의 특징은 총 2개로

  • 정수, 문자열등 다양한 데이터형식에 대해서 %d같은 서식문자 없이 자동으로 처리해준다.
  • << 표시는 c언어에서 보던 쉬프트 연산자가 아닌 삽입 연산자다. (즉 cout에 "HELLO WORLD와 ENDL를 전달.)

std::endl는문장이 끝났다고 알리는 표준 라이브러리 객체로 자동으로 개행을 해준다

더보기
닫기

아니 그러면 \n 랑 std::endl중 뭘 써야하는데??

 

A tour to C++ 책에서의 판단은 \n이 더 안전하고 좋다고 합니다.

전문가용 C++ 에서는 책에 직접적인 노출은 없었지만 대부분 예제에서 endl를 쓰긴 합니다.

 

또 한 알고리즘문제 푸는 곳 백준같은 곳에서 endl는 리모트에서 오류가 날 확률이 있기 때문에..

하지만 std::endl 가 너무 편한걸..

 

3. 이스케이프 시퀸스 \n......

\n 줄 바꿈
\t
\r 캐리지 리턴
\\ 역슬래시 \
\" 따움표

 

 

예약어 inline 
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

//함수의 선언앞에inline예약어를 적용한다.
inline int DoMax(int _a, int _b);

int main(void){
    

    int tResult = 0;

    tResult = DoMax(3, 2);

    cout << tResult << endl;

    return 0;
}



int DoMax(int _a, int _b)
{
    //삼항연산자
    //(조건식)?A:B
    return (_a > _b) ? _a : _b;

}

함수앞에 inline을 붙여주면 됩니다.

in(안에) line(코드) 즉 코드 라인 내부에 들어간다고 보면 됩니다.

 

코드 상으로는 함수 형태를 띄고있지만, 컴파일 과정에서 한단계식 보면 코드 내부로 들어간걸 볼 수 있습니다.

 

 

장점 단점
함수 호출 비용이 없으므로 실행속도가 빠름 실제로 정확하게 정의할려면 어려움과 컴파일의 inline 거부
  메모리 관점으로 부적합

 

inlining을 실행할지는 컴파일러가 결정하므로 그 여부가 거부될수있습니다.

 

 

namespace
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

const void Doit();
const void Doit();

int main()
{
    Doit();
    Doit();

    return 0;
}


const void Doit()
{
    cout << "DOit()" << endl;
}

const void Doit()
{
    cout << "DOit()" << endl;
}

 

만약 이름이 똑같은 함수를 선언하고 실행한다며 변수의 이름이 같아지므로 오류가 납니다.

이런 충돌을 방지하기 위해 만들어진 것이 namespace입니다

 

쉽게 설명하자면 namespace는 우리가 선언한 함수나, 구조체, 변수의 소속을 정해주는 겁니다

 

A소속 -> Doit

B소속 -> Doit

 

식물반과 병아리반의 소속된 같은 이름만 가지고 있는 함수 예시.

 

 

 

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

namespace Name_0
{
    const void Doit();
}

namespace Name_1
{
    const void Doit();
}


int main()
{


    Name_0::Doit();
    Name_1::Doit();

    return 0;
}

// :: 영역 결정 연산자 (범위 지정 연산자) scope resolution operator
//해당 부품이 어디에 속하는지를 나타내는 연산자
const void Name_0::Doit()
{
    cout << "DOit()" << endl;
}

const void Name_1::Doit()
{
    cout << "DOit()" << endl;
}

 

선언은

namespace [어디소속?]

{

함수, 구조체, 객체등등

}

 

소환

[소속]::[함수이름]

 

:: 땀아니야?

땀이 아니라 범위 확인 연산자로 서로 다른 범위에서 사용되는 식별자를 식별하고 구분하는 데 사용됩니다.

 

 

using namespace std;

using namespace std;

std::cin std::cout 을 붙이기 귀찮다면 std::를 때고 항상 사용할 수 있게 해줍니다

즉 using namepsace std는 std라는 소속을 가진녀석들을 사용하겠다는 뜻입니다.

 

하지만

C++17 권장 기준및 책의 서필기준으로

using namespace std; 의 사용은 위험을 초발한다고 합니다

 

간단하게 말하면 함수 겹침및 여러 가지 이유가 있는데 자세한 건

https://hyuncpp.tistory.com/entry/using-namespace-std%EC%9D%98-%EC%9C%84%ED%97%98%EC%84%B1%EC%97%90-%EA%B4%80%ED%95%98%EC%97%ACPS 

(와 국대)

 

using namespace std의 위험성에 관하여(PS)

글 제목이 다소 자극적으로 보일 수 있어서 결론부터 말씀드리겠습니다.  using namespace std는 저희가 짜는 코드(PS)에는 매우매우매우매우 안전합니다. C++을 통해 PS 코드를 작성하게 될 때 꽤 많은

hyuncpp.tistory.com

https://sexycoder.tistory.com/16

 

참고하시고 가급적 C++ 17? 인가에서 추가된 특정함수만 std::를 안붙이게 사용하게 

using std::cout;
using std::endl;
using std::cin;

이런 것만 사용하는걸 추천드리는.. 개인적인 의견입니다.

 

cpp_default_param

 

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

int DoAddintive(int _A, int _B); //함수는 기능 부품

int CalcuAttackDamage(int _Strength = 0, int _HP = 1, int _HitRatio = 1); // 선언할 때 기본값을 지정해 줄 수 있다.

//기본값은 맨 오른쪽 뒤에서부터 차례대로 채워야 한다
int CalcuDefensePoint(int _Stength , int _HP = 3);

int main()
{
    
    int tResult = DoAddintive(3, 4);
    cout << tResult << endl;

    tResult = CalcuAttackDamage(3, 4, 5);
    cout << tResult << endl;

    tResult = CalcuAttackDamage();
    cout << tResult << endl;


    tResult = CalcuAttackDamage(6);
    cout << tResult << endl;


    tResult = CalcuDefensePoint(2,5);
    cout << tResult << endl;
    return 0;
}


int DoAddintive(int _A, int _B)
{
    return _A + _B;
}

int CalcuAttackDamage(int _Strength, int _HP, int _HitRatio)
{
    return _Strength * _HP + _HitRatio;
}

int CalcuDefensePoint(int _Stength, int _HP)
{
    return _Stength * _HP;
}

 

이렇게 매개변수의 기본 값을 선언해줄 수 있습니다.

 

단.

//기본값은 맨 오른쪽 뒤에서부터 차례대로 채워야 한다
int CalcuDefensePoint(int _Stength , int _HP = 3);

기본값은 맨 오른쪽부터 차례대로 채워야 합니다.

 

int CalcuDefensePoint(int _Stength = 2, int _HP);

오류 발생.

 

 

 

Reference 참조자

 

int main(void)
{
    int x = 32;
    int& reference = x;

    reference = 40;

    cout << reference << " " << x << endl;


}

둘다 40 40 출력

 

변수의 타입 뒤에 &가 붙으면 레퍼런스가 됩니다.

즉 원본 변수에 대한 포인터 취급.

 

만약 두 변수의 주소를 확인한다면 동일한 주소가 나옵니다. 

C++은 동일한 버퍼에 주소에 여러개의 이름을 부여할 수 있는 겁니다.

즉 두개의 함수는 동일한 주소를 가르키니까 하나의 값만 바까도 따라서 바뀝니다

 

C++은 뛰어난 Call by Reference 제공하는데요

 

void addOne(int i) // 복제본이 전달 call by value

void addOne(int& i) // 원본 변수 지급 call by reference

 

call by address

//call by address

inline const void swaps(int* _a, int* _b)
{
    int temp = 0;
    temp = *_a;
    *_a = *_b;
    *_b = temp;
}

swaps(&a, &b);

call by reference

inline const void swaps(int& _a, int& _b)
{
    int temp = 0;
    temp = _a;
    _a = _b;
    _b = temp;
}

 

 

 

1. 참조자의 타입은 대상이 되는 변수의 타입과 일치해야 합니다.
2. 참조자는 선언과 동시에 초기화되어야 합니다.
3. 참조자는 한 번 초기화되면, 참조하는 대상을 변경할 수 없습니다.

int main(void)
{
	int &ref1; // 초기화 되지않았으므로 error!

	int &ref2 = 3; // 상수가 올 수 없으므로 error!

	return 0;
}

 

https://underground2.tistory.com/151

 

 

malloc free 절대 쓰면 안됩니다.

CPP에서는

 

 

 

 

정답