독고솜의 인생일지
Day - 1 본문
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://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에서는
정답