![article thumbnail image](https://blog.kakaocdn.net/dn/caQKZY/btqDohq5RmQ/g3Yp2koztXGCyPKH0UJie0/img.png)
기본 자료형 소개
Fundamental Data Types
자료형: 자료의 형태
int i = 1; -> 초기화, 객체지향으로 넘어가면 매우 중요하다.
정수, 실수, 문자, 불리언 등 여러가지 자료형이 있고, 메모리에 저장된다. 각 자료형마다 사이즈가 다르다. 저장 방식도 타입마다 조금씩 다르다.
문장을 저장하려면 String을 사용한다. 기본 데이터 타입은 아니나, 표준처럼 사용되는 경향이 있다.
음수가 가능한 타입은 signed, 가능하지 않은 타입은 unsigned. unsigned의 처리 속도가 더 빠른 경우가 있다.
컴파일러에 따라서 사이즈가 달라질 수 있다.
정해진 메모리에 담을 수 있는 사이즈만 담을 수 있다.
최근에는 사용하기 직전에 변수를 선언하는 것을 선호한다.
1. 디버깅 편리
2. 객체, 클래스 등으로 나누기 편함
#include <iostream>
int main()
{
using namespace std;
// 내부적으로 숫자로 저장한다. (1/0)
bool bValue = false;
cout << bValue << endl;
// 내부적으로 숫자로 저장한다.
char chValue = 'A';
char chValue2 = 65;
cout << chValue << ", " << chValue2 << endl;
// f를 붙이지 않으면 double literal
// float f = 1.1; => warning 'initializing': truncation from 'double' to 'float'
float fValue = 3.141592f;
double dValue = 3.141592;
cout << fValue << endl;
cout << dValue << endl;
// auto: 빌드할 때 자동으로 자료형을 결정한다.
auto aValue = 3.141592;
auto aValue2 = 3.141592f;
cout << aValue << endl;
cout << aValue2 << endl;
// sizeof(변수or자료형): 해당 변수or자료형의 메모리 크기를 출력
cout << sizeof(bool) << endl;
cout << sizeof(bValue) << endl;
// 변수 초기화 방법
// 2,3은 객체지향 넘어가서 직접 만든 데이터 타입을 초기화할 때 많이 사용함
// uniform initialization은 데이터 타입이 맞지 않는 경우 에러 발생시킴
// 1,2는 warning 띄우고 처리하긴 해 줌
int a = (int)123.4; // 1. copy initialization
int b(int(123.4)); // 2. direct initialization
int c{ 123 }; // 3. uniform initialization
// 같은 데이터 타입의 경우에만 연속으로 선언 가능
// 우측의 변수만 초기화하는 것은 좋지 않음
int k = 0, l(123), m{ 456 };
return 0;
}
정수형 (Integers)
char: 1바이트
short: 2바이트
int: 2바이트(C++ 표준 크기), 대부분 4바이트를 사용하고 있음
long: 4바이트
long long: 8바이트, C++11 type
signed 정수의 경우, 맨 첫 번째 비트는 부호에 사용함
#include <iostream>
#include <cmath>
#include <limits>
int main()
{
using namespace std;
short s = 1; // 2 bytes = 2 * 8 bits = 16 bits / 2^16가지 수 표현 가능
int i = 1;
long l = 1;
long long ll = 1;
cout << sizeof(short) << endl; // 2
cout << sizeof(int) << endl; // 4
cout << sizeof(long) << endl; // 4
cout << sizeof(long long) << endl; // 8
cout << std::pow(2, sizeof(short) * 8) << endl; // unsigned - 65535, -1은 부호용
cout << std::pow(2, sizeof(short) * 8 - 1) - 1 << endl; // signed - 32767, 부호와 0 제외
cout << std::numeric_limits<short>::max() << endl;
cout << std::numeric_limits<short>::min() << endl;
cout << std::numeric_limits<short>::lowest() << endl;
s = 32767;
s += 1; // 32768 (++s, s++)
cout << "32768? " << s << endl; // overflow
short s2 = std::numeric_limits<short>::min();
cout << "min() " << s2 << endl;
s2 -= 1;
cout << s2 << endl; // overflow
// 주의! unsigned int에 signed int를 넣으면 unsigned로 바꿔 줌
unsigned int i2 = -1;
cout << i2 << endl;
// 주의! 정수끼리의 연산은 정수로 저장함
cout << 22 / 4 << endl;
cout << (float)22 / 4 << endl;
return 0;
}
#include <iostream>
#include <limits>
//int
//unsigned int
int main()
{
using namespace std;
cout << "int size: " << sizeof(int) << endl;
cout << "u-int size: " << sizeof(unsigned int) << endl;
cout << "\nint max: " << std::numeric_limits<int>::max() << endl;
cout << "u-int max: " << std::numeric_limits<unsigned int>::max() << endl;
cout << "\nint min: " << std::numeric_limits<int>::min() << endl;
cout << "u-int min: " << std::numeric_limits<unsigned int>::min() << endl;
cout << "\nint lowest: " << std::numeric_limits<int>::lowest() << endl;
cout << "u-int lowest: " << std::numeric_limits<unsigned int>::lowest() << endl;
return 0;
}
C++ 11 고정 너비 정수(Fixed-width Integers)
어떠한 플랫폼이든 똑같은 데이터 사이즈를 사용하는 것.
#include <iostream>
//#include <cstdint>
// iostream에서 cstdint를 include하고 있기 때문에
// iostream을 include하고 있다면별도로 하지 않아도 된다.
int main()
{
using namespace std;
std::int16_t i(5); // 16비트(2바이트) 데이터 타입
std::int8_t myint = 65; // char, 캐릭터형
cout << myint << endl;
std::int_fast8_t fi(5); // 8비트 중 가장 빠른(fast) 데이터 타입
std::int_least64_t fl(5); // 적어도 64비트를 갖는 데이터 타입
return 0;
}
무치형 (보이드, void)
void my_funtion(void)
{
}
int main()
{
//void my_void; error! void는 메모리를 차지하지 않는다.
int i = 123;
float f = 123.456f;
void *my_void; // 주소
// 데이터 타입이 다르더라도 주소의 데이터 타입은 동일하다.
my_void = (void*)&i;
my_void = (void*)&f;
return 0;
}
부동소수점수 floating point numbers
float: 4바이트
double: 8바이트
long double: 8바이트(최소 크기), 구현할 때는 8, 12, 16 등으로 사용함
#include <iostream>
#include <iomanip>
#include <limits>
#include <cmath>
int main()
{
using namespace std;
float f(3.141592f); // f를 붙이지 않으면 double -> float
double d(3.141592);
long double ld(3.141592);
cout << sizeof(f) << endl;
cout << sizeof(d) << endl;
cout << sizeof(ld) << 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;
cout << numeric_limits<float>::lowest() << endl;
cout << numeric_limits<double>::lowest() << endl;
cout << numeric_limits<long double>::lowest() << endl;
// 3.14 = 31.4 * 0.1
// 3.14 * 100 == 3.14e2
cout << 3.14 << endl;
cout << 31.4e-1 << endl;
cout << 31.4e-2 << endl;
cout << 31.4e1 << endl;
cout << 31.4e2 << endl;
cout << 1.0 / 3.0 << endl; // 0.333333
cout << std::setprecision(16);
cout << 1.0 / 3.0 << endl; // 0.333333... (16자리까지)
float f2(123456789.0f); // 10 significant digits
cout << std::setprecision(9);
cout << f2 << endl; // 123456792 => 오차
double d2(0.1);
cout << d2 << endl;
cout << std::setprecision(17);
cout << d2 << endl; // 0.100000...001
double d3(1.0);
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; // 1
cout << d4 << endl; // 0.9999...99989, 오차가 누적된다
double zero = 0.0;
double posinf = 5.0 / zero;
double neginf = -5.0 / zero;
double nan = zero / zero;
cout << posinf << " " << std::isnan(posinf) << " " << std::isinf(posinf) << endl;
cout << neginf << " " << std::isnan(neginf) << " " << std::isinf(neginf) << endl;
cout << nan << " " << std::isnan(nan) << " " << std::isinf(nan) << endl;
cout << 0.3 << " " << std::isnan(0.3) << " " << std::isinf(0.3) << endl;
return 0;
}
#include <iostream>
#include <iomanip>
/*
3.141592
31.41
0.001000
123.0002
0.0000000001
234560000.000
*/
int main()
{
using namespace std;
cout << 3.141592e0 << endl;
cout << 3.141e1 << endl;
cout << 1.0e-3 << endl;
cout << 1.2300002e+2 << endl;
cout << 1.0e-10 << endl;
cout << 2.3456e+8 << endl;
return 0;
}
불리언 자료형과 조건문 if
true(1) / false(0)
#include <iostream>
bool isEqual(int a, int b)
{
bool result = (a == b);
return result;
}
int main()
{
using namespace std;
bool b1 = true; // copy initialization
bool b2(false); // direct initialization
bool b3{ true }; // uniform initiaalization
b3 = false;
cout << std::boolalpha; // true false로 출력하기
cout << b3 << endl;
cout << !b1 << endl; // not 연산자 true->false, false->true
cout << std::noboolalpha; // 1 0으로 출력하기
// && AND operator: 두 개 다 true인 경우 true
cout << (true && true) << endl; // true
cout << (true && false) << endl; // false
cout << (false && true) << endl; // false
cout << (false && false) << endl; // false
// || OR operator: 한 개 이상 true인 경우 true
cout << (true || true) << endl; // true
cout << (true || false) << endl; // true
cout << (false || true) << endl; // true
cout << (false || false) << endl; // false
// 조건문 if: 조건에 따라서 실행할지 안 할지를 결정한다.
// 두 줄 이상을 실행하고 싶을 때는 중괄호{}를 이용한다.
if (false)
{
cout << "This is true" << endl;
cout << "True second line" << endl;
}
else
cout << "This is false" << endl;
cout << isEqual(1, 1) << endl; // true
cout << isEqual(2, 5) << endl; // false
// if문은 0이면 false, 그 외는 전부 true 처리!
if (5)
{
cout << "true" << endl;
}
else
cout << "false" << endl;
// 주의! 불리언 값을 입력할 때, 문자가 아니라 0/1로 입력해야 한다!
// 0이 아니면 true 처리를 하는 것을 주의한다.
// 이러한 위험성이 있는, 문제가 생길 수 있는 코딩은 피하자.
cout << std::boolalpha;
bool b;
cin >> b;
cout << "Your input: " << b << endl;
return 0;
}
#include <iostream>
// 정수 하나를 입력받고 그 숫자가 홀수인지 짝수인지 출력하는 프로그램
// 나머지 연산자 사용
int main()
{
using namespace std;
int input_n = 0;
cout << "정수를 입력하세요." << endl;
cin >> input_n;
if (input_n == 0)
{
cout << "0입니다." << endl;
}
else if (input_n % 2 == 0) {
// 짝수라면
cout << input_n << "는 짝수입니다." << endl;
}
else
{
// 홀수라면
cout << input_n << "는 홀수입니다." << endl;
}
return 0;
}
문자형 char type
ASCII TABLE
#include <iostream>
#include <limits>
int main()
{
using namespace std;
char c1(65); // c1 = 65; c1{ 65 };
char c2('A'); // 한 글자를 표현할 때는 따옴표 사용 / 문자열 "Hello"
cout << c1 << " " << c2 << " " << int(c1) << " " << int(c2) << endl;
// c-style casting
cout << (char)65 << endl; // A
cout << (int)'A' << endl; // 65
// cpp style
cout << char(65) << endl; // 65로 초기화되는 char를 만든다.
cout << int('A') << endl;
// static_cast<변환할타입>(변수,리터럴)
cout << static_cast<char>(65) << endl;
cout << static_cast<int>('A') << endl;
char ch(97); // a
cout << ch << endl;
cout << static_cast<int>(ch) << endl;
cout << ch << endl; // 원래 변수 값이 바뀌지는 않음
// 입력받은 내용을 버퍼에 가지고 있음
cin >> c1;
cout << c1 << " " << static_cast<int>(c1) << endl;
cin >> c1;
cout << c1 << " " << static_cast<int>(c1) << endl;
cout << sizeof(char) << endl;
cout << (int)std::numeric_limits<char>::max() << endl; // 127
cout << (int)std::numeric_limits<char>::lowest() << endl; // -128
cout << sizeof(unsigned char) << endl;
cout << (int)std::numeric_limits<unsigned char>::max() << endl; // 255
cout << (int)std::numeric_limits<unsigned char>::lowest() << endl; // 0
// '\n' 하나의 글자로 동작함! 줄 바꿈
// endl: 버퍼에 있는 것을 무조건 출력하고 줄 바꿈
// std::flush: 버퍼에 있는 것을 모두 출력함
cout << int('\n') << endl; // 10
cout << "This is first line \nsecond line" << endl;
cout << "This is first line" << endl;
cout << "second line";
// '\t' 탭
// "를 출력하고 싶으면 '\"'
// '\a' 소리
cout << "\n\n" << int('\t') << endl; // 9
cout << "This is first line \tsecond line \"\a" << endl;
wchar_t c; // Windows
char32_t c3; // 이모티콘 등 유니코드 문자 사용
return 0;
}
#include <iostream>
//ASCII 표에 있는 여러가지 문자들을 cin/cout으로 입출력
int main()
{
using namespace std;
char input_c = ' ';
char star_c = '*';
char num_c = 47;
cout << num_c << star_c << "문자를 입력하세요." << star_c << num_c << endl;
cin >> input_c;
cout << "입력하신 문자: " << input_c << endl;
int input_i = 0;
cout << "\n" << num_c << star_c << "숫자(0-127)를 입력하세요." << star_c << num_c << endl;
cin >> input_i;
cout << "입력하신 문자: " << static_cast<char>(input_i) << endl;
return 0;
}
리터럴 상수 literal constants
#include <iostream>
int main()
{
using namespace std;
float pi = 3.14f;
int i = 1234u; // u: unsigned, l: long, UL: unsigned long ...
int i2 = (unsigned int)1234;
unsigned int n = 5u;
long n2 = 5L;
double d = 6.0e-10;
// decimal : 0 1 2 3 4 5 6 7 8 9 10
// octal : 0 1 2 3 4 5 6 7 10 11 12 13
// hexa : 0 1 2 3 4 5 6 7 8 9 A B C D E F 10
// 0011 1010 1111 1111
// 3A7F... 표현이 간편하기 때문에 많이 사용함
int x = 012; // 8진수, 10
int y = 0xF; // 16진수, 15
cout << x << endl;
cout << y << endl;
// binary literal
int z = 0b1010; // 2진수, 10
cout << z << endl;
// 컴파일러가 리터럴 속 '를 무시하기 때문에 숫자를 직접 다룰 때 편리함
int a = 0b1011'1111'1010;
cout << a << endl;
// magic number 사용 후 주석 다는 것보다는 상수 이용하는 것이 좋음
// magic number: Unique values with unexplained meaning or multiple occurrences which could (preferably) be replaced with named constants
const int price_per_item = 10;
int num_items = 123;
int price = num_items * price_per_item;
return 0;
}
심볼릭 상수 symbolic constants
#include <iostream>
#include "MY_CONSTANTS.h"
#define PRICE_PER_ITEM 30
// C++에서는 상수 대체용으로 매크로 사용 안 함!!
// 1. debugging 어려움
// 2. 적용 범위가 너무 넓음
using namespace std;
void printNumber(const int my_number)
{
// 입력으로 들어온 값을 바꾸지는 않기 때문에 파라미터에 const를 많이 붙임
// const int& 변수 형태로 많이 사용함
// my_number = 456; error!
int n = my_number; // 바꿔야 한다면 따로 복사하여 사용함
cout << my_number << endl;
}
int main()
{
// 변수값이 변경되지 않아야 하는 경우, const를 통해 변수를 고정함
// 주의! 선언과 동시에 초기화되어야 함
// 주의! 자료형과 const 순서에 따라 의미가 달라지는 경우가 있음
const double gravity{ 9.8 };
double const gravity2{ 9.8 }; // 가능
// gravity = 1.2; error!
printNumber(123);
// compile time에 결정되는 상수
// constexpr: 컴파일 때 결정되는 상수를 구분하기 위함
const int my_const(123);
constexpr int my_const2(123);
int number;
cin >> number;
// 변수로 상수를 초기화
// runtime에 결정되는 상수
const int special_number(number);
// constexpr int special_number(number); error!
number = 123;
// special_number(123); error!
const int price_per_item = 30;
int num_item = 123;
//int price = num_item * PRICE_PER_ITEM;
int price = num_item * price_per_item;
// 헤더 파일 사용
double radius;
cin >> radius;
double circumference = 2.0 * radius * constants::moongravity;
return 0;
}
#pragma once
namespace constants
{
// 재사용 가능!
constexpr double pi(3.141592);
constexpr double avogadro(6.0221413e23);
constexpr double moongravity(9.8 / 6.0);
// ...
}
해당 포스트는 '홍정모의 따라하며 배우는 C++' 강의를 수강하며 개인 백업용으로 메모하였습니다.
인프런: https://www.inflearn.com/course/following-c-plus
홍정모의 따라하며 배우는 C++ - 인프런
만약 C++를 쉽게 배울 수 있다면 배우지 않을 이유가 있을까요? 성공한 프로그래머로써의 경력을 꿈꾸지만 지금은 당장 하루하루 마음이 초조할 뿐인 입문자 분들을 돕기 위해 친절하고 자세하게 설명해드리는 강의입니다. 초보로 시작하더라도 중급을 넘어 고급 프로그래머로 가는 길목에 들어서고 싶으시다면 최고의 디딤돌이 되어드리겠습니다. 여러분의 꿈을 응원합니다! 초급 프로그래밍 언어 C++ 온라인 강의 C++
www.inflearn.com