C++/C++ 기초 플러스 6판(Book)

[C++] 데이터 처리

suppresswisely 2025. 3. 1. 18:21

객체 지향 프로그래밍(OOP)의 진수는 사용자가 데이터형을 스스로 설계하고 확장 할 수 있다는 데에 있다.

C++에 내장된 데이터형에는 기본형복합형이 있다. 기본형에는 정수를 표현할 수 있는 정수형과, 부동 소수점 형이 있다. 복합형 데이터형에는 기본형을 기초로 하여 만들어지는 배열, 문자열, 포인터, 구조체가 있다.

 

간단한 변수

컴퓨터에 정보를 저장할려면 다음과 같은 세 가지를 알아야 한다.

어디에 저장되는가?, 어떤 값이 저장되는가?, 어떤 종류의 정보인가?

 

변수 이름

변수 규칙중 두개의 밎줄 문자로 시작하는 이름이나, 밑줄 문자와 대문자로 시작하는 이름은, 그것을 사용하는 컴파일러와 리소스가 사용하기로 예약되어 있다.

 

이 규칙은 __time_stop 또는 _Donut과 같은 이름을 사용해도 컴파일러 에러가 발생하지 않고, 정의되지 않은 이상한 동작을 이르킨다는 뜻에서 다른 규칙과는 성격이 좀 다르다. 이러한 이유는 이름은 적법하지만 컴파일러가 사용하기로 예약되어 있기 때문이다.

 

short, int, long,long long 정수형

현재 많은 C++들이 short형을 16비트로, long형을 32비트로 사용하는 최소 보증 표준을 따르고 있다. 그러나 int형에 대해서는 여전히 선택의 여지가 남아 있다. int형은 이 표준을 따르면서도 폭이 16, 24, 32비트가 될 수 있다.

 

C++ 시스템의 정수 크기가 얼마인지 알고 싶으면, 데이터형의 크기를 알아내는 C++의 도구를 사용할 수 있다.

첫 번째 방법은 sizeof 연산자를 사용하는 것이다. sizeof 연산자는 변수나 데이터형의 크기를 바이트 단위로 리턴한다.

바이트의 의미는 컴파일러에 따라 다르므로, 2바이트 int형이 어떤 C++에서는 16비트인 반면에, 다른 C++에서는 32비트가 될 수 있다.

 

두 번째 방법은 여러 가지 정수들의 범위에 대한 정보가 들어 있는 climits 헤더 파일을 열어 보는 것이다.

 

초기화

C++는 C와 다른 초기화 문법을 가지고 있다.

int owls = 101;  // 전통적인 C 스타일의 초기화 문법
int wres(432);  // C++의 새로운 초기화 문법, wrens를 432로 초기화

int hamburgers = { 24 };
int emus{ 7 }

int rocs = { };  // 0으로 초기화
int psychics{ };  // 0으로 초기화

 

unsigned형

C++는 표현 한계값을 벗어날 때(오버플로와 언더플로가 발생할 때) 부호 없는(usinged) 정수형의 경우 최소값 혹은 최대값이 들어간다. 부호있는(signed) 정수형의 경우에는 항상 이와 같이 동작한다고 보장할 수 없다. 그러나 현제 대부분의 C++는 이와 같은 방식으로 동작하고 있다.

 

어느 정수형을 사용할 것인가?

메모리를 절약하는 것이 매우 중요한 일이라면 short형과 int형이 크기가 같을지라도 short형을 사용해야 한다. 예를 들어, 16비트 int형을 사용하는 DOS 시스템에서 32비트 int형을 사용하는 시스템으로 프로그램을 가져간다면, int형배열은 두 배의 메모리를 요구할 것이다.

 

C++가 상수의 데이터형을 결정하는 방법

정수형 상수는 22와 같이 프로그램에 직접 써 넣는 정수를 말한다. C++는 특별한 이유가 없다면 정수형 상수를 모두 int형으로 저장한다. 그러나 특정 데이터형을 의미하는 접미어를 상수에 붙였을 때와 값이 너무 커서 int형으로 저장할 수 없을 때에는 그렇지 않다.

 

char형: 문자와 작은 정수

char형은 실제로 또 하나의 정수이다. 대부분의 컴퓨터 시스템들은 256개보다 적은 개수의 문자들을 지원한다. 이러한 문자들은 1바이트만으로 충분히 나타낼 수 있다. 미국에서 가장 많이 사용하는 문제 세트는 ASCII이다.

 

멤버 함수: cout.put()

멤버 함수는 클래스에 속하고, 클래스의 데이터를 다루는 방법을 정의한다. 멤버 함수를 사용하려면 마침표(.)로 객체 이름(cout)과 함수 이름(put())을 서로 연결하야 한다. 이 마침표를 멤버 연산자(membership operator)라고 부른다.

 

cout.put()이 왜 필요할까? 그것은 역사적인 이유 때문이다. C++ Release 2.0 이전에, cout은 문자 "변수"들을 문자로 출력하였지만, 문자 "상수"들은 수로 출력했다. 이 문제는 초기 버전들이 문자 "상수"를 int형으로 저장한 데에서 비롯되었다. 즉, 문자"상수" 'M'에 해당하는 코드 77이 16비트 또는 32비트로 저장되었다. 그러나 char형 변수는 8비트만을 차지했다. 그래서 다음과 같은 구문은 

 

char  ch = 'M'

 

문자 상수 'M'으로부터 char형 변수 ch로 8비트(의미 있는 8비트)만을 복사했다. 이것은 문자 상수 'M'과 char형 변수 ch가 동일한 값을 가지고 있더라도 cout에게는 서로 다르게 보였다는 것을 의마한다. 그래서 다음과 같은 구문은

cout << '$';

 

문자 $를 출력하지 않고, '$'에 해당하는 ASCII 코드 36을 출력했다. 그러나 다음과 같은 구문은 원하는 대로 $를 출력했다.

cout.put('$');

 

signed char형과 unsigned char형

char형은 signed형이나 unsigned형으로 미리 정해져 있지 않다. 그것은 C++ 시스템 개발자가 하드웨어 특성에 맞춰 알맞은 char형을 정할 수 있도록 하기 위한 배려이다.

 

확장형 char형: wchar_t

때로는 프로그램이 1바이트(8비트)로 표현할 수 없는 문자 세트를 처리하는 경우가 있다. 이를 두 가지 방법으로 처리한다.

 

첫째, 확장 문자 세트가 시스템의 기본 분자 세트면, 컴파일러 개발업체가 char형을 처음부터 2바이트(16비트) 또는 그 이상으로 만드는 것이다.

 

둘째, 기본 문자 세트와 확장 문자 세트를 동시에 지원하는 것이다. 즉, 보통의 8비트 char형으로 기본 문자 세트를 나타내고, wchar_t형(wide cahracter type에서 각각 따 왔다.)으로 확장 문자 세트를 나타내는 것이다.

 

const 제한자

#define문보다 더 쉽게 기호 상수를 다루는 방법이 있다. 그것을 바로 const 키워드를 사용하여 변수를 선언하고 초기화하는 것이다.

키워드 const는 선언의 의미를 제한하므로 제한자(qualifier)라고 부른다.

 

초기에 논의한 #define문으로 충분하다고 주장할 것이다. 그러나 const를 사용하는 것이 더 좋다.

첫 번째 이유는 데이터형을 명시적으로 지정할 수 있다는 점이고

두 분째 이유는 C++의 활동 범위 규칙(scoping rules)에 의해 그 정의를 특정 함수나 파일에서만 사용할 수 있도록 제한할 수 있다는 점이다.

세 번째 이유는 배열이나 구조체와 같은 보다 복잡한 데이터형에도 const를 사용할 수 있다는 점이다.

 

부동 소수점수

수 34.1245와 있을 때, 기본값이 0.341245이고 스케일이 100이다. 

C++가 부동 소수점을 나타내는 두 번째 방법은 3.45E6과 같이 지수 표기(Enotation)를 사용하는 것이다. 3.45E6은 값 3.45에 1,000,000을 곱하라는 뜻이다.

 

지수 표기는 E 또는 e를 사용할 수 있고, 지수는 + 또는 -부호를 가질 수 있다.

음의 지수를 사용하는 것은 10의 거듭제곱을 곱하는 것이 아니라, 10의 거듭제곱으로 나누는 것이다. 그래서 8.33E-4는 0.000833을 의미한다.

 

부동 소수점형 상수

프로그램은 부동 소수점형 상수를 어떤 부동 소수점형으로 저장할까? 8.24나 2.4E8과 같은 부동 소수점형 상수는 기본적으로 double형으로 저장된다.

 

부동 소수점의 장단점

부동 소수점은 정수에 비해 두 가지 장점을 가진다. 

첫째, 정수와 정수 사이에 있는 값을 나타낼 수 있다.

둘째, 스케일을 사용하여 매우 큰 범위의 값을 나타낼 수 있다.

그러나 부동 소수점 연산은 수치 연산 보조 프로세서(math coprocessor)가 없는 컴퓨터에서 정수 연산보다 속도가 느리다. 또한 정밀도를 잃을 수 있다.(타입 변환 또는 연산 시 저장할 변수보다 상수가 비트 수가 많을 경우 남은 비트를 버린다.)

 

수식에서 데이터형 변환

자동 데이터형 변환은 어떤 수식의 값을 평가할 때 bool, char, unsigned char, signed char, short혈 값은 모두 int형으로 변환된다. 특히 true는 1로, false는 0으로 변환된다. 이러한 변환을 정수 승급(integral promotion)이라 한다.

 

매개변수를 전달할 때의 형 변환

현명한 일은 아니지만, 함수 원형이 매개변수를 제어하는 것을 막을 수도 있다. 그러한 경우에, C++는 char형과 short형에 대해(signed와 unsigned)정수 승급을 수행한다.

 

데이터형 변환자

데이터형 변환자는 두 가지 형태로 사용된다.

(typeName) value
typeName (value)

 

첫 번째 형태는 C에서 사용하던 방법이다. 두 번째 형태는 순전히 C++에서만 새롭게 사용된다. 두 번째 형태는 순전히 C++에서만 새롭게 사용된다.

static_cast<typeName> (value)