문자열

 

hello world같은 글을 문자열이라고 한다.
문자열을 사용할땐 string을 include해서 사용한다.
string은 기본자료형이 아닌 사람들이 만들어 놓은 사용자 정의 자료형으로 생각하면된다.
다른 기본자료형처럼 =,(),{}방식으로 정의가 가능하다.
숫자가 입력가능하지만 정수형이 아닌 문자형 ""으로 입력해야한다.
입력받을땐 다른 자료형과 같이 cin사용하는 것이 아닌 std::getline(std::cin,str);을 사용한다.
정수형(int)을 입력받고 std::getline(std::cin,str);을 사용하면 기존 버퍼에 남아있던 정수가 출력된다.
std::cin.ignore(32767,'\n');
std::cin.ignore(std::numeric_limits::max(), '\n');
을 이용해 정수입력이후 문자열을 입력받을 수 있다.
+,+=로 문자열에 문자열을 추가해줄 수 있다. append라고한다.
문자열 길이는 .length()로 확인할 수 있다.
string 문자열은 마지막에 문장마무리표시가 들어가있어 길이 1이 추가된다.

 

#include <iostream>
#include <string>
#include <limits>

using namespace std;

int main()
{
	//문자열을 출력한다.
	//아래글자는 char[12]로 출력된다.
	cout << "hello world" << endl;

	int age = 0;
	cin >> age;
	cout << age << endl;
	//cin 버퍼 초기화
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	const string str = "hello world";
	cout << str << endl;
	//숫자입력
	string num = "123";


	string num2 = "";
	//문자열 입력
	std::getline(std::cin, num);
	std::getline(std::cin, num2);

	//문자열 더하기(append)
	cout << num + num2 << endl;
	num += "test";

	//문자열 길이
	cout << num.length() << endl;
	return 0;
}

형변환

 

변수 자료형 알아보는 방법
typeinfo를 사용해 자료형을 알 수 있다.
typeinfo(변수).name()형식
사용하는 이유
- 리터럴은 double지만 변수가 int형이라면 int로 저장된다.

암시적형변환
- 프로그래머가 설정하지않는데 형변환되는 경우
1. 작은것을 큰것으로 바꿀땐 적용된다.
  ex)float -> double로 변경될때 적용된다.
2. numeric conversion의 문제점
  ex)int -> char 큰자료형(작은자료형의 크기를 넘을때)에서 
             작은자료형으로 갈경우에 제대로 저장되지 않는다.
3.unsigned의 문제점도 있다.unsined int는 int보다 접근순위가 높다.

명시적형변환
- 프로그래머가 설정한 형변환   
- 대표적으로 세가지방법이 있다.
c++스타일
int i2 = int(4.0);
c스타일
i2 = (int)4.0;
다른방법
i2 = static_cast(4.0);

 

#include <iostream>
#include <cmath>
#include <typeinfo>

int main()
{
	using namespace std;

	//int형으로 저장된다.
	int a = 123.4;
	cout << a << endl;
	cout << typeid(4.0).name() << endl;

	float f = 123.4f;
	double d = f;
	d = 123.4567891011;
	f = d;

	int i = 30000;
	char c = i;
	//제대로 저장이 안된다.
	cout << static_cast<int>(c) << endl;

	//명시적형변환
	//c++스타일
	int i2 = int(4.0);
	//c스타일
	i2 = (int)4.0;
	//다른방법
	i2 = static_cast<int>(4.0);
	return 0;
}

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;
}

정수형 (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

+ Recent posts