개인적으로 공부한 C++ 내용을 공유합니다.

Hello World!


#include <iostream>

int main()
{
	std::cout << "Hello, World!!!" << std::endl;
	return (0);
}

iostream헤더는 C++의 표준 입출력을 포함하고 있습니다.

std::cout은 무언가를 출력시켜주는 것이고
std::endl은 한줄 엔터를 쳐서 나타내라는 표시 즉, 개행을 나타냅니다.

여기서 std:: 에서 std는 C++ 표준 라이브러리의 모든 함수 객체 등이 정의된 이름 공간(namespace)입니다.

이름 공간 이란, 어떤 정의된 객체에 대해 어디 소속인지 지정해주는 것을 나타냅니다. 코드의 크기 늘어나거나 다른 사람들이 쓴 코드를 가져다 쓰는 경우가 많아지면서 중복된 이름을 가진 함수들이 많아지게되는데, C++ 에서는 이를 구분하기 위해 같은 이름이라도 소속된 이름 공간이 다르면 다른 것으로 취급하도록 했습니다.

namespace header1 {
	int		foo();
	void	bar();
}
namespace header2 {
	int		foo();
	void	bar();
}

위와 같은 예시가 있을 때, header1.hheader2.h를 모두 include한다면, header1::foo(), header2::foo()와 같이 각각의 네임스페이스를 붙여 같은 이름의 함수를 쓸 수 있습니다.

#include <iostream>

using namespace std;

int main()
{
	cout << "Hello, World!!!" << endl;
	return (0);
}

위와 같이 using namespace std; 를 사용하여 어떠한 이름 공간을 사용하겠다고 선언을 할 수 있는데 이는 권장되지 않습니다. 그 이유는 std 에 이름이 겹치는 함수를 만들게 된다면, 오류가 발생하기 때문입니다. 따라서 혹시 모를 충돌을 위해 사용하지 않는 것을 권장합니다.

namespace {
	int a;
	int test() {}
}

위에 처럼 하나의 파일 안에 namespace를 이름을 정하지 않고 구성하여 변수나 함수를 정의했다고 했을 때 현재 파일에서는 atest 앞에 특정 namespace::를 사용하지 않더라도 사용할 수 있다. 하지만 다른 파일에서는 atest를 접근할 수 없다. 이는 static처럼 선언한 것과 같이 특정 파일 내에서만 사용할 수 있도록 된 것임을 나타낸다.


C와 C++은 친구


C와 C++은 if, else, switch, for, while, break, continue 등등 기본적인 문법 구조가 똑같다. 따라서 C에서 사용했던 것과 동일하게 문법을 사용하면 된다. 또한 C에서 되던 것은 C++ 에서 거의 100% 된다고 봐도 무방하다.


참조자 도입


참조자는 특정 변수의 별명을 말한다. 즉 별명을 이용해서 한 변수를 나타내는 변수를 여러개 만드는 것이다.

#include <iostream>

int main()
{
	int		a = 3;
	int&	another_a = a;

	another_a = 5;
	std::cout << "a : " << a << std::endl;
	std::cout << "another_a : " << another_a << std::endl;

	return (0);
}

참조자는 선언과 동시에 누구의 별명이 될 것인지 같이 선언해주어야한다.
참조자를 정하는 방법은 가리키고자 하는 타입 뒤에 &를 붙이면 된다.
참조자는 메모리 상에 공간을 할당하지 않고 별명으로 가리키려는 변수의 메모리를 같이 사용한다.
참조자의 참조자 타입은 금지되어 있으며 참조자의 참조자를 사용하려면 참조자를 참조자의 타입으로 받으면 된다.

// 문제의 코드

int main()
{
	int a = 3;
	int& another_a;

	return (0);
}

상수와 같은 코드상의 값을 리터럴이라고 하는데 const 형의 참조자를 사용하면 리터럴 또한 상수 참조자로 참조할 수 있다.

참조자는 배열로 선언할 수 없는데, 그 이유는 배열이 되기위해선 주소값이 존재해야하는데 참조자는 메모리상에 존재하지 않기 때문이다. 이러한 모순 때문에 선언할 수 없다.

하지만 다음과 같이 배열의 크기를 명시하여 각각의 배열의 값을 참조자로 선언할 수 있다.

int arr[3] = {1, 2, 3};
int (&ref)[3] = arr;

이렇게 되면 ref[0]부터 res[2]가 각각 arr[0]부터 arr[2]의 레퍼런스가 된다.

다음과 같이 2차원 배열도 가능하다.

int arr[3][2] = {1, 2, 3, 4, 5, 6};
int (&ref)[3][2] = arr;

참조자를 사용할 때 주의해야 할 점이 하나 더 있는데, 레퍼런스를 리턴하는 함수에서 지역 변수의 레퍼런스를 리턴하지 않도록 조심해야 한다는 점이다. 지역변수는 그 함수가 끝나면 사라지므로 그 지역변수를 레퍼런스하고 있는 참조자는 잘못된 영역의 접근을 하게 된다. 이것을 댕글링 레퍼런스(Dangling reference)라고한다.

⤧  Next post Oh-My-C-Lang - Section 3 - 02 ⤧  Previous post Oh-My-C-Lang - Section 2, 3 - 01