공부/C++

1. C++ 프로그래밍의 기본

bokob 2024. 3. 26. 00:29

1.1 C++ 기본 요소와 화면 출력

소스 파일의 확장자 cpp

소스 파일의 확장자

  • C 프로그램의 소스 파일: *.c
  • C++ 프로그램의 소스 파일: *.cpp

 

main 함수

main() 함수

  • C++  프로그램의 실행을 시작하는 함수
    • main() 함수가 종료하면 C++ 프로그램 종료
  • main() 함수의 c++ 표준 모양
int main(){ // main의 리턴 타입 int
    // ....
    return 0; // 0이 아닌 다른 값으로 리턴 가능
}
// C 애서는 된다
void main(){ // 표준 아님
    // ...
}

 

  • main()에서 return문 생략 가능
int main(){
    // ...
    // return 0; // 개발자의 편리를 위해 return 문 생략 가능
    // main의 return문은 운영체제가 받아서 처리한다
}

 

#include <iostream>

#include <iostream>

전처리기(C++ Preprocessor)에게 내리는 지시

  • <iostream> 헤더 파일을 컴파일 전에 소스에 확장하도록 지시

 

<iostream> 헤더 파일

표준 입출력을 위한 클래스와 객체, 변수 등이 선언됨

  • iostream 클래스 선언
    • iostream: 문자 단위로 입출력을 동시에 할 수 있는 스트림 클래스
  • cout, cin, <<, >> 등 연산자 선언
#include <iostream>

int main(){
    int width;
    std::cout<<"Hello\n";
    std::cin>>width;
}

 

  • <iostream.h> 헤더파일
    • 구버전의 C++ 표준에서 사용하던 헤더파일
    • 구버전 컴파일러에서 사용

 

stream

스트림(stream)

데이터의 흐름, 혹은 데이터를 전송하는 소프트웨어 모듈

  • 흐르는 시내와 유사한 개념

스트림의 양 끝에는 프로그램과 장치 연결

  • 보낸 순서대로 데이터 전달
  • 입출력 기본 단위: 바이트

 

C++의 스트림 종류

입력 스트림

  • 입력 장치, 네트워크, 파일로부터 데이터를 프로그램으로 전달하는 스트림

출력 스트림

  • 프로그램에서 출력되는 데이터를 출력 장치, 네트워크, 파일로 전달하는 스트림

 

C++ 입출력 스트림 버퍼

C++ 입출력 스트림은 버퍼를 가짐

키 입력 스트림 버퍼

목적

  • 입력 장치로부터 입력도니 데이터를 프로그램으로 전달하기 전에 일시 저장
  • 키 입력 도중 수정 가능
    • <backspace> 키가 입력되면 이전에 입력된 키를 버퍼에서 지움

프로그램은 사용자의 키 입력이 끝난 시점에서 읽음

  • <Enter> 키: 키 입력의 끝을 의미
  • <Enter> 키가 입력된 시점부터 키 입력 버퍼에서 프로그램이 읽기 시작

 

스크린 출력 스트림 버퍼

목적

  • 프로그램에서 출력된 데이터를 출력 장치로 보내기 전에 일시 저장
  • 출력 장치를 반복적으로 사용하는 비표율성 개선

버퍼가 꽉 차거나 강제 출력 명령 시에 출력 장치에 출력

 

키 입력 스트림과 버퍼의 역할

 

스크린 출력 스트림과 버퍼의 역할

 

 

C++ 표준은 스트림 입출력만 지원

2가지 형태의 입출력 방식

스트림 입출력 방식(stream I/O)

  • 스트림 버퍼를 이용한 입출력 방식
  • 입력된 키는 버퍼에 저장
    • <Enter> 키가 입력되면 프로그램이 버퍼에서 읽어가는 방식
  • 출력되는 데이터는 일차적으로 스트림 버퍼에 저장
    • 버퍼가 꽉 차거나 '\n'을 만나거나, 강제 출력 명령의 경우에만 버퍼가 출력 장치에 출력

저수준 입출력 방식(raw level console I/O)

  • 키가 입력되는 즉시 프로그램에 키 값 전달
    • -<backspace> 키 자체도 프로그램에 바로 전달
    • - 게임 등 키 입력이 즉각적으로 필요한 곳에 사용
  • 프로그램이 출력하는 즉시 출력 장치에 출력
  • 컴파일러마다 다른 라이브러리나 API 지원: C++ 프로그램의 호환성 낮음

 

C++ 표준은 스트림 방식만 지원

  • 스트림 입출력은 모든 표준 C++ 컴파일러에 의해 컴파일 됨 -> 높은 호환성

 

출력 객체인 cout을 이용한 화면 출력

C++에서의 출력: 출력 객체인 cout 이용

"cout<<값" 형식으로 출력

  • << 연산자 다음에 기본형의 변수를 지정하면 자동으로 데이터 형에 맞추어 출력
  • 정수, 실수, 문자열 출력 가능 <- 기본형에 대해 연산자 오버로딩 되어있음
std::cout<<"Hello\n";

 

cout 객체

스크린 출력 장치에 연결된 표준 C++ 출력 스트림 객체

<iostream> 헤더 파일에 선언. std 이름 공간에 선언:std::cout으로 사용

 

<< 연산자

스트림 삽입 연산자(stream insertion operator)

  • C++ 기본 산술 시프트 연산자(<<)가 스트림 삽입 연산자로 재정의 됨
  • ostream 클래스에 구현됨. 오른쪽 피연산자를 왼쪽 스트림 객체에 삽입
  • cout 객체에 연결된 화면에 출력

여러 개의 << 연산자로 여러 값 출력

std::cout<<"Hello"<<"World!";

 

문자열 및 기본 타입의 데이터 출력

bool, char, short, int, long, float, double 타입 값 출력

int n = 3;
char c = '#''
std::cout<<c<<5.5<<'-'<<n<<"hello"<<true;

 

연산식뿐 아니라 함수 호출도 가능

std::cout<<"n + 5 ="<<n+5;
std::cout<<f(); // 함수 f()의 리턴값을 출력

 

출력 형식 조정

std::cout<<123;                  // 123 출력
std::cout.width(10);             // 출력할 내용의 폭 지정
                                 // 10칸 확보, 오른쪽 정렬, 남는 공간은 빈 공백
std::cout<<123;                  // _______123 출력 : 앞쪽에 빈칸 7개 출력

std::cout.setf(ios::base::left); // 왼쪽 정렬
std::cout<<123                   // 123_______ 출력 : 뒤쪽에 빈칸 7개 출력

 

다음 줄로 넘어가기

'\n'

  • << 연산자가 '\n' 문자를 cout의 스트림 버퍼에 단순히 삽입

endl 조작자

  • <iostream> 헤더파일에 있는 함수. << 연산자가 호출
  • '\n'을 cout의 스트림 버퍼에 넣고, cout에게 현재 스트림 버퍼에 있는 데이터를 즉각 장치에 출력하도록 지시 (버퍼를 비움)
std::cout<<"Hello"<<'\n';      // 더 빠르다.
std::cout<<"Hello"<<std::endl; // 버퍼를 비우기 때문에 더 느리다.

 

1.2  namespace

namespace 개념

이름(identifier) 충돌이 발생하는 경우

  • 여러 명이 서로 나누어 프로젝트를 개발하는 경우
  • 오픈소스 혹은 다른 사람이 작성한 소스나 목적 파일을 가져와서 컴파일 하거나 링크하는 경우
  • 해결하는데 많은 시간과 노력이 필요

 

namespace 키워드

이름 충돌 해결

  • 2003년 새로운 ANSI C++ 표준에서 도입

개발자가 자신만의 이름 공간을 생성할 수 있도록 함

  • 이름 공간 안에 선언된 이름은 다른 이름 공간과 별도 구분
namespace KIM
{
    int add(int a, int b)
    {
        return a+b;
    }
    // KIM 이라는 이름 공간
    // 이 곳에 선언된 모든 이름은 KIM 이름 공간에 생성된 이름
}

// 다른 곳에 KIM이라는 namespace 만들어도 같은 공간으로 인식한다.
namespace KIM
{
    int minus(int a, int b)
    {
        return a-b;
    }
}

이름 공간 사용

  • 이름 공간::이름

 

namespace 사용

 

번외) GCC 컴파일러에서 분할한 소스코드를 컴파일 할 때

1. 분할한 소스 코드를 오브젝트 파일로 컴파일

g++ -c (.cpp 이름) -o (.o 이름)

2. main()이 있는 소스코드 컴파일

g++ (main()이 있는 .cpp 이름) (분할소스코드.o) -o (컴파일 후 만들어질 실행파일)

 

3. 실행 파일명 입력

 

std:: 란?

std

ANSI C++ 표준에서 정의한 이름 공간(namespace) 중 하나

  • <iostream> 헤더 파일에 선언된 모든 이름: std 이름 공간 안에 있음
  • cout, cin, endl 등

std 이름 공간에 선언된 이름을 접근하기 위해 std::접두어 사용

  • std::cout, std::cin, std::endl

 

std:: 생략

using 지시어 사용

using std::cout; // cout에 대해서만 std::생략
...
cout<<"Hello"<<std::endl;

 

using namespace std; // std 이름 공간에 선언된 모든 이름에 std:: 생략
...
cout<<"Hello"<<endl; // std::생략

 

1.3 입출력

cin을 이용한 키 입력

C++에서의 입력 - 입력 객체인 cin 이용

"cin>>변수" 형식으로 입력

  • >> 연산자 다음에 기본형의 변수를 지정하면 자동으로 다양한 데이터 형에 맞추어 입력 처리
    • - 입력받을 값의 형식 지정할 필요 없음 -> 변수의 데이터 형에 따라 입력
cout<<"너비와 높이 입력>>";
cin>>width>>height;
cout<<width<<'\n'<<height<<'\n';

width에 23, height에 36 입력

>> 연산자

스트림 추출 연산자(stream extraction operator)

  • C++ 산술 시프트 연산자(>>)가 <iostream> 헤더 파일에 스트림 추출 연산자로 재정의 됨
  • 입력 스트림에서 값을 읽어 변수에 저장

연속된 >> 연산자를 사용하여 여러 값 입력

  • 단, 문자열을 입력할 때는 빈칸 없이 입력해야 한다.
    • >> 연산자는 빈칸이 입력될 때까지를 하나의 입력으로 처리하므로 빈칸을 포함한 문자열을 입력받으려면 별도의 방법을 사용해야한다.

 

<Enter> 키를 칠 때 변수에 값 전달

cin의 특징

입력 버퍼를 내장하고 있음

<Enter> 키가 입력될 때까지 입력된 키를 입력 버퍼에 저장

도중에 <Backspace> 키를 입력하면 입력된 키 삭제

 

>> 연산자

<Enter> 키가 입력되면 비로소 cin의 입력 버퍼에서 키 값을 읽어 변수에 전달

 

cin으로부터의 키 입력 오류

입력 오류가 발생하면?

입력받을 데이터보다 더 큰 데이터나, 자료형이 다른 데이터를 입력받을 경우

  • 입력버퍼에 쓸데없는 데이터가 남게 됨. ex) int형의 변수 a에 문자 'A'를 입력하면 문자 'A'가 버퍼에 남음

 

해결책

cin 객체 내부상태 초기화(입력오류 flag 초기화), 입력 버퍼 초기화

 

cin.fail()

  • cin 오류시 1을 반환하고 아니면 0을 반환

 

cin.clear()

  • cin 객체의 내부 상태 flag를 초기화시켜 cin 관련 기능이 정상 작동하도록 함.
  • 오류 사실 제거

 

cin.ignore(최대확인글자수, '문자'): 입력 버퍼 지우기

  • 최대 수만큼 버퍼에 있는 문자를 지우고, 혹시 '문자'가 나타나면 '문자'까지 지우고 스톱
cin>>val;

if(cin.fail()==1){ // I/O 오류가 발생하면
    cin.clear(); // 모든 오류비트 clear
    cin.ignore(256, '\n'); // 최대 256개의 문자 무시가능, 개행문자를 만나면 추출을 멈춤
}

 

C++ 문자열

C++의 문자열 표현 방식: 2가지

C-스트링 방식: '\0'로 끝나는 문자 배열

  • 문자열의 저장: 배열 또는 동적으로 메모리 할당
char ptr[10] = "ab" // 마지막에 자동으로 null 들어감
char* ptr = "ab";   // 메모리에 상수처럼 박힌거라 못바꾼다

// C-스트링 문자열
char name1[6] = {'G', 'r', 'a', 'c', 'e', '\0'}; // name1은 문자열 "Grace"
// 단순 문자 배열
char name2[5] = {'G', 'r', 'a', 'c', 'e'};       // name2는 문자열이 아니고 단순 문자 배열

 

string 클래스 이용

  • <string> 헤더 파일에 선언됨
  • 다양한 멤버 함수 제공, 문자열 비교, 복사, 수정 등

 

C 언어에서 사용한 문자열 라이브러리

C-스트링으로 문자열 다루기

C언어에서 사용한 함수 사용 가능

  • strcmp(), strlen(), strcpy() 등

<cstring>이나 <string.h> 헤더 파일 include

<cstring> 헤더 파일을 사용하는 것이 바람직함

  • <cstring>이 C++ 표준 방식

 

cin을 이용한 문자열 입력

문자열 입력

#include <iostream>
using namespace std;

int main()
{

    char name[6]; // 5개의 문자를 저장할 수 있는  char 배열
    cin>>name;
    cout<<name;
}

// 좌:입력, 우: 출력
// 마이클 -> 마이클
// 마 이 클 -> 마

 

cin.getline()을 이용한 문자열 입력

공백이 낀 문자열을 입력 받는 방법

cin.getline(char buf[], int size, char delimitChar)

  • buf에 최대 size-1개의 문자 입력. 끝에 '\0' 붙임
  • delimitChar를 만나면 입력 중단. 끝에 '\0' 붙임
    • delimitChar의 디폴트 값은 '\n'(<Enter> 키)
// 최대 99개의 문자를 읽어 address 배열에 저장
// 도중에 <Enter> 키를 만나면 입력 중단
char address[100];
cin.getline(address, 100, '\n');

 

getline() 함수: 한 줄(개행문자까지 모두) 단위로 읽어 들임

  • 기본적으로 한 줄을 읽어 들임. 여기서 한 줄의 구분은 enter키(개행문자, 새줄문자, \n)까지를 한 줄로 인식함
  • 입력된 문자열은 마지막에 있는 개행문자(엔터키, \n)는 저장이 되지 않음. 대신 이 자리에 '\0'라고 하는 NULL 문자가 저장되어 문자열이 완성됨.

 

 

s2는 i 만나면 입력 중단

 

C++에서 문자열을 다루는 string 클래스

string 클래스

  • C++에서 강력 추천
  • C++ 표준 클래스
  • 문자열의 크기에 따른 제약 없음
    • string 클래스가 스스로 문자열 크기에 맞게 내부 버퍼 조절
  • 문자열 복사, 비교, 수정 등을 위한 다양한 함수와 연산자 제공
  • 객체 지향적
  • <string> 헤더 파일에 선언
  • #include <string> 필요
  • C-스트링보다 다루기 쉬움

 

getline() 함수 사용법

getline() 함수를 C++ 스타일의 문자열과 함께 사용하는 방법

 

getline() 함수를 C 스타일의 문자열과 함께 사용하는 방법

 

#include <iostream>와 전처리

 

<iostream> 헤더 파일은 어디에?

<iostream> 파일은 텍스트 파일

컴파일러가 설치된 폴더 아래 include 폴더에 존재

 

#include <헤더파일> 와 #include "헤더파일"

#include <헤더파일>

  • '헤더파일'을 찾는 위치: 컴파일러가 설치된 폴더
  • #include <iostream>
    • <iostream> 헤더 파일은 컴파일러가 제공

 

#include "헤더파일"

  • '헤더파일'을 찾는 위치: 현재 디렉토리
  • 직접 만든 헤더를 사용할 때

 

'공부 > C++' 카테고리의 다른 글

4. 클래스와 객체의 기본  (0) 2024.04.09
3. 개선된 함수 기능  (0) 2024.03.31
2. 포인터와 레퍼런스  (1) 2024.03.30
0. C++ 시작  (0) 2024.03.24
C++ 공부  (0) 2024.03.14