관리 메뉴

SImpAS

C++ 기초 :: 변수와 자료형 본문

IT - Programming(시작)/C++

C++ 기초 :: 변수와 자료형

SIAS simpas 2018.03.11 17:42

이전 강좌에서 배웠던 쓸모 없는 프로그램인 'Hello World'이 약간 왜 배우는지 미심쩍어 보인다. 그냥 몇줄만 작성하고, 컴파일 한 후에, 나온 프로그램을 실행하면, 정말로 간단한 문장 하나를 컴퓨터 화면에 띄워줄 수 있다. 이는 분명 프로그램을 작성하는 것보다, 우리가 직접 컴퓨터 화면에 적는게 더 빠를거다.


하지만 프로그래밍은 이런 간단한 문장 하나하나를 출력하는 것만 할 수 있는건 아니다. 실제 우리가 하는 일을 좀더 효율적으로 도와줄 수 있는 프로그ㅡ램을 만들기 위해서는, 변수의 개념을 알 필요가 있다.


이해를 돕기 위해 한가지 가정을 하나 해보자, 숫자 5를 기억한 다음 2를 동시에 외우라고 누군가가 지시를 하면, 서로 다른 숫자 두개를 동시에 외워야한다. 그 다음 누군가가 첫번째 말했던 숫자에 1을 더하라고 지시하고 5+1 = 6의 결과와 2를 동시에 기억속에 저장을 하고, 새로운 지시로서 두 숫자의 차를 구하라고 한다면, 4라는 결과를 내야한다.


위의 모든 과정을 컴퓨터는 두개의 변수로 간단하게 처리할 수 있다. 위의 계산을 C++로 표현을 하면, 다음과 같다:


1
2
3
4
= 5;
= 2;
= a + 1;
result = a - b;
cs


분명 위의 예제는 작은 두 정수만 사용했기 때문에 너무나도 쉬운 예제였지만, 저러한 간단한 계산들을 수십, 수백, 수천만개를 외워야하고, 그 결과들을 전부 원할 때 사용할 수 있을 정도로 세련되게 다룰줄 알아야한다면, 어떻겠는가, 컴퓨터에게 감사를 표하자.


이제 우리는 메모리의 한 부분으로서 변수를 정의하고 값을 저장할 수 있게 됐다.


각각의 변수들은 스스로를 묘사하면서, 다른 변수와 구분이 되는 이름이 필요하다. 예를들어, 위의 코드에서, 변수명은 a, b, result 였지만, 우리는 C++ 식별자로서 유효한 이름이면서, 와닿는 이름을 지어야한다.


식별자(변수명)


유효한 변수명으로서 병수명은 한개 이상의 글자와 숫자 또는 밑줄(_)들의 연속된 배열로 구성되어야한다. 공백이나, 구두점, 상징같은 이모티콘은 변수명의 이름으로 포함될 수 없다. 게다가 변수명은 이름의 첫글자가 글자여야 한다. 물론 밑줄(_)로도 변수명의 이름의 첫글자로 이용할 수 있지만, 대부분의 상황에서, 밑줄(_)로 시작하는 변수들은 컴파일러가 특정지어놓은 키워드나 외부 변수명들을 예약어로서 여길 수 있다. (밑줄 2개를 연속적으로 쓰는것도 예약어로서 여길 수 있음)

(예약어란? 컴파일러에서 이미 의미나 용법이 지정되어 있는 용어로서, 프로그래머가 임의로 다른 목적이나 의미로 바꾸어 사용할 수 없으며, 물론 변수 이름으로도 사용할 수 없다)


C++은 다양한 목적으로 이미 많은 키워드들을 예약어로 만들어 놓았는데, 우리는 그러한 이름들을 피해서 변수 이름을 지어야한다. C++에서 표준 예약어로 정의해 놔서 우리가 변수명으로서 사용할 수 없는 이름들은 다음과 같다:

alignas, alignof, and, and_eq, asm, auto, bitand, bitor, bool, break, case, catch, char, char16_t, char32_t, class, compl, const, constexpr, const_cast, continue, decltype, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, noexcept, not, not_eq, nullptr, operator, or, or_eq, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_assert, static_cast, struct, switch, template, this, thread_local, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while, xor, xor_eq

컴파일러에 따라서 다른 예약어가 존재할 수도 있다.


매우 중요 : C++은 대소문자를 구분하는 언어이기 때문에, 대문자로 쓰여진 변수명과, 소문자로 쓰여진 변수명은 엄연히 다르다는 뜻이다. 예를들어 변수명 RESULT 와 Result, result 3개의 변수들은 각각 다른 변수들을 나타내는 의미이다.


기본적인 자료형들


변수의 값은 컴퓨터 메모리 불특정한 어딘가에 0과 1의 구성으로 저장된다. 사실 어딘가에 저장되긴 하지만, 당장 우리 프로그램은 변수가 저장되는 정확한 위치를 알필요가 없고, 간단히 변수의 이름으로 변수의 값을 불러올 수 있다는 사실만을 알아두자. 당장 컴퓨터 프로그램이 알아야하는건, 변수가 저장되는 위치보다는, 어떤 종류의 데이터로, 변수의 값이 저장되느냐 이다. 정수형의 값을 가졌느냐, 글자로 구성된 값이냐, 실수형의 값이냐에 따라서 비록 저장하는 값들이 모두 0과 1로 이루어져 있어도, 모두 다른 종류의 변수이다. 같은 방법으로 해석되지 않으며, 대부분의 상황에서, 보통 다른 종류의 변수라면, 메모리에서 차지하는 공간이 다르다.


기본적인 데이터 자료형은 대부분의 시스템에 의해서 지원되는 기본 저장 단위를 나타내는 언어로 직접 구현되는 유형으로, 다음과 같이 분류될 수 있다:


  • Character types: 주로 'A'나 '$'와 같이 한 문자를 나타낸다 가장 기본적인 타입은 'char' 이고 1 byte의 문자를 저장할 수 있으며, 주로 1 byte는 영어 한 문자, 혹은 특수기호 한 문자 정도가 된다. 더 많은 글을 저장하기 위해, 더 많은 자료형을 제공한다.
  • Numerical integer types: 7이나 1024 같은 숫자를 저장할 수 있다. 저장 가능한 크기가 다양하도록 자료형을 제공하고 있으며, 음수가 되냐 안되냐 에따라서 signed, unsigned 라는 형식이 추가로 붙을 수 있다.
  • Floating-point types: 실수, 3.14 나 0.01 같이 실수 범위의 숫자들을 저장할 수 있고, 어떤 실수형중에서도 어떠한 자료형을 쓰느냐에 따라서 정밀도가 달라진다.
  • Boolean type: 논리적 자료형으로, true 나 false, 이 두상태만 표현할 수 있는 자료형이며 C++에서 bool 로 알려져있다.  

다음은 C++의 기본 자료형을 모두 보여준것이다:

GroupType names*Notes on size / precision
Character typeschar

정확히 1 byte의 사이즈 = 8 bits

char16_t

char 자료형보다 작으면 안됨. 최소 16 bits

char32_t

char16_t 자료형보다 작으면 안됨. 최소 32 bits

wchar_t

character 자료형 중에서 가장 큰 크기 지원

Integer types (signed)

signed char

character의 char와 같은 크기. 최소 8 bits

signed short int

char보다 작으면 안됨. 최소 16 bits

signed int

short 보다 작으면 안됨. 최소 16 bits

signed long int

int 보다 작으면 안됨. 최소 32 bits

signed long long int

long 보다 작으면 안됨. 최소 64 bits

Integer types (unsigned)unsigned char

signed integer types와 크기는 같음

(단, 음수 불가능)

unsigned short int
unsigned int
unsigned long int
unsigned long long int
Floating-point typesfloat
double

float 보다 정밀도 높음

long double

dobule 보다 정밀도 높음

Boolean typebool
Void typevoid

저장공간 X

Null pointerdecltype(nullptr)


* integer(정수형) 자료형의 이름들은 signed 없이 간결하게 쓸수 있다. 즉, int는 signed int 와 같은 의미이다. 위 표에서, 이탤릭체로 사용한 글자는 선택사항이며, 이탤릭체로 쓰지 않은 부분만 써도 어떤 자료형인지 식별 가능하다는 뜻이다.


위 표에서 각각의 그룹에서, 각각의 자료들은 크기(컴퓨터 메모리를 얼마나 차지하느냐)를 제외하곤 아무런 차이점이 없다. 물론 이름도 다름 그냥 첫번째에서 마지막 자료로 갈수록 저장할 수 있는 크기들이 커진다.


위의 표에서 char(정확히 1 byte) 이외의 다른 모든 기본 자료형에는 표준 크기가 없다(최소 크기는 있다). 그러므로 자료형은 정확하게 이 최소 크기를 맞출 필요가 없다. 이것은 위의 기본 자료형들이 최소 크기와 정확하지 않도록 표준 크기가 존재하지 않지만, 모든 컴파일러나 기계에서 표준 크기가 존재하지 않는것은 아니다. 각각의 컴파일러 도구들은 프로그램이 실행될 환경에서 가장 적절한 크기가 되도록 이러한 자료형들의 표준 크기를 구체화 시킬수도 있다. 이렇게 표준 크기를 따로 지정해 놓지 않은 C++은 다양한 플랫폼과, 다양한 작업환경, 현재와 미래에서 유연성있게 사용 가능하도록 한다.


위 표의 사이즈는 모두 bit로 표현됐다. 더 많은 bits를 자료형이 저장할 수 있으면, 더 명확하게 값을 나타낼수 있는 동시에, 메모리 공간을 더 많이 소비한다:

크기

고유 대표 값

Notes
8-bit256= 28
16-bit65 536= 216
32-bit4 294 967 296= 232 (~4 billion)
64-bit18 446 744 073 709 551 616= 264 (~18 billion billion)


integer(정수형) 자료형에서는, 표현할수 있는 수가 더 많다는 것은, 표현할 수 있는 수의 범위가 더 크다는 뜻이다. 예를들어, 16-bit unsigned integer 는 0~65535 사이의 숫자를 나타낼수 있는 반면에, signed의 경우에는 -32768 ~ 32767 까지의 숫자를 표현 할 수 있다. 양수범위에서 unsigned의 반 정도가 signed의 범위 정도라는 것을 알 수 있다. 이는 같은 signed의 자료형 크기와 같은 양의 정수의 범위를 표현하면 unsigned가 됨을 알수 있다. 대부분의 상황에서 signed를 쓰지만, 희귀하게 순수한 양수들을 표현하려고 할 때, unsgined를 쓴다.


실수형 float 같은 경우에 크기는, 소수점 계산에 있어서 정밀도를 높여주는 것을 나타낸다.


자료형의 크기나 정밀도가 그리 중요하지 않은 프로그램이라면, 보편적으로 문자 char, 정수형 int 그리고 실수형 double을 사용하여 나타내고, 위 표의 다른 자료형들은 매우 특별한 상황에서만 사용된다.


numeric_limits(header <limits>) 클래스를 이용해서 특정 시스템이나 컴파일러에서 기본 자료형의 속성값을 얻을 수 있다. 그리고 어떤 이유에서, 특정한 크기의 자료형이 필요하다면, header <cstdint>에서 크기가 고정된 자료형들을 정의해주고 제공한다.


위에 소개된 자료형들중 characters, integers, floating-point, boolean을 통틀어서 산술 자료형이라 부르고 있고, 두개의 자료형이 추가로 존재한다: 자료형이 없음을 나타내는 void, 포인터의 특별한 자료형인 nullptr. 두 자료형 모두 앞으로 배울 포인터에 관한 강좌에서 논의될것이다.


C++은 위에 설명된 기본적인 자료형에 기반하여 복합 데이터 자료형이라고 불리며, C++의 주요 강점중 하나로, 다양한 자료형을 지원한다. 역시 추후에 공개될 강좌에서 만날수 있을것이다.


변수 선언


C++에서 변수를 사용하기 위해선 변수를 사용하기 전에 선언을 해줄 필요가 있다. 선언을 함으로써, 컴퓨터에게 변수를 저장해야하는 크기와 어떻게 그 값을 가져올 것인지 알려줄 수 있다. 변수를 선언하는 문법으로, 우선 straightforward 방식이 있다: 간단하게 자료형이 무엇인지 쓰고, 변수 이름을 쓰는 방법이다. 예를들자면:

1
2
int a;
float mynuber;
cs

이런 방법이 있으며, 위에서 두가지의 유효한 변수 선언을 성공적으로 시행한 것이다. 첫번째 변수는 자료형 int와 변수명 a, 두번째 변수는 자료형 float와 변수명 mynuber, 이렇게 두가지 변수 선언을 했고, 한번 선언을하면 사용중인 프로그램의 나머지 부분에서 사용될 수 있다.

같은 자료형을 가진 변수들을 한번에 선언하기 위해서, 변수명들을 콤마(,)로 구분하여 한개의 명령어로 선언할 수 있다:

1
int a, b, c;
cs

위의 변수선언 총 3개의 변수(a, b, c)의 변수를 int라는 자료형으로 선언했고, 다음 코드와 완벽하게 같은 뜻이다:

1
2
3
int a;
int b;
int c;
cs


변수들이 프로그램 안에서 어떠한 방식으로 사용되는지 알아보기 위해, 전체 C++코드로 한번 작성해보자:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// operating with variables
 
#include <iostream>
using namespace std;
 
int main(){
    // declaring variables;
    int a, b;
    int result;
    
    // process:
    a = 5;
    b = 2;
    a = a + 1;
    result = a - b;
 
    // print out the result :
    cout << result;
 
    // terminate the program:
    return 0;
}
cs


변수 제외를 제외한 나머지 문장들이 어색해도 나중에 나올 챕터에서 다 배울 예정이니 걱정하지마라.


변수 초기화


위의 예제어서 변수들이 선언 되고, 처음 값을 할당하기 전에는 정해지지 않은 값을 가지고 있다. 변수에 값을 넣는 동작은 변수 선언과 동시에 이루어질 수 있으며, 이를 변수 초기화라 부른다.


C++에서는 3가지의 변수 초기화 방법을 지원한다. 다 같은 의미이며, 언어가 몇년에 걸쳐 진화 했음을 연상시킨다.


첫번째 초기화 방법은 잘 알려진 c-like 초기화 방법이다(c에서 가져왔기 때문). 변수 이름과 변수의 값을 등호로 연결시키는 구조이다:

자료형 변수명 = 초기값;

예를들어, x 라는 이름과 int라는 자료형을 가진 변수를 0의 값을 가지도록 초기화하기 위해서는 다음과 같다: 


1
int x = 0;
cs

두번째 방법으로는 constructor 초기화가 있다 (C++에서 소개됨), 초기화할 값을 괄호(()) 안에 넣는 방법이다:

자료형 변수명 (초기값);

예를들면 다음과 같다: 

1
int x (0);
cs


마지막 방법으로는 unifor 초기화가 있다. 바로 위의 초기화 방법과 유사하지만, 괄호 대신에 중괄호를 사용한다 ({}) - (2011 C++ 표준 개정안에 소개됨):

자료형 변수명 {초기값};

예를들면:

1
int x {0};
cs



위의 3가지 방법 모두 C++에서 동등하게 변수 초기화 방법으로써 사용가능하다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// initialization of variables
 
#include <iostream>
using namespace std;
 
int main(){
    int a = 5;            // initial value: 5
    int b(3);             // initial value: 3
    int c{2};             // initial value: 2
    int reault;           // initial value undetermined
 
    a = a + b;
    result = a - c;
    cout << result;
 
    return 0;
}
cs



Type deduction: auto 와 decltype


새로운 변수가 선언되고 초기화 됐을때, 컴파일러는 선언된 초기값으로 그 변수가 어떠한 자료형인지 스스로 판단할수 있다. 아래 상황에서는, auto 자료형을 써도 변수가 어떤 자료형을 가지고 있는지 구분하기엔 충분하다:

1
2
int foo = 0;
auto bar = foo;    // the same as: int bar = foo;
cs


여기 bar이라는 변수명을 가지고 자료형이 auto인 변수가 있다. 이 자료형을 가진 bar의 자료형은 초기화 될때 쓰인 값의 자료형과 똑같으며, 위 상황에서는 foo의 자료형인 int라는 자료형을 가지게 된다.


변수를 초기화하지 않고도, decltype이라는 자료형을 사용해서 type deduction을 할 수 있다:


1
2
int foo = 0;
decltype(foo) bar;    // the same as: int bar;
cs


여기 위에 있는 bar이라는 변수는 foo라는 변수의 자료형과 같도록 선언이 된다.


auto와 decltype은 최근 C++에 추가된 강력한 특징이다. 하지만 type deduction의 특징은, 코드를 작성할때, type deduction이 아니고 다른 방식으로 변수를 얻을 수 없을 때, 혹은 코드의 가독성을 향상을 위한 것이라고 한다. 위와 같은 상황은 이 type deduction을 사용할 만한 상황이 아니다. 위 상황에선 오히려 가독성을 떨어지게 만든다, 때문에, 코드를 읽을때에 bar의 자료형을 알고 싶다면 foo의 자료형이 무엇인지 꼭 한번 찾아봐야 하게 만든다.


strings에 대한 소개


앞서 소개한 자료형들은 코드를 작동 시키는 시스템에서 처리되는 가장 기본적인 자료형들이다. 하지만 C++언어의 주요 강점중 하나인 복합 자료형은 기본 자료형들은 단순히 빌드를 위한것임을 알려준다.


복합 자료형의 예로 string 클래스가 있다. 이 자료형을 가진 변수는 char의 자료형을 가진 문자열들의 연속으로, 단어나 문장을 저장할 수 있는 매우 유용한 특징을 가지고 있다.


기본 자료형과 가지는 첫번째 차이점은 변수를 선언하고 사용하기 위해서는 프로그램이 string이라는 자료형을 자정하고 있는 표준 라이브러리인 <string> 헤더파일을 포함해야한다는 점이다.

1
2
3
4
5
6
7
8
9
10
11
// my first string
#include <iostream>
#include <string>
using namespace std;
 
int main(){
    string mystring;
    mystring = "This is a string";
    cout << mystring;
    return 0;
}
cs


This is a string
cs


이전 예제에서 볼수 있듯이, string은 유효한 문자열들의 구성이라면, 초기화 될 수 있다. 마치 숫자 관련 자료형들이 유효한 숫자들을 저장할 수 있듯이. 기본 자료형들과 똑같이 선언하는 방법 또한 모두 지원한다. 

1
2
3
string mystring = "This is a string";
string mystring ("This is a string");
string mystring {"This is a string"};
cs


string 자료형 역시 기본 자료형들과 같이 초기화 없이 선언될 수 있으며, 중간에 값을 바꿀 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
// my first string
#include <iostream>
#include <string>
using namespace std;
 
int main(){
    string mystring;
    mystring = "This is the initial string content";
    cout << mystring << endl;
    mystring = "This is a different string content";
    cout << mystring << endl;
    return 0;
}
cs


This is the initial string content
This is a different string content
cs


endl을 출력하는것은(cout으로 삽입하는것은) ends the line (새로운 줄을 출력스트림으로 출력한다)는것을 나타낸다.


string 클래스는 복합 자료형이다. 위의 예제에서 볼 수 있듯이, 복합 자료형은 기본자료형과 똑같은 방식으로 작동한다: 문법도 같고, 선언하는 방식도 같고, 초기화 하는 방식도 같다.


이상.

'IT - Programming(시작) > C++' 카테고리의 다른 글

C++ 기초 :: 변수와 자료형  (0) 2018.03.11
C++ 기초 :: 프로그램의 시작  (0) 2018.03.07
Intro :: 컴파일러  (2) 2018.03.02
0 Comments
댓글쓰기 폼