Using
동일한 이름을 가진 변수,함수가 생길 수 있다.
클래스,namespace가 다르게 해결할 수 있다.

모호성(Ambiguity)
using namespace로 여러 namespace를 불러오면 똑같은 변수가 있을 수 있다.
그러면 namespace를 생략하고 사용할 수 없다.
namespace명::변수명 으로 사용하던지 아니면 {}영역을 구분줘서 사용해야한다.

using namespace를 선언하면 취소할 수 없다.
최대한 분리하여 사용하자.

#include <iostream>

namespace a
{
	int a1(2);
}
namespace b
{
	int a1(3);
}

int main()
{
	//std::를 생략할 수 있다.
	using namespace std;
	//아래처럼 하나만 불러와 사용할 수 있다.
	//using std::cout;

	//cout << "hello" << endl;

	//아래 두namespace에 똑같은 이름의 변수가 있다.
	//사용할려면 영역을 분리해서 사용하자
	{
		using namespace a;
		cout << a1 << endl;
	}
	{
		using namespace b;
		cout << a1 << endl;
	}
	

	return 0;
}

auto 키워드

큰프로그램을 작성하면 많은 변수를 작성하게 된다.
변수의 자료형을 프로그래머가 매번 정하면 효율이 떨어지게된다.

auto는 형추론을 통해 자동으로 자료형을 정해준다.
auto는 형추론을 해야하기해 자동화를 해주어야한다.

함수 리턴타입도 auto로 설정할 수 있다.
함수 리턴 값도 변수로 저장할때 auto로 설정가능하다.
파라미터타입은 auto로 설정할 수 없다.

파라미터타입 설정은 template로 사용할 수 있다.

#include <iostream>

//리턴타입을 auto로 설정했다.
auto add(int a, int b)
{
	return a + b;
}

//-> double방식으로 설정할 수 있다.
auto add(double a, double b) -> double
{
	return a + b;
}

int main()
{
	using namespace std;

	//int a = 123;
	//int형
	auto a = 123;
	//double형
	auto b = 23.4;

	//함수 리턴 값도 auto로 설정가능하다.
	auto result = add(1, 3);
	
	return 0;
}



전역변수(Global Variable)

cpp파일 모두에서 사용할 수 있는 변수를 전역변수(Global Variable)이라 한다.
전역변수는 가급적 사용을 하지 않아야 한다.
부득이한 경우로 사용할 상황도 생긴다.

정적변수(Static Variable)
디버깅,테스트할때 자주 사용한다.
변수 선언할때 static을 선언해 준다.
정적변수는 초기화해 사용해야 한다.

전역변수와 정적변수의 차이점

static이 없으면 일정 범위 안에서 변수가 선언될 때 메모리를 할당받고 반납하고 반복한다.
여러 함수에서 전역변수를 수정하면 문제가 생길 수 있다.

static이 있으면 영역안에 변수가 선언될 때 메모리를 할당받고 초기화하지 않는다.
변수가 선언되어있으면 재사용한다.

지역변수(local vriable),정적변수(static vriable)는 
{} 지역 안에서 사용하기 때문에 변수가 다른 곳에 영향을 주지 않는다.


내부연결
전역변수를 cpp 안에서만 사용하게 하려면 static을 선언해준다.
한 cpp파일에서만 전역변수가 사용되는 것은 내부연결(Internal Linkage)이라고 한다.

외부연결
extern선언을 이용해 여러 cpp파일에서 한 변수, 함수를 사용할 수 있다.

static : 다른 cpp 파일로부터 접근이 안된다.
const : 값을 변경 못한다.
extern : 다른 cpp파일에서 접근이 가능하다. 초기화하면 다른 곳에선 초기화를 해주면 안 된다.
extern const: 다른 cpp파일에서 접근 가능하다. 초기화해주어야 한다.

 

MyConst.h

#pragma once
//#pragma once 헤더 파일 중복 include를 막아준다.

namespace Constants
{
	//전체적으로 사용되는 상수를 선언한다.
	extern const double pi;
	extern const double grivity;

}

main.cpp

#include <iostream>
#include "MyConst.h"

using namespace std;

//전역변수 선언
int a = 123;
//정적변수 선언
void getTest()
{
	//정적변수는 꼭 초기화해야한다.
	static int a = 1;
	++a;
	cout << a << endl;
}

//다른 cpp 함수,변수 사용하기
//forward declaration
//어딘가에 있을 함수를 찾는다.
//extern 선언이 생략되어 있다.
//extern void getCppTest();
//프로그램전체에서 확인한다.
void getCppTest();
extern int a2;

int main()
{
	//전역변수(Global variabel)이 출력된다.
	cout << a << endl;
	//지역변수(local variabel)이다.
	//범위가  {}로 정해진다.
	int a = 0;

	//지역변수(Global variabel)가 출력된다.
	cout << a << endl;

	//전역연산자를 사용하면 전역변수로 출력기가능하다.
	cout << ::a << endl;

	//static을 선언해 정적변수를 사용하기 Test
	//getTest()함수를 불러오면
	//static int a를 메모리에 할당받는다.
	getTest();
	//두번째 함수 출력때 static이 있으면 변수가 선언되 있으면 재사용한다.
	getTest();

	getCppTest();

	cout << a2 << endl;
	//header에 상수를 선언해 test에서 불러오면 Constants와 메모리 주소가 다르다.
	//cpp파일을 만들어 extern header엔 정의만하고 cpp 파일에서 extern으로 정의해주면
	//같은 메모리 주소를 사용하는 걸 볼 수 있다.
	cout << "main : " << Constants::pi << " 주소: " << &Constants::pi << endl;
	return 0;
}

MyConst.cpp

namespace Constants
{
	//전체적으로 사용되는 상수를 선언한다.
	extern const double pi(3.141592);
	extern const double grivity(9.8);

}

test.cpp

#include <iostream>
#include "MyConst.h"

//초기화를 해줘야한다.
extern int a2 = 0;
void getCppTest() 
{
	using namespace std;
	cout << "test : " << Constants::pi << " 주소: " << &Constants::pi << endl;
	
}

지역변수
지역안에서 선언된 변수

범위 Scope
- 어디까지 적용되는가?
지속기간 Duration
- 메모리에 언제까지 적재되는가?


{}으로 지역을 구분한다. 

{}블록안에서 선언된 변수는 {}블록에서만 사용가능하다.
같은 블록안에서는 같은이름으로 변수를 선언하면 에러가 난다.
하지만 {{}}내부블록 안에서는 같은이름의 변수가 선언이 가능하다.
내부블록에서는 밖에 선언된 같은이름의 함수는 숨기고
내부블록안에 선언된 변수를 사용한다.

함수도 같은 이름은 불가능 하다.
하지만 파라미터가 다르다면 다른 함수로 볼 수 있다.

같은 이름의 함수를 사용하지 않는것이 좋지만
만약에 사용할려면 namespace를 사용해 사용한다.
namespace안에 namespace를 선언할 수 있다.

변수는 가급적 사용하는곳에서만 살아남게 선언한다.
객체지향프로그래밍의 기본적인 철학이다.

 

동적할당에선 범위,지속기간이 분리된다. 

#include <iostream>

using namespace std;

//만약에 같은이름의 변수와,함수를 사용하고 싶다면
//namespace를 사용한다.
namespace work1
{
	int a = 0;
	void getTest() {
		a += 1;
		cout << "work1::getTest() : " << a << endl;
	}
	
}


int a = 0;
void getTest() {
	a += 2;
	cout << "getTest() : " << a << endl;
}

int main()
{
	
	//apple변수를 선언해서 사용할 수 있게 된다.
	//OS로 부터 int메모리를 할당 받는다.
	//int main(){}안에서 사용가능 하다.
	int apple = 5;
	cout << apple << endl;
	if(true)
	{
		//{}밖에서 선언된 변수는 안 {}에서도 사용가능 하다.
		//apple변수가 위에 되어있기에 사용할 수 있다.
		//apple = 1;
		//cout << apple << endl;
		
		//같은이름으로 변수 선언이 가능하다.
		//내부 {} 안에서만 적용된다.
		//외부에 있는 apple은 같은 이름이 선언될 경우 숨긴다.
		//가급적이면 이름을 다르게 정하는것이 좋다.
		int apple = 1;
		cout << apple << endl;

		getTest();
		work1::getTest();
	}
	cout << apple << endl;

	return 0;
}

비트단위연산자
각각의 비트끼리 계산하는 연산자
int등의 계산은 타입단위 계산이다.

과거에는 메모리가 충분하지 않았다.
bool은 0,1만으로 표현되지만 1Byte를 사용해야한다.

비트단위연산자를 통해 데이터를 많이 채워 넣을 수 있다.
그리고 속도가 더빨라진다.

<<,>>,~,&,|,^ 여섯가지가 있다.
<<,>>는 cout,cin에서 사용하는 것과는 다르다.

 

#include <iostream>
//2진수로 변경해주는 라이브러리
#include <bitset>

using namespace std;

int main()
{
	//<<,>>는 cout,cin 에서 사용하는건 다른 의미이다.

	unsigned int a = 3;

	//2진수가 출력된다.
	cout << std::bitset<4>(a) << " : " << a << endl;

	//이진수를 오른쪽으로 한자리씩 보낸다. 2면 두자리 이동한다.
	//1일때 6,2일때 12,3일때 24 2제곱(연산숫자)로 계산되는걸 알 수 있다.
	//2의 제곱을 곱하고 싶을경우에 훨씬 빠르게 사용할 수 있다.
	unsigned  int b = a << 4;

	cout << std::bitset<4>(b) << " : " << b <<  endl;

	a = 1024;
	//2진수가 출력된다.
	cout << std::bitset<16>(a) << " : " << a << endl;
	//<<와 반대로 나누기가 2가된다.
	b = a >> 1;
	cout << std::bitset<16>(b) << " : " << b << endl;
	b = a >> 2;
	cout << std::bitset<16>(b) << " : " << b << endl;
	b = a >> 3;
	cout << std::bitset<16>(b) << " : " << b << endl;
	
	//~ NOT 반대로 출력된다.
	cout << std::bitset<16>(a) << " : " << a << endl;
	cout << std::bitset<16>(~a) << " : " << ~a << endl;

	//&,^,|을 확인해보자.
	//AND,OR,XOR의 조건에 맞게 출력된다.
	//2진수 출력하기
	a = 0b1100;
	b = 0b0110;

	//아래형식으로 쓸 수 있다.
	a &= b;

	cout << std::bitset<4>(a & b) << endl;
	cout << std::bitset<4>(a | b) << endl;
	cout << std::bitset<4>(a ^ b) << endl;

	return 0;
}

비트플래그

bool타입은 1Byte라 8bit를 사용한다.

생각해보면 메모리 낭비가 심하다.

1바이트는 8bit이기에 bool타입을 8가지 정보를 사용할 수 있다.

메모리를 낭비하지않고 정보를 담고 싶을때 유용하게 사용할 수 있다.
게임 아이템 정보에 많이 사용된다.

#include <iostream>
#include <bitset>

using namespace std;

int main()
{
	//4가지 아이템이 있다고 가정해보자.
	bool item1_flag = false;
	bool item2_flag = false;
	bool item3_flag = false;
	bool item4_flag = false;

	//아이템이 많아지면 bool변수를 많이 만들어야한다.
	//함수를 만들면 최대 아이템갯수가 파라미터 갯수가 될 수도 있다.
	
	//아이템은 가지고있다,없다 두가지로 생각할 수 있다.
	
	//아이템이 8가지 종류가 있다는 가정하에 char를 사용한다.
	
	const unsigned char opt0 = 1 << 0;
	const unsigned char opt1 = 1 << 1;
	const unsigned char opt2 = 1 << 2;
	const unsigned char opt3 = 1 << 3;

	cout << std::bitset<8>(opt0) << endl;
	cout << std::bitset<8>(opt1) << endl;
	cout << std::bitset<8>(opt2) << endl;
	cout << std::bitset<8>(opt3) << endl;

	unsigned char items_flag = 0;
	//00000000이 출력된다.
	//8자리의 숫자로 숫자하나당 각자 아이템 소유정보를 저장한다.
	cout << "NoItem : " << std::bitset<8>(items_flag) << endl;
	
	//|= OR를 사용해 아이템 습득 정보를 변경할 수 있다.
	//0번째 자리의 아이템을 습득했다.
	items_flag |= opt0;
	cout << "0Item Get : " << std::bitset<8>(items_flag) << endl;
	
	items_flag |= opt3;
	cout << "3Item Get : " << std::bitset<8>(items_flag) << endl;

	//&= 와 ~을 이용해 아이템 분실을 변경 할 수 있다.
	//opt0 = 00000000이다.
	//~opt0 = 11111111이다.
	//AND조건을 사용하면 둘다 1일때만 1이기에 아이템정보를 0으로 변경한다.
	items_flag &= ~opt0;
	cout << "0Item Lost : " << std::bitset<8>(items_flag) << endl;

	//아이템 보유여부 확인
	if (items_flag & opt3) {
		cout << "3번아이템 보유중" << endl;
	}

	//아이템 보유여부 확인
	if (items_flag & opt0) {
		cout << "0번아이템 보유중" << endl;
	}
	else {
		cout << "0번아이템 없음" << endl;
	}
	
	//두가지 아이템 습득할 경우
	//opt0 | opt1 는 00000011이다.
	items_flag |= (opt0 | opt1);

	if ((items_flag & opt1) && !(items_flag & opt2)) {
		items_flag ^= opt1;
		items_flag ^= opt2;
	}
	cout << std::bitset<8>(items_flag) << endl;


	unsigned int pixel_color = 0xDAA520;

	cout << std::bitset<32>(pixel_color) << endl;

	unsigned char red, green, blue;
	return 0;
}

함수보단 연산자(Operator)를 사용하는 게 편하다.
한식에 더하기,곱하기가 있으면 우선순위를 정해야 한다.

기본상식
- ()가 없어도  + 보단 *가 먼저다.
- ()가 있으면 우선순위 변경된다.

결합법칙 *,/가 있으면 우선순위가 어찌 정해질까?
*,/,%는 같은 우선순위를 가지고 있다. 
Left to Right형식으로 왼쪽부터 계산한다.

위와 같은 룰들이 있지만 ()를 통해 우선순위를 명확히 표현하는 것이 좋다.

Unary plus

*는 +보다 우선순위가 높지만 +3,-3은 우선 순위가 높다.

2^3은 2의 3제곱이아니다.
cmath를 사용해 제곱한다.

#include <iostream>
//제곱 사용
#include <cmath>
using namespace std;

int main()
{
	//함수보단 연산자(Operator)를 사용하는게 편하다.
	//한식에 더하기,곱하기가 있으면 우선순위를 정해야한다.
	//()가 없어도  + 보단 *가 먼저다.
	//()가 있으면 우선순위 변경된다.
	int x = 4 + 2 * 3;
	x = (4 + 2) * 3;

	//결합법칙 *,/가 있으면 우선순위가 어찌 정해질까?
	// *,/,% 같은 우선순위를 가지고 있다. 
	//Left to Right형식으로 왼쪽부터 계산한다.
	x = 3 * 4 / 2;

	//위와 같은 룰들이 있지만 ()를 통해 우선순위를 명확히 표현하는것이 좋다.
	
	//Unary plus
	//+3,-3은 우선 순위가 높다.
	x = +3;
	x = 3 + -3;

	//2^3은 2의 3제곱이아니다.
	//cmath를 사용해 제곱한다.
	x = std::pow(2, 3);
	cout << x << endl;

	return 0;
}

/ 는 나누기이다.
c++에서 int,float 나누기는 서로 다르다.
숫자가 하나라도 실수라면 실수로 출력된다. 

int형을 나누기 하게되면 정수이여야 하기 때문에 소수를 절삭한다.

% 나머지연산자는 왼쪽 숫자의 부호를 따른다.

#include <iostream>

int main()
{
	using namespace std;

	int x = 1;
	int y = -x;
	
	cout << y << endl;

	y = 2;

	int z = x + y;
	cout << z << endl;


	//% 는 나머지이다.
	//int,float 나머지는 서로 다르다.
	//숫자가 하나라도 실수라면 실수로 출력된다. 
	x = 7;
	y = 4;
	cout << x / y << endl;
	cout << float(x) / y << endl;

	//int형이면 정수이여야하기 때문에 0.5를 절삭한다.
	//2가 출력된다.
	cout << -5 / 2 << endl;

	//% 나머지연산자는 왼쪽숫자의 부호를 따른다.
	cout << -5 % 2 << endl;

	//x가 가르키고있는 메모리의 정보를 z가 가르키고있는 메모리에 저장한다.
	z = x;
	//z = z + y;와 같다.
	//코딩할 때 코드의 양을 줄여준다.
	//오타를 줄일 수 있다.
	//+=,*=,/=,%= 다 가능하다.
	z += y;

	return 0;
}

증감연산자

많이 쓰이고 쉽지만 실수할 때가 많다.

++,--의 특징은 앞에 붙일 수 있고 뒤에도 붙일 수 있다.

++,--가 앞에 붙으면 먼저 계산하지만 뒤에 붙으면 작업 후 마지막에 계산한다.

#include <iostream>

using namespace std;

int add(int a, int b)
{
	return a + b;
}

int main()
{

	int c = 6;

	//아래형식으로 코딩하면 안된다.
	//cout << add(c, ++c) << endl;

	int y = 2;

	cout << add(c, ++y) << endl;

	return 0;
}

sizeof
데이터형의 크기를 알고 싶을 때 사용한다.
struct, class 등 사용자가 만든 자료형도 크기를 확인할 수 있다.
Byte로 출력된다.
int = 4Byte = 32bit

sizeof는 연산자(operator)이다.

쉼표 연산자
,comma operator
주의를 하며 사용해야 한다.
int c = (++a, ++b);는
++a;
++b;
c = b;와 같다.

c = a, b;는
왼쪽 값을 메모리에 저장한다.
,는 =보다 연산자 순위가 낮다.
뒤에 값을 넣어주고 싶다면 c = (a,b);로 해준다.

for문이 아니면 풀어서 여러 줄로 사용하는 게 좋다.

조건부 연산자(삼항 연산자)
conditioanl operator
int a = 3 > 4 ? 1 : 0;
조건이 맞다면 왼쪽 값 다르다면 오른쪽 값을 메모리에 저장한다.

#include <iostream>

using namespace std;

int main()
{
	//sizeof 변수,타입 모두 넣을 수 있다.
	//struct,class등 사용자가 만든 자료형도 크기를 확인할 수 있다.
	cout << sizeof(int) << endl;
	int a = 3;
	cout << sizeof a << endl;

	int b = 10;
	/*int c = (++a, ++b);
	cout << c << endl;
	cout << a << endl;*/
	int c;
	c = a, b;
	cout << c << endl;

	bool sale = true;

	//조건부연산자.
	const int price = (sale == true) ? 10 : 100;

	cout << price << endl;

	cout << ((10 % 2 == 0) ? "GOOD" : "BAD") << endl;
	return 0;
}

관계 연산자
숫자 두 개를 비교하는 연산자이다.

실전에서 일어날 수 있는 문제점들이 있다.
== 같다.
!= 다르다.
> 왼쪽이 크다.
< 오른쪽이 크다.
>= 왼쪽이 크거나 같다.
<= 오른쪽이 크거나 같다.

float부동소수점끼리 비교는 문제점이 있다.
100 - 99.99와 10 - 9.99 두 가지를 비교하면 같지 않게 나온다.
오차의 한계를 개발자가 지정해 비교한다.

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
	double d1(100 - 99.99);
	double d2(10 - 9.99);
	//0.01이 출력된다.
	cout << d1 << endl;
	//0.01이 출력된다.
	cout << d2 << endl;
	cout << d1 - d2 << endl;

	
	if (d1 == d2)
		cout << "같다" << endl;
	else
		cout << "다르다" << endl;

	//오차의 한계를 사람의 손으로 지정한다.
	const double epsilon = 1e-10;
	cout << epsilon << endl;
	cout << std::abs(d1 - d2) << endl;
	if (std::abs(d1 - d2) < epsilon)
		cout << "거의 같다" << endl;
	else
		cout << "다르다" << endl;

	return 0;
}

문자형 char
컴퓨터 내부에선 모두 숫자(ASCII CODE)로 표현된다.

32~127번까지는 화면에 출력가능한 숫자가 나온다.

한글자는 'a'('')로 표현 문자열은 "Hello, Wolrd"("") 로 표현한다.

cin으로 여러개의 문자를 입력받으면 첫글자를 저장하고 나머지 문자는 버퍼(임시저장소)에 저장한다.

\n(줄바꿈),\t(줄간격맞추기)등 \로 시작하는 문자는 여러 기능을 수행한다.
",'등을 출력하고 싶으면 \를 사용한다. ex)\'안녕\'
\n은 가시적으로 두글자로 보이지만 한글자로 적용된다.

\n과 endl의 차이점
\n이 있으면 버퍼에 저장된다.
endl이 있으면 무조건 출력한다(버퍼에 있는걸 모두 출력한다).

#include  <iostream>

int main() 
{ 
using namespace std; 

//둘다 A가 출력된다. 
char c1(65); 
char c2('A'); 

//윈도우용 프로그램에서 사용 
wchar_t c; 
//이모티콘등 unicode를 사용가능하다. 
char32_t c3; 

cout << c1 << " " << c2 << endl; 

//캐스팅 
//C style 
cout << (char)65 << endl; 
cout << (int)'A' << endl; 

//C++ style 
cout << char(65) << endl; 
cout << int('A') << endl; 

//위에 캐스팅은 강제로 변환하는 개념이다. 
//아래 방법은 기본타입을 변환할때 컴파일러에게 확인후 변환한다. 
cout << static_cast(65) << endl; 
cout << static_cast('A') << endl; 

char ch(97); 
cout << ch << endl; 
cout << static_cast(ch) << endl; 
cout << ch << endl; 

//버퍼 테스트 abc 입력하면 바로 출력된다. 
cin >> c1; 
cout << c1 << " " << static_cast(c1) << endl; 
cin >> c1; 
cout << c1 << " " << static_cast(c1) << endl;  
cin >> c1; 
cout << c1 << " " << static_cast(c1) << endl; 


//범위 체크 
cout << sizeof(char) << endl; 
cout << (int)std::numeric_limits::max() << endl; 
cout << (int)std::numeric_limits::lowest() << endl; 

cout << sizeof(unsigned char) << endl; 
cout << (int)std::numeric_limits::max() << endl; 
cout << (int)std::numeric_limits::lowest() << endl; 

cout << '\a' << endl; 

return 0; 
}

리터럴 literal 

상수란? 변하지 않는 것
3.14

const를 사용하면 변수의 값을 변경할 수 없다.

 

#include <iostream>

int main()
{
	using namespace std;
	//상수 변하지 않는것.
	3.14;

	//pi는 메모리에 공간을 차지하고 있다.
	//pi는 변수이다.
	float pi = 3.14f;

	//signed unsigned로 변경
	//int i = -12345u;
	//위 아래 같다.
	//i = (unsigned)-12345;

	//const 값을 변경할 수 없다.
	const float pi2 = 3.14;
	
	//Decimal 10진수
	// 0 1 2 3 4 5 6 7 8 9
	//Octal 8진수
	// 0 1 2 3 4 5 6 7 10 11 12 13
	//Hexa 16진수
	// 0 2 3 4 5 6 7 8 9 A B C D E F

	//0이붙으면 8진수로 인식한다.
	int x = 012;
	cout << x << endl;

	//0x가 붙으면 16진수로 인식한다.
	x = 0xF;
	cout << x << endl;

	//0b가 붙으면 2진수로 인식한다.
	x = 0b0111;
	cout << x << endl;

	//리터럴 상수
	//10은 갯수이다.
	int price = x * 10;

	//매직넘버(상수)를 입력하는 것보단 만들어 사용한다.
	//주석 대신 사용한다.
	const int price_num = 10;
	price = x * price_num;

	return 0;

}

심볼릭 symbolic

 

#define PRICE 30;
기존 c사용자는 매크로를 사용했다.

 

매크로의 단점
맨위에 설정해놓기에 디버깅이 힘들다.
매크로의 적용범위가 쓸모없이 너무 넓어진다.

 

매크로 대신 const를 사용한다.

적용범위 안에서 표현해서 사용하는것이 좋다. 
const int price = 30;

심볼릭 상수란?
const 를 헤더파일로 만들어 모아놓으면 사용하기 좋다.
헤더파일로 만들어 놓으면 재사용이 용이하다.
또 한곳에 모여있으면 코드 변경이 쉽고 영향력이 넓어진다.

main.cpp

#include  <iostream>
#include "MY_CONSTANTS.h" 

using namespace std; 

//파라미터를 변경하지 못하게 const로 생성한다. 
void printNumber(const int num) 
{ 
//이함수 안의 영역에 num 생성되고 
//호출될때 인자 4가 입력된다. 

//값을 변경할 시 변수를 생성한다. 
int n = num; 
n = 456; 
cout << num << endl; 
} 

int main() 
{ 
//값을 변경할 수 없다. 
//컴파일러가 변경을 막아준다. 
const double gravity{ 9.8 }; 
//const위치는 상관없으나 보통 앞에 붙인다. 
double const gravity2{ 9.8 }; 

//아래 코드는 에러가 난다. 
//gravity = 3.2; 

printNumber(4); 

//컴파일할 때 생성되기에 컴퓨터가 알 수 있다. 
const int my_const(123); 
//constexpr은 컴파일할때 생성되는 함수를 표현할 때 사용한다. 
constexpr int my_const2(123); 
int number; 
cin >> number; 

//아래 const는 실행을 해봐야 알 수 있다. 
const int special_num(number); 
//constexpr을 사용하면 에러가 난다. 
//constexpr int special_num2(num); 

//기존 c사용자는 매크로를 사용했다. 
//맨위에 설정해놓기에 디버깅이 힘들다. 
//매크로의 적용범위가 너무 넓어진다. 
#define PRICE 30; 
//아래로 사용하는 것이 좋다. 
const int price = 30; 

//헤더파일로 const를 뺴놓는다 
double d1 = constants::pi; 

return 0; 
} 


MY_CONSTANTS.h

#pragma once 

namespace constants 
{ 
constexpr double pi(3.141592); 
constexpr double avogadro(6.02214); 
}

'개발 소발 > 개발 C++(기초)' 카테고리의 다른 글

c++ 비트단위연산자,비트플래그란?  (0) 2019.07.04
c++ 연산자종류  (0) 2019.07.03
c++ 정수형,부동소수점수란?  (0) 2019.06.28
c++ namespace란?  (0) 2019.06.26
c++ 헤더파일 만드는 이유  (0) 2019.06.26

정수형 (integers)

문자
-char 1Byte

 

정수의 종류
- Short 2Byte
- int 2Byte(대부분 4Byte)
- long 4Byte
- long long *byte(C99/C++11 type)

컴파일러 스펙에 처리용량이 따라 달라질 수 있다.

int i = 1;
00000000 1Byte
00000000 1Byte
00000000 1Byte
00000001 1Byte

int형은 위처럼 4Byte로 구성 첫 한 비트는 부호에 사용된다.


주의할 점(OverFlow)
표현할 수 있는 숫자를 넘어가는 수가 들어오면 반대로 가장큰 수가 저장된다.
- 가장큰수를 넘어가면 가장작은수
- 가장 작은수를 넘어가면 가장큰수

 

#include <iostream>
#include <cmath>
#include <limits>

using namespace std; 

int main() 
{ 
short s = 32767; 
int i = 1; 
long l = 1; 
long long ll = 1; 

//2출력 
//00000000 00000001 
cout << sizeof(s) << endl; 
//최대출력수 보기 32767 
cout << pow(2, sizeof(short) * 8 - 1) - 1 << endl; 
cout << numeric_limits::max() << endl; 
cout << numeric_limits::min() << endl; 
cout << numeric_limits::lowest() << endl; 

s = s + 1; 
//-32768이 출력된다.  
//이 현상을 overflow라고 한다. 
//2진수로 표현할 수 있는 숫자를 넘어가면 가장 작은 수로 변경된다. 
cout << s << endl; 


//2진수로 표현할 수 있는 가장 작은 숫자를 넘어가면 가장큰 수로 변경된다. 
s = numeric_limits::min(); 
s = s - 1; 
//32767이 출력된다. 
cout << s << endl; 


unsigned int i2 = -1; 
//overflow가 발생하여 큰 숫자가 출력된다. 
cout << i2 << endl; 

//int형으로 저장한다. 
int i3 = 22 / 4; 
cout << i3 << endl; 


//4출력 
cout << sizeof(i) << endl; 
//4출력 
cout << sizeof(l) << endl; 
//8출력 
cout << sizeof(ll) << endl; 

return 0; 
}

 

C++ 11 고정 너비 정수
Fixed-width Integers

int 형이 플랫폼마다 byte사용량이 다를 수 있다.

불확실성이 있으면 프로그래밍에 불안이 된다.
이로인해 고정 너비 정수가 나오게되었다.

멀티플랫폼 프로그래밍때 사용된다.

cstdint를 include해서 사용한다

int16_t : 16bit 2byte로 변경한다.
int8_t : 8bit 1byte로 변경한다.
주의점 : 8bit는 char형태라 문자로 변경된다.

자세한것은 나중에 사용할때 알아보기로하자.

#include <iostream>
#include <cstdint>

int main() 
{ 
using namespace std; 

//2Byte로 변경 
int16_t i(5); 
//1Byte로 변경 char형태 
//특별히 쓸일 아니면 쓰지말자 
int8_t myInt = 65; 

//A로 출력된다. 
cout << myInt << endl; 

return 0; 
}

 

부동소수점수
floating point numbers

실수 다루기
실수는 정수보다 더 정밀한 숫자이다.

부동소수점수 종류

이름 float double Long double
최소크기 4Byte 8Byte 8Byte
전형적인크기 4Byte 8Byte 8,12 or 16Byte

최근에 나온 언어들은 double기본으로 사용하나
큰 메모리를 사용하는 프로젝트에선 float가 좋다.

1.0/3.0을 하면  0.3333333333333333333333333~~~이될텐데
0.333333으로 출력된다.

iomanip안에 setprecision을 사용하여 출력 숫자를 늘릴 수 있다.

 

숫자 무한대도 표현이 된다.


5.0/0.0 inf
-5.0/0.0 - -inf
0/0 -nan(ind)
로 출력된다.

cmath를 include해서 isnan,isinf함수로 확인을 할 수 있다.

주의할 점: 컴퓨터의 계산방법은 우리생각과 다를 수 있다.

#include <iostream>
#include <iomanip>
#include <limits>

int main() 
{ 
using namespace std; 


//3.14 == 31.4 * 0.1 
//31.4e-1는 같다 
//e는 십진수 e-1은 10의 -1제곱 
float f(3.141592f); 
double d(3.141592); 
long double ld(3.141592); 

cout << sizeof(float) << endl; 
cout << sizeof(double) << endl; 
cout << sizeof(long double) << endl; 

cout << numeric_limits::min() << endl; 
cout << numeric_limits::min() << endl; 
cout << numeric_limits::min() << endl; 


//iomanip로 출력 숫자를 정할 수 있다. 
cout << 1.0 / 3.0 << endl; 
cout << setprecision(16) << 1.0 / 3.0 << endl; 

//출력할 수 있는 가장 가까운 수를 출력한다. 
d = 0.1; 
cout << d << endl; 
cout << setprecision(17) << d << endl; 

return 0; 
}

'개발 소발 > 개발 C++(기초)' 카테고리의 다른 글

c++ 연산자종류  (0) 2019.07.03
c++ 문자형,리터럴상수,심볼릭상수 란?  (0) 2019.07.01
c++ namespace란?  (0) 2019.06.26
c++ 헤더파일 만드는 이유  (0) 2019.06.26
c++ 키워드,식별자란?  (0) 2019.06.26

namespace(명칭공간) 사용이유
- 이름이 같은 함수가 있으면 에러가 난다.
- 같은 함수명을 유지하고 싶을때 namespace를 생성하여 함수명을 유지한다.

namespace특징
- namespace안에 namespace를 생성할 수 있다.
- namespace안에 함수를 불러 올때 ::을 사용한다.
- namespace도 다른 함수,변수들과 공통된 이름은 생성하지 못한다.
- std::cout처럼 사용하기 귀찮다면 using namespace std;를 사용하면 cout을 사용할 수 있다.
- 같은 코드안에 같은 함수명이 있다면 에러난다.

 

#include <iostream>

using namespace std;

namespace NamespaceTest
{
	int test(int a, int b)
	{
		return a + b;
	}
	namespace InnerSpace
	{
		int test(int a, int b)
		{
			return a + b;
		}
	}
}

namespace NamespaceTest2
{
	int test(int a, int b)
	{
		return a + b;
	}
	 
}


int main()
{

	using namespace NamespaceTest;

	//using namespace NamespaceTest; 를 통해 test함수를 바로 쓸 수 있다.
	cout << test(1, 3) << endl;
	//NamespaceTest namespace안에 InnerSpace를 불러올 수 있다.
	cout << InnerSpace::test(1, 3) << endl;
	//함수명은 같지만 다른 namespace에 있는 함수를 사용할 수 있다.
	cout << NamespaceTest2::test(1, 3) << endl;

	return 0;
}

'개발 소발 > 개발 C++(기초)' 카테고리의 다른 글

c++ 문자형,리터럴상수,심볼릭상수 란?  (0) 2019.07.01
c++ 정수형,부동소수점수란?  (0) 2019.06.28
c++ 헤더파일 만드는 이유  (0) 2019.06.26
c++ 키워드,식별자란?  (0) 2019.06.26
c++ 함수란?  (0) 2019.06.25

헤더파일 만드는 이유
- 파일 하나를 길게 코딩하면 복잡한 프로그램을 제작할때 힘들다.
- 공통으로 사용되는 모듈을 재사용하기위해 분리한다.

예를들어 쉬운코드로 더하기 모듈을 만든다고 했을때
두숫자,세숫자,네숫자등 덧셈들의 함수를 만들면 코드의 양이 많아진다.

또 한 선언을 사용할 수는 있지만 똑같이 코드가 길어질 수 있다.

줄이기위해 헤더파일에 정의하여 사용한다.


main.cpp

//<>는 표준에 들어있는 특별한것 컴파일러설치할때 따라들어온다. 
#include  
//헤더파일에 선언을 해놓고 사용한다고 생각하면된다. 
#include "add.h" 

using namespace std; 
/* 
선언으로 가능하긴 하지만 여러개의 덧셈이 추가되면 선언으로 하기엔 양이 너무 많다. 

int add(int a, int b, int c); 
int add(int a, int b); 
*/ 
int main() 
{ 
cout << add(1, 3) << endl; 
cout << add(1, 3, 6) << endl; 

return 0; 
} 




add.h

#pragma once 
int add(int a, int b); 
int add(int a, int b, int c); 


add.cpp

int add(int a, int b) 
{ 
return a + b; 
} 

int add(int a, int b, int c) 
{ 
return a + b + c; 
} 




'개발 소발 > 개발 C++(기초)' 카테고리의 다른 글

c++ 정수형,부동소수점수란?  (0) 2019.06.28
c++ namespace란?  (0) 2019.06.26
c++ 키워드,식별자란?  (0) 2019.06.26
c++ 함수란?  (0) 2019.06.25
c++ 입력,출력  (0) 2019.06.25

키워드는 c++프로그래밍(다른 언어도 비슷하다)에서 지원하는 것들이다.
if,return,int 등이있다.

키워드는 변수명에 들어가면 안된다.

식별자는 변수,함수,클래스명등을 말한다.

변수,함수,클래스명은 숫자로 시작못한다.
변수명은 너무길지 않으면서 의미를 충분히 표현할 수 있게하자.
변수명 _(언더바)로 분리하는 경우가 많다.
변수명은 대문자로 잘 쓰지않는다.
ex)int num_apples;
ex)int numApples;

함수명은 프로젝트 그룹에 따라 유연성있게 대문자,소문자로 시작할지 보고 정하자.

클래스명은 대부분 대문자로 시작한다.

변수,함수명이 너무길어 질거같으면 주석으로 처리하자.

 

#include <iostream>

//GetNumber() getNumber()둘다 상관없다.
void getNumber()
{

}

//클래스명은 대문자로 대부분 대문자로 시작한다.
class MyClass
{
public:
	int m_variable;
};

int main()
{
	//사과의 숫자를 담는 int형 변수로 변수명만 보면 알 수 있다.
	int num_apples;
	//_(언더바)형식이 아닌 대문자로 구분하는 방법도 있다.
	int numApples;
}

 

'개발 소발 > 개발 C++(기초)' 카테고리의 다른 글

c++ namespace란?  (0) 2019.06.26
c++ 헤더파일 만드는 이유  (0) 2019.06.26
c++ 함수란?  (0) 2019.06.25
c++ 입력,출력  (0) 2019.06.25
c++ 객체,변수,초기화,대입이란?  (0) 2019.06.25

+ Recent posts