시작하면서
본 강좌는 C language를 어느 정도 아는 사람을 위한 C++ 기초 강좌입니다. 따라서 C를 전혀 모르는 분은 C기초부터 공부한 다음 이 강좌를 보시면 되겠습니다.
OOP(Object-Oriented Programming)란
우리가 살고있는 세상은 거의 모든 사물이 객체(Object)로 이루어져 있다.
사람, 나무, 자동차 등등이 객체가 된다. 예를 들어 자동차는 엔진, 차체, 타이어 등으로 이루어져있고, 또 엔진은 자동차를 움직이게 한다.
이처럼 실세계를 아주 가깝게 반영하는 프로그래밍이 OOP이다.
객체지향 프로그래밍은 프로그래머들이 절차형 방식보다 빠르게 목적(응용 프로그램을 완성하고 디버깅하는 것)을 달성할 수 있도록 해주는 좋은 프로그래밍 수단이다.
객체지향 프로그래밍은 변수를 다루기 위해 그 주변에서 기다리기보다는 껍질속의 데이터를 동작시키며, 프로그램의 변수들은 그것을 어떻게 처리할지를 알고 있는 것이다. 변수의 내용을 출력할 때가 되면 변수를 출력하는 것이 아니라 스스로 출력하도록 변수에게 알려주면 된다. 이러한 신기한 프로그래밍 방법이 실제로는 아주 자연스런 프로그래밍 방법이다.
printf()은 C에서 사용하는 출력함수이고 cout은 C++에서 사용하는 출력객체이다.
cout은 printf() 보다 사용하기 더 간편하다.
아래의 문장을 보자.
cout<< "Hello C++";
이 문장은 화면에 "Hello C++"이라고 출력한다.
<<은 좌측-쉬프트의 비트 연산자이지만 출력을 위해서도 사용된다.
얼마간, cout를 화면(출력 장치)으로 생각하자. 위의 문장은 "Hello C++"를 화면으로 보내라는 명령이라고 생각하면 된다.
화면이나 다른 출력장치 | << " Hello C++ " |
예제 | ☞ | cout으로 출력 |
#include
#include
void main(){
clrscr();
int i=10;
cout<< "Hello C++";
cout<< "n";
cout<< i;
cout<< "n";
cout<< "End";
}
예제 | ☞ | cout으로 출력2 |
#include
#include
void main(){
clrscr();
int i=65;
float f=1.2345;
double d=-1234.56789;
cout<< "int i is:" << i << "n";
cout<< "float f is:"<< f << "n";
cout<< "double d is:"<< d << "n";
getch();
}
scanf()함수를 대체한 객체이다.
cout을 하면으로 생각할 수 있듯이 cin은 키보드라고 할수 있다. 키보드로부터 입력을 받을 때 사용한다. 아래의 문장을 보자.
cin >> a;
키보드로부터 변수 a에 값을 입력받는다.
키보드 | >> a |
예제 | ☞ | cin으로 입력 |
#include
#include
void main(){
clrscr();
int a;
cout <<"What is the number: ";
cin >> a;
cout << "nnThe number is " << a;
getch();
}
cerr은 에러 메시지를 보낼 때 사용된다. cerr은 버퍼를 사용하지 않고 바로 출력하여 사용자가 에러 메시지를 바로 볼 수 있게 해준다.
예제 | ☞ | cerr으로 에러메시지 보내기 |
// 나눗셈 예제
#include
#include
void main(){
clrscr();
int a=10;
int b;
cout <<"What is the number: ";
cin >> b;
if (a==0)
cerr << "Worng number"; // 0으로 나눌 수 없으므로 에러 메시지를 출력
else
cout << "a / b is " << a/b;
getch();
}
혼자 해보기1 | |
국어, 영어, 수학 점수를 입력받아 평균을 구하여 출력하는 프로그램을 작성하라. |
혼자 해보기2 | |
혼자 해보기1에서 에러 메시지를 출력하는 코드를 추가해 보자. |
입력하거나 출력하는 데이터를 스트림(stream)이라고 하고 이런 조작기들을 스트림 조작기(stream manipulators)라고 한다.
[표] I/O 스트림 조작기 | |
조작기 | 설명 |
dec hex oct endl ends flush setbase(int n) resetiosflags(long f) setiosflags(long f) setfill(int c) setprecision(int n) setw(int n) | 10진수 전환 베이스를 설정한다. 16진수 전환 베이스를 설정한다. 8진수 전환 베이스를 설정한다. 개행문자('n')를 삽입하고 스트림 내용을 지운다. 문자열에 널 문자를 삽입한다. 출력 스트림의 내용을 지운다. n진수로 전환 설정한다. 형식 플래그인 f.f에 의해 지정된 형식을 지운다. 형식 플래그인 f.f에 의해 지정된 형식을 설정한다. c로 채우기 문자를 설정한다. n으로 부동 소수점 유효자리를 설정한다. n으로 필드 폭을 설정한다. |
[표] resetiosflags()와 setiosflags()를 위한 형식 플래그 값. | |
형식 플래그 이름 | 설명 |
ios::left ios::right ios::scientific ios::fixed ios::dec ios::hex ios::oct ios::uppercase ios::showbase ios::showpos ios::showpoint | setw() 폭 안에 출력을 좌측 정돈한다. setw() 폭 안에 출력을 우측 정돈한다. 과학용 표기로 출력을 형식 지정한다. 10진수 형식으로 숫자를 형식 지정한다. 10진수로 숫자를 형식 지정한다. 16진수로 숫자를 형식 지정한다. 8진수로 숫자를 형식 지정한다. 16진수와 과학용 표기의 문자를 대문자로 형식 지정한다. ( 0x123을 0X123으로, 2.34e+05를 2.34E+05로 ) 수치 베이스 접두 문자를 출력한다.( 16진수의 0x나 8진수의 0 ) 양수를 출력할 때 플러스 부호, +를 출력한다. 정확도를 위해 필요하다면 끝의 0들을 표시한다. |
형식 플래그의 값들은 상수이다. 영역 지정 연산자(::)는 나중에 설명한다.
형식 플래그는 두 함수 resetiosflags()와 setiosflags()에서만 작동한다.
예제 | ☞ | 조작기 사용 |
#include
#include
#include
void main(){
int num=220;
clrscr();
cout << "The decimal num is " << num << "n"; // The decimal num is 220
cout << "The hexadecimal num is " << hex << num << "n";
// The hexadecimal num is dc
cout << "The octal num is " << setbase(8) << num << "n";
// The octal num is 334
cout << setbase(10);
cout << 12345 << "n"; // 12345
cout << setw(20) << 12345 << "n"; // ' 12345'
cout << setw(20) << setfill('*')<< 12345 << "n"; // ***************12345
cout << setiosflags(ios::left);
cout << setw(10) << 12345 << "n"; // 12345*****
cout << setiosflags(ios::hex) << 45 <<"n"; // 2d
cout << setiosflags(ios::hex | ios::uppercase) << 45 <<"n"; // 2D
getch();
}
cin은 공백을 무시한다. 공백을 포함하려면 cin.get()을 사용한다.
get(char *string, int length [, char terminator])
[]부분은 생략할 수 있다. 함수의 매개변수 생략은 오버로드함수에 가서 배우기로하고 그냥 넘어가자. terminator는 생략하면 'n'이 디폴트가 된다.
변수 string에 최대 length까지 받아들일 수 있으며 종료자를 만나면 중지한다.
예제 | ☞ | get()으로 문자열 받아들이기 |
#include
#include
#include
void main(){
char name[80];
clrscr();
cout << "What is your name? ";
cin.get(name,30);
cout << "your name is :" << name << endl;
getch();
}
get()은 입력버퍼에 개행문자를 남겨둔다. 따라서 get()을 두 번 사용하면 문제가 발생한다.
cout << "What is your name? ";
cin.get(name,30);
cout << "your name is :" << name <
cout << "What is your city? ";
cin.get(city,30);
cout << "your city is :" << city << endl;
city에는 아무것도 입력 받지 못한다. 사용자의 입력을 기다리지 않고 끝나버린다. 이유는 첫 번째 get()이 'n'을 남겨두고 두 번째 get()이 'n'을 읽어드린다. 따라서 city="" 이다.
이를 해결하는 방법은 getline()을 써는 것이다.
예제 | ☞ | getline()으로 두 번 읽기 |
#include
#include
#include
void main(){
char name[80], city[30];
clrscr();
cout << "What is your name? ";
cin.getline(name,80);
cout << "your name is :" << name <
cout << "What is your city? ";
cin.getline(city,30);
cout << "your city is :" << city << endl;
getch();
}
::(scope resolution operator)는 지역변수와 전역변수의 이름이 같을 때 전역변수를 사용한다고 C++에게 알려준다. 지역변수에 우선권을 갖는 전역변수를 원하면 변수 앞에 ::를 두면 된다. ::의 중요한 OOP적 사용은 나중에 보게 될 것이다.
예제 | ☞ | cout으로 출력 |
#include
#include
int a=10; //전역변수
void main(){
int a=20; //지역변수
clrscr();
cout << a<
cout << ::a<
getch();
}
const를 이용하여 프로그램 내에서 값을 변경하지 않도록 할 수 있다.
const float PI=3.141592;
const int NUM=123;
const는 만들면서 바로 초기화하여야 한다. 나중에 값을 바꾸려고 하면 에러가 발생한다.
NUM=100; <-- 에러 발생
함수에서 const 매개변수
int func( const int x){
명령
}
위의 함수에서 const int x를 주목하자. 매개변수가 const int 형이다.
그럼 매개변수로서 const가 와야 하는가?... 그런 의미가 아니라 func()내에서 x의 값을 변경할 수 없다는 의미이다.
아래의 문장은 오류가 없다.
int a=10;
func(a);
그러나 매개변수의 값을 바꿀려고 하면 에러가 난다.
int func2(const int x){
x=10; // 에러 발생
return 1;
}
inline 결과형 func( 매개변수 리스트 ){
명령
}
인라인 함수는 C에서 #define과 비슷한 역할을 한다.
인라인 함수는 실제로 함수 호출이 발생하는 않지만 함수가 호출되는 곳에서 라인속(inline)으로 코드가 복사된다. 따라서 호출시간이 절약되고 그만큼 빨라지게 되는 것이다.
Turbo c++은 인라인을 무시할 수도 있다. 인라인 함수가 8라인 이상이거나 for문이나 while 문 등의 반복문을 포함하면 인라인화 되지 않는다. 인라인 함수는 호출되는 곳에 코드가 복사되므로 inline이 많으면 실행파일의 크기가 크지는 단점이 있다.
void 포인트는 어떤 데이터 형도 가리킬 수 있는 포인트 변수이다.
void 포인트 | int | |
float | ||
double | ||
char |
void *vp;
int i=10;
char c='A';
vp=&i;
vp=&c;
void 포인트 변수 vp는 int형 변수를 가리킬 수 있고 char형 변수도 가리키고 있다.
그러나 역 참조할 때 void형은 형변환을 해주어야 한다.
int *b;
b= (int *)vp; // vp를 int형 포인트로 변환한다.
예제 | ☞ | void 포인트 사용 |
#include
#include
#include
void main(){
void *vp;
int i=20;
char c='A';
clrscr();
vp=&i;
cout << *(int *)vp << endl;
vp=&c;
cout << *(char *)vp << endl;
getch();
}