[C++] 표준입출력, 데이터 형식, 변수

happyyeom·2025년 7월 4일

C++표준 입출력

C에서는 stdio.h에 있는 scanf, printf를 이용하여 입출력을 한다. 물론 C++에서도 scanf, printf로 입출력을 할 수 있지만, 표준입출력은 iostream에 정의되어 있는 cin, cout을 사용한다.

#include <iostream>

int main() {
	int num_1, num_2;

	std::cout << "Enter num_1:"; //문자열"Enter num_1:" 출력
	std::cin >> num_1; //사용자에게 정수를 입력받아 num_1에 저장

	std::cout << "Enter num_2:"; //문자열"Enter num_2:" 출력
	std::cin >> num_2; //사용자게엑 정수를 입력받아 num_2에 저장

	std::cout << "num_1 + num_2 = " << num_1 + num_2 << std::endl;
	//std::endl;은 end line의 줄임말로 줄바꿈을 출력하고 출력버퍼를 비움
	//출력버퍼: 프로그램이 출력할 내용을 잠깐 모아두는 공간
	/*
	std::cout << "Hello";
	std::cout << "World";
	이런 코드가 있다고 할 때, 실제로는 바로바로 출력되는 게 아니라
	버퍼에 저장되다가 프로그램이 끝나거나, 줄바꿈하거나, flush하거나 할 때 
	한꺼번에 화면에 나옴
	*/


	return 0; /*원래 int main()처럼 반환값이 있는 함수는
	return문을 포함해야 하지만, main함수는 특별한 함수이므로
	생략해도 return 0을 반환한다.*/
}

위에 코드에서 cin, cout앞에 붙어있는 std::는 std라는 네임스페이스에 접근할 때 쓰는 표현이다. standard의 줄임말로 C++에서 흔히 사용하는 여러 가지 함수와 클래스, 객체, 유틸리티가 정의된 네임스페이스이다. 네임스페이스는 내부식별자에 범위를 부여해 여러 라이브러리를 포함할 때 이름이 충돌하는 것을 방지하려고 사용한다.
쉽게 말해 네임스페이스는 "라이브러리나 코드 묶음을 대표하는 이름표"라고 칭할 수 있다.

cout

c언어에서 출력은 printf를 사용하고 %d,%f,%s와 같은 형식 지정자로 출력형식을 지정해야하지만 C++에서는 cout이라는 스트림 객체를 사용, 형식 지정자를 사용하지 않고도 문자열이나 정수, 부동 소수점 등을 출력할 수 있다.

cout은 <<연산자로 출력 대상을 전달한다. 연산자가 가리키는 방향은 정보의 흐름을 나타낸다.
<<를 여러 개 이용하면 연속해서 출력할 수도 있다.

cin

scanf와 같은 용도로는 cin을 사용한다. cout을 <<를 사용했던 것과는 반대로 cin으로 받아온 데이터를 넘겨야하므로 >>연산자를 이용한다.
입력받을 데이터의 형식 지정자는 입력하지 않아도 된다. scanf는 입력된 데이터의 형식을 확인하지 않지만, cin입력된 데이터의 형식을 확인한다.

데이터 형식

파이썬처럼 변수의 형식을 자동으로 결정해주지는 않아 형식을 직접 지정해 주어야 해 런타임 오류도 줄고 메모리를 효율적으로 사용할 수 있다는 장점이 있다. 데이터 형식은 5가지로 분류할 수 있다. 세부형식은 더 많지만 대표적인 것들만 정리한 표이다.

주의할점 char는 c,c++에서 문자를 다룰 때 사용하는 대표적인 데이터 형식이다. 하지만 char는 1byte(=8bit)정수를 저장하는 역할을 할 뿐, 문자전용 데이터 형식은 아니다. 저장된 정수를 아스키 코드로 변환하여 사용한다.

char형만으로는 한글과 한자를 제대로 표현할 수 없고 wchar_t형을 사용하거나 UTF-8인코딩 후(한글처럼 큰 글자들을 3칸짜리 블록으로 쪼개서 저장하는 방법) 표현할 수 있다.

C++에서 지역변수, 전역변수

#include <iostream>
using namespace std;

int value = 1;

int main() {
	int value = -1;

	cout << value << endl;
	cout << ::value << endl;

	return 0;
}

만약 위처럼 지역변수와 전역변수의 이름이 같은데 지역 범위 내에 전역 변수와 같이 사용한다면 컴파일러는 지역변수를 우선으로 접근한다. 이때 전역변수에는 ::를 붙이면 접근할 수 있다.

하지만 가급적 지역변수와 전역변수의 이름을 같게 지정하는 것은 피하도록 한다.

L-value, R-value

c언어에서 L-value, R-value는 각각 왼쪽과 오른쪽 값을 의미했고 대입연산자를 기준으로 구분했지만 C++에서는 단순히 대입연산자 기준으로만 구분하지 않는다.
- L-value: 메모리 위치를 가리키거나 수정할 수 있는 표현식 ex)변수 이름, 배열 요소, 클래스 멤버
- R-value: 임시 값이나 메모리상에 위치가 없는 값을 가리키는 표현식 ex)임시 객체, 리터럴

	a=1; //성공. a는 L-value, 1은 R-value
	1=a; //오류. 1은 L-value가 될 수 없음

	a=b+1; //성공. a는 L-value, b+1은 R-value
	b+1=a; //오류. b+1은 L-value가 될 수 없음

	a=b; //성공. a와b 모두 L-value

위는 L-value와 R-value의 특징이다.

형변환

프로그래밍을 하다보면 변수의 형식을 변경해서 사용해야 할 때가 있다. 이를 위해 암시적 형변환과 명시적 형변환 두가지 형식 변환 방법이 있다.

암시적 형변환이란

	float float_value = 1.5f;

	double double_value = float_value;
	//숫자 승격: 데이터 유실 없음
	int int_value = float_value;
	//숫자 변환: 데이터 유실 발생

이런 식으로 형식을 지정해주지 않아도 컴파일러가 알아서 형식을 변환해주는 것을 말한다. 이때 위의 형변환은 더 큰 ㅂ부동소수점 자료인 double로 변환됐기에 이를 숫자 승격이라하며 아래 형변환은 서르 다른 자료형이거나 크기가 더 작은 자료형으로 변환하는 숫자 변환이기에 데이터가 유실될 가능성이있다. 실제로 int_value를 출력하면 결과가 1인 것을 확인할 수 있다.

명시적 형변환이란

	int int_a = 10;
	int int_b = 5;

	int int_avg = (int_a + int_b) / 2;
	float float_avg_1 = (int_a + int_b) / 2;
    //암시적 형변환
	float float_avg_2 = float(int_a + int_b) / 2;
    //명시적 형변환

우선 암시적 형변환이 발생한 곳부터 살펴보자. 나름 소수점이 발생할 수 있으므로 결과값을 float형으로 받았는데 float_avg_1의 결과값은 7.5가 아닌 7이 나온다. 그 이유는 컴파일러가 int_a + int_b를 정수형 R-value로 처리했기 때문에 정수형 R-value / 2또한 정수가 된 것이다.
이러한 문제를 해결하기 위해 명시적형변환을 사용한다. 코드를 살펴보면 int_a + int_b를 float형 R-value로 변환할 것을 명시적으로 표기함으로써 이후의 연산은 모두 float형으로 처리된다. 따라서 float_avg_2의 결과를 출력해보면 우리가 원하는 7.5인 것을 확인할 수 있다.

profile
🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳

0개의 댓글