728x90
반응형

Program Language/C & C++ 112

[C++] 계산기 만들기 (2) input

Input 입력 읽기는 종종 프로그램에서 가장 곤란한 부분이다. 사람과 의사소통하기 위해 프로그램은 그 사람의 변덕, 관습 및 겉으로 보기에 무작위적인 오류에 대처해야 한다. 사람이 기계에 더 적합한 방식으로 강요하는 것은 공격적으로 간주되기도 한다. 저수준 입력 루틴의 작업은 문자를 읽고 문자에서 더 높은 수준의 토큰을 구성하는 것이다. 이런 토큰은 상위 수준 루틴에 대한 입력 단위다. 여기서 저수준 입력은 ts.get()에 의해 수행된다. 저수준 입력 루틴을 작성하는 것이 일상적인 작업일 필요는 없다. 많은 시스템은 이를 위한 표준 기능을 제공한다. 먼저 Token_stream의 전체 정의를 확인해 보자. class Token_stream { public: Token_stream(istream& s)..

[C++] 계산기 만들기 (1) parser

부동 소수점 숫자에 대한 중위 연산자로 네 가지 표준 산술 연산을 제공하는 간단한 탁상용 계산기 프로그램을 만들어보자. 사용자는 변수를 정의할 수도 있다. 예를 들어 주어진 입력 r = 2.5 area = pi ∗ r ∗ r (pi는 미리 정의됨) 계산기 프로그램은 다음과 같은 결과를 보여 줍니다. 2.5 19.635 여기서 2.5는 첫 번째 입력 라인의 결과이고 19.635는 두 번째 라인의 결과다. 이 계산기는 네 개의 메인 파트로 구성된다. (parser, 입력 함수, 기호 테이블, driver). 실제로 이것은 구문 분석기가 구문 분석을 수행하고 입력 기능이 입력 및 어휘 분석을 처리하며 기호 테이블이 영구 정보를 보유하고 driver가 초기화, 출력 및 오류를 처리하는 소형 컴파일러다. 더 유용..

[C++] range-for 문

가장 간단한 루프는 range-for 명령문이다. 단순히 범위의 각 요소에 대한 프로그래머 액세스 권한을 제공한다. int sum(vector& v) { int s = 0; for (int x : v) s+=x; return s; } for(int x : v)는 "범위 v의 각 요소 x에 대해" 또는 "v에 있는 각 x에 대해"로 읽을 수 있다. v의 요소는 처음부터 마지막까지 순서대로 동작된다. 요소(여기서는 x)를 명명하는 변수의 범위는 for문이다. 콜론 뒤의 표현식은 시퀀스(범위)를 나타내야 한다. 즉, 반복자를 얻기 위해 v.begin() 및 v.end() 또는 begin(v) 및 end(v)를 호출할 수 있는 값을 생성해야 한다. 컴파일러는 먼저 begin 및 end 멤버를 찾고 이를 사용하려..

[C++] 선언 명령문

선언은 명령문이다. 변수가 static으로 선언되지 않으면 제어 thread가 선언을 통과할 때마다 초기화가 실행된다. 명령문이 사용될 수 있는 모든 곳에서 선언을 허용하는 이유는 프로그래머가 초기화되지 않은 변수로 인한 오류를 최소화하고 코드에서 더 나은 지역성을 허용할 수 있도록 하기 위한 것이다. 보유할 값이 있기 전에 변수를 도입해야 하는 이유는 거의 없다. void f(vector& v, int i, const char∗ p) { if (p==nullptr) return; if (ii;) { if (i

[C++] Enumerations

열거형은 사용자가 지정한 정수 값 집합을 보유할 수 있는 유형이다. 열거형의 가능한 값 중 일부는 열거자(enumerator)로 명명되고 호출된다. enum class Color { red, green, blue }; 이것은 열거자가 red, green, blue인 Color라는 열거를 정의한다. enumberation은 enum으로 축약된다. 열거형에는 두 가지 종류가 있다. enum class : 열거자의 이름 (예:red)이 열거형에 대해 local이고 해당 값이 다른 유형으로 암시적으로 변환되지 않는 경우. plain enum : 열거자 이름이 열거형과 동일한 범위에 있고 해당 값이 암시적으로 정수로 변환되는 경우 일반적으로 enum class는 fewer suprises 하기 때문에 선호하는 편..

[C++] Unions

Union은 가장 큰 구성원만큼만 공간을 차지하도록 모든 구성원이 동일한 주소에 할당되는 구조체다. 당연히 Union은 한 번에 한 구성원에 대해서만 값을 보유할 수 있다. 예를 들어 이름과 값을 보유하는 기호 테이블 항목을 고려해 보자. enum Type { str, num }; struct Entry { char∗ name; Type t; char∗ s; // use s if t==str int i; // use i if t==num }; void f(Entry∗ p) { if (p−>t == str) cout s; // ... } s와 i 멤버는 절대 동시에 사용할 수 없기 대문에 공간을 낭비하고 있다. 다음과 같이 둘 다 Union의 구성원이어야 함을 지정하여 쉽게 복구할 수 있다. union V..

[C++] 구조체의 필드(field)

이진 변수를 나타내기 위해 전체 byte(char or bool)를 사용하는 것은 고급스러워 보이지만 char는 C++에서 독립적으로 할당되고 주소 지정될 수 있는 가장 작은 객체다. 그러나 구조체의 필드와 같이 여러 개의 작은 변수를 함께 묶는 것이 가능하다. 필드는 종종 bit 필드라고 한다. 구성원은 점유할 비트 수를 지정하여 필드로 정의된다. 이름 없는 필드가 허용된다. 그것들은 명명된 필드의 의미에 영향을 미치지 않지만 일부 machine-dependent 한 방식으로 레이아웃을 개선하는 데 사용할 수 있다. struct PPN { // R6000 Physical Page Number unsigned int PFN : 22; // Page Frame Number int : 3; // unused..

[C++] 구조체의 POD(plain old data)

때때로 객체를 단순하게 "plain old data" (메모리의 연속 byte sequence)로 취급하고 런타임 다형과 같은 고급 개념에 대해 걱정하지 않으려고 한다. 종종 그렇게 하는 이유는 하드웨어가 할 수 있는 가장 효율적인 객체 이동의 방법이기 때문이다. 예를 들어 복사 생성자의 100번 호출을 사용하여 100개의 요소 배열을 복사하는 것은 일반적으로 단순 블록 이동 명령을 사용하는 std::memcpy()를 호출하는 것만큼 빠르지 않을 것이다. 생성자가 inline 된 경우에도 optimizer가 최적화를 발견하기 어려울 수 있다. 이러한 "trick"은 드문 일이 아니며 vector와 같은 컨테이너 구현 및 저수준 I/O 루틴에서 중요하다. 그것들은 불필요하며 상위 레벨 코드에서는 피해야 한..

[C++] 구조체와 배열

당연하게도 배열을 포함하는 구조체와 구체의 배열을 사용할 수 있다. struct Point { int x,y }; Point points[3] {{1,2},{3,4},{5,6}}; int x2 = points[2].x; struct Array { Point elem[3]; }; Array points2 {{1,2},{3,4},{5,6}}; int y2 = points2.elem[2].y; 구조체에 built-in 된 배열은 해당 객체로 취급할 수 있다. 초기화(인수 전달 및 함수 반환 포함) 및 할당에서 배열을 포함하는 구조체를 복사할 수 있다. Array shift(Array a, Point p) { for (int i=0; i!=3; ++i) { a.elem[i].x += p.x; a.elem[i]...

[C++] 구조체와 클래스

구조체는 기본적으로 멤버가 공개되는 클래스다. 따라서 구조체는 멤버 함수를 가질 수 있다. 특히 구조체는 생성자를 가질 수 있다. struct Points { vector elem;// must contain at least one Point Points(Point p0) { elem.push_back(p0);} Points(Point p0, Point p1) { elem.push_back(p0); elem.push_back(p1); } // ... }; Points x0; // error : no default constructor Points x1{ {100,200} }; // one Point Points x1{ {100,200}, {300,400} }; // two Points 단순히 멤버를 순서..

[C++] 구조체 이름

형식의 이름은 선언이 완성된 직후가 아니라 발견된 직후에 사용할 수 있게 된다. struct Link { Link∗ previous; Link∗ successor; }; 그러나 선언이 완성될 때까지 구조체는 새 객체를 선언할 수 없다. struct No_good { No_good member; // error : recursive definition }; 컴파일러가 No_good의 크기를 결정할 수 없기 때문에 이것은 오류다. 두 개(혹은 그 이상)의 구조체가 서로 참조할 수 있도록 하려면 이름을 구조체의 이름으로 선언할 수 없다. struct List; // struct name declaration: List to be defined later struct Link { Link∗ pre; Link∗ ..

[C++] 구조체 layout

구조체의 객체는 선언된 순서대로 멤버를 보유한다. 예를 들면 다음과 같다. struct Readout { char hour; // [0:23] int value; char seq; // sequence mark ['a':'z'] }; 다음과 같이 메모리에 배치된 Readout 객체의 멤버를 상상할 수 있다. 멤버는 선언 순서대로 메모리에 할당되므로 시간의 주소는 값의 주소보다 작아야 한다. 그러나 구조체의 객체 크기가 반드시 해당 멤버 크기의 합일 필요는 없다. 이는 많은 machine이 특정 유형의 객체가 아키텍처의 종속 경계에 할당되거나 그러한 객체가 있는 경우 훨씬 더 효율적으로 처리해야 하기 때문이다. 예를 들면 정수는 종종 단어 word의 경계에 할당된다. 이러한 machine에서 객체는 적절하..

[C++] 구조체 (structure)

배열은 동일한 유형의 요소 집합이다. 가장 단순한 형태의 구조체는 임의 유형의 요소 집합이다. struct Address { const char∗ name; // "Jim Dandy" int number; // 61 const char∗ street; // "South St" const char∗ town; // "New Providence" char state[2]; // 'N' 'J' const char∗ zip; // "07974" }; 이것은 미국 내 누군가에게 메일을 보내기 위해 필요한 항목으로 구성된 Address라는 유형을 정의한다. 종료를 위한 세미콜론(;)을 잊지 말자. Address 유형의 변수는 다른 변수와 똑같이 선언할 수 있으며 개별 멤버는 점(.) 연산자를 사용하여 접근할 수 있..

[C++] 참조에 대한 참조

유형에서 참조에 대한 참조를 가져오면 참조 유형에 대한 일종의 특수한 참조가 아니라 해당 유형에 대한 참조를 얻게 된다. 그러나 어떤 종류의 참조일까? lvalue 참조일까? rvalue 참조일까? using rr_i = int&&; using lr_i = int&; using rr_rr_i = rr_i&&; // ‘‘int && &&’’ is an int&& using lr_rr_i = rr_i&; // ‘‘int && &’’ is an int& using rr_lr_i = lr_i&&; // ‘‘int & &&’’ is an int& using lr_lr_i = lr_i&; // ‘‘int & &’’ is an int& 즉, lvalue 참조가 상상 이긴다. 이것에는 의미가 있다. 유형으로 할 수 있..

[C++] rvalue 참조

하나 이상의 참조 종류를 갖는 기본 아이디어는 객체의 다양한 사용을 지원하는 것이다. non const lvalue 참조는 참조 사용자가 참조할 수 있는 객체를 참조한다. const value 참조는 상수를 참조하며, 이는 참조의 사용자다. rvalue 참조는 참조 사용자가 할 수 있는 임시 객체를 참조한다. 일반적으로 객체가 다시는 사용되지 않을 것이라고 가정하고 수정한다. 참조가 임시를 참조하는지 알고 싶을 때가 있다. 만약 그렇다면 값 비싼 복사 작업을 저렴한 이동 작업으로 바꿀 수 있기 때문이다. 잠재적으로 엄청난 양의 정보를 가리키는 small descriptor로 표현되는 객체(문자열 혹은 목록)는 소스가 다시 사용되지 않을 것이라는 것을 안다면 간단하고 저렴하게 이동할 수 있다. 전형적인 예..

[C++] lvalue 참조

형식 이름에서 표기법 X&는 'X에 대한 참조'를 의미한다. lvalue에 대한 참조에 사용되므로 종종 lvalue 참조라고 한다.\ void f() { int var = 1; int& r {var}; // r and var now refer to the same int int x = r; // x becomes 1 r = 2; // var becomes 2 } 참조가 무언가에 대한 이름인지 확인하려면(즉, 객체에 바인딩됨) 참조를 초기화해야 한다. int var = 1; int& r1 {var}; // OK: r1 initialized int& r2; // error : initializer missing extern int& r3; // OK: r3 initialized elsewhere 참조 초기화..

728x90
반응형