음악, 삶, 개발

1 - Getting Started 본문

개발 공부/C++ Primer (5th Edition)

1 - Getting Started

Lee_____ 2020. 8. 6. 04:25

< 목차 >

 


    Chapter 소개

    이 챕터에서는 C++ 의 기본적인 요소 type, variable, expression, statement, function 등을 소개할것이다.

    이 챕터를 읽은후에 당신은 매우 심플한 프로그램을 작성하고, 컴파일하고 실행할수있게 될것이다.

    이 챕터 이후의 챕터들에서는 이 챕터에 소개된 기능을 훨씬 더 자세히 설명해나갈것이다.

    프로그래밍 언어를 배우는 가장 좋은 방법은 프로그램을 만들어보는것이다.

    이 챕터에서는 서점의 문제를 해결해줄수있는 프로그램을 작성해볼것이다.

     

    우리의 서점은 transaction 들이 담긴 파일을 가지고있다.

    각 transaction 은 3개의 data를 가지고있다.

    첫번째는 책의 id (ISBN - International Standard Book Number) 이고, 두번째는 책의 판매량, 세번째는 책의 가격이다.

    서점의 주인은 각 책의 총 판매액과 평균 판매 금액을 계산하기위해 이 파일을 읽는다.

    이런 프로그램을 작성하기위해서, 우리는 몇가지 C++ 기능들을 알아야한다.

    추가적으로 어떻게 프로그램을 compile 하고 실행하는지도 알아야한다.

    우리가 무엇을 해야할지는 대략 아래와 같다.

    • variable 을 정의한다.
    • input 과 output 을 한다.
    • data 를 보관하기위해 data structure (자료 구조) 를 사용한다.
    • 2개의 기록이 동일한 ISBN 을 가지고있는지 테스트한다.
    • 모든 기록을 process 할 loop 을 transaction 파일에 포함한다.

    우리의 위의 사항들을 어떻게 C++ 로 해결할수있는지 앞으로 배울것이다.


    1.1 Writing a Simple C++ Program

    모든 C++ 프로그램은 1개 이상의 함수를 포함하고, 이 함수들중 하나는 반드시 main 이라는 이름의 함수여야한다.

    아래는 운영체제에게 값을 return 하는 단순한 main 함수이다.

    int main() {
    	
        return 0;
    
    }

    함수의 정의는 4가지의 요소로 구성된다.

    1. return type
    2. 함수 이름 (비워놓을수도 있음)
    3. 괄호 () 안에 parameter list 
    4. 함수 body 

    main 함수가 다른 함수와 달리 특별한 부분이 있다하더라도,

    일반적인 함수를 정의하는 방식과 동일하게 main 함수를 정의한다.

    위의 코드에 main 함수는 ( ) 안에 어떤 parameter 도 존재하지않지만,

    6.2.5 (p. 218) 에서 우리가 main 을 위해 사용할수있는 다른 parameter type 들을 다룰것이다.

    main 함수는 return type 으로 int 를 가져야하며,

    int 란 integer (정수) 를 나타내는 type 이다.

    int type 을 built-in type 이라고 하며, C++ 언어 자체가 정의한 type 이다.

    함수 정의의 마지막 부분인 함수 body 는 

    열린 중괄호 curly brace { 로 시작하여 닫는 중괄호 } 로 끝나는 문장 block (a block of statements) 이다.

    Lee : 앞으로는 문장이라고 하지않고, statement 라고 하겠음. 영어에 익숙해져야함. 
    {
    
    	return 0;
    
    }

     

    이 block 안에 유일한 statement 인 return 은 함수를 끝내는 statement 이다.

    또한 return 은 함수의 호출자 (function caller) 에게 값을 보낼수있다.

    return문이 값을 포함할때 이 값은 반드시 함수의 return type 과 동일하거나 호환(compatible) 하는 type 이여야한다.

    위의 코드에서 main 의 return type 은 int 이기때문에, return값 역시 int 인 0 이다.

    return문 뒤에 붙은 semicolon ; 은 C++ 의 모든 statement 의 끝에 반드시 와야한다.

    만약 ; 을 붙이지않는다면 매우 미스터리한 compiler error 메세지가 발생할수있다.

    대부분의 시스템에서, main 이 return 하는 값은 status indicator (상태를 표시하는것) 이다.

    return값이 0 이라면 성공을 나타내고, 0 이 아닌 값의 의미는 각 시스템에 의해 정의된다.

    일반적으로 0 이 아닌 값은 error 가 발생했음을 나타낸다.

    Key Concept : Types

    Type 이란 프로그래밍 이 책에서 계속해서 다룰 프로그래밍의 근간을 이루는 개념이다.

    Type 은 data 의 내용과 이 data 로 가능한 연산을 정의한다.

    우리의 프로그램이 처리하는 모든 data 는 variable (변수) 에 저장되며, 

    모든 variable 은 type 을 가지고있다.

    v 라는 이름의 variable 의 type 이 T 라면, 

    "v 는 type T 를 가지고있다" 또는 "vT다" 라고 말한다.


    1.1.1 Compiling and Excuting Our Program

    프로그램을 작성했다면, compile 해야한다.

    프로그램을 compiler 하는 방법은 운영체제와 compiler 에 따라 다르다.

    어떻게 당신의 compiler 가 작동하는지 알고자한다면, reference 메뉴얼을 참조하거나, 

    똑똑한 동료에게 물어보라.

    많은 PC 에 기반한 compiler 들은 build 와 분석 tool 을 포함한 compiler 를 가지고있는

    IDE (intergrated development envoirmoment) 에서 구동된다.

    이러한 환경은 대규모 프로그램을 개발하는 데 큰 자산이 될 수 있지만 효과적으로 사용하는 방법을 배우려면 상당한 시간을 요한다.

    이러한 환경을 사용하는 방법을 배우는 것은 이 책의 범위를 벗어난다.

    IDE 의 compiler 를 포함하여, 대부분의 compiler 들은 command-line interface 을 제공한다.

    그렇게하면 먼저 C ++ 학습에 집중할 수 있으며 또한 일단 언어를 이해하면 IDE를 배우기가 더 쉬울 것이다.

    Programe Source File Naming Convention (프로그램 소스 파일 명명 규칙)

    당신이 command-line interface 나 IDE 둘중 뭘 쓰던지간에,

    대부분의 compiler 들은 프로그램의 source code 가 1개 이상의 파일안에 저장될것으로 예상한다.

    프로그램 파일들은 일반적으로 source file 이라고 한다.

    대부분의 시스템에서 소스 파일의 이름은 suffix (접미사)로 끝나며

    마침표 뒤에 하나 이상의 문자가 온다. suffix 는 파일이 C ++ 프로그램임을 시스템에 알려준다.

    다른 컴파일러는 다른 suffix 규칙을 사용한다.

    대부분은 .cc, .cxx, .cpp, .cp, .C 를 포함한다.

    Running the Compiler from the Command Line 

    command-line interface를 사용하는 경우 일반적으로

    콘솔 창 (예 : UNIX 시스템의 shell 창 또는 Windows의 명령 프롬프트 창)에서 프로그램을 컴파일한다.

     

    우리의 main 프로그램 prog1.cc 라는 파일안에 있다면,

    위와 같은 명령어로 compile 할수있다.

    여기서 CC는 컴파일러를 명명하고 $는 시스템 prompt 이다.

    compiler 는 실행파일을 생성한다. 

    Window 시스템에서 실행파일의 이름은 prog1.exe 가 될것이고

    UNIX compiler 는 실행 파일을 a.out이라는 파일에 넣는 경향이 있다.

    Windows에서 실행 파일을 실행하려면 실행 파일 이름을 제공하고 .exe 확장자를 생략 할 수 있다.

    일부 시스템에서는 파일이 현재 디렉토리 또는 폴더에 있다하더라도

    파일의 위치를 ​​명시 적으로 지정해야한다.

    이런 경우에는 아래와 같이 작성한다.

    “.” 뒤에 backslash가 있으면 파일이 현재 디렉토리에 있음을 나타낸다.

    UNIX에서 실행 파일을 실행하기 위해서는 파일 확장자를 포함한 전체 파일 이름을 사용한다.

    파일 위치를 지정해야하는 경우 실행 파일이 현재 디렉토리에 있음을 나타 내기 위해

    "." 뒤에 forward slash를  붙혀 사용한다.

    main에서 return된 값은 시스템 종속 방식으로 access된다.

    UNIX 및 Windows 시스템은 프로그램을 실행 한 후 적절한 echo 명령을 실행해야한다.

    UNIX 시스템에서는 다음과 같이 작성하여 상태를 얻는다.

    Windows 시스템의 상태를 확인하기 위해서는 다음과 같이 작성한다.

    Running the GNU or Microsoft Compilers

    C ++ compiler 를 실행하는 데 사용되는 명령은 compiler 와 운영 체제에 따라 다르다.

    가장 일반적인 compiler 는 GNU compiler 와 Microsoft Visual Studio compiler 이다.

    기본적으로 GNU compiler 를 실행하는 명령은 g++이다.

    $ g++ -o prog1 prog1.cc

    $ 는 시스템 prompt 이다.

    -o prog1 은 compiler 의 argument 이자 실행파일이 될 파일의 이름을 지정한다.

    이 명령어는 운영체제에 따라 prog1 또는 prog1.exe 라는 이름으로 된 실행파일을 생성한다.

    UNIX 에서는 실행파일은 suffx 를 가지고있지않고,

    Windows 에서는 suffix 는 .exe 이다.

    만약 -o prog1 을 생략한다면, compiler 는 UNIX 에서는 a.out Windows 에서는 a.exe 라는 이름의 

    실행파일을 생성한다.

    사용중인 GNU 컴파일러의 release에 따라 C ++11 지원을 켜려면 -std = c ++ 0x를 지정해야한다.

    Microsoft Visual Studio 2010 compiler 를 실행하는 명령어는 cl 이다.

    여기에 C:\Users\me\Programs> 이 시스템 prompt 이고,

    Users\me\Programs 이 현재 디렉토리 (현재 폴더) 의 이름이다. 

    cl 명령은 compiler 를 호출하고, /EHsc 는 표준 예외 처리를 설정하는 compiler 옵션이다.

    Microsoft compiler는 첫 번째 source file 이름에 해당하는 이름으로 실행 파일을 자동으로 생성한다.

    실행 파일에는 suffix .exe가 있으며 source file 과 이름이 같다.

    이 경우 실행 파일의 이름은 prog1.exe 이다.

    compiler 에는 일반적으로 문제가있는 구문에 대한 경고를 생성하는 옵션이 포함되어 있다.

    일반적으로 이러한 옵션을 사용하는 것이 좋다.

    -Wall 을 GNU 컴파일러와 함께 사용하고 /W4 를 Microsoft 컴파일러와 함께 사용하는 것이 좋다.

    자세한 내용은 자신이 사용하는 compiler의 사용 설명서를 참조하라.

     


    1.2 A First Look at Input/Output

    C++ 언어는 입력 또는 출력(IO)을 수행하기 위한 statement를 정의하지 않는다.

    대신, C++는 입출력(및 기타 많은 설비)을 제공하는 광범위한 표준 라이브러리를 포함한다.

    이 책의 예제를 포함하여 여러 목적을 위해 IO library의 몇 가지 기본 개념과 연산만 알면 된다.

    이 책에있는 대부분의 예제는 iostream library를 사용한다.

    iostream library의 기본은 각각 입력 및 출력 스트림을 나타내는 istream ostream이라는 두 가지 유형이다.

    stream 은 IO 장치에서 읽거나 쓴 일련의 문자이다.

    stream 이라는 용어는 문자가 시간이 지남에 따라 순차적으로 생성되거나 소비됨을 제안하기위한 것이다.

    Standard Input and Output Objects

    library 는 4개의 IO 객체로 구성되어있다.

    입력을 처리하기 위해 cin (see-in)이라는 이름의 istream type의 객체를 사용한다.

    이 객체를 standard input (표준 입력) 이라고도 한다.

    출력을 처리하기 위해 cout (see-out)이라는 ostream type의 객체를 사용한다.

    이 객체를 standard ouput (표준 출력) 이라고도 한다.

    library는 또한 cerr clog (각각 see-err 및 see-log로 발음)라는 두 개의 다른 ostream 객체를 정의한다.

    일반적으로 경고 및 오류 메시지에 대해 standard error (표준 오류) 라고하는 cerr을 사용하고

    프로그램 실행에 대한 일반 정보를 위해 clog를 사용한다.

    일반적으로 시스템은 이러한 각 객체를 프로그램이 실행되는 창과 연결한다.

    따라서 cin에서 읽을 때 프로그램이 실행중인 창에서 데이터를 읽고 

    cout, cerr 또는 clog에 쓸 때 출력이 동일한 창에 기록된다.

    A Program That Uses the IO Library

    IO library 를 사용하여, 우리의 main 프로그램이 사용자에게 2개의 숫자를 받고,

    이것들의 합을 출력하도록 할수있다.

    #include <iostream>
    
    int main() {
    
        std::cout << "Enter two numbers: " << std::endl;
        int v1 = 0, v2 = 0;
        std::cin >> v1 >> v2;
        std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;
    
        return 0;
    
    }

    위의 프로그램이 시작되면 아래와 같은 메세지를 출력한다.

    그 후 사용자의 input 을 기다린다.

    사용자가 만약 "3 7" 을 입력하였다면

    아래와같은 메세지를 출력한다.

    #include <iostream>

    위 코드의 의미를 알아보도록 하자.

    이 첫번째 줄은 compiler 에게 iostream library 를 사용하고자한다고 알리는것이다.

    대괄호 angle bracket < > 안에 이름 (여기서는 iostream) 은 header 를 나타낸다.

    library 기능을 사용하는 모든 프로그램은 관련 헤더를 포함해야한다.

    #include 지시문(directive) 은 한 줄에 작성해야하며, header 이름과 #include는 같은 줄에 나타나야합니다.

    일반적으로 #include 지시문은 모든 함수 외부에 나타나야한다.

    일반적으로 소스 파일의 시작 부분에 프로그램에 대한 모든 #include 지시문을 넣는다.

    Writing to a Stream

    main body 의 첫 번째 statement는 expression(표현식)을 실행한다.

    C ++에서 expression은 결과를 산출하며 하나 이상의 operand(피연산자) 와 일반적으로 operator(연산자)로 구성된다.

    std::cout << "Enter two numbers: " << std::endl;

    이 statement 에서 expression 은 output 연산자 << 를 사용하여 메세지를 출력한다.

    << 연산자는 2개의 피연산자를 사용하는데, 왼쪽 피연산자는 ostream 객체여야하며,

    오른쪽 피연산자는 출력할 값이다.

    연산자는 주어진 값을 주어진 ostream에 기록한다.

    output 연산자의 결과는 왼쪽 피연산자이다.

    즉, 결과는 주어진 값을 쓴 ostream이다.

    우리의 output statement 는 << 연산자를 2번 사용하고있는데,

    첫 번째 연산자의 결과가 두 번째 연산자의 왼쪽 피연산자가된다.

    따라서 아래의 expression 과 동일하다.

    (std::cout << "Enter two numbers:") << std::endl;

    각 연산자는 동일한 왼쪽 피연산자를 가지는데 (이경우 std::cout),

    아래와 같이 2개의 statement 로 동일한 output 을 출력할수있다.

    std::cout << "Enter two numbers: ";
    std::cout << std::endl;

    첫 번째 << 연산자는 사용자에게 메시지를 print한다.

    해당 메시지는 큰 따옴표 double quotatin " " 로 묶인 일련의 문자 인 string literal 이다.

    " " 안에 text 는 표준 출력으로 print 된다.

    2번째 << 연산자는 manipulator 라는 특수한 값인 endl 을 출력한다.

    endl 을 사용하는것은 현재 line 을 끝내고 device 와 연관된 buffer 를 flush 하는 효과가 있다.

    buffer 를 flush 하는것은 프로그램이 지금까지 생성한 모든 출력이 

    기록되기를 기다리는 메모리에 있는 것이 아니라 실제로 출력 스트림에 기록되도록 한다.

    프로그래머는 종종 디버깅 중에 print statement를 추가한다. 

    이러한 statement는 항상 스트림을 flush 해야한다.

    그렇지 않으면 프로그램이 충돌하면, 출력이 buffer에 남아 프

    로그램이 충돌 한 위치에 대한 잘못된 추론이 발생할 수 있다.

    Using Names from the Standard Library

    섬세한 독자라면 위의 프로그램이 cout endl 대신에 std::coutstd::endl 를 

    사용한것을 보았을것이다.

    이 prefix std::cout endl 라는 이름이 std 라는 namespace 안에 정의된것들임을 나타낸다.

    namespace를 사용하면 우리가 정의한 이름과

    library 내에서 동일한 이름 사이의 우연한 충돌을 방지 할 수 있다.

    표준 library 안에 정의된 모든 이름은 std 라는 namespace 안에 속해있다.

    library 가 namespace 를 사용할때 한 가지 부작용은 

    우리가 library 안에 이름을 사용할때 std 라는 namespace 를 반드시 명시해줘야한다. (explicitly)

    std::cout 을 보면 scope 연산자 :: 를 사용하는데, 

    이는 우리가 std 라는 namespace 안에 정의된 cout 을 사용하고자함을 의미한다.

    Reading from a Stream

    사용자에게 입력을 요청한후, 우리는 그 입력을 읽기 원할것이다.

    이 입력을 유지하기위해 v1v2 라는 이름에 2개의 variable 을 정의한다.

    int v1 = 0, v2 = 0;

    이러한 변수는 정수 (integer) 를 나타내는 built-in type 인 int 로 정의하고,

    0 으로 초기화 (initialize) 한다.

    우리가 변수를 초기화하는것은, 변수 생성과 동시에 값을 제공하는것이다.

    std::cin >> v1 >> v2;

    이 statement 는 입력을 읽는다.

    입력 연산자 >> 는 출력 연산자와 유사하게 작동하는데,

    istream을 왼쪽 피연산자 (left-hand operand) 로, 객체를 오른쪽 피연산자 (right-hand operand) 로 사용한다.

    주어진 istream 으로부터 데이터를 읽고, 주어진 객체에 이 데이터를 저장한다.

    출력 연산자처럼, 입력 연산자는 왼쪽 피연산자를 결과값으로 return 한다.

    따라서 이 표현식은 아래와 동일하다.

    (std::cin >> v1) >> v2;

    >> 연산자는 왼쪽 피연산자를 return 하기때문에 일련의 입력 요청을 단일 statement 로 결합할수있다.

    이 입력 operation은 std::cin에서 두 값을 읽어서 첫 번째는 v1에 저장하고 두 번째는 v2에 저장한다.

    operation은 결과적으로 아래와 같이 실행된다.

    std::cin >> v1;
    std::cin >> v2;

    Completing the Program

    이제 남은것은 우리의 결과를 print 하는것이다.

      std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;

    이 statement는 사용자에게 입력을 요청하는것보다 길지만 개념적으로 유사하다.

    표준 출력에 각 피연산자를 print한다.

    이 예에서 흥미로운 점은 피연산자가 모두 같은 종류의 값이 아니라는 것이다.

    일부 피연산자는 "The sum of"와 같은 string literal 이고,

    다른 것은 v1, v2와 같은 int 값과 산술 표현식 (arithmetic expression) 인  v1 + v2를 evalute 한 결과이다.

    library는 이러한 각기 다른 type의 피연산자를 처리하는 입력 및 출력 연산자의 버전을 정의한다.


    1.3 A Word about Comments

    우리의 프로그램이 훨씬 더 복잡해지기 전에 C++가 comment (주석)을 어떻게 처리하는지 살펴 봐야한다.

    comment 는 인간을 위한것이다.

    comment일반적으로 알고리즘을 요약하거나, 변수의 목적을 식별하거나

    또는 코드의 다른 불분명한 부분을 명확히 하기 위해 사용된다

    compiler 는 comment 를 무시하므로 프로그램의 동작이나 성능에 영향을주지 않는다.

    compilercomment를 무시하지만, 우리 코드의 독자들은 comment를 무시하지 않는다.

    프로그래머는 시스템 문서의 다른 부분이 최신 버전이 아닌 경우에도 comment를 신뢰하는 경향이 있다.

    코드를 읽는이의 오해를 유도할수있는 comment 는 no comment 보다 못하다.

    당신의 code 를 변경하고자한다면, comment 를 업데이트하는것도 있지말라!

    Kinds of Comments in C++

    C++ 에서는 2가지 종류의 comment 가 있는데, single-line 과 paired 이다.

    single-line comment 는 double slash // 로 시작하여 새 line 으로 끝난다.

    // 의 우측에 오는 모든것은 compiler 에게 무시된다.

    이 single-line comment 는 추가적인 double slash 를 포함하여 어떠한 종류의 text 든 포함할수있다. 

    또다른 종류인 comment pair 는 /* and */ 를 사용하며, C 로부터 온것이다.

    comment pair 는 /* 로 시작하여 */ 로 끝나고 또다른 */ 이 아닌 어떠한 text 든 포함할수있다.

    compiler 는 /**/ 사이의 모든것을 comment 로 간주한다.

    comment pair 는 tab 과 space, new line 이 허용되는 모든것에 위치할수있다.

    comment pair는 프로그램의 여러 줄에 걸쳐있을 수 있지만 그렇게 할 필요는 없다.

    comment pair가 여러 줄에 걸쳐있는 경우 내부 줄이 여러 줄 comment 의 일부임을 시각적으로 나타내는 것이 좋다.

    우리의 스타일은 comment의 각 줄을 별표 * (asterisk)로 시작하여 전체 범위가 여러 줄의 주석의 일부임을 나타내는것이다.

    프로그램에는 일반적으로 이 두 가지 comment 형식이 혼합되어 있다.

    comment pair는 일반적으로 여러 줄 설명에 사용되는 반면

    double slash comment 는 반줄 및 한 줄 설명에 사용되는 경향이 있다.

    #include <iostream>
    /*
     * Simple main function
     * Read two numbers and write their sum 
     */ 
    
    int main() {
    
        // prompt user to enter two numbers
        std::cout << "Enter two numbers: " << std::endl;
        int v1 = 0; , v2 = 0; // variables to hold the input we read
        std::cin >> v1 >> v2; // read input
        std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;
    
        return 0;
    
    
    }

    Comment Pairs Do Not Nest

    comment pair 는 /* 로 시작하여 */ 로 끝난다.

    따라서 하나의 comment pair 는 다른 comment pair 안으로 중첩될수없다.

    이런 실수로 인해 발생되는 compiler 에러 메세지는 매우 미스터리하고 당혹스러운것이다.

    /*
     * comment pairs /* */ cannot nest.
     * "cannot nest" is considered source code,
     * as is the rest of the program
     */
    
    int main() {
    
        return 0;
    
    }

    우리는 종종 디버깅 중에 코드 block을 comment 처리해야한다.

    이런 과정에서 코드에 중첩 된 comment pair가 포함될 수 있다.

    코드 block을 comment  처리하는 가장 좋은 방법은 무시하려는 섹션의 각 줄 시작 부분에

    single-line comment 를 삽입하는 것이다.

    // /*
    //  * everything inside a single-line comment is ignored
    //  * including nested comment pairs
    //  */

    1.4 Flow of Control (제어 흐름)

    statement들은 일반적으로 순차적으로 실행된다.

    block의 첫 번째 statement가 먼저 실행되고 두 번째 statement가 실행되는 방식이다.

    하지만 순차적인 실행만을 사용하여 작성할 수있는 프로그램은 거의 없다.

    따라서 프로그래밍 언어는보다 복잡한 실행 경로를 허용하는 다양한 제어 흐름 statement를 제공한다.


    1.4.1 The while Statement

    while 문은  주어진 조건이 참인 한 코드 섹션을 반복적으로 실행한다.

    while 문을 사용하여 다음과 같이 1부터 10까지의 숫자를 더하는 프로그램을 작성할 수 있다.

    #include <iostream>
    
    int main() {
    
        int sum = 0, val = 1;
        // keep excuting the while as long as val is less than or equal to 10
        while (val <= 10) {
    
            sum += val; // assigns sum + val to sum
            ++val; // add 1 to val
    
        }
    
        std::cout << "Sum of 1 to 10 inclusive is " << sum << std::endl;
    
        return 0;
    
    }

    이 프로그램을 compile 후 실행하면 아래와 같이 출력된다.

    while 문은 아래와 같은 형태로 작성한다.

    while 은 condition 을 테스트하고, condition 이 false 일때까지 statement 를 실행한다.

    condition 은 true 또는 false 를 산출하는 표현식(expression)이다. 

    condition 이 true 일때, statement 는 실행된다.

    statement 를 실행한후에 condition 은 다시 test 된다.

    condition 이 다시 true 이면 statement 는 다시 실행된다.

    while 은 우리를 대신해 condition 을 test 하고,

    condition 이 false 일때까지 statement 를 실행한다.

     

    이 프로그램에서 while 문을 다시 살펴보자.

    // keep excuting the while as long as val is less than or equal to 10
    while (val <= 10) {
    
        sum += val; // assigns sum + val to sum
        ++val; // add 1 to val
    
    }

    이 condition 은 val 10 을 비교하기위하여

    less-than-or-equal (작거나 같은) <= 연산자를 사용한다.

    val 10 보다 작거나 같으면, condition 은 true 이다.

    condition 이 true 라면, while 의 body 가 실행된다.

    이 경우, body 는 2개의 statement 로 이루어진 block 이다.

    {
    
        sum += val; // assigns sum + val to sum
        ++val; // add 1 to val
    
    }

    block 은 중괄호 curly brace { } 로 감싼 0 개 이상 statement 의 sequence 이다.

    이 block 은 compound assignment 연산자인 += 를 사용하고있다.

    이 연산자는 오른쪽 피연산자를 왼쪽 피연산자와 더한후, 그 결과값을 왼쪽 피연산자에 저장한다.

    이 연산자는 아래의 코드와 동일하다.

    sum = sum + val; // assign sum + val to sum

    따라서, 이 block 의 첫번째 statement 는 val 가 sum 을 더하여 sum 다시 저장한다.

     

    다음 statement 인,

    ++val; // add 1 to val

    은 prefix increment (증감) 연산자 ++ 를 사용한다.

    증감 연산자는 1 을 피연산자에 더한다.

    ++val 이라고 적는것은 val = val + 1 과 같다.

    while 의 body 가 실행된후, loop 은 condition 을 다시 한번 산출한다 (evaluate).

    val 의 값이 여전히 10보다 작거나 같다면 while 의 body 는 다시 실행된다.

    이 loop 은 condition 을 test 하고, body 를 실행하면서 val 이 더 이상 10 보다 작거나 같지않을때까지

    계속된다.

    val 이 10보다 크면 프로그램은 while loop에서 빠져 나가고,

    while 다음에 오는 statement로 실행을 계속한다.

    이 경우 statement는 output을 print하고, 그다음 return 하고, 프로그램을 완료한다.


    1.4.2 The for Statement

    우리의 while 문에서 우리는 loop 이 얼마나 실행될지 컨트롤하기위해서 변수 val 을 사용했다.

    우리는 val 의 값을 condition 안에서 테스트한후, while 의 body 에서 val 을 증가시켰다.

    condition 에서 변수를 사용하고 body에서 해당 변수를 증가시키는이 패턴은

    너무 자주 발생하기때문에 이 패턴을 따르는 코드를 축약하는 두 번째 문인 for 문을 소개한다.

    위에서 while 로 작성했던 1 부터 10 까지의 합을 구하는 프로그램을 

    for 문을 통하여 재작성해보자.

    #include <iostream>
    
    int main() {
    
        int sum = 0;
        // sum values from 1 through 10 inclusive
    
        for (int val = 1; val <= 10; ++val) {
    
            sum += val; // equivalent to sum = sum + val
    
            std::cout << "Sum of 1 to 10 inclusive is " << sum << std::endl;
    
        }
    
        return 0;
    
    }

    이 코드에서 for 문을 살펴보자.

    for (int val = 1; val <= 10; ++val) {
    
        sum += val; 
    
    }

    for 문은 2개의 파트로 구성되어있다 : header, body

    header 는 body 가 얼마나 자주 실행될지 컨트롤한다.

    header 는 다시 3개의 파트로 구성된다 : init statement, condtion, expression

    int val = 1;

    이 init statement 는 val 이라는 이름의 int 객체를 정의하고, 초기값을 1로 주었다.

    변수 val 은 오직 for 안에서만 존재한다.

    따라서 val 을 loop 이 끝난뒤에 사용하는것은 불가능하다.

    init statement 는 for 안에서 오직 단 한번만 실행된다.

    val <= 10

    이 condition 은 val 의 현재값과 10 을 비교한다.

    이 condition 은 loop 이 돌때마다 매번 테스트된다.

    val 이 10 보다 작거나 같은 동안, for 의 body 는 실행된다.

    ++val;

    이 expression 은 for body 이후 실행된다.

    이 expression 은 prefix increment 연산자 ++val 을 사용하고있기때문에,

    val 1 을 더한다.

    expression 이 실행된후에 for 는 condition 을 reset 한다.

    val 의 새로운값이 여전히 10보다 작거나 같다면, for loop 의 body 는 다시 한번 실행된다.

    body 가 실행된후, val 은 다시 한번 증가한다.

    따라서 loop 은 condition 이 false 일때까지 계속 실행된다.

    이 loop 에서 for 의 body 는 합계를 구한다.

    sum += val;

    for 의 실행흐름을 마지막으로 정리해보자.

    1. val 을 만들고 1로 초기화한다.
    2. val 10 보다 작거나 같은지 테스트한다. true 라면 for 의 body 를 실행, false 면 loop 을 빠져나가 다음 code 를 실행한다.
    3. val 을 증가시킨다.
    4. 2번째 -> 3번째 step 을 condition 이 true 일때까지 반복한다.

    1.4.3 Reading an Unknown Number of Inputs

    지금까지 우리는 1부터 10까지 더하는 프로그램을 만들어봤다.

    이 프로그램을 사용자가 입력한 숫자들을 더하는 프로그램으로 확장해보자.

    이 경우, 우리는 얼마나 많은 숫자가 더해질지 모른다.

    대신에 우리는 더 이상 읽을 숫자가 없을때까지 숫자를 계속 읽을것이다.

    #include <iostream>
    
    int main() {
    
        int sum = 0; , value = 0;
        // read until end-of-file, caculating a running total of all values read
        while (std::cin >> value) {
    
            sum += value; // equivalent to sum = sum + vale
    
        }
        
        std::cout << "Sum is : " << sum << std::endl;
    
        return 0;
    
    }

    우리가 

    를 입력한다면 출력은 아래와 같다.

    main 안에 첫번째 줄은 sum 과 value 라는 0 으로 초기화된 2개의 int 변수를 정의한다.

    우리는 입력되는 숫자를 보존하기위해 value 를 사용한다.

    우리는 while 의 condition 안에 있는 data 를 읽는다.

    while (std::cin >> value)

    while 의 condition 을 산출하는것은 아래의 expression 을 실행한다.

    std::cin >> value

    이 expression 은 standard input 의 다음 숫자를 읽고, value 에 저장한다.

    input 연산자 >> 는 왼쪽 피연산자를 return 한다. (이경우 std::cin)

    따라서 std::cin 을 condition 으로 테스트하는것이다.

    istream 을 condition 으로 사용한다는것은, stream 의 state 를 테스트하는것이다.

    이 stream 이 vaild 하다면, 혹은 stream 이 error 를 만나지않았다면 테스트는 성공한것이다.

    istream 은 우리가 end-of-file 을 입력했거나 invaild input (예 : 정수가 아닌 값) 을 만나면 invaild 된다. 

    invaild state 인 istream 은 condition 에서 false 로 산출된다.

    따라서 우리의 while 은 end-of-file 또는 input error 를 만날때까지 실행된다.

    우리의 while body 는 현재값을 sum 에 더하기위해

    compound assignment 연산자 += 를 사용한다.

    condition 이 실패하면 while 은 끝이나고, 다음 statement 인 endl 로 끝나는 sum 을 print 한다.

     

    Entering an End-of-File from the Keyboard

     

    우리가 키보드를 사용하여 프로그램에 입력할때, 운영체제마다 end-of-file 을 나타내는 규칙이 다르다.

    Windows 에서 end-of-file 은 ctrl+z 를 누른채 enter 키를 누르는것이다.

    Unix (Mac OS X 포함) 에서 end-of-file 은 ctrl + d 이다.

     

    Compilation Revisited

     

    compiler의 임무중 하나는 프로그램의 error 를 발견하는것이다.

    compiler는 프로그램 작성자의 의도를 발견 하지는 못하고, 오직 프로그램의 형태에 관한 error 만을 발견할수있다.

    compiler 가 발견할수있는 error 의 종류에 대해 알아보자.

     

    Syntax error 

     

    프로그래머가 C++ 에서 작성한 문법적인 error 이다.

    아래 프로그램은 일반적으로 우리가 실수할수있는 syntax error 에 대한 예이다.

    comment 로 각 error 에 관한 설명들을 달아놓았다.

    // error : missing ) in parameter list for main
    int main ( {
    
        // error : used colon, not a semicolon, after endl
        std::cout << "Read each file." << std::endl :
    
        // error : missing quotes around string literal
        std::cout << Update master. << std::endl;
    
        // error : second output operator is missing
        std::cout << "Write new master." std::endl;
    
        // error : missing ; on return statement
        return 0
    
    }

     

    Type error

     

    C++ 의 각 data 들은 연관된 type 을 가지고있다.

    예를 들어, value 10 은 int type 이다. (대부분 "10 은 int 다!" 라고 말한다)

    "hello" (" " 를 포함하여) 는 string literal 이다.

    가장 흔한 error 중 하나는 string literal 을 int 를 받아야할 함수의 인자로 넘기는것이다.

     

    Declaration error

     

    C++ 프로그램에 사용된 모든 이름은 반드시 사용되기전에 선언되어야한다.

    가장 빈번한 선언 error 는 std:: 를 앞에 붙이는것을 까먹는것이다.

    #include <iostream>
    
    int main() {
    
        int v1 = 0, v2 = 0;
        std::cin >> v >> v2; // error : uses "v" not "v1"
    
        // error : cout not defined; should be std::cout
        cout << v1 + v2 << std::endl;
    
        return 0;
    
    }

    error 메세지는 대부분 line number 와 compiler 가 잘못되었다고 생각하는것에 대한 간략한 설명이 담겨있다.

    compiler 가 알려주는 error 를 고치는것은 좋은 습관이다.

    종종 하나의 error 가 계단식 영향을 미칠수있고, 이는 compiler 가 존재하는 error 보다 훨씬 더 많은 error 를 report 하게한다.

    따라서 최대한 적은 수의 명백한 fix 를 한 후에는 코드를 반드시 다시 컴파일하는 것이 good practice 이다.

    이러한 방식을 edit-compile-debug 라고 한다.


    1.4.4 The if Statement

     

    다른 언어들 처럼 C++ 도 조건이 있는 실행을 하기위한 if 문을 제공한다.

    if 문을 사용하여 입력한 숫자중 각 숫자가 몇번 나타나는지 계산하는 프로그램을 만들어보자.

     

    #include <iostream>
    
    int main() {
    
        // currVal is the number we're couting; we'll read new values into val.
        int currVal = 0, val = 0;
    
        // read first number and ensure that we have data to process.
        if (std::cin >> currVal) {
    
            int cnt = 1; // store the cout for the current value we're processing
    
            // read the remaining numbers
            while (std::cin >> val) {
    
                // if the values are the same
                if (val == currVAL) {
    
                    ++cnt; // add 1 to cnt
    
                }
    
                // otherwise, print the count for the previous value
                else {
    
                    std::cout << currVal << " occurs " << cnt << " times" << std::endl;
    
                    currentVal = val; // remember the new value
                    cnt = 1; // reset the counter
    
                }
    
            } // while loop ends here
    
            // remember to print the count for the last value in the file.
            std::cout << currVal << " occurs " << cnt << " times" << std::endl;
    
    
        } // outermost if statement ends here
    
        return 0;
    
    }

    아래와 같은 입력을 하면.

    아래와 같이 출력된다.

    이 프로그램의 대부분이 우리가 앞서 작성했던 프로그램과 비슷하다.

    우리는 val currVal을 정의하면서 시작한다.

    currVal 은 우리가 새고있는 숫자가 무엇인지 계속해서 추적한다.

    val 은 우리가 입력한 각 숫자를 보존한다.

    첫번째 if 문인

    if (std::cin >> currVal) {
    
    }

    은, 입력이 비어있지않다는것을 확인한다.

    while 처럼 if 도 condition 을 산출한다.

    if condition 은 우리가 읽는 값을 currVal 로 집어넣는다.

    읽는것이 성공했다면, condition 은 true 가 되고, { } 안에 있는 block 을 실행한다.

    이 block 은 return 문후에 끝이 난다.

    우리가 정의한 cnt 는 각 숫자가 몇번 발생했는지 count 한다.

    while loop 은 standard input 으로부터 들어오는 숫자들을 읽는다.

    while 의 body 는 2번째 if 문을 포함하는 block 이다.

    // if the values are the same
    if (val == currVAL) {
    
        ++cnt; // add 1 to cnt
    
    }
    
    // otherwise, print the count for the previous value
    else {
    
        std::cout << currVal << " occurs " << cnt << " times" << std::endl;
    
        currentVal = val; // remember the new value
        cnt = 1; // reset the counter
    
    }

    if 안에 condition 은 equality 연산자 (동등 연산자) ==valcurrVal 가 동일한지 테스트한다.

    이 condition 이 true 라면, 즉시 cnt 를 증가시킨다.

    cnt 의 증가는 우리가 currVal 을 한번 더 보았음을 나타낸다.

    하지만 이 condition 이 false 라면 즉, val currVal 과 같지않다면 else 안의 statement 를 실행한다.

    이 statement 는 output statement 와 2개의 assignment 로 구성되어있다.

    이 assignment 는 cnt 1 로, 우리가 방금 읽었던 값인 currVal val 로 reset 한다.

     

    Warning

     

    C++ 는 = 을 assignment (대입) 로, == 를 equality (동등) 로 사용한다.

    이 연산자들은 둘다 condition 안에 등장할수있다.

    이로인해 발생하는 가장 흔한 실수는 == 을 의도했는데 condition 안에 = 를 사용하는것이다. 

     

    Key Concept : Indentation and Formatting of C++ Programs

     

    C++ 프로그램은 매우 자유로운 형태이다.

    이것이 의미하는건, { } (curely brace) , 들여쓰기 (indentation), comment, 새로운 줄등은 

    프로그램이 의미하는것에 아무런 영향이 없다.

    예를 들어, main 의 body 의 시작을 나타내는 { main 과 같은 줄에 올수있고,

    우리가 원하는 어떠한 위치에든 상관없이 사용할수있다.

    유일한 요구 사항은 open curly {main의 매개 변수 목록 다음의 공백 또는 주석이 아닌 첫 번째 문자 여야한다는 것이다.

    우리가 이렇게 자유롭게 formatting 할때 프로그램에는 아무 영향이 없다하더라도, 가독성에는 영향을 미친다.

    예를 들어, 우리는 main 의 모든 code 를 단 한줄로 우측으로 쭈욱 길게 작성할수도있다는것이다.

    이는 legal 이지만 당연히 매우 읽기 힘들것이다.

    C 또는 C ++ 프로그램을 포맷하는 올바른 방법에 대해서는 끝없는 논쟁이 일어난다.

    간략하게 말하면, 정해진 방식은 없지만 언제나 일관성 (consistency) 을 유지해야한다는것이다.

    대부분의 프로그래머는 위의 코드처럼 프로그램의 보조 부분을 들여쓰기한다.

    또한 함수를 구분하는 중괄호를 자체 줄에 두는 경향이 있다.

    또한, 연산자가 정렬되도록 복합 IO 표현식을 들여쓰는것이 좋다.

    프로그램이 더 정교 해짐에 따라 다른 들여 쓰기 규칙이 명확해질 것이다.

    명심해야 할 중요한 것은 프로그램을 포맷하는 다른 방법 또한 가능하다는것이다.

    늘 formatting 스타일을 선택할 때 가독성과 이해도에 어떤 영향을 미치는지 생각해보라.

    하나의 style 을 사용하기로 결정했다면, 일관되게 사용하라.


    1.5 Introducing Classes

    우리의 bookstore 문제를 해결하기위해 마지막으로 우리가 이해야할 기능은,

    어떻게 transaction 데이터를 data 구조로 나타내냐는것이다.

    C++ 에서는 우리가 원하는 data 구조를 class 를 정의함으로써 정의한다.

    class 는 type 과, 이 type 과 연관된 연산들의 모음을 정의한다.

    class 의 메카니즘은 C++ 에서 가장 중요한 기능이다.

    사실, C ++ 디자인의 주요 초점은 built-in type처럼 자연스럽게 동작하는 class type을 정의 할 수 있도록하는 것이다.

    이 section 에서는 우리의 bookstore 프로그램에서 사용할수있는 간단한 class 를 만들어볼것이다.

    우리가 뒤에 chapter 로 가면서 type, expression, statement, function 에 대하여 배우고 난뒤

    이 class 를 구현할것이다.

    class 를 사용하기위하여 우리는 아래의 3가지를 알아야한다.

    • 이름이 무엇인가?
    • 이 class 는 어디에 정의되어있는가?
    • 어떠한 operation 을 지원하는가?

    우리의 bookstore 문제에 대해서, class 이름은 Sales_item 이고, 

    이미 Sales_item.h 에 정의되어있다고 가정하자.

    앞서 보아왔듯이, library 를 사용하기위해서 우리는 연관된 header 를 include 해야한다.

    이와 유사하게, class 에 접근하기위해서 header 를 사용해야한다.

    관습적으로, header 파일 이름은 header 파일안에 정의된 class 의 이름으로부터 파생된다.

    header file 읜 보통 .h 라는 suffix 로 끝이난다.

    하지만 몇몇 프로그래머들은 .H, .hpp, .hxx 를 사용하기도한다.

    standard library 의 header 들은 일반적으로 어떤 suffix 도 가지고있지않다.

    compiler 는 보통 header 파일 이름의 형태에 대해 신경쓰지않지만, IDE 는 가끔 그렇지않다.


    1.5.1 The Sales_item Class

    Sales_item class의 목적은 책의 총 수익, 판매 된 사본 수, 평균 판매 가격을 나타내는 것이다.

    어떻게 이러한 데이터가 저장되고 계산되는지는 우리의 관심사가 아니다.

    클래스를 사용하기 위해 어떻게 구현되는지는신경 쓸 필요가 없다.

    대신 우리가 알아야 할 것은 해당 type의 operation 객체가 무엇을 수행할수있는지이다.

    모든 class 는 type 을 정의한다.

    이 type 이름은 class 의 이름과 동일하다.

    따라서 우리의 Sales_item class 는 Sales_item 이라는 이름의 type 을 정의하고,

    built-in type 처럼 class type 의 variable 을 아래와 같이 정의할수있다.

    Sales_item item;

    위의 item 은 아래와 같이 말할수있다.

    "Sales_item type 의 객체"

    "Sales_item 객체"

    "a Sales_item"

     

    Sales_item type 의 변수를 정의할수있다는것은 아래의 것들을 할수있음을 의미한다.

    • Sales_item 객체로부터 isbn 을 가져올수있는 isbn 함수를 호출할수있다.
    • Sales_item type 의 객체를 읽고 쓰기위해 (read and write) >> 연산자와 << 연산자를 사용할수있다.
    • Sales_item 객체를 다른 객체에 대입하기위해 = 연산자를 사용할수있다.
    • 2개의 Sales_item 객체를 더하기위해 + 연산자를 사용할수있다. 
    • Sales_item 객체를 다른 객체에 더하기위해 += 연산자를 사용할수있다.

    Key Concept : Classes Define Behavior

     

    명심해야할것은 Sales_item class 의 저가가 이 class 의 객체에 의해 수행될수있는 모든 행동들을 직접 정의한다는것이다.

    즉, Sales_item class 가 Sales_item 객체가 생성될때, 

    또는 assignment, addition, input, output 연산자들이 사용되었을때 무엇을 할지 정의한다는것이다.

    일반적으로 class 의 저자가 class type 의 객체가 할수있는 모든 operation을 결정한다.

    지금까지는 우리가 알수있는 Sales_item 객체가 할수있는 operation 은 오직 이 섹션에서 다루고있는것들이다.

     

    Reading and Writing Sales_items

     

    우리는 Sales_item 객체가 할수있는 operation 을 알고있기때문에,

    우리는 이 class 를 사용하는 프로그램을 작성할수있다.

    예를 들어, 아래 프로그램은 표준 input에서 Sales_item 객체로 데이터를 읽고 (read),

    Sales_item 을 다시 표준 output 으로 쓰는 (write) 프로그램이다.

    #include <iostream>
    #include "Sales_item.h"
    
    int main() {
    
        Sales_item book;
    
        // read ISBN, number of copies sold, and sales price
        std::cin >> book;
    
        // write ISBN, number of copies sold, total revenue, and average price
        std::cout << book << std::endl;
    
        return 0;
    
    }

    프로그램에 아래와같이 입력되었다면..

    아래와 같이 출력될것이다.

    우리의 입력은 이 책 4권을 24.99달러에 팔았다는것을 이야기하고,

    출력은 총 4권이 팔렸고, 총 수익은 99.96 달러고, 각 책의 평균 가격은 24.99 달러임을 나타낸다.

    이 프로그램은 2개의 #include 지시어로 시작한다.

    이들 중 하나는 새로운 형태를 사용하고있다.

    표준 library 의 header 는 angle bracket < > 로 감싸져있는 반면,

    표준 library 가 아닌 것은 double quotes " " 로 감싸져있다.

    main 안에서 우리는 book 이라는 이름의 객체를 정의했다.

    이 객체는 표준 input 으로 읽는 데이터를 보관할것이다.

    2번째 statement 는 객체로 데이터를 읽어들이고,

    3번째 statement 는 표준 output 으로 이 객체를 출력한다.

     

    Adding Sales_items

     

    더 흥미로운 예제는 2개의 Sales_item 객체를 더하는것이다.

    #include <iostream>
    #include "Sales_item.h"
    
    int main() {
    
        Sales_item item1, item2;
        std::cin >> item1 >> item2; // read a pair of transactions
        std::cout << item1 + item2 << std::endl; // print their sum
        return 0;
    
    }

    이 프로그램에 아래의 입력을 한다면,

    출력은 아래와 같다.

    이 프로그램은 Sales_itemiostreaminclude 하는것으로 시작한다.

    다음으로, 우리는 transaction 들을 보관하기위해 2개의 Sales_item 객체를 정의한다.

    우리는 표준 입력로부터 받는 데이터를 이 객체들로 읽어들인다.

    출력 표현식은 더하기를 수행하고, 결과를 print 한다.

    우리는 앞서 page 6 에서 만들었던 프로그램과의 유사성에 주목할 필요가있다.

    우리는 2개의 입력을 read 후 이것들의 합을 write 한다.

    이 유사성을 주목할만한 이유는 2개의 정수를 합해서 print 하는대신에,

    2개의 Sales_item 객체를 합해서 print 한다는것이다.

    중요한건 우리가 이야기하는 합 "Sum" 의 개념이 서로 다르다는것이다.

    int 의 합의 경우 관습적으로 2개의 숫자값을 더하는것인 반면에,

    2개의 Sales_item 객체의 구성요소 (component) 를 더한 결과 인 sum 은 개념적으로 새로운 의미를 사용한다.

     

    Using File Redirection

     

    우리의 프로그램에 이 transaction 들을 매번 입력하는것은 매우 지루한 일이다.

    대부분의 운영체제는 file redirection 을 지원한다.

    이 기능은 명명된 파일을 표준 입,출력과 연결하게 해준다.

    $ addItems <infile >outfile

     

    $가 시스템 프롬프트이고 우리의 프로그램이 addItems.exe (또는 UNIX 시스템의 경우 addItems)라는 실행 파일로 compile되었다고 가정하면 이 명령은 infile이라는 파일에서 transaction을 읽고 출력을 outfile이라는 파일로 현재 디렉토리에 기록한다.


    1.5.2 A First Look at Member Functions

    2개의 Sales_item 을 더하는 우리의 프로그램은 이 객체들이 같은 ISBN 을 가지고있는지 체크해야한다.

    아래와 같이 할수있다.

    #include <iostream>
    #include "Sales_item.h"
    
    int main() {
    
        Sales_item item1, item2;
        std::cin >> item1 >> item2;
    
        // first check that item1 and item2 represent the same book.
        if (item1.isbn() == item2.isbn()) {
    
            std::cout << item1 + item2 << std::endl;
    
            return 0; // indicate success
    
        } else {
    
            std::cerr << "Data must refer to same ISBN" << std::endl;
    
            return -1; // indicate failure
    
        }
    
    
    }

    이전 버전과 이 프로그램의 다른점은 ifelse 이다.

    if 의 condition 을 이해하지못한다고 하더라도, 우리는 이 프로그램이 무엇을 하는지 알수있다.

    condition 이 성공하면 이전과 동일한 출력을 작성하고 성공을 나타내는 0return 한다.

    condition 이 실패하면 else 다음에 block을 실행하여 메시지를 print하고 error indicator를 return 한다.

     

    What Is a Member Function?

     

    if 의 condition 을 보자.

    item1.isbn() == item2.isbn()

    위의 코드에서 isbn 을 member 함수라고 한다.

    member 함수는 class 의 일부로 정의되는 함수이다.

    member 함수는 method 라고도 불린다.

    일반적으론ㄴ 우리는 객체를 대신하여 member 함수를 호출한다.

    item1.isbn

    위의 코드에서 dot 연산자 . 을 사용하는것은 item1 이라는 이름의 객체에 isbn 이라는 member 를 원한다고 표현하는것이다.

    . 연산자는 class type 의 객체만 적용할수있다.

    왼쪽 피연산자는 반드시 class type 의 객체여야하며,

    오른쪽 피연산자는 반드시 type 의 member 이름이여야한다.

    . 연산자의 결과는 오른쪽 피연산자의 이름으로된 member 이다.

    우리가 member 함수를 접근하기위해 . 연산자를 사용하는것은 보통 이 함수를 호출하기위함이다.

    함수의 호출은 call 연산자 () 를 사용하여 호출한다.

    () 연산자는 list of arugments (비어있을수있음) 을 감싸는 괄호쌍이다.

    isbn member 함수는 argument 를 받지않기때문에 

    item1.isbn()

    위의 코드는 item1 이라는 객체의 member 인 isbn 함수를 호출하는것이다.

    이 함수는 item1 에 저장되는 ISBN 을 return 한다.

    = 연산자 오른쪽에 있는 item2 또한 같은 방식으로 ISBN 을 return 한다.

    이 2개의 ISBN 이 같다면, condition 은 true 가 되고 그렇지않으면 false 다.


    1.6 The Bookstore Program

    우리는 이제 우리의 bookstore 문제를 해결할 준비가 되었다.

    우리는 판매 transaction 파일을 읽고 각 책의 판매 된 총 부수, 총 수익 및 평균 판매 가격을 보여주는 report를 생성해야한다.

    여기서 각 ISBN의 모든 거래가 입력에서 함께 그룹화되었다고 가정하겠다.

    우리의 프로그램은 각 ISBN의 데이터를 total이라는 변수에 combine 할것이다.

    우리는 trans라는 두 번째 변수를 사용하여 읽은 각 transaction 을 보관할것이다.

    만약 trans total 이 동일한 ISBN 을 나타낸다면, total 을 업데이트하고,

    그렇지않으면 total 을 print 하고 우리가 방금 읽은 transaction 을 reset 할것이다.

    #include <iostream>
    #include "Sales_item.h"
    
    int main() {
    
        Sales_item total; // variable to hold data for the next transaction
    
        // read the first transaction and ensure that there are data to process
        if (std::cin >> total) {
    
            Sales_item trans; // variable to hold the running sum
    
            // read and process the remaining transactions
            while (std::cin >> trans) {
    
                // if we're still processing the same book.
                if (total.isbn() == trans.isbn()) {
    
                    total += trans; // update the running total
    
                }
    
                else {
    
                    // print results for the previous book
                    std::cout << total << std::endl;
                    total = trans; // total now refers to the next book.
    
                }
    
            }
    
            std::cout << total << std::endl; // print the last transaction
    
        } else {
    
            // no input! warn the user
            std::cerr << "No data?!" << std::endl;
    
            return -1; // indicate failure
    
        }
    
        return 0;
    
    }

    이 프로그램은 지금까지 우리가 보아왔던 것들중 가장 복잡하다.

    하지만 모두 우리가 보았던것들을 사용하고있다.

    표준 library 의 iostream Sales_item.hinclude 함으로써 시작한다.

    main 안에는 ISBN 의 data 를 sum 하기위한 total 이라는 객체를 정의한다.

    첫번째 transaction 을 total 로 읽어들이고, read 가 성공했는지 테스트한다.

    read 가 실패했다면 else 로 이동하여, 사용자에게 input 이 없다고 말한다.

    기록을 성공적으로 읽었다고 가정하면, if 안의 block 을 실행한다.

    이 block 은 우리가 읽는 transaction 들을 보관할 transe 라는 객체를 정의함으로 시작된다.

    read 가 계속 성공하는한, while 의 body 는 계속 실행된다.

    while 의 body 는 단일 if 문이다. 

    if 문은 2개의 ISBN 이 동일한지를 체크한다.

    서로 동일하다면 += 연산자에 의해 trans total 에 더한다.

    동일하지않다면 total 안에 저장된 값을 print 하고 total trans 를 대입함으로써 reset 한다.

    if 문을 실행한후에 while 의 condition 으로 돌아가 다음 transaction 을 읽고,

    이 과정이 더 이상 읽을 기록이 없을때까지 반복된다.

    while 이 끝나면 total 은 마지막 ISBN 을 포함하고있다. 

    가장 바깥 쪽의 if 문을 끝내는 block의 마지막 statement에서 마지막 ISBN에 대한 데이터를 write 한다.


    Chapter Summary

    이 챕터에서는 단순한 C++ 프로그램을 만들고, compile 하고, 실행하는것에 대하여 소개하였다.

    운영체제가 우리의 프로그램을 실행하는 함수인 main 을 어떻게 정의하는지 배웠고,

    어떻게 변수를 정의하는지, 어떻게 입력과 출력을 하는지, 어떻게 if, for, while 문을 작성하는지를 배웠다.

    또한 C ++에서 가장 기본적인 기능인 class를 소개하고,

    어떻게 다른 사람이 정의한 class 의 객체를 만들고 사용하는지 배웠다.

    이후의 챕터들에서는 어떻게 우리의 class 를 직접 정의하는지에대해 배울것이다.


    Defined Terms

    - 책에는 각 용어 설명이 담겨있는데, 너무 길어서 생략. 자세한 설명은 책 54p 참조

     

    argument 

    assignment

    block

    buffer

    built-in type

    cerr

    character string literal

    cin

    class

    class type

    clog

    comments

    condition

    cout 

    curly brace

    data structure

    edit-compile-debug

    end-of-file

    expression

    for statement 

    function

    function body

    function name

    header

    if statement

    initialize

    iostream

    istream

    library type

    main

    manipulator

    member function

    method

    namespace

    ostream

    parameter list

    return type

    source file

    standard error

    standard input

    standard library

    standard output

    statement

    std

    string literal

    uninitialized variable

    variable

    while statement

    () operator

    ++ operator

    += operator

    . operator

    :: operator

    = operator

    -- operator

    << operator

    >> operator

    #include

    == operator

    != operator

    <= operator

    < operator

    >= operator

    > operator