Eat Study Love

먹고 공부하고 사랑하라

SW 만학도/C++

1. C++ Standard Library (1)

eatplaylove 2024. 3. 21. 22:23

 

아 ~ 이게 무슨 영어, 중국어 배우는 것도 아니고

 

코딩하나 하는데도 프로그래밍 언어가 너무 많다;;

 

이거 누가 통일 좀 안 시키나ㅠㅠ

 

그래도 써먹을데가 분명히 있다고 하니까 이놈의 C++ 공부도 한 번 시작해본다.

 

C에비해 C++이 나은 점

 

 

C++의 장점은 위와 같다고 한다. 정확히 이게 어떤 걸 의미하는 지는 차차 알아가 봐야 할 부분

 

모든 프로그래밍 언어를 배울 때 처럼 Hello C++ 부터 공부해보자ㅠㅠ

 

First C++ Program

#include <iostream>

int main(void)
{
    std::cout << "Hello C++!!" << std::endl;
    // Hello C++!!
    return 0;
}

 

 

 

- C++ printf를 위한 Compile 과정에선 C와는 다른 차이점이 있다.

 

 

 

1) Compile : gcc hello.c -o hello ----> g++ helloC++.cpp -o helloC++ -std=c++11

(g++ : Invoke the GNU C++ compiler, -o : Output file name, -std=c++11 : Use C+11 Standard)

 

2) Header file : stdio.h --> iostream ( C++ Header file 종류 장난 없다.. 엄청 많고 다 암기 必 )

 

3) Print function : printf; --> std::cout

 

4) New line : ' \n ' --> std::endl

 

#include <iostream>

int main(void)
{
    int num;
    std::cin >> num ;               // input
    std::cout << num << std::endl;  // output
    // 입력한 int 를 output으로 출력

    return 0;
}

 

- Input을 받아서 Output으로 출력해주는 코드

 

Namespaces

 

- cin 과 cout은 predefined 며 globally accessible한 Variable이다.

 

- 그리고 각 각 istream , ostream class의 object들이다.

 

- cin / cout을 사용할 땐 반드시 namespace인 std를 std::cin 과 같이 prefix하여 사용해줘야 한다.

 

- Namespace를 써야 같은 이름의 object와 구분지어 naming conflict를 막을 수 있다.

(C++에선 global scope에 있던 identifier(function name,type name, variable name)들을 namespace를 통해 name scope로 바꿔주어 name conflict를 막아준다.)

 

- 즉, object이름이 같아도 출신 namespace가 다르면 다른 놈 취급한다는 뜻!( std::cin ≠ myNS::cin )

- C++ Standard Library에는 common I/O operations와 각종 Data structure, algorithm(such as cin, cout) 같은 것들이 std namespace 안에 encapsulated 되어 있다.

 

- namespace를 특정짓기 위해선 scope resolution operator ' :: ' 를 사용한다.

 

#include <iostream>

namespace myspace
{
    int a, b;

    void setValue(int newA, int newB)
    {
        a = newA;
        b = newB;
    }
}

int main(void)
{   
    myspace::a = 1;
    myspace::b = 2;

    std::cout << myspace::a << std::endl;
    std::cout << myspace::b << std::endl;
    /*
    1
    2
    */
    
    myspace::setValue(3,4);
    std::cout << myspace::a << std::endl;
    std::cout << myspace::b << std::endl;
    /*
    3
    4
    */
    return 0;
}

 

- namespace 안 함수를 main에서 실행시켜도 a,b variable 값이 그에 따라 바뀌넹..

 

- 하나의 Namespace 안에서 선언된 Variable a, b는 그 안에선 그냥 쓰일 수 있지만 그곳을 벗어나면 :: operator를 써서 scope resolution을 해야 한다.

 

namespace myspace
{
    int a, b;
}
namespace myspace
{
    void setValue(int newA, int newB)
    {
        a = newA;
        b = newB;
    }
}

 

 

- 같은 namespace에 대한 코드도 Region을 나눠서 적을 수 있다.

 

Namespace - using

 

- Using은 namespace에 direct access를 제공해준다.

 

- Using은 namespace 전체에 대해서도 사용할 수 있다. 근데 이게 편하긴 하지만 naming conflict 유발 가능성은 up

 

#include "iostream"

namespace myname1
{
    int x = 1;
}

namespace myname2
{
    double x = 2.3456;
}

int main(void){
    using myname1::x;
    std::cout << x << std::endl; //namespace 생략
    std::cout << myname2::x << std::endl;
    /*
    1
    2.3456
    */
    return 0;
}

 

#include "iostream"

namespace myname1
{
    int x = 1;
}

namespace myname2
{
    double x = 2.3456;
}

int main(void){
    using namespace std;
    cout << myname1::x << endl;
    cout << myname2::x << endl;
    /*
    1
    2.3456
    */
    return 0;
}

 

 

- Using은 Global 하게 선언 하던, main함수 안에 선언하던 동일하게 동작하는듯 하다.

 

using namespace std;
using namespace myname1;

int main(void){
    using namespace myname2;
    cout << x << endl;
    cout << y << endl;
    /*
    1
    2.3456
    */
    return 0;
}

 

Namespaces - Aliasing

 

- 이미 존재하는 Namespace에 alias를 만들 수 있다.

 

#include "iostream"

namespace myname1
{
    int x = 1;
}

namespace myname2
{
    double x = 2.3456;
}

int main(void){
    namespace myname3 = myname1;

    std::cout << myname3::x << std::endl;

    /*
    1
    */
    return 0;
}

 

 

- 모든 C++ Standard Library의 Entities(Variables, types, constants, and functions)들은 std namespace안에 선언되어 있다.

 

- 그래서 using namespace std; <-- naming conflict 유발 확률 높! library를 여러 개 참조하는 경우에 특히 주의

 

 

Namespaces ≠ Header Files

 

- Std namepsace가 iostream, string, algorithm 등 다양한 header에 span해 있는 것처럼 Namespace와 Header file은 연관이 많다.

 

- Header file은 여러 개의 Namespace 정의를 포함하고 있을 수 있다.

 

 

Standard I / O Streams

 

#include <iostream>
using namespace std;

int main(void)
{
    int num;
    cout << "Enter a number: " << endl;
    cin >> num;
    cout << "You've entered: " << num << endl;
    /*
    Enter a number: 
    19
    You've entered: 19
    */


    return 0;
}

 

 

- cin 과 cout과 같은 I / O Stream은 in/output operation을 담당하고 C++ Standard Library의 일부이다.

 

cin

 

 

#include <iostream>
using namespace std;

int main(void)
{
    int age;
    double salary;
    char grade;

    cout << "age, salary, grade type gogo: " <<endl;

    cin >> age;
    cin >> salary;
    cin >> grade;

    cout << "age: " << age << endl;
    cout << "salary: " << salary << endl;
    cout << "grade: " << grade << endl;
    /*
    age, salary, grade type gogo: 
    29
    6000
    A+
    age: 29
    salary: 6000
    grade : A
*/
    return 0;
}

 

 

- 위 코드에서 20 300 6을 다양하게 입력해보면 아래와 같이 나온다.

 

age, salary, grade type gogo: 
20 300 6
age: 20
salary: 300
grade: 6

age, salary, grade type gogo: 
20\n300\n6
age: 20
salary: 0
grade:

age, salary, grade type gogo: 
20abc 300 6
age: 20
salary: 0
grade:

 

- >> operator는 적절한 type으로 input stream을 variable에 assign 해준다.

( "scanf("%d",&age)와 같은 conversion 필요없다. 요건 편하네!)

 

- cin은 기대되는 variable type을 참고하여 예상값을 최대한 많이 읽는데, white space가 뜨면 멈춘다.

 

 1) Char : One character을 읽는다.

 

 2) int : non-numeric charcter가 뜰 때까지 읽는다.

 

 3) string : White Space가 뜰 때까지 읽는다.

 

- 초과 된 charcter 들은 buffer에 남아 있고, 추가되는 input operations에 의해 읽힐 수 있다.

 

- cin은 chain multiple input operation이 가능하다.

 

#include <iostream>

int main(void)
{
    int age;
    int salary;
    int grade;

    std::cin >>age>>salary>>grade;
    std::cout <<"age: " <<age<<std::endl;
    std::cout <<"salary: " <<salary<<std::endl;
    std::cout <<"grade: " <<grade<<std::endl;

    return 0;
}
--------------
//cout도 된다
int main(void)
{
    int age;
    int salary;
    int grade;

    std::cin >>age>>salary>>grade;
    // std::cout <<"age: " <<age<<std::endl;
    // std::cout <<"salary: " <<salary<<std::endl;
    // std::cout <<"grade: " <<grade<<std::endl;
    std::cout << age<< std::endl<< salary<< std::endl<<grade<< std::endl;
    return 0;
}

 

 

- cin : object , >> : method

 

cin chain rule이 가능한 이유

 

Cin - Error Handling

 

- cin에 적절한 값이 들어왔는지 체크하는 것도 중요하다.

 

- cin.clear() : error state를 clear 해준다.

- cin.ignore() : input buffer에 있는 charcters 들을 skip 해준다.

 

#include <iostream>
#include <limits>

using namespace std;
int main(void)
{
    int num;
    cout << "num : ";
    if(!(cin >> num)){
        cout << "not a num!" <<endl;
        cin.clear(); // clear the error state
        cin.ignore(numeric_limits<streamsize>::max(),'\n'); // 보통 그냥 cin.ignore(32767,'\n')을 한다.. limits include하기 구찮
        //ignore up to 32767 characters until a \n is removed
    }

}

 

Cin - Reading a Line

 

- getline function은 cin에서 전체 라인을 읽어 string으로 변환한다.

- 문자를 읽을땐 cin >> 보다 getline이 낫다. 공백을 포함한 모든 input을 정확히 전달하기 위해서!

 

#include <iostream>
#include <string>

int main(void){
    std::string mystr;
    std::getline(std::cin,mystr);
    std::cout << "string : " << mystr << std::endl;
    return 0;
}
--------------------
/*$ ./cinout
ABC BOY 야야
string : ABC BOY 야야*/

 

 

cout

 

 

- cin의 반대 개념이다.

 

- 마찬가지로 type conversion 필요 없이 적절한 타입의 output data를 변환해준다.

 

#include <iostream>
int main(void)
{   using namespace std;
    int a = 5;
    cout << a << endl; //5
    cout << &a << endl; //0x61fe1c
    cout << "HI" << endl; //HI
    return 0;
}

 

- endl 은 크게 2가지 역할이 있다.

 

 1) new line '\n'을 추가해준다.

 2) Output buffer에 있는 것들을 flush 해준다. 즉, output buffer에 있던 data들이 즉시 유저에게 보이도록 해준다.

 

- Flush? : flush manipulator는 '\n' 없이 flush 해준다. ex) " cout << text << flush; "

- endl 을 사용하지 않는다면, output buffer는 특정 조건에서만 flush가 된다.

 

 1) buffer가 꽉 찼다.

 

 2) cin이 user input을 읽었다.

 

 3) Program이 정상적으로 종료되었다.

 

 

cout - Formatting Output

 

#include <iostream>
using namespace std;
int main(void)
{   double pi = 3.141592651231252;
    cout << "pi with 2 decimal: "<<pi<<endl;
    //pi with 2 decimal: 3.14159
    return 0;
}

 

 

- 숫자를 몇 digit 출력할 것인지 정할 수 있다 by setprecision ( include <iomanip> )

 

#include <iostream>
#include <iomanip>
using namespace std;
int main(void)
{   double pi = 3.141592651231252;
    cout << "pi with 2 decimal: "<<setprecision(2)<<pi<<endl;
    cout << "pi with 2 decimal: "<<setprecision(3)<<pi<<endl;
    cout << "pi with 2 decimal: "<<setprecision(4)<<pi<<endl;

// pi with 2 decimal: 3.1
// pi with 2 decimal: 3.14
// pi with 2 decimal: 3.142

    return 0;
}

 

 

- setprecision과 함께 floating digit을 컨트롤하고 싶다? --> fixed

 

#include <iostream>
#include <iomanip>
using namespace std;
int main(void)
{   double pi = 3.156392651231252;

    cout<<"pi: "<<setprecision(2)<<fixed<<pi<<endl;
    cout<<"pi: "<<setprecision(3)<<fixed<<pi<<endl;
    cout<<"pi: "<<setprecision(4)<<fixed<<pi<<endl;
    // pi: 3.16
    // pi: 3.156
    // pi: 3.1564 //소숫점 아래는 자동 반올림처리네
    return 0;
}

 

 

- setprecision 과 fixed로 숫자 notation도 조정할 수 있다.

 

#include <iostream>
#include <iomanip>
using namespace std;
int main(void)
{   double pi = 12345678.91011123123;

    cout<<"pi: "<<setprecision(2)<<pi<<endl;
    //scientific notation
    cout<<"pi: "<<setprecision(2)<<fixed<<pi<<endl;
    //fixsed-point notation
    return 0;
// pi: 1.2e+07
// pi: 12345678.91

}

 

 

- Leading Zeros : setfill과 setw를 이용해 숫자의 길이조절 및 여백을 채워 넣을 문자or 숫자를 선정할 수 있다.

 

#include <iostream>
#include <iomanip> //formatting을 위해 필요
using namespace std;
int main(void)
{
    int num = 5;
    cout << setfill('A') << setw(4) << num <<endl;
    //AAA5
    cout << setfill('2') << setw(4) << num <<endl;
    //2225
}

 

 

- 기타 도움이 될만한 Method는 아래와 같다.. 와나 외울 게 왜이리 많아 ㅠㅠ

 

 

암기 또 암기..!

 

 

요즈음은 CHAT GPT , COPILOT이 다 코딩해주는 시대라던데

코딩영역에 이렇게 암기할 게 많아서야..ㅠㅠ

 

효율을 추구하는 공학도인데 학습분야가 넘 비효율적이다!!

 

 

 

 

 

'SW 만학도 > C++' 카테고리의 다른 글

6. Out_of_class Definition & Operator Overloading  (0) 2024.04.10
5. Classes  (0) 2024.04.09
4. Functions and Memory Management  (1) 2024.03.29
3. C++ Standard Library (3)  (1) 2024.03.24
2. C++ Standard Library (2)  (1) 2024.03.22