본문 바로가기
Computer language

[Ch.02] 홍정모의 따라하며 배우는 C++

by IJustGo 2020. 9. 6.

CH.02 변수와 기본적인 자료형

2.1 기본 자료형 소개(Fundamental Data Types)

#include <iostream>
using namespace std;

int main()
{
	bool bValue = false;
	char chValue = 'A';
	char chValue2 = 65;
	float fValue = 3.141592f;
	double dValue = 3.141592;

	cout << (bValue ? 1 : 0) << endl;
	cout << chValue << endl;
	cout << (int)chValue << endl;
	cout << chValue2 << endl;
	cout << bValue << endl;
	cout << fValue << endl;
	cout << dValue << endl;

	cout << sizeof(bool) << endl;
	cout << sizeof(chValue) << endl;
	cout << sizeof(float) << endl;
	cout << sizeof(dValue) << endl;


	int a1 = 123;	 //copy initialization
	int a(123);		 //direct initialization
	int b{ 123 };	 //uniform initialization

	int a2(4.5);
	// int b{ 4.5 }; 오류뜸. uniform initialization이 더 엄격함.

	//같은 Data Types끼리만 가능.
	//선택적으로 초기화가 가능한데 이런식으론 ex. int k, l, m =123; 하진 말자.
	//m만 초기화 한것인데 k, l , m 전부 123으로 초기화 한 것 처럼 보임.
	int k = 1, l = 123, m = 123;

	return 0;
}

- char에 A를 대입했을때 숫자로 저장되므로 int로 형변환후 출력해보면 숫자가 뜸.

 

 

 

 

 

 

 

 

 

 

2.2 정수형(Integers)

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
	short	s = 1; // 2btyes = 2 * 8 bits = 16 bits
	int		i = 1;
	long	l = 1;
	long long ll = 1;

	cout << sizeof(short) << endl;
	cout << sizeof(int) << endl;
	cout << sizeof(long) << endl;
	cout << sizeof(long long) << endl;

	//각각의 자료형에는 사이즈가 정해져있고 그 범위를 벗어나면 예기치못한 일이 생길수 있다.
	cout << std::pow(2, sizeof(short) * 8 - 1) - 1 << endl; //sign부호비트 제외. 양수는 0~32767
	cout << std::numeric_limits<short>::max() << endl;	
	cout << std::numeric_limits<short>::min() << endl;
	cout << std::numeric_limits<short>::lowest() << endl;

	s = 32767;
	s = s + 1; //32768예상. but...

	cout << s << endl; //-32768, overflow 
	
	short s2 = std::numeric_limits<short>::min();
	s2 = s2 - 1;

	cout << s2 << endl; //32767, overflow

	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
	unsigned int i = -1;
	cout << i << endl; // 4294967295, overflow, 컴파일러가 오류로 인식 X

	int k = 22 / 4;
	cout << k << endl; //5, 5.5가 나와야 하는데 0.5가 짤림.
	cout << 22 / (float)4 << endl; // 피연산자 두 개중 하나만 float면 5.5로 나옴.

	return 0;
}

 

 

 

 

 

 

 

 

 

2.5 부동소수점수(floating point numbers)

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

using namespace std;


int main()
{
    float f2;
    double d2;
    long double ld2;

    cout << sizeof(f2) << endl;
    cout << sizeof(d2) << endl;
    cout << sizeof(ld2) << endl;

    cout << numeric_limits<float>::max() << endl;
    cout << numeric_limits<double>::max() << endl;
    cout << numeric_limits<long double>::max() << endl;

    //min() 최소 절댓값
    cout << numeric_limits<float>::min() << endl;
    cout << numeric_limits<double>::min() << endl;
    cout << numeric_limits<long double>::min() << endl;

    //lowest() 최솟값
    cout << numeric_limits<float>::lowest() << endl;
    cout << numeric_limits<double>::lowest() << endl;
    cout << numeric_limits<long double>::lowest() << endl;

    float f(3.141592f); // 3.14 = 31.4 * 0.1
    double d(3.141592);
    long double ld(3.141592);

    cout << 3.14 << endl;
    cout << 31.4e-1 << endl;
    cout << 31.4e1 << endl;
    cout << 31.4e2 << endl;

    cout << std::setprecision(16);
    cout << 1.0 / 3.0 << endl;

    float f3(123456789.0f); //10 significant digits

    cout << std::setprecision(9);
    cout << f3 << endl; // 오차 발생

    double d3(0.1);
    double d4(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
    cout << d3 << endl;
    cout << std::setprecision(17);
    cout << d3 << endl; // 오차 발생
    cout << d4 << endl; // 오차 발생

    double zero = 0.0;
    double posinf = 5.0 / zero;
    double neginf = -5.0 / zero;
    double nan = zero / zero;

    cout << posinf << endl;
    cout << neginf << endl;
    cout << nan << endl;

    return 0;
}

2.6 불리언 자료형과 조건문 if

#include <iostream>
using namespace std;


//함수이름 만들때 동사+명사, 동사+형용사로 많이함.
bool isEqual(int a, int b)
{
	bool result = (a == b);
	return result;
}

int main()
{
	bool b1 = true; //copy initialization
	bool b11 = 0;	 //'''     '''
	bool b2(false);  //direct  '''
	bool b3{ true }; //uniform '''
	b3 = false;

	cout << std::boolalpha; //이거 지우면 0,1로 출력됨.
	cout << b3 << endl;
	cout << b1 << endl;

	cout << std::noboolalpha;
	cout << !true << endl;
	cout << !false << endl; //!는 not operator

	cout << !b1 << endl;
	cout << !b2 << endl; //교수님은 not operator 안쓸수 있으면 안쓰신다. 버그나면 찾기가 힘들다.

	cout << (true && true) << endl;   //true
	cout << (true && false) << endl;  //false
	cout << (false && true) << endl;  //false
	cout << (false && false) << endl; //false

	cout << (true || true) << endl;   //true
	cout << (true || false) << endl;  //true
	cout << (false || true) << endl;  //true
	cout << (false || false) << endl; //false

	if (false)
	{
		cout << "This is true " << endl;
		cout << "True second line " << endl;
	}
	else
		cout << "This is false" << endl;

	cout << std::boolalpha;
	cout << isEqual(1, 1) << endl;
	cout << isEqual(0, 3) << endl;

	if (5)
	{
		cout << "True" << endl;
	}
	else
		cout << "False" << endl;

	bool b;
	cin >> b;
	cout << std::boolalpha;
	cout << "Your input : " << b << endl; //true라고 입력하면 false뜬다.

	return 0;
}

Practice

- 정수 하나를 입력받고 그 숫자가 홀수인지 짝수인지 출력하는 프로그램을 만들어봅시다. (Hint. 나머지 연산자 이용)

 

2.7 문자형 char type

#include <iostream>
#include <limits>
using namespace std;

int main()
{

    char c1(65);
    char c2('A'); //한 글자를 표현할때는 ''사용, 문자열을 표현할때는 ""사용.

    //char은 데이터 저장은 숫자로 저장이 된다. 하지만 출력할땐 아스키코드 변환으로 문자출력됨.
    cout << c1 << " " << c2 << " " << int(c1) << " " << int(c2) << endl;

    // 1. c-style casting
    cout << (char)65 << endl; //int형 Data 65를 char로 형변환.
    cout << (int)'A' << endl; //char형 Data A를 int로 형변환.

    // 2. C++ style, 정확히 따지자면 형변환은 아닌데 C++에선 이걸 형변환 느낌으로 사용.
    cout << char(65) << endl;
    cout << int('A') << endl;

    // 3. c++ 형변환.
    cout << static_cast<char>(65) << endl;
    cout << static_cast<int>('A') << endl;
    // 1,2는 강제로 변환하는 것이고, 3은 컴파일러한테 먼저 확인받는 느낌?
    // 그리고 static_cast를 사용하면 남들이 봤을때 cast하는 것을 분명히 알 수 있게 해줌.

    char ch(97);
    
    //static_cast()안에 변수를 넣을 수 있고, 그 후에 변수가 변하지 않음.
    cout << ch << endl;
    cout << static_cast<int>(ch) << endl;
    cout << ch << endl;

    char c3(65);

    //입력받은 내용을 버퍼에 저장해둠.
    //1에서 ab를 입력해두면 a만 먼저 처리해두고 b는 저장해뒀다가 아래 2 명령때 사용됨.
    cin >> c3; // 1
    cout << c3 << " " << static_cast<int>(c3) << endl;

    cin >> c3; // 2
    cout << c3 << " " << static_cast<int>(c3) << endl;
    

    cin >> c3;
    cout << c3 << " " << static_cast<int>(c3) << endl;

    cin >> c3;
    cout << c3 << " " << static_cast<int>(c3) << endl;

    char c4(65);

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

    char c5(65);

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


    // endl과 \n의 차이 -- \n은 단지 줄바꿈이다.
    // endl은 cout버퍼에 있는 내용들을 일단 화면에 다 출력 후 줄 바꿈.
    // cf. std::flush 이건 버퍼에 있는 내용들을 출력후 줄바꿈X.
    cout << int('\n') << endl; // 10
    cout << "This is first line \nsecond line\n";
    cout << "This is first line" << endl;
    cout << "second line";

    cout << "This is first line /t second line\" \? \a"; // \t, \", \?, \a 

    wchar_t c6;
    char16_t c7;
    char32_t c8;

    return 0;
}

practice

- ASCII 표에 들어 있는 여러가지 문자들을 cin/cout으로 입출력 해봅시다.

 

2.8 리터럴 상수(literal constants)

#include <iostream>
using namespace std;

int main()
{
	// 3.14는 입력하는 순간 끝임. 변수처럼 바꿀수가 없다. 이런걸 literal constants라고 부름.
	float pi = 3.14f;
	 
	int x = 012; // 앞에 0 붙이면 8진수 표현.
	cout << x << endl; // 10

	int x1 = 0xF; // 앞에 0x붙이면 16진수 표현. cf. 16진수 쓰면 코드가 짧아져서 의외로 16진수 많이 사용함.
	cout << x1 << endl; // 15

	int x2 = 0b1010; // cf. int x2 = 0b1100'1110'0011; 이런식으로 중간중간 ' 넣을 수 있음. (다른 진법에도 가능)
	cout << x2 << endl; // 10

	// const 이용해서 변수 만들어서 사용하면 편함.
	const int price_per_item = 10;
	int num_itmes = 2;
	int price = num_itmes * price_per_item;
	
	return 0;
}

 

2.9 심볼릭 상수(symbolic constants)

Chapter2_9.cpp

#include <iostream>
#include "MY_CONSTANT.h"
using namespace std;


void printNumber(const int my_number)
{
	int n = my_number;
	cout << my_number << endl;
}

int main()
{
	//const는 고정된 숫자를 사용할 때 사용하고 나중에 실수로 숫자를 변경하는 것을 막아준다.
	//반드시 초기화를 해줘야됨.
	const double gravity{ 9.8 }; 

	//gravity = 1.2;
	
	printNumber(123);

	int number;
	cin >> number;

	const int special_number(number); //런타임때 상수가 결정.

	constexpr int my_const(123); // 컴파일하면서 상수가 결정.

	// #define PRICE_PER_ITEM 30 const대신 #define하면 안좋은점.
	// 1. 디버깅할때 불편하다. 2. #define은 전처리기이므로 코드 전체에 영향을 준다.
	const int price_per_item = 30;
	int num_item = 123;
	int price = num_item * price_per_item;

	double radius;
	cin >> radius;

	double circumference = 2.0 * radius * constants::pi;

	return 0;
}

MY_CONSTANT.h

#pragma once

//필요한 상수들이 있으면 한군데에 모아서 정리하는 것이 좋다.
namespace constants
{
	constexpr double pi(3.141592);
	constexpr double avogadro(6.0221413e23);
	constexpr double moon_gravity(9.8 / 6.0);
}11