[C++] 유효 범위와 연결 및 네임스페이스, 입출력 조작자, Date & Time
LastMod:
👨💻 개인 공부 기록용 블로그 입니다.
💡 틀린 내용이나 오타는 댓글, 메일로 제보해주시면 감사하겠습니다!! (__)
42 Cursus - Cpp Module을 진행하기 위해 정리했었던 C++98 기본 개념들로, C++11, C++14와 다른 내용이 있을 수 있습니다.
각 개념은 정리한 시간 순으로 배치되어 있으며, 한 포스트에 배치된 개념이 크게 관련이 없을 수 있습니다.
유효 범위(Scope)와 연결(Linkage),네임스페이스 (Namespaces)
- 이름들은 유효 범위 (Scope)라고 하는 소스코드의 일부 불연속적인 부분내에서만 볼 수 있다.
- C와 같이,
{}
로 구분 되는 블록 스코프 안에서 선언된 변수는 잠재적으로 블록 내에서만 수명을 유지한다. - 스코프 내에서, 정규화 되지 않는 이름 조회를 통해 해당 이름과 선언을 연결시킬 수 있다.
- 이름 조회 (Name Lookup)는 프로그램 내에서 이름을 발견했을 때, 이름과 선언을 연결시키는 작업이다.
- 예를 들어
std::endl;
의 경우, 먼저std
라는 정규화 되지 않은 이름을 찾아서std
선언과 연결 시킨 후, 정규화된 이름인endl
을std
선언 내에서 찾아서endl
의 선언과 연결시킨다.
- 연결(Linkage)은 해당 변수를 사용할 수 있는 파일의 접근 가능 여부를 나타낸다.
- 외부 연결을 가지는 변수는 여러 파일에서 사용할 수 있다.
- 내부 연결을 가지는 변수는 하나의 파일 내에서만 사용할 수 있다.
- 함수 내에서 선언된 변수는 함수 내 스코프에서만 사용할 수 있으므로 연결을 가지지 않는다.
- 자동 변수(Automatic Variable)는 C에서의 지역 변수와 비슷하며, 함수의 매개변수, 블록 스코프 내에서 선언된 변수 등을 의미한다.
- 블록 내에서만 유효하며, 블록이 종료되면 메모리에서 사라진다.
- 스택 메모리에 저장되며, 초기화 하지 않으면 쓰레기값이 들어간다.
- 정적 변수 (Static Variable) 또한 C에서의 정적 변수와 비슷하다.
- 데이터 메모리에 저장된다. 따로 초기화 하지 않으면 0으로 초기화된다.
- 연결을 가지지 않는 정적 변수는 블록 내부에서
static
키워드를 통해 정의한다. (C에서의 정적 변수) - 내부 연결을 가지는 정적 변수는 하나의 파일 내의 모든 블록에서 접근 및 사용이 가능하다.
- 전역 변수 처럼 선언하지만
static
키워드가 붙어있으며,extern
으로 다른 파일에서 가져갈 수 없다.
- 전역 변수 처럼 선언하지만
- 외부 연결을 가지는 정적 변수 = 전역 변수
- 네임스페이스 (Namespace)는 C++에서 이름 충돌을 방지하는 방법 중 하나이며, 내부 식별자에 범위를 제공하는 선언적 영역이다.
namespace spacedot1{
int foo();
}
namespace spacedot2{
int foo();
}
// 두 foo 함수는 다른 네임스페이스에 존재한다.
namespace spacedot1 {
int func(){
foo(); // 해당 공간 내에선 알아서 spacedot1::foo() 가 실행된다.
spacedot2::foo(); // 네임스페이스를 명시했으므로 spacedot2:foo()가 실행된다.
}
}
using
키워드를 이용하여 네임스페이스나 네임스페이스 내에 존재하는 엔티티를 지정할 수 있다.- 예를 들어
using spacedot1::foo();
의 경우,foo()
를 호출하면 자동으로 spacedot1 안에 있는foo()
를 가져와 호출한다. using namespace std;
를 통해 std 네임스페이스내에 존재하는 엔티티들을std::
없이 가져다가 사용할 수 있다.- 그러나 이것은 권장되지 않는 방법이다. c++의 표준 라이브러리가 워낙 방대하여, 사용자가 구현하는 함수와 이름이 겹치기 쉽기 때문이다. 따라서 사용할 때마다 네임스페이스를 명시하는 것이 가장 좋은 방법이다.
- 예를 들어
- 네임스페이스의 이름을 지정하지 않아도 사용할 수 있다. 이를 익명 네임스페이스 라고 하는데,
static
키워드와 비슷한 역할을 한다.- 해당 범위 내에 존재하는 요소들은 그 파일 내에서만 사용할 수 있다.
- 익명 네임스페이스 내에 요소들은 전부 내부 연결을 가진다고 보면 된다.
입출력 조작자 (I/O Manipulators)
- 조작자(Manipulator)는
<<
또는>>
연산자를 통해 입출력 형식을 제어할 수 있게 해준다. - 조작자는 인자 없이 호출되며, 스트림에 대한 참조를 인자로써 삼는 함수로 구현된다.
- 인자를 받는 조작자는 정해지지 않은 타입의 객체를 반환하는 함수로 구현된다. 이러한 것들은 요청된 동작을 수행하도록
<<
또는>>
연산자를 재정의 한다.
일부 관련된 함수 정리
std::endl
: 개행 후 output stream을 flush 한다.- flush만 하려면
std::flush
를 호출하면 되며, 불완전한 출력을 즉시 생성하는데에 사용한다.
- flush만 하려면
std::dec
,std::hex
,std::oct
: 숫자의 출력 형식을 변경std::setprecision(n)
: 소수의 플로팅 포인트를 변경std::setfill(n)
: 빈 공간을 채우는 문자를 n으로 변경std::setw(n)
: 출력 필드의 width를 변경
Date & Time Utility
std::time_t, std::time
- gettimeofday() 에서 썼던
gettimeofday()
로 얻을 수 있는timeval
구조체와 비슷한 역할을 한다고 보면 될 것 같다. - OS마다, 혹은 컴파일러마다 자료형이 다르게 선언되어 있으며, arm64 MacOSX 13에서는
long
으로 선언되어 있다. - [
std::time_t](http://en.cppreference.com/w/cpp/chrono/c/time_t) time( [std::time_t](http://en.cppreference.com/w/cpp/chrono/c/time_t) * arg );
으로 시간 값을 얻을 수 있다.
std::localtime
- C++스타일의
std::tm
구조체를 채우는 함수.time_t
를 인자로 받으며, 내부적으로 시,분,초,일,월,연,요일 등을integer
로 저장하고 있다.
std::strftime
std::size_t strftime( char* str, std::size_t count, const char* format, const std::tm * time );
printf()
와 비슷하게,std::tm
을 인자로 받아서 포맷팅을 해주고, 포맷팅 된 시간을 문자열로 바꾸어 저장해주는 함수.
Leave a comment