아 ~ 이게 무슨 영어, 중국어 배우는 것도 아니고
코딩하나 하는데도 프로그래밍 언어가 너무 많다;;
이거 누가 통일 좀 안 시키나ㅠㅠ
그래도 써먹을데가 분명히 있다고 하니까 이놈의 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 - 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 |