개인 공부/C++

[C++] Chapter 01 정리

Koalitsiya 2023. 3. 22. 13:12

C++에서 입/출력 방식

C++에서는 C언어와 달리 기본 헤더 파일이 <stdio.h>가 아닌 <iostream>이고, printf와 scanf를 대체하는 std::cout, std::cin이 존재한다. 그리고 cin/cout을 통한 입/출력에는 별도의 포맷 지정이 필요하지 않다.

#include <iostream>

int main() {
	int num = 20;

	std::cout << "Hello World!" << std::endl;
	std::cout << "Hello " << "World!\n";

	std::cout << num << " A";
	std::cout << " 3.14\n";

	return 0;
}

 

 

지역 변수 선언

C언어에서는 지역변수의 선언이 가장 먼저 등장해야했지만 C++에서는 지역변수의 선언 위치에 제한을 두지 않는다.

#include <iostream>

int main() {
	int val1, val2;
	int result = 0;

	std::cout << "두 개의 숫자입력: ";
	std::cin >> val1 >> val2;

	if (val1 < val2) {
		for (int i = val1 + 1; i < val2; i++)
			result += i;
	}
	else {
		for (int i = val2 + 1; i < val1; i++)
			result += i;
	}

	std::cout << "두 수 사이의 정수 합: " << result << std::endl;

	return 0;
}

 

 

함수 오버로딩(Function Overloading)

C언어에서 함수는 함수명으로 구분되지만 C++에서는 매개변수의 타입과 개수로 구분되기 때문에 동일한 이름의 함수 정의가 허용되고, 이를 함수 오버로딩(Function Overloading)이라고 한다. 

#include <iostream>

void swap(int& a, int& b) {
	int tmp;

	if (a < b) {
		tmp = a;
		a = b;
		b = tmp;
	}
}

void swap(char& a, char& b) {
	char tmp;

	if (a < b) {
		tmp = a;
		a = b;
		b = tmp;
	}
}

void swap(double& a, double& b) {
	double tmp;

	if (a < b) {
		tmp = a;
		a = b;
		b = tmp;
	}
}

 

 

매개변수의 디폴트 값(Default Value)

함수를 사용할 때 함수의 매개변수 선언에 값을 지정함으로 써 해당 인자가 전달되지 않으면 지정된 값이 전달된 것으로 판단하여 작동할 수 있다.

매개변수의 디폴트 값을 지정할 때에는 아래의 규칙을 지켜야한다.

  • 함수의 선언 부분에 위치해야한다.
  • 선언된 매개변수의 수보다 적은 수의 인자가 전달되었을 시 전달되는 인자는 왼쪽에서부터 채워지기 때문에 디폴트 값은 오른쪽부터 채워나가야한다.
#include <iostream>

int BoxVolume(int length, int width = 1, int height = 1);

int main() {
	std::cout << "[3, 3, 3] : " << BoxVolume(3, 3, 3) << std::endl;
	std::cout << "[5, 5, D] : " << BoxVolume(5, 5) << std::endl;
	std::cout << "[7, D, D] : " << BoxVolume(7) << std::endl;
	//모든 값에 디폴트 값이 지정된 것이 아니기에 아래는 컴파일 에러가 발생한다.
	//std::cout << "[D, D, D] : " << BoxVolume() << std::endl;

	return 0;
}

int BoxVolume(int length, int width, int height) {
	return length * width * height;
}

 

 

인라인(Inline) 함수

 C언어의 매크로 함수를 일반 함수처럼 정의할 수 있도록 만든 것이다.

#include <iostream>

inline int SQUARE(int x) {
	return x * x;
}

int main() {
	std::cout << SQUARE(5) << std::endl;
	std::cout << SQUARE(12) << std::endl;

	return 0;
}

 

 

이름공간 / 네임스페이스(namespace)

 이름공간, 즉 네임스페이스란 함수 이름이 같아서 발생하는 이름충돌을 방지하기 위해 만들어진 문법적인 요소이다.

네임스페이스는 아래의 특성을 가진다.

  • 동일한 네임스페이스에 정의된 함수를 호출할 때는 네임스페이스를 명시할 필요가 없다.
  • 네임스페이스는 다른 네임스페이스 안에 삽입될 수 있다. 즉, 네임스페이스는 중첩될 수 있다.
  • 범위 지정 연산자 :: 을 이용해 네임스페이스를 지정한다.
  • using을 통해 네임스페이스을 지정하지 않고 호출하겠다는 것을 명시할 수있다. 
#include <iostream>

namespace Bcom {
    void SimpleFunc(void);
}
 
namespace Bcom {
    void PrettyFunc(void);
}
 
namespace Pcom {
    void SimpleFunc(void);
}
 
int main() {
    Bcom::SimpleFunc();
 
    return 0;
}
 
void Bcom::SimpleFunc() {
    std::cout << "Bcom이 정의한 함수" << std::endl;
    PrettyFunc();\
    Pcom::SimpleFunc();\
}
 
void Bcom::PrettyFunc() {
    std::cout << "So Pretty~" << std::endl;
}
 
void Pcom::SimpleFunc() {
    std::cout << "Pcom이 정의한 함수" << std::endl;
}

 

 

using

네임스페이스의 지정 없이 함수를 호출하겠다는 것을 선언하는 데 사용되는 키워드이다.

#include <iostream>

using namespace std;

int main() {

	cout << "범위 지정 연산자 없이도 네임스페이스 std에 정의된 함수를 호출";

	return 0;
}

 

 

개인적인 추가 내용

C++에서도 <stdio.h>나 <cstdio> 헤더파일을 사용해 printf와 scanf를 사용할 수 있으며 아래 그림을 통해 알 수 있듯 printf와 scanf에 비해 cout, cin은 현저히 느린 속도를 가진다.

이는 cin/cout이 stdio.h와 iostream 두 개의 버퍼를 같이 사용하여 동기화 유지하는 작업이 추가되어 있기 때문인데 이를 해결하기 위해 printf / scanf를 사용하거나 아래 코드를 통해 cin / cout의 stdio.h와의 동기화를 해제시켜주면 된다. 

ios::sync_with_stdio(false);
cin.tie(NULL);

단, 이 방식을 사용할 경우 c의 입출력방식(printf, scanf 등)과 같이 사용할 수 없게 되고, 싱글 스레드 환경에서만 사용 가능하기 때문에 실무에서는 사용해선 안되고 코딩테스트같은 알고리즘 문제에서만 사용해야한다.