[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